def setup(): """ Generates the Cryptosystem Parameters. """ G = EcGroup(nid=713) g = G.hash_to_point(b"g") hs = [G.hash_to_point(("h%s" % i).encode("utf8")) for i in range(4)] o = G.order() return (G, g, hs, o)
def BL_setup(Gid = 713): G = EcGroup(Gid) q = G.order() g = G.hash_to_point(b"g") h = G.hash_to_point(b"h") z = G.hash_to_point(b"z") hs = [G.hash_to_point(("h%s" % i).encode("utf-8")) for i in range(4)]#the number of generators we wish to compute return (G, q, g, h, z, hs)
def BL_setup(Gid=settings.SERVER_GID): # Parameters of the BL schemes G = EcGroup(Gid) q = G.order() g = G.hash_to_point(b"g") h = G.hash_to_point(b"h") z = G.hash_to_point(b"z") hs = [G.hash_to_point(("h%s" % i).encode("utf8")) for i in range(2)] # 2-> hs[0], hs[1] return (G, q, g, h, z, hs)
def BL_setup(Gid = 713): G = EcGroup(Gid) q = G.order() g = G.hash_to_point(b"g") h = G.hash_to_point(b"h") z = G.hash_to_point(b"z") hs = [G.hash_to_point(("h%s" % i).encode("utf-8")) for i in range(100)]#what is this return (G, q, g, h, z, hs)
def BL_setup(Gid=713): # Parameters of the BL schemes G = EcGroup(713) q = G.order() g = G.hash_to_point(b"g") h = G.hash_to_point(b"h") z = G.hash_to_point(b"z") hs = [G.hash_to_point(("h%s" % i).encode("utf8")) for i in range(100)] return (G, q, g, h, z, hs)
def setup(): """ Generates parameters for Commitments """ G = EcGroup() g = G.hash_to_point(b'g') h = G.hash_to_point(b'h') o = G.order() return (G, g, h, o)
def helper_function_reconstruct(self, t, n): Gq = EcGroup() p = Gq.order() g = Gq.generator() G = Gq.hash_to_point(b'G') params = (Gq, p, g, G) # Decide on a secret to be distributed m = p.from_binary(b'This is a test') # Initiate participants, and generate their key-pairs priv_keys = [] pub_keys = [] for i in range(n): (x_i, y_i) = pvss.helper_generate_key_pair(params) priv_keys.append(x_i) pub_keys.append(y_i) # Encrypt secret, create shares and proof (pub, proof) = pvss.gen_proof(params, t, n, m, pub_keys) # Decryption # Calculate what a correct decryption should be expected_decryption = m * g # Let participants decrypt their shares and generate proofs proved_decryptions = [ pvss.participant_decrypt_and_prove(params, x_i, enc_share) for (x_i, enc_share) in zip(priv_keys, pub['Y_list']) ] if pvss.batch_verify_correct_decryption( proved_decryptions, pub['Y_list'], pub_keys, p, G) is False: print("Verification of decryption failed") S_list = [S_i for (S_i, decrypt_proof) in proved_decryptions] return (expected_decryption, S_list, p)
def setup_ggm(nid = 713): """Generates the parameters for an EC group nid""" G = EcGroup(nid) g = G.hash_to_point(b"g") h = G.hash_to_point(b"h") o = G.order() return (G, g, h, o)
def setup_ggm(nid=713): """Generates the parameters for an EC group nid""" G = EcGroup(nid) g = G.hash_to_point(b"g") h = G.hash_to_point(b"h") o = G.order() return (G, g, h, o)
def setup(): """Generates the Cryptosystem Parameters.""" G = EcGroup(nid=713) g = G.hash_to_point(b"g") h = G.hash_to_point(b"h") o = G.order() return (G, g, h, o)
def setup(): """ generate all public parameters """ G = EcGroup() o = G.order() g = G.generator() h = G.hash_to_point("mac_ggm".encode("utf8")) return (G, o, g, h)
def setup(nid=713): """ generates cryptosystem parameters """ G = EcGroup(nid) g = G.generator() hs = [G.hash_to_point(("h%s" % i).encode("utf8")) for i in range(4)] o = G.order() return (G, g, hs, o)
def credential_setup(): """ Generates the parameters of the algebraic MAC scheme""" G = EcGroup() g = G.hash_to_point(b"g") h = G.hash_to_point(b"h") o = G.order() params = (G, g, h, o) return params
class CPSIClient: """ Client for a single set PSI """ def __init__(self, curve: int = EC_NID_DEFAULT): """ Constructor for the client of a single set PSI :param curve: NID of the elliptic curve to use. """ self.group = EcGroup(curve) def query(self, kwds: List[str]) -> Tuple[Bn, List[bytes]]: """ Generate a query from the keywords. :param kwds_ms: Multi set of keywords to be queried. :return: a query """ secret = self.group.order().random() query_enc = list() for kwd in kwds: kwd_pt = self.group.hash_to_point(kwd.encode(ENCODING_DEFAULT)) kwd_enc = secret * kwd_pt kwd_enc_bytes = kwd_enc.export() query_enc.append(kwd_enc_bytes) return (secret, query_enc) def compute_cardinality(self, secret: Bn, reply: List[bytes], published) -> int: """ Compute the cardinalyty of the intersection of sets between the reply to a query and the list of points published by the server. :param reply: reply from the server :param published: list of point published by the server :return: cardinalityof the intersection of sets """ secret_inv = secret.mod_inverse(self.group.order()) kwds = list() for kwd_h in reply: kwd_pt = EcPt.from_binary(kwd_h, self.group) kwd_pt_dec = secret_inv * kwd_pt kwd_bytes = kwd_pt_dec.export() kwds.append(kwd_bytes) # The intersection of the 2 sets is the number of matches. return len(set(kwds) & set(published))
def test_full(self): # Generate parameters (should be same in other parts of program) Gq = EcGroup() p = Gq.order() h = Gq.generator() G = Gq.hash_to_point(b'G') params = (Gq, p, G, h) # Decide on a secret to be distributed m = p.from_binary(b'This is a test') # Set (t,n)-threshold parameters n = 4 t = 3 # Initiate participants, and generate their key-pairs priv_keys = [] pub_keys = [] for i in range(n): (x_i, y_i) = pvss.helper_generate_key_pair(params) priv_keys.append(x_i) pub_keys.append(y_i) # Encrypt secret, create shares and proof (pub, proof) = pvss.gen_proof(params, t, n, m, pub_keys) # Prove generates shares validity print("Test verify") Y_list = pub['Y_list'] C_list = pub['C_list'] assert cpni.DLEQ_verify_list(p, h, pub_keys, C_list, Y_list, proof) is True # Decryption # Calculate what a correct decryption should be expected_decryption = m * G # Let participants decrypt their shares and generate proofs proved_decryptions = [ pvss.participant_decrypt_and_prove(params, x_i, enc_share) for (x_i, enc_share) in zip(priv_keys, pub['Y_list']) ] # Check participants proofs if pvss.batch_verify_correct_decryption( proved_decryptions, pub['Y_list'], pub_keys, p, G) is False: print("Verification of decryption failed") # Use participants decrypted shares to recreate secret S_list = [S_i for (S_i, decrypt_proof) in proved_decryptions] actual_decryption = pvss.decode(S_list[0:-1], [1, 2, 3], p) # Verify secret print("Test decrypt") assert expected_decryption == actual_decryption
class CPSIServer: """ Server for a single set PSI """ def __init__(self, curve: int = EC_NID_DEFAULT): """ Constructor for the server of a single set PSI :param curve: NID of the elliptic curve to use. :return: """ self.group = EcGroup(curve) def publish(self, kwds: List[str]) -> Tuple[Bn, List[bytes]]: """ Generate a list of points on the EC corresponding to a document's keywords. :param kwds: list of keywords in the document. :return: a list of points on the EC corresponding to a document's keywords """ secret = self.group.order().random() pub = list() for kwd in kwds: kwd_pt = self.group.hash_to_point(kwd.encode(ENCODING_DEFAULT)) kwd_enc = secret * kwd_pt kwd_enc_bytes = kwd_enc.export() pub.append(kwd_enc_bytes) return (secret, pub) def reply(self, secret: Bn, query: List[bytes]) -> List[bytes]: """ Compute a reply to a query. :param query: Query to be answered. :return: reply to the query """ reply = list() for kwd_h in query: kwd_pt = EcPt.from_binary(kwd_h, self.group) kwd_enc = secret * kwd_pt kwd_enc_bytes = kwd_enc.export() reply.append(kwd_enc_bytes) return reply
def __call__(self, a, b, x=None): """ Get a conjunction of two range-power-of-two proofs. Args: a: Lower limit :math:`a` b: Upper limit :math:`b` x: Value for which we construct a range proof """ group = EcGroup() g = group.hash_to_point(b"g") h = group.hash_to_point(b"h") r = Secret(value=group.order().random()) com = (x * g + r * h).eval() a = ensure_bn(a) b = ensure_bn(b) num_bits = (b - a - 1).num_bits() offset = Bn(2)**num_bits - (b - a) com_shifted1 = com - a * g com_shifted2 = com_shifted1 + offset * g x1 = Secret() x2 = Secret() if x is not None: x1.value = x.value - a x2.value = x.value - a + offset com_stmt = DLRep(com, x * g + r * h) p1 = PowerTwoRangeStmt( com=com_shifted1, g=g, h=h, num_bits=num_bits, x=x1, randomizer=r, ) p2 = PowerTwoRangeStmt( com=com_shifted2, g=g, h=h, num_bits=num_bits, x=x2, randomizer=r, ) return com_stmt & p1 & p2
class MSPSIServer: """ Server for a multi set PSI """ def __init__(self, curve: int = EC_NID_DEFAULT): """ Constructor for the server of a multi set PSI :param curve: NID of the elliptic curve to use. """ self.group = EcGroup(curve) @staticmethod def published_len(published: CuckooFilter) -> int: """ Compute the size of a given published data. :param published: published data """ published_data = published[1] capacity = published_data.capacity bucket_size = published_data.bucket_size return capacity * bucket_size def publish(self, docs: List[List[str]]) -> Tuple[Bn, Tuple[int, CuckooFilter]]: """ Generate a list of lists of points on the EC corresponding to a document's keywords. :param docs: a list of list of keywords for each document. :return: a secret with wich the keywords were encrypted and a cuckoo filter containing the encrypted keywords. """ cuckoo_capacity = 0 for kwds in docs: cuckoo_capacity += len(kwds) cuckoo_capacity *= CUCKOO_FILTER_CAPACITY_FRACTION # Ensure some minimal capacity on filter cuckoo_capacity = max(CUCKOO_FILTER_CAPACITY_MIN, int(cuckoo_capacity)) secret = self.group.order().random() pub = CuckooFilter(capacity=cuckoo_capacity, bucket_size=CUCKOO_FILTER_BUCKET_SIZE, fingerprint_size=CUCKOO_FILTER_FINGERPRINT_SIZE) for doc_id, kwds in enumerate(docs): encoded_doc_id = doc_id.to_bytes(DOC_ID_SIZE, byteorder="big") for kwd in kwds: kwd_pt = self.group.hash_to_point(kwd.encode(ENCODING_DEFAULT)) kwd_enc = secret * kwd_pt kwd_enc_bytes = kwd_enc.export() kwd_docid_bytes = kwd_encode(encoded_doc_id, kwd_enc_bytes) pub.insert(kwd_docid_bytes) return (secret, (len(docs), pub)) def reply(self, secret: Bn, query: List[bytes]) -> List[Bn]: """ Compute a reply to a query. :param secret: secret with which the keywords were encrypted during the publication :param query: query to be answered :return: reply to the query """ reply = list() for kwd_h in query: kwd_pt = EcPt.from_binary(kwd_h, self.group) kwd_enc = secret * kwd_pt kwd_enc_bytes = kwd_enc.export() reply.append(kwd_enc_bytes) return reply
from petlib.ec import EcGroup from zksk import Secret, DLRep group = EcGroup() # Create the base points on the curve. g0 = group.hash_to_point(b"one") g1 = group.hash_to_point(b"two") g2 = group.hash_to_point(b"three") # Preparing the secrets. # In practice, they probably should be big integers (petlib.bn.Bn) x0 = Secret(value=3) x1 = Secret(value=40) x2 = Secret(value=50) # Set up the proof statement. y0 = x0.value * g0 y1 = x1.value * g1 y2 = x2.value * g2 stmt = (DLRep(y0, x0 * g0) | DLRep(y1, x1 * g1)) & DLRep(y2, x2 * g2) # Execute the protocol. prover = stmt.get_prover() verifier = stmt.get_verifier() commitment = prover.commit() challenge = verifier.send_challenge(commitment) response = prover.compute_response(challenge) assert verifier.verify(response)
PK{ (x0, x1, x2): (Y0 = x0 * G0 + x1 * G1) & (Y1 = x1 * G1 + x2 * G2) } WARNING: if you update this file, update the line numbers in the documentation. """ from petlib.ec import EcGroup from zksk import Secret, DLRep from zksk.composition import AndProofStmt group = EcGroup() # Create the base points on the curve. g0 = group.generator() g1 = group.hash_to_point(b"one") g2 = group.hash_to_point(b"two") g3 = group.hash_to_point(b"three") # Preparing the secrets. # In practice, they probably should be big integers (petlib.bn.Bn) x0 = Secret() x1 = Secret() x2 = Secret() # Set up the proof statement. # First, compute the values, "left-hand side". y1 = 4 * g0 + 5 * g1 y2 = 4 * g2 + 7 * g3
def test_protocol(): # Parameters of the BL schemes G = EcGroup(713) q = G.order() g = G.hash_to_point(b"g") h = G.hash_to_point(b"h") z = G.hash_to_point(b"z") hs = [G.hash_to_point(("h%s" % i).encode("utf8")) for i in range(100)] # Inputs from user R = q.random() L1 = 10 L2 = 20 #age C = R * hs[0] + L1 * hs[1] + L2 * hs[2] m = b"Hello World!" # Inputs from the Issuer # TODO: check ZK on C x = q.random() y = x * g # Preparation rnd = q.random() z1 = C + rnd * g z2 = z + (-z1) ## Send: (rnd,) to user if rnd % q == 0: raise z1 = C + rnd * g gam = q.random() zet = gam * z zet1 = gam * z1 zet2 = zet + (-zet1) tau = q.random() eta = tau * z # Validation: Issuer u, r1p, r2p, cp = [q.random() for _ in range(4)] a = u * g a1p = r1p * g + cp * z1 a2p = r2p * h + cp * z2 ## Send(a, ap = (a1p, a2p)) # User side assert G.check_point(a) assert G.check_point(a1p) assert G.check_point(a2p) t1, t2, t3, t4, t5 = [q.random() for _ in range(5)] alph = a + t1 * g + t2 * y alph1 = gam * a1p + t3 * g + t4 * zet1 alph2 = gam * a2p + t5 * h + t4 * zet2 # Make epsilon H = [zet, zet1, alph, alph1, alph2, eta] Hstr = list(map(EcPt.export, H)) + [m] Hhex = b"|".join(map(b64encode, Hstr)) epsilon = Bn.from_binary(sha256(Hhex).digest()) % q e = epsilon.mod_sub(t2, q).mod_sub(t4, q) ## Send: (e,) to Issuer c = e.mod_sub(cp, q) r = u.mod_sub((c * x), q) ## Send: (c,r, cp, rp = (r1p, r2p)) to User ro = r.mod_add(t1, q) om = c.mod_add(t2, q) ro1p = (gam * r1p + t3) % q ro2p = (gam * r2p + t5) % q omp = (cp + t4) % q mu = (tau - omp * gam) % q signature = (m, zet, zet1, zet2, om, omp, ro, ro1p, ro2p) gam_hs = [gam * hsi for hsi in hs] zet1p = zet1 - L2 * gam_hs[2] # Check verification equation lhs = (om + omp) % q rhs_h = [zet, zet1p, ro * g + om * y, ro1p * g + omp * zet1p, ro2p * h + omp * zet2, ## problem mu * z + omp * zet] Hstr = list(map(EcPt.export, rhs_h)) + [m] Hhex = b"|".join(map(b64encode, Hstr)) rhs = Bn.from_binary(sha256(Hhex).digest()) % q # Check the (future) ZK proof assert zet == gam * z gam_hs = [gam * hsi for hsi in hs] gam_g = gam * g #assert rnd * gam_g + R * gam_hs[0] + L1 * gam_hs[1] + L2 * gam_hs[2] == zet1 assert rnd * gam_g + R * gam_hs[0] + L1 * gam_hs[1] == zet1 - L2 * gam_hs[2] print(rhs == lhs)
# Different way to define secrets. x = Secret() x = Secret(value=42) # If secret come with values, prover will get them. x = Secret(value=4, name="x") y = x.value * g stmt = DLRep(y, x * g) prover = stmt.get_prover() # Otherwise, a prover needs to have the values as a dictionary. x = Secret(name="x") value = 4 stmt = DLRep(value * g, x * g) prover = stmt.get_prover({x: value}) # Example of a bit more complex expression. x = Secret() y = Secret() g = group.hash_to_point(b"one") h = group.hash_to_point(b"two") expr = x * g + y * h # Expressions can be evaluated. x = Secret(value=5) expr = x * g expr.eval() # Evaluations can simplify definitions of proof statements. stmt = DLRep(expr.eval(), expr)
def pet_setup(): G = EcGroup() g = G.generator() hs = [G.hash_to_point(("h%s" % i).encode("utf8")) for i in range(4)] o = G.order() return (G, g, hs, o)
class MSPSIClient: """ Client for a multi set PSI """ def __init__(self, curve: int = EC_NID_DEFAULT): """ Constructor for the client of a multi set PSI :param curve: NID of the elliptic curve to use """ self.group = EcGroup(curve) def query(self, kwds: List[str]) -> Tuple[Bn, List[bytes]]: """ Generate a query from the keywords. :param kwds_ms: Multi set of keywords to be queried :return: a secret to generate the query and the query itself """ secret = self.group.order().random() query_enc = list() for kwd in kwds: kwd_pt = self.group.hash_to_point(kwd.encode(ENCODING_DEFAULT)) kwd_enc = secret * kwd_pt kwd_enc_bytes = kwd_enc.export() query_enc.append(kwd_enc_bytes) return (secret, query_enc) def compute_cardinalities( self, secret: Bn, reply: List[bytes], published: Tuple[int, CuckooFilter]) -> List[int]: """ Compute the cardinalyty of the intersection of sets between the reply to a query and the list of lists of points published by the server. :param secret: secret with which the query was encrypted :param reply: reply from the server :param published: list of lists of point published by the server :return: list of cardinalities for the intersection between the reply and each published list of points. """ n_docs = published[0] published_data = published[1] secret_inv = secret.mod_inverse(self.group.order()) cardinalities = [] # For optimisation the following assumptions are made # - all keywords in the query are different. # - all keywords in the document are different. kwds_dec = list() for kwd_h in reply: kwd_pt = EcPt.from_binary(kwd_h, self.group) kwd_pt_dec = secret_inv * kwd_pt kwd_bytes = kwd_pt_dec.export() kwds_dec.append(kwd_bytes) for doc_id in range(n_docs): n_matches = 0 encoded_doc_id = doc_id.to_bytes(DOC_ID_SIZE, byteorder="big") for kwd_dec in kwds_dec: kwd_docid_bytes = kwd_encode(encoded_doc_id, kwd_dec) if published_data.contains(kwd_docid_bytes): n_matches += 1 cardinalities.append(n_matches) return cardinalities
def test_protocol(): # Parameters of the BL schemes G = EcGroup(713) q = G.order() g = G.hash_to_point(b"g") h = G.hash_to_point(b"h") z = G.hash_to_point(b"z") hs = [G.hash_to_point(("h%s" % i).encode("utf8")) for i in range(100)] # Inputs from user R = q.random() L1 = 10 L2 = 20 C = R * hs[0] + L1 * hs[1] + L2 * hs[2] m = b"Hello World!" # Inputs from the Issuer # TODO: check ZK on C x = q.random() y = x * g # Preparation rnd = q.random() z1 = C + rnd * g z2 = z + (-z1) ## Send: (rnd,) to user if rnd % q == 0: raise z1 = C + rnd * g gam = q.random() zet = gam * z zet1 = gam * z1 zet2 = zet + (-zet1) tau = q.random() eta = tau * z # Validation: Issuer u, r1p, r2p, cp = [q.random() for _ in range(4)] a = u * g a1p = r1p * g + cp * z1 a2p = r2p * h + cp * z2 ## Send(a, ap = (a1p, a2p)) # User side assert G.check_point(a) assert G.check_point(a1p) assert G.check_point(a2p) t1, t2, t3, t4, t5 = [q.random() for _ in range(5)] alph = a + t1 * g + t2 * y alph1 = gam * a1p + t3 * g + t4 * zet1 alph2 = gam * a2p + t5 * h + t4 * zet2 # Make epsilon H = [zet, zet1, alph, alph1, alph2, eta] Hstr = list(map(EcPt.export, H)) + [m] Hhex = b"|".join(map(b64encode, Hstr)) epsilon = Bn.from_binary(sha256(Hhex).digest()) % q e = epsilon.mod_sub(t2, q).mod_sub(t4, q) ## Send: (e,) to Issuer c = e.mod_sub(cp, q) r = u.mod_sub((c * x), q) ## Send: (c,r, cp, rp = (r1p, r2p)) to User ro = r.mod_add(t1, q) om = c.mod_add(t2, q) ro1p = (gam * r1p + t3) % q ro2p = (gam * r2p + t5) % q omp = (cp + t4) % q mu = (tau - omp * gam) % q signature = (m, zet, zet1, zet2, om, omp, ro, ro1p, ro2p) # Check verification equation lhs = (om + omp) % q rhs_h = [ zet, zet1, ro * g + om * y, ro1p * g + omp * zet1, ro2p * h + omp * zet2, ## problem mu * z + omp * zet ] Hstr = list(map(EcPt.export, rhs_h)) + [m] Hhex = b"|".join(map(b64encode, Hstr)) rhs = Bn.from_binary(sha256(Hhex).digest()) % q # Check the (future) ZK proof assert zet == gam * z gam_hs = [gam * hsi for hsi in hs] gam_g = gam * g assert rnd * gam_g + R * gam_hs[0] + L1 * gam_hs[1] + L2 * gam_hs[2] == zet1 print(rhs == lhs)
""" Proof of knowledge of two discrete logarithms: PK{ (x0, x1): y = x0 * g0 + x1 * g1 } WARNING: if you update this file, update the line numbers in the documentation. """ from petlib.ec import EcGroup from zksk import Secret, DLRep group = EcGroup() # Create the base points on the curve. g0 = group.hash_to_point(b"g0") g1 = group.hash_to_point(b"g1") # Preparing the secrets. # In practice, they probably should be big integers (petlib.bn.Bn) x0 = Secret() x1 = Secret() # Set up the proof statement. # First, compute the value, "left-hand side". y = 4 * g0 + 42 * g1 # Next, create the proof statement. stmt = DLRep(y, x0 * g0 + x1 * g1) # Simulate the prover and the verifier interacting.
from petlib.ecdsa import do_ecdsa_sign, do_ecdsa_setup from hashlib import sha512 from genzkp import ZKProof, ZKEnv, ConstGen, Sec from itertools import chain from collections import defaultdict, Counter import binascii import json import uuid import random import qrcode G = EcGroup(934) order = G.order() h = G.generator() sleeve = "nothing_up_my_sleeve" g = G.hash_to_point(sleeve.encode('utf-8')) #secret!!! sig_key = order.random() kinv_rp = do_ecdsa_setup(G, sig_key) #not secret ver_key = sig_key * h def commit(a, r): return a * h + r * g def genRealCommitments(vote, k, R): real_commitment = commit(vote, R) rb = [order.random() for i in range(k)]