Multi input functional encryption library for python
pip install pymife
- (Selective Secure) DDH based scheme from https://eprint.iacr.org/2015/017.pdf
- (Selective Secure) LWE based scheme from https://eprint.iacr.org/2015/017.pdf
- (Adaptive Secure) Damgard based scheme from https://eprint.iacr.org/2015/608.pdf
- (Adaptive Secure) LWE based scheme from https://eprint.iacr.org/2015/608.pdf
- (Adaptive Secure) DDH based scheme from https://eprint.iacr.org/2016/440.pdf
- (Adaptive Secure) DDH based scheme from https://eprint.iacr.org/2018/206.pdf
- (Adaptive Secure) Damgard based scheme from https://eprint.iacr.org/2017/972.pdf
- (Adaptive Secure with Random Oracle) DDH based scheme from https://eprint.iacr.org/2017/989.pdf
- (Adaptive Secure) Damgard based scheme from https://eprint.iacr.org/2019/487.pdf, using Damgard single input
- (Adaptive Secure with Random Oracle) Decentralized DDH based scheme from https://eprint.iacr.org/2019/020.pdf
- The implementation of these schemes are not fully optimized and not peer-reviewed, recommended to only use for research / testing purpose.
- More schemes will be added in the future
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.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.
- https://eprint.iacr.org/2015/017.pdf
- https://eprint.iacr.org/2015/608.pdf
- https://eprint.iacr.org/2016/440.pdf
- https://eprint.iacr.org/2017/972.pdf
- https://eprint.iacr.org/2017/989.pdf
- https://eprint.iacr.org/2018/206.pdf
- https://eprint.iacr.org/2019/020.pdf
- https://eprint.iacr.org/2019/487.pdf
- https://github.com/fentec-project/CiFEr/blob/master/src/innerprod/simple/lwe.cr2html