Multi input functional encryption library for python
pip install pymife
from mife.single.selective.ddh import FeDDH
n = 10
x = [i for i in range(n)]
y = [i + 10 for i in range(n)]
key = FeDDH.generate(n)
c = FeDDH.encrypt(x, key)
sk = FeDDH.keygen(y, key)
m = FeDDH.decrypt(c, key.get_public_key(), sk, (0, 1000))
from mife.single.selective.lwe import FeLWE
n = 10
x = [i - 10 for i in range(n)]
y = [i for i in range(n)]
key = FeLWE.generate(n, 4, 4)
c = FeLWE.encrypt(x, key)
sk = FeLWE.keygen(y, key)
m = FeLWE.decrypt(c, key.get_public_key(), sk) % key.p
from mife.single.damgard import FeDamgard
n = 10
x = [i for i in range(n)]
y = [i + 10 for i in range(n)]
key = FeDamgard.generate(n)
c = FeDamgard.encrypt(x, key)
sk = FeDamgard.keygen(y, key)
m = FeDamgard.decrypt(c, key.get_public_key(), sk, (0, 1000))
from mife.single.lwe import FeLWE
n = 10
x = [i - 10 for i in range(n)]
y = [i for i in range(n)]
key = FeLWE.generate(n, 4, 4)
c = FeLWE.encrypt(x, key)
sk = FeLWE.keygen(y, key)
m = FeLWE.decrypt(c, key.get_public_key(), sk)
from mife.single.fhiding.ddh import FeDDH
n = 4
x = [i for i in range(n)]
y = [i + 10 for i in range(n)]
key = FeDDH.generate(n)
c = FeDDH.encrypt(x, key)
sk = FeDDH.keygen(y, key)
m = FeDDH.decrypt(c, key.get_public_key(), sk, (0, 1000))
from mife.single.quadratic.ddh import FeDDH
n = 2
x = [i + 2 for i in range(n)]
y = [i + 3 for i in range(n)]
f = [[i + j + 1 for j in range(n)] for i in range(n)]
key = FeDDH.generate(n)
c = FeDDH.encrypt(x, y, key)
sk = FeDDH.keygen(f, key)
m = FeDDH.decrypt(c, key.get_public_key(), sk, (0, 1000))
from mife.multi.damgard import FeDamgardMulti
n = 3
m = 5
x = [[i + j for j in range(m)] for i in range(n)]
y = [[i - j + 10 for j in range(m)] for i in range(n)]
key = FeDamgardMulti.generate(n, m)
cs = [FeDamgardMulti.encrypt(x[i], key.get_enc_key(i)) for i in range(n)]
sk = FeDamgardMulti.keygen(y, key)
m = FeDamgardMulti.decrypt(cs, key.get_public_key(), sk, (0, 2000))
Using Curve25519
from mife.multi.damgard import FeDamgardMulti
from mife.data.curve25519 import Curve25519
n = 25
m = 25
x = [[i * 10 + j for j in range(m)] for i in range(n)]
y = [[i - j - 5 for j in range(m)] for i in range(n)]
key = FeDamgardMulti.generate(n, m, Curve25519)
cs = [FeDamgardMulti.encrypt(x[i], key.get_enc_key(i)) for i in range(n)]
sk = FeDamgardMulti.keygen(y, key)
res = FeDamgardMulti.decrypt(cs, key.get_public_key(), sk, (-10000000, 10000000))
Using P256 from fastecdsa
from mife.multi.damgard import FeDamgardMulti
from mife.data.fastecdsa_wrapper import WrapCurve
from fastecdsa.curve import P256
n = 25
m = 25
x = [[i * 10 + j for j in range(m)] for i in range(n)]
y = [[i - j - 5 for j in range(m)] for i in range(n)]
key = FeDamgardMulti.generate(n, m, WrapCurve(P256))
cs = [FeDamgardMulti.encrypt(x[i], key.get_enc_key(i)) for i in range(n)]
sk = FeDamgardMulti.keygen(y, key)
res = FeDamgardMulti.decrypt(cs, key.get_public_key(), sk, (-10000000, 10000000))
from mife.multiclient.rom.ddh import FeDDHMultiClient
n = 3
m = 5
x = [[i + j for j in range(m)] for i in range(n)]
y = [[i - j + 10 for j in range(m)] for i in range(n)]
tag = b"testingtag123"
key = FeDDHMultiClient.generate(n, m)
cs = [FeDDHMultiClient.encrypt(x[i], tag, key.get_enc_key(i)) for i in range(n)]
sk = FeDDHMultiClient.keygen(y, key)
m = FeDDHMultiClient.decrypt(cs, tag, key.get_public_key(), sk, (0, 2000))
from mife.multiclient.damgard import FeDamgardMultiClient
n = 3
m = 5
x = [[i + j for j in range(m)] for i in range(n)]
y = [[i - j + 10 for j in range(m)] for i in range(n)]
tag = b"testingtag123"
key = FeDamgardMultiClient.generate(n, m)
cs = [FeDamgardMultiClient.encrypt(x[i], tag, key.get_enc_key(i), key.get_public_key()) for i in range(n)]
sk = FeDamgardMultiClient.keygen(y, key)
m = FeDamgardMultiClient.decrypt(cs, key.get_public_key(), sk, (0, 2000))
from mife.multiclient.decentralized.ddh import FeDDHMultiClientDec
n = 3
m = 5
x = [[i + j for j in range(m)] for i in range(n)]
y = [[i - j + 10 for j in range(m)] for i in range(n)]
tag = b"testingtag123"
pub = FeDDHMultiClientDec.generate(n, m)
keys = [pub.generate_party(i) for i in range(n)]
for i in range(n):
for j in range(n):
if i == j: continue
keys[i].exchange(j, keys[j].get_exc_public_key())
for i in range(n):
keys[i].generate_share()
cs = [FeDDHMultiClientDec.encrypt(x[i], tag, keys[i]) for i in range(n)]
sk = [FeDDHMultiClientDec.keygen(y, keys[i]) for i in range(n)]
m = FeDDHMultiClientDec.decrypt(cs, tag, pub, sk, (0, 2000))
from mife.multiclient.decentralized.palia import Palia
n = 3
m = 5
x = [[i + j for j in range(m)] for i in range(n)]
y = [[i - j + 10 for j in range(m)] for i in range(n)]
tag = b"testingtag123"
pub = Palia.generate(n, m)
keys = [pub.generate_party(i) for i in range(n)]
for i in range(n):
for j in range(n):
if i == j: continue
keys[i].exchange(j, keys[j].get_exc_public_key())
for i in range(n):
keys[i].generate_share()
mk = Palia.generate_query_key(pub)
pk = mk.getPublicKey()
enc_y = Palia.encrypt_query(y, pk, pub)
cs = [Palia.encrypt(x[i], tag, keys[i]) for i in range(n)]
sk = [Palia.keygen(enc_y, keys[i]) for i in range(n)]
m = Palia.decrypt(cs, tag, pub, sk, y, mk, (0, 2000))
from mife.multiclient.rom.ddh import FeDDHMultiClient
import json
n = 3
m = 5
x = [[i + j for j in range(m)] for i in range(n)]
y = [[i - j + 10 for j in range(m)] for i in range(n)]
tag = b"testingtag123"
key = FeDDHMultiClient.generate(n, m)
cs = [FeDDHMultiClient.encrypt(x[i], tag, key.get_enc_key(i)) for i in range(n)]
sk = FeDDHMultiClient.keygen(y, key)
print(f"enc_key = {json.dumps([key.get_enc_key(i).export() for i in range(n)])}")
print(f"msk = {json.dumps(key.export())}")
print(f"ct = {[json.dumps(cs[i].export()) for i in range(n)]}")
print(f"secret_key = {json.dumps(sk.export())}")
print(f"pub_key = {json.dumps(key.get_public_key().export())}")
All of the DDH and Damgard schemes support custom group. You can implement your own group class by extending /src/mife/data/group.py
as base class.
To use custom group, simply pass the group class to the generate
function.
This library has implemented prime order group and curve25519 group.
For Random Oracle Model MCFE-DDH scheme, you can also supply your own hash function by using the same signature as the default hash function found in /src/mife/multiclient/ddh.py
.
For Function Hiding and Quadratic scheme, you can supply your own pairing group better efficiency.