def test_fails(): G, priv_dec, pub_enc = dh_get_key() message = u"Hello World!" ciphertext = dh_encrypt(pub_enc, message) iv, real_ciphertext, tag, pub_enc = ciphertext # Test for random iv with raises(Exception) as excinfo: rand_iv = urandom(16), real_ciphertext, tag, pub_enc dh_decrypt(priv_dec, rand_iv) assert 'decryption failed' in str(excinfo.value) # Test for random tag with raises(Exception) as excinfo: rand_tag = iv, real_ciphertext, urandom(16), pub_enc dh_decrypt(priv_dec, rand_tag) assert 'decryption failed' in str(excinfo.value) # Test for random public key with raises(Exception) as excinfo: G = EcGroup() rand_dec = G.order().random() rand_p = rand_dec * G.generator() rand_pub = iv, real_ciphertext, tag, rand_p dh_decrypt(priv_dec, rand_pub) assert 'decryption failed' in str(excinfo.value) # Test for a random private_key with raises(Exception) as excinfo: dh_decrypt(EcGroup().order().random(), ciphertext) assert 'decryption failed' in str(excinfo.value)
def time_scalar_mul(): # setup curve G = EcGroup(713) # NIST curve d = G.parameters() a, b, p = d["a"], d["b"], d["p"] g = G.generator() gx0, gy0 = g.get_affine() order = G.order() r = order.random() gx2, gy2 = (r * g).get_affine() # First a value with low hamming weight scalar_1 = Bn.from_hex('11111111111111111111111111111111111111111') # The second scalar value with a much higher hamming weight scalar_2 = Bn.from_hex('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF') # Scalar values with higher hamming weight will take longer to # compute the multiplication of. t1 = time.clock() x2, y2 = point_scalar_multiplication_double_and_add( a, b, p, gx0, gy0, scalar_1) t2 = time.clock() runtime = t2 - t1 print("Runtime for scalar 1: " + str(runtime)) t1 = time.clock() x2, y2 = point_scalar_multiplication_double_and_add( a, b, p, gx0, gy0, scalar_2) t2 = time.clock() runtime = t2 - t1 print("Runtime for scalar 2: " + str(runtime))
def setup(): ''' Setup the parameters of the mix crypto-system ''' group = EcGroup() order = group.order() generator = group.generator() o_bytes = int(math.ceil(math.log(float(int(order))) / math.log(256))) return group, order, generator, o_bytes
def dh_get_key(): """ Generate a DH key pair """ G = EcGroup() priv_dec = G.order().random() pub_enc = priv_dec * G.generator() return (G, priv_dec, pub_enc)
def mix_client_n_hop(public_keys, address, message): """ Encode a message to travel through a sequence of mixes with a sequence public keys. The maximum size of the final address and the message are 256 bytes and 1000 bytes respectively. Returns an 'NHopMixMessage' with four parts: a public key, a list of hmacs (20 bytes each), an address ciphertext (256 + 2 bytes) and a message ciphertext (1002 bytes). """ G = EcGroup() # assert G.check_point(public_key) assert isinstance(address, bytes) and len(address) <= 256 assert isinstance(message, bytes) and len(message) <= 1000 # Encode the address and message # use those encoded values as the payload you encrypt! address_plaintext = pack("!H256s", len(address), address) message_plaintext = pack("!H1000s", len(message), message) ## Generate a fresh public key private_key = G.order().random() client_public_key = private_key * G.generator() ## ADD CODE HERE return NHopMixMessage(client_public_key, hmacs, address_cipher, message_cipher)
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 test_Point_scalar_mult_montgomerry_ladder(): """ Test the scalar multiplication using double and add. """ from pytest import raises from petlib.ec import EcGroup, EcPt G = EcGroup(713) # NIST curve d = G.parameters() a, b, p = d["a"], d["b"], d["p"] g = G.generator() gx0, gy0 = g.get_affine() r = G.order().random() gx2, gy2 = (r * g).get_affine() from Lab01Code import is_point_on_curve from Lab01Code import point_scalar_multiplication_montgomerry_ladder x2, y2 = point_scalar_multiplication_montgomerry_ladder( a, b, p, gx0, gy0, r) assert is_point_on_curve(a, b, p, x2, y2) assert gx2 == x2 assert gy2 == y2
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 test_steady(): G = EcGroup() g = G.generator() x = G.order().random() pki = {"me": (x * g, x * g)} client = KulanClient(G, "me", x, pki) ## Mock some keys client.Ks += [bytes(urandom(16))] # Decrypt a small message ciphertext = client.steady_encrypt(b"Hello World!") client.steady_decrypt(ciphertext) # Decrypt a big message ciphertext = client.steady_encrypt(b"Hello World!" * 10000) client.steady_decrypt(ciphertext) # decrypt an empty string ciphertext = client.steady_encrypt(b"") client.steady_decrypt(ciphertext) # Time it import time t0 = time.clock() for _ in range(1000): ciphertext = client.steady_encrypt(b"Hello World!" * 10) client.steady_decrypt(ciphertext) t = time.clock() - t0 print() print(" - %2.2f operations / sec" % (1.0 / (t / 1000)))
def Ct_dec_unit_test(): try: G = EcGroup() x_1 = G.order().random() y_1 = x_1 * G.generator() x_2 = G.order().random() y_2 = x_2 * G.generator() x_3 = G.order().random() y_3 = x_3 * G.generator() # E1 = Ct.enc(y_1 + y_2, 2) E = copy(E1) E.b = E1.partial_dec(x_1) # E3 = Ct.enc(y_1, 22) E4 = Ct.enc(y_2 + y_3, E3) E5 = copy(E4) E5.b = E4.partial_dec(x_1) return ((E.dec(x_2) == 2) and (E1.dec(x_1 + x_2) == 2) and (E5.dec(x_2 + x_3) == 22)) except Exception: return False
def measure_mix_and_decrypt_execution_times(num_ciphertexts_l, m_value=4, curve_nid=415, n_repetitions=1): """Measure the execution time for mix and decrypt operations.""" group = EcGroup(curve_nid) key_pair = elgamal.KeyPair(group) pk = key_pair.pk measures = list() for num_ciphertexts in num_ciphertexts_l: LOGGER.info("Running mix and decrypt with %d ctxts.", num_ciphertexts) ctxts = [ pk.encrypt(i * group.generator()) for i in range(num_ciphertexts) ] for _ in range(n_repetitions): mixnet_per_server = MixNetPerTeller(key_pair, pk, ctxts, m_value) proof_time = mixnet_per_server.time_mixing decryption_time = mixnet_per_server.time_decrypting measures.append([num_ciphertexts, proof_time, decryption_time]) return measures
def setup(): ''' Setup the parameters of the mix crypto-system ''' G = EcGroup() o = G.order() g = G.generator() o_bytes = int(math.ceil(math.log(float(int(o))) / math.log(256))) return G, o, g, o_bytes
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 test_gen_polynomial(self): Gq = EcGroup() p = Gq.order() px = pvss.gen_polynomial(3, 42, p) for pi in px: assert pi < p
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 test_Pedersen_Shorthand(): # Define an EC group G = EcGroup(713) order = G.order() ## Proof definitions zk = ZKProof(G) zk.g, zk.h = ConstGen, ConstGen zk.x, zk.o = Sec, Sec zk.Cxo = Gen zk.add_proof(zk.Cxo, zk.x * zk.g + zk.o * zk.h) print(zk.render_proof_statement()) # A concrete Pedersen commitment ec_g = G.generator() ec_h = order.random() * ec_g bn_x = order.random() bn_o = order.random() ec_Cxo = bn_x * ec_g + bn_o * ec_h env = ZKEnv(zk) env.g, env.h = ec_g, ec_h env.Cxo = ec_Cxo env.x = bn_x env.o = bn_o sig = zk.build_proof(env.get()) # Execute the verification env = ZKEnv(zk) env.g, env.h = ec_g, ec_h assert zk.verify_proof(env.get(), sig)
def test_Pedersen_Env(): # Define an EC group G = EcGroup(713) order = G.order() ## Proof definitions zk = ZKProof(G) g, h = zk.get(ConstGen, ["g", "h"]) x, o = zk.get(Sec, ["x", "o"]) Cxo = zk.get(Gen, "Cxo") zk.add_proof(Cxo, x*g + o*h) # A concrete Pedersen commitment ec_g = G.generator() ec_h = order.random() * ec_g bn_x = order.random() bn_o = order.random() ec_Cxo = bn_x * ec_g + bn_o * ec_h env = ZKEnv(zk) env.g, env.h = ec_g, ec_h env.Cxo = ec_Cxo env.x = bn_x env.o = bn_o sig = zk.build_proof(env.get()) # Execute the verification env = ZKEnv(zk) env.g, env.h = ec_g, ec_h assert zk.verify_proof(env.get(), sig)
def test_broad(): G = EcGroup() g = G.generator() x = G.order().random() a, puba = pair(G) b, pubb = pair(G) c, pubc = pair(G) a2, puba2 = pair(G) b2, pubb2 = pair(G) c2, pubc2 = pair(G) pki = {"a": (puba, puba2), "b": (pubb, pubb2), "c": (pubc, pubc2)} client = KulanClient(G, "me", x, pki) msgs = client.broadcast_encrypt(b"Hello!") pki2 = {"me": x * g, "b": (pubb, pubb2), "c": (pubc, pubc2)} dec_client = KulanClient(G, "a", a, pki2) dec_client.priv_enc = a2 dec_client.pub_enc = puba2 namex, keysx = dec_client.broadcast_decrypt(msgs) assert namex == "me"
def test_Point_doubling(): """ Test whether the EC point doubling is correct. """ from pytest import raises from petlib.ec import EcGroup, EcPt G = EcGroup(713) # NIST curve d = G.parameters() a, b, p = d["a"], d["b"], d["p"] g = G.generator() gx0, gy0 = g.get_affine() gx2, gy2 = (2 * g).get_affine() from Lab01Code import is_point_on_curve from Lab01Code import point_double x2, y2 = point_double(a, b, p, gx0, gy0) assert is_point_on_curve(a, b, p, x2, y2) assert x2 == gx2 and y2 == gy2 x2, y2 = point_double(a, b, p, None, None) assert is_point_on_curve(a, b, p, x2, y2) assert x2 == None and y2 == None
def verifyVotes(ver_d): G = EcGroup(int(ver_d['G'])) g = strToEcPt(ver_d['g'], G) h = strToEcPt(ver_d['h'], G) sleeve = ver_d['sleeve'] #verify construction of g from sleeve verifyParams(G, g, h, sleeve) #print(ver_d['receipts'][0]['voter_id']) #verify commitments for each vote for receipt in ver_d['receipts']: sortc = sorted(receipt['challenges']) proof_list = [] for sk in sortc: ktr = [] for cmt in receipt['challenges'][sk]['proof']: ktr.append(strToEcPt(cmt, G)) proof_list.append(ktr) #print(proof_list) verifyCommitment(strToEcPt(receipt['commitment_to_everything'], G), receipt['vote_commitment'], proof_list, receipt['rx'], G, h, g) verifyChallenge(receipt['challenges'], receipt['vote_commitment'], G, h, g) ver_d['receipts'].sort(key = lambda x: x['voter_id']) vote_commits = [strToEcPt(v['vote_commitment'], G) for v in ver_d['receipts']] #print(vote_commits) #verify proofs for proof in ver_d['proofs']: if proof['proof_type'] == 'unmask': verifyPermutation(list(map(lambda s: strToEcPt(s,G) , proof['pm_vote_commitments'].split(' '))), vote_commits, list(map(Bn.from_hex,proof['maskers'].split(' '))), list(map(int, proof['pi'].split(' '))), g) #print("ok") elif proof['proof_type'] == 'open': verifyMaskedCommitments(list(map(lambda s: strToEcPt(s,G), proof['pm_vote_commitments'].split(' '))), proof['comm_pairs'], ver_d['tally'], h, g) else: print("Unrecognized proof type: " + proof('type'))
def test_Alice_encode_15_hop(): """ Test sending a multi-hop message through 1-hop """ from os import urandom G = EcGroup() g = G.generator() o = G.order() private_keys = [o.random() for _ in range(15)] public_keys = [pk * g for pk in private_keys] address = b"Alice" message = b"Dear Alice,\nHello!\nBob" m1 = mix_client_n_hop(public_keys, address, message) out = mix_server_n_hop(private_keys[0], [m1]) for i in range(13): out = mix_server_n_hop(private_keys[i + 1], out) out = mix_server_n_hop(private_keys[14], out, final=True) assert len(out) == 1 assert out[0][0] == address assert out[0][1] == message
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 mix_client_one_hop(public_key, address, message): """ Encode a message to travel through a single mix with a set public key. The maximum size of the final address and the message are 256 bytes and 1000 bytes respectively. Returns an 'OneHopMixMessage' with four parts: a public key, an hmac (20 bytes), an address ciphertext (256 + 2 bytes) and a message ciphertext (1002 bytes). """ G = EcGroup() assert G.check_point(public_key) assert isinstance(address, bytes) and len(address) <= 256 assert isinstance(message, bytes) and len(message) <= 1000 # Encode the address and message # Use those as the payload for encryption address_plaintext = pack("!H256s", len(address), address) message_plaintext = pack("!H1000s", len(message), message) ## Generate a fresh public key private_key = G.order().random() client_public_key = private_key * G.generator() ## ADD CODE HERE return OneHopMixMessage(client_public_key, expected_mac, address_cipher, message_cipher)
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") hs = [G.hash_to_point(("h%s" % i).encode("utf8")) for i in range(4)] o = G.order() return (G, g, hs, o)
def _make_table(start=conf.LOWER_LIMIT, end=conf.UPPER_LIMIT): G = EcGroup(nid=713) g = G.generator() o = G.order() i_table = {} n_table = {} ix = start * g trunc_limit = conf.TRUNC_LIMIT for i in range(start, end): #i_table[str(ix)] = str(i) #Uncompressed #Compression trick trunc_ix = str(ix)[:trunc_limit] #print ix #print trunc_ix if trunc_ix in i_table: i_table[trunc_ix] = i_table[trunc_ix] + "," + str(i) else: i_table[trunc_ix] = str(i) n_table[str((o + i) % o)] = str(ix) ix = ix + g #print type(ix) #print type(ix.export()) print "size: " + str(len(i_table)) return i_table, n_table
def execute_Alice_encode_hop(hops, use_blinding_factor=False): """ Test sending a multi-hop message through 1-hop """ from os import urandom G = EcGroup() g = G.generator() o = G.order() private_keys = [o.random() for _ in range(hops)] public_keys = [pk * g for pk in private_keys] address = b"Alice" message = b"Dear Alice,\nHello!\nBob" # Execute the encoding with the client implementation m1 = mix_client_n_hop(public_keys, address, message, use_blinding_factor) # Walk through the hops with the server implementation out = [m1] for hop in range(0, hops - 1): out = mix_server_n_hop(private_keys[hop], out, use_blinding_factor) out = mix_server_n_hop(private_keys[hops - 1], out, use_blinding_factor, final=True) # Check the result assert len(out) == 1 assert out[0][0] == address assert out[0][1] == message
def test_Pedersen(): # Define an EC group G = EcGroup(713) order = G.order() ## Proof definitions zk = ZKProof(G) g, h = zk.get(ConstGen, ["g", "h"]) x, o = zk.get(Sec, ["x", "o"]) Cxo = zk.get(Gen, "Cxo") zk.add_proof(Cxo, x * g + o * h) # A concrete Pedersen commitment ec_g = G.generator() ec_h = order.random() * ec_g bn_x = order.random() bn_o = order.random() ec_Cxo = bn_x * ec_g + bn_o * ec_h # Execute the proof env = {"g": ec_g, "h": ec_h, "Cxo": ec_Cxo, "x": bn_x, "o": bn_o} sig = zk.build_proof(env) # Execute the verification env_verify = {"g": ec_g, "h": ec_h} assert zk.verify_proof(env_verify, sig)
def ecdsa_key_gen(): """ Returns an EC group, a random private key for signing and the corresponding public key for verification""" G = EcGroup() priv_sign = G.order().random() pub_verify = priv_sign * G.generator() return (G, priv_sign, pub_verify)
def dh_decrypt(priv, ciphertext_and_pub, aliceVer=None): """ Decrypt a received message encrypted using your public key, of which the private key is provided. Optionally verify the message came from Alice using her verification key.""" G = EcGroup() # Ciphertext_and_pub should be a 5-tuple of iv, c, tag, public_key, signature shared_key = ciphertext_and_pub[3].pt_mul(priv) #change it to bits using export() shared_key = shared_key.export() ## decrypt_message(K, iv, ciphertext, tag): digest_of_key = sha256(shared_key).digest() # reduce size of hash digest_of_key = digest_of_key[:16] plaintext = decrypt_message(digest_of_key, ciphertext_and_pub[0], ciphertext_and_pub[1], ciphertext_and_pub[2]) if aliceVer is not None: result = ecdsa_verify(G, aliceVer, plaintext, ciphertext_and_pub[4]) if result == False: raise Exception("Signature not valid") else: result = None return (plaintext, result)