def grant(private_key, public_key, signer): kfrags = pre.split_rekey(delegating_privkey=private_key, signer=signer, receiving_pubkey=public_key, threshold=10, N=20) return kfrags
def test_correctness_proof_serialization(alices_keys): delegating_privkey, signing_privkey = alices_keys delegating_pubkey = delegating_privkey.get_pubkey() signer = Signer(signing_privkey) priv_key_bob = keys.UmbralPrivateKey.gen_key() pub_key_bob = priv_key_bob.get_pubkey() params = delegating_privkey.params _unused_key, capsule = pre._encapsulate(delegating_pubkey) kfrags = pre.split_rekey(delegating_privkey, signer, pub_key_bob, 1, 2) # Example of potential metadata to describe the re-encryption request metadata = b"This is an example of metadata for re-encryption request" cfrag = pre.reencrypt(kfrags[0], capsule, metadata=metadata) proof = cfrag.proof proof_bytes = proof.to_bytes() # A CorrectnessProof can be represented as # the 228 total bytes of four Points (33 each) and three BigNums (32 each). # TODO: Figure out final size for CorrectnessProofs # assert len(proof_bytes) == (33 * 4) + (32 * 3) == 228 new_proof = CorrectnessProof.from_bytes(proof_bytes) assert new_proof._point_e2 == proof._point_e2 assert new_proof._point_v2 == proof._point_v2 assert new_proof._point_kfrag_commitment == proof._point_kfrag_commitment assert new_proof._point_kfrag_pok == proof._point_kfrag_pok assert new_proof.bn_sig == proof.bn_sig assert new_proof.kfrag_signature == proof.kfrag_signature assert new_proof.metadata == proof.metadata
def test_cfrag_serialization_with_proof_but_no_metadata(alices_keys): priv_key_alice, pub_key_alice = alices_keys _unused_key, capsule = pre._encapsulate(pub_key_alice.point_key) kfrags = pre.split_rekey(priv_key_alice, pub_key_alice, 1, 2) cfrag = pre.reencrypt(kfrags[0], capsule, provide_proof=True) cfrag_bytes = cfrag.to_bytes() proof = cfrag.proof assert proof is not None assert proof.metadata is None # A CFrag can be represented as the 131 total bytes of three Points (33 each) and a CurveBN (32). # TODO: Figure out final size for CFrags with proofs #assert len(cfrag_bytes) == 33 + 33 + 33 + 32 == 131 new_cfrag = pre.CapsuleFrag.from_bytes(cfrag_bytes) assert new_cfrag._point_e1 == cfrag._point_e1 assert new_cfrag._point_v1 == cfrag._point_v1 assert new_cfrag._bn_kfrag_id == cfrag._bn_kfrag_id assert new_cfrag._point_noninteractive == cfrag._point_noninteractive new_proof = new_cfrag.proof assert new_proof is not None assert new_proof._point_e2 == proof._point_e2 assert new_proof._point_v2 == proof._point_v2 assert new_proof._point_kfrag_commitment == proof._point_kfrag_commitment assert new_proof._point_kfrag_pok == proof._point_kfrag_pok assert new_proof._bn_kfrag_sig1 == proof._bn_kfrag_sig1 assert new_proof._bn_kfrag_sig2 == proof._bn_kfrag_sig2 assert new_proof._bn_sig == proof._bn_sig assert new_proof.metadata is None
def test_alice_sends_fake_kfrag_to_ursula(N, M): priv_key_alice = keys.UmbralPrivateKey.gen_key() pub_key_alice = priv_key_alice.get_pubkey() priv_key_bob = keys.UmbralPrivateKey.gen_key() pub_key_bob = priv_key_bob.get_pubkey() plaintext = b'peace at dawn' ciphertext, capsule = pre.encrypt(pub_key_alice, plaintext) cleartext = pre.decrypt(capsule, priv_key_alice, ciphertext) assert cleartext == plaintext k_frags = pre.split_rekey(priv_key_alice, pub_key_bob, M, N) # Alice tries to frame the first Ursula by sending her a random kFrag k_frags[0].bn_key = BigNum.gen_rand() for k_frag in k_frags: c_frag = pre.reencrypt(k_frag, capsule) capsule.attach_cfrag(c_frag) with pytest.raises(Exception): _ = pre.decrypt(capsule, priv_key_bob, ciphertext, pub_key_alice)
def test_correctness_proof_serialization(): priv_key_alice = keys.UmbralPrivateKey.gen_key() pub_key_alice = priv_key_alice.get_pubkey() priv_key_bob = keys.UmbralPrivateKey.gen_key() pub_key_bob = priv_key_bob.get_pubkey() _unused_key, capsule = pre._encapsulate(pub_key_alice.point_key) kfrags = pre.split_rekey(priv_key_alice, pub_key_bob, 1, 2) # Example of potential metadata to describe the re-encryption request metadata = b"This is an example of metadata for re-encryption request" cfrag = pre.reencrypt(kfrags[0], capsule, metadata=metadata) capsule.attach_cfrag(cfrag) proof = cfrag.proof proof_bytes = proof.to_bytes() # A CorrectnessProof can be represented as # the 228 total bytes of four Points (33 each) and three BigNums (32 each). # TODO: Figure out final size for CorrectnessProofs # assert len(proof_bytes) == (33 * 4) + (32 * 3) == 228 new_proof = CorrectnessProof.from_bytes(proof_bytes) assert new_proof._point_e2 == proof._point_e2 assert new_proof._point_v2 == proof._point_v2 assert new_proof._point_kfrag_commitment == proof._point_kfrag_commitment assert new_proof._point_kfrag_pok == proof._point_kfrag_pok assert new_proof._bn_kfrag_sig1 == proof._bn_kfrag_sig1 assert new_proof._bn_kfrag_sig2 == proof._bn_kfrag_sig2 assert new_proof._bn_sig == proof._bn_sig assert new_proof.metadata == proof.metadata
def test_capsule_as_dict_key(alices_keys): priv_key_alice, pub_key_alice = alices_keys plain_data = b'peace at dawn' ciphertext, capsule = pre.encrypt(pub_key_alice, plain_data) # We can use the capsule as a key, and successfully lookup using it. some_dict = {capsule: "Thing that Bob wants to try per-Capsule"} assert some_dict[capsule] == "Thing that Bob wants to try per-Capsule" kfrags = pre.split_rekey(alices_keys.priv, alices_keys.pub, 1, 2) cfrag = pre.reencrypt(kfrags[0], capsule) capsule.attach_cfrag(cfrag) cfrag = pre.reencrypt(kfrags[1], capsule) capsule.attach_cfrag(cfrag) # Even if we activate the capsule, it still serves as the same key. cleartext = pre.decrypt(ciphertext, capsule, alices_keys.priv, alices_keys.pub) assert some_dict[capsule] == "Thing that Bob wants to try per-Capsule" assert cleartext == plain_data # And if we change the value for this key, all is still well. some_dict[capsule] = "Bob has changed his mind." assert some_dict[capsule] == "Bob has changed his mind." assert len(some_dict.keys()) == 1
def test_challenge_response_serialization(): priv_key = pre.gen_priv() pub_key = pre.priv2pub(priv_key) _unused_key, capsule = pre._encapsulate(pub_key) kfrags = pre.split_rekey(priv_key, pub_key, 1, 2) cfrag = pre.reencrypt(kfrags[0], capsule) capsule.attach_cfrag(cfrag) ch_resp = pre.challenge(kfrags[0], capsule, cfrag) ch_resp_bytes = ch_resp.to_bytes() # A ChallengeResponse can be represented as # the 228 total bytes of four Points (33 each) and three BigNums (32 each). assert len(ch_resp_bytes) == (33 * 4) + (32 * 3) == 228 new_ch_resp = pre.ChallengeResponse.from_bytes(ch_resp_bytes) assert new_ch_resp.point_eph_e2 == ch_resp.point_eph_e2 assert new_ch_resp.point_eph_v2 == ch_resp.point_eph_v2 assert new_ch_resp.point_kfrag_commitment == ch_resp.point_kfrag_commitment assert new_ch_resp.point_kfrag_pok == ch_resp.point_kfrag_pok assert new_ch_resp.bn_kfrag_sig1 == ch_resp.bn_kfrag_sig1 assert new_ch_resp.bn_kfrag_sig2 == ch_resp.bn_kfrag_sig2 assert new_ch_resp.bn_sig == ch_resp.bn_sig
def test_cheating_ursula_sends_garbage(N, M): priv_key_alice = keys.UmbralPrivateKey.gen_key() pub_key_alice = priv_key_alice.get_pubkey() # Bob priv_key_bob = keys.UmbralPrivateKey.gen_key() pub_key_bob = priv_key_bob.get_pubkey() sym_key, capsule_alice = pre._encapsulate(pub_key_alice.point_key) kfrags = pre.split_rekey(priv_key_alice, pub_key_bob, M, N) cfrags, metadata = [], [] for i, kfrag in enumerate(kfrags[:M]): # Example of potential metadata to describe the re-encryption request metadata_i = "This is an example of metadata for re-encryption request #{}" metadata_i = metadata_i.format(i).encode() cfrag = pre.reencrypt(kfrag, capsule_alice, metadata=metadata_i) capsule_alice.attach_cfrag(cfrag) cfrags.append(cfrag) # Let's put random garbage in one of the cfrags cfrags[0]._point_e1 = Point.gen_rand() cfrags[0]._point_v1 = Point.gen_rand() capsule_alice._reconstruct_shamirs_secret(pub_key_alice, priv_key_bob) # activate capsule with pytest.raises(pre.GenericUmbralError): _unused_key = pre._decapsulate_reencrypted(pub_key_bob.point_key, priv_key_bob.bn_key, pub_key_alice.point_key, capsule_alice) assert not pre._verify_correctness( capsule_alice, cfrags[0], pub_key_alice.point_key, pub_key_bob.point_key, ) # The response of cheating Ursula is in cfrags[0], # so the rest of CFrags chould be correct: for cfrag_i, metadata_i in zip(cfrags[1:], metadata[1:]): assert pre._verify_correctness( capsule_alice, cfrag_i, pub_key_alice.point_key, pub_key_bob.point_key, ) # Alternatively, we can try to open the capsule directly. # We should get an exception with an attached list of incorrect cfrags with pytest.raises(pre.UmbralCorrectnessError) as exception_info: _ = pre._open_capsule(capsule_alice, priv_key_bob, pub_key_alice) correctness_error = exception_info.value assert cfrags[0] in correctness_error.offending_cfrags assert len(correctness_error.offending_cfrags) == 1
def test_cheating_ursula_sends_garbage(N, M): priv_key_alice = keys.UmbralPrivateKey.gen_key() pub_key_alice = priv_key_alice.get_pubkey() # Bob priv_key_bob = keys.UmbralPrivateKey.gen_key() pub_key_bob = priv_key_bob.get_pubkey() sym_key, capsule_alice = pre._encapsulate(pub_key_alice.point_key) kfrags = pre.split_rekey(priv_key_alice, pub_key_bob, M, N) cfrags, challenges, metadata = [], [], [] for i, kfrag in enumerate(kfrags[:M]): cfrag = pre.reencrypt(kfrag, capsule_alice) # Example of potential metadata to describe the challenge request metadata_i = { 'ursula_id': i, 'timestamp': time.time(), 'capsule': bytes(capsule_alice), 'cfrag': bytes(cfrag) } metadata_i = str(metadata_i).encode() metadata.append(metadata_i) challenge = pre._challenge(kfrag, capsule_alice, cfrag, metadata_i) capsule_alice.attach_cfrag(cfrag) assert pre._check_challenge(capsule_alice, cfrag, challenge, pub_key_alice.point_key, pub_key_bob.point_key, metadata_i) cfrags.append(cfrag) challenges.append(challenge) # Let's put random garbage in one of the cfrags cfrags[0].point_eph_e1 = Point.gen_rand() cfrags[0].point_eph_v1 = Point.gen_rand() capsule_alice._reconstruct_shamirs_secret(pub_key_alice, priv_key_bob) # activate capsule with pytest.raises(pre.GenericUmbralError): sym_key2 = pre._decapsulate_reencrypted(pub_key_bob.point_key, priv_key_bob.bn_key, pub_key_alice.point_key, capsule_alice) assert not pre._check_challenge(capsule_alice, cfrags[0], challenges[0], pub_key_alice.point_key, pub_key_bob.point_key, metadata[0]) # The response of cheating Ursula is in capsules[0], # so the rest of challenges chould be correct: for i, challenge in enumerate(challenges[1:], 1): cfrag = cfrags[i] assert pre._check_challenge(capsule_alice, cfrag, challenge, pub_key_alice.point_key, pub_key_bob.point_key, metadata[i])
def test_cfrag_serialization_no_proof_no_metadata(alices_keys, bobs_keys): delegating_privkey, signing_privkey = alices_keys delegating_pubkey = delegating_privkey.get_pubkey() _receiving_privkey, receiving_pubkey = bobs_keys signer_alice = Signer(signing_privkey) _unused_key, capsule = pre._encapsulate(delegating_pubkey.point_key) kfrags = pre.split_rekey(delegating_privkey, signer_alice, receiving_pubkey, 1, 2) cfrag = pre.reencrypt(kfrags[0], capsule, provide_proof=False) cfrag_bytes = cfrag.to_bytes() proof = cfrag.proof assert proof is None curve = default_curve() assert len(cfrag_bytes) == CapsuleFrag.expected_bytes_length(curve) new_cfrag = pre.CapsuleFrag.from_bytes(cfrag_bytes) assert new_cfrag._point_e1 == cfrag._point_e1 assert new_cfrag._point_v1 == cfrag._point_v1 assert new_cfrag._kfrag_id == cfrag._kfrag_id assert new_cfrag._point_noninteractive == cfrag._point_noninteractive new_proof = new_cfrag.proof assert new_proof is None
def umbralize(): data = request.get_json() resp = {} sk_A = data['sk_A'] pk_B = data['pk_B'] M = data['M'] N = data['N'] sk_A = base64.b64decode(sk_A) sk_A = keys.UmbralPrivateKey.from_bytes(sk_A) pk_B = base64.b64decode(pk_B) pk_B = keys.UmbralPublicKey.from_bytes(pk_B) kfrags = pre.split_rekey(sk_A, pk_B, M, N) bytekfrags = [ base64.encodestring(bytes(kfrag)).decode('ascii') for kfrag in kfrags ] resp['bytekfrags'] = bytekfrags return jsonify(resp)
def test_decryption_fails_when_it_expects_a_proof_and_there_isnt(N, M, alices_keys, bobs_keys): """Manually injects umbralparameters for multi-curve testing.""" delegating_privkey, signing_privkey = alices_keys delegating_pubkey = delegating_privkey.get_pubkey() signer = Signer(signing_privkey) priv_key_bob, pub_key_bob = bobs_keys plain_data = b'peace at dawn' ciphertext, capsule = pre.encrypt(delegating_privkey.get_pubkey(), plain_data) kfrags = pre.split_rekey(delegating_privkey, signer, pub_key_bob, M, N) capsule.set_correctness_keys(delegating=delegating_privkey.get_pubkey(), receiving=pub_key_bob, verifying=signing_privkey.get_pubkey()) for kfrag in kfrags[:M]: cfrag = pre.reencrypt(kfrag, capsule) capsule.attach_cfrag(cfrag) # Even thought we can successfully attach a CFrag, if the proof is lost # (for example, it is chopped off a serialized CFrag or similar), then decrypt # will still fail. cfrag.proof = None with pytest.raises(cfrag.NoProofProvided): _cleartext = pre.decrypt(ciphertext, capsule, priv_key_bob)
def encrypt(): # Get data from request json_data = json.loads(request.data.decode('utf-8')) data = json_data["hash"].encode( 'utf-8') #, json_data['alice_pubkey'], json_data['alice_privkey'] alice_pubkey, alice_privkey = gen_alice() # Encrypt some data plaintext = data ciphertext, capsule = pre.encrypt(alice_pubkey, plaintext) alice_signing_privkey = keys.UmbralPrivateKey.gen_key() alice_signing_pubkey = alice_signing_privkey.get_pubkey() alice_signer = Signer(alice_signing_privkey) # Perform split-rekey and grant re-encryption policy alice_kfrags = pre.split_rekey(alice_privkey, alice_signer, bob_pubkey, 10, 20) policy_id = mock_kms.grant(alice_kfrags) alice_pubkey.from_bytes response = { "ciphertext": bytes_to_string(ciphertext), "policy_id": policy_id, "capsule": bytes_to_string(capsule.to_bytes()), "alice_pubkey": bytes_to_string(alice_pubkey.to_bytes()), "alice_signing_pubkey": bytes_to_string(alice_signing_pubkey.to_bytes()) } return jsonify(response)
def main(m, n, filenames): files = [open(filename, 'w') for filename in filenames] config.set_default_curve() alice_privkey = keys.UmbralPrivateKey.gen_key() alice_pubkey = alice_privkey.get_pubkey() bob_privkey = keys.UmbralPrivateKey.gen_key() bob_pubkey = bob_privkey.get_pubkey() mock_kms = MockNetwork() sys.stderr.write('Server with PID %s is ready to pipe messages.\n' % os.getpid()) for line in sys.stdin: ciphertext, capsule = pre.encrypt(alice_pubkey, line.rstrip('\n').encode('utf8')) alice_kfrags = pre.split_rekey(alice_privkey, bob_pubkey, m, n) policy_id = mock_kms.grant(alice_kfrags) bob_cfrags = mock_kms.reencrypt(policy_id, capsule, m) bob_capsule = capsule for cfrag in bob_cfrags: bob_capsule.attach_cfrag(cfrag) decrypted = pre.decrypt(ciphertext, bob_capsule, bob_privkey, alice_pubkey) for file in files: file.write('%s\n' % decrypted.decode('utf8')) file.flush() mock_kms.revoke(policy_id)
def test_m_of_n(N, M, alices_keys, bobs_keys): delegating_privkey, signing_privkey = alices_keys delegating_pubkey = delegating_privkey.get_pubkey() signer = Signer(signing_privkey) priv_key_bob, pub_key_bob = bobs_keys params = delegating_privkey.params sym_key, capsule = pre._encapsulate(delegating_pubkey) capsule.set_correctness_keys(delegating=delegating_privkey.get_pubkey(), receiving=pub_key_bob, verifying=signing_privkey.get_pubkey()) kfrags = pre.split_rekey(delegating_privkey, signer, pub_key_bob, M, N) for kfrag in kfrags: assert kfrag.verify(signing_privkey.get_pubkey(), delegating_privkey.get_pubkey(), pub_key_bob) for i, kfrag in enumerate(kfrags[:M]): # Example of potential metadata to describe the re-encryption request metadata = "This is an example of metadata for re-encryption request #{}" metadata = metadata.format(i).encode() cfrag = pre.reencrypt(kfrag, capsule, metadata=metadata) capsule.attach_cfrag(cfrag) assert cfrag.verify_correctness(capsule) sym_key_from_capsule = pre._open_capsule(capsule, priv_key_bob) assert sym_key == sym_key_from_capsule
def test_activated_capsule_serialization(): priv_key = pre.gen_priv() pub_key = pre.priv2pub(priv_key) _unused_key, capsule = pre._encapsulate(pub_key) kfrags = pre.split_rekey(priv_key, pub_key, 1, 2) cfrag = pre.reencrypt(kfrags[0], capsule) capsule.attach_cfrag(cfrag) capsule._reconstruct_shamirs_secret() rec_capsule_bytes = capsule.to_bytes() # An activated Capsule is: # three points, representable as 33 bytes each (the original), and # two points and a bignum (32 bytes) (the activated components), for 197 total. assert len(rec_capsule_bytes) == (33 * 3) + (33 + 33 + 32) new_rec_capsule = pre.Capsule.from_bytes(rec_capsule_bytes) # Again, the same three perspectives on equality. assert new_rec_capsule == capsule assert new_rec_capsule.activated_components( ) == capsule.activated_components() assert new_rec_capsule._point_eph_e_prime == capsule._point_eph_e_prime assert new_rec_capsule._point_eph_v_prime == capsule._point_eph_v_prime assert new_rec_capsule._point_noninteractive == capsule._point_noninteractive
def test_m_of_n(N, M, alices_keys, bobs_keys): priv_key_alice, pub_key_alice = alices_keys priv_key_bob, pub_key_bob = bobs_keys sym_key, capsule = pre._encapsulate(pub_key_alice.point_key) kfrags = pre.split_rekey(priv_key_alice, pub_key_bob, M, N) for kfrag in kfrags: assert kfrag.verify(pub_key_alice.point_key, pub_key_bob.point_key) for i, kfrag in enumerate(kfrags[:M]): # Example of potential metadata to describe the re-encryption request metadata = "This is an example of metadata for re-encryption request #{}" metadata = metadata.format(i).encode() cfrag = pre.reencrypt(kfrag, capsule, metadata=metadata) capsule.attach_cfrag(cfrag) assert pre._verify_correctness( capsule, cfrag, pub_key_alice.point_key, pub_key_bob.point_key, ) # assert capsule.is_openable_by_bob() # TODO: Is it possible to check here if >= m cFrags have been attached? sym_key_from_capsule = pre._open_capsule(capsule, priv_key_bob, pub_key_alice) assert sym_key == sym_key_from_capsule
def test_simple_api(N, M, curve=default_curve()): """Manually injects umbralparameters for multi-curve testing.""" params = UmbralParameters(curve=curve) delegating_privkey = UmbralPrivateKey.gen_key(params=params) delegating_pubkey = delegating_privkey.get_pubkey() signing_privkey = UmbralPrivateKey.gen_key(params=params) signing_pubkey = signing_privkey.get_pubkey() signer = Signer(signing_privkey) receiving_privkey = UmbralPrivateKey.gen_key(params=params) receiving_pubkey = receiving_privkey.get_pubkey() plain_data = b'peace at dawn' ciphertext, capsule = pre.encrypt(delegating_pubkey, plain_data) cleartext = pre.decrypt(ciphertext, capsule, delegating_privkey) assert cleartext == plain_data capsule.set_correctness_keys(delegating=delegating_pubkey, receiving=receiving_pubkey, verifying=signing_pubkey) kfrags = pre.split_rekey(delegating_privkey, signer, receiving_pubkey, M, N) for kfrag in kfrags: cfrag = pre.reencrypt(kfrag, capsule) capsule.attach_cfrag(cfrag) reenc_cleartext = pre.decrypt(ciphertext, capsule, receiving_privkey) assert reenc_cleartext == plain_data
def test_simple_api(N, M, curve=default_curve()): """Manually injects umbralparameters for multi-curve testing.""" params = UmbralParameters(curve=curve) priv_key_alice = keys.UmbralPrivateKey.gen_key(params=params) pub_key_alice = priv_key_alice.get_pubkey() priv_key_bob = keys.UmbralPrivateKey.gen_key(params=params) pub_key_bob = priv_key_bob.get_pubkey() plain_data = b'peace at dawn' ciphertext, capsule = pre.encrypt(pub_key_alice, plain_data, params=params) cleartext = pre.decrypt(ciphertext, capsule, priv_key_alice, params=params) assert cleartext == plain_data kfrags = pre.split_rekey(priv_key_alice, pub_key_bob, M, N, params=params) for kfrag in kfrags: cfrag = pre.reencrypt(kfrag, capsule, params=params) capsule.attach_cfrag(cfrag) reenc_cleartext = pre.decrypt(ciphertext, capsule, priv_key_bob, pub_key_alice, params=params) assert reenc_cleartext == plain_data
def test_m_of_n(N, M, alices_keys, bobs_keys): priv_key_alice, pub_key_alice = alices_keys priv_key_bob, pub_key_bob = bobs_keys sym_key, capsule = pre._encapsulate(pub_key_alice.point_key) kfrags = pre.split_rekey(priv_key_alice, pub_key_bob, M, N) for kfrag in kfrags: assert kfrag.verify(pub_key_alice.point_key, pub_key_bob.point_key) for kfrag in kfrags[:M]: cfrag = pre.reencrypt(kfrag, capsule) capsule.attach_cfrag(cfrag) ch = pre.challenge(kfrag, capsule, cfrag) assert pre.check_challenge(capsule, cfrag, ch, pub_key_alice.point_key, pub_key_bob.point_key) # assert capsule.is_openable_by_bob() # TODO: Is it possible to check here if >= m cFrags have been attached? # capsule.open(pub_bob, priv_bob, pub_alice) capsule._reconstruct_shamirs_secret() sym_key_from_capsule = pre.decapsulate_reencrypted(pub_key_bob.point_key, priv_key_bob.bn_key, pub_key_alice.point_key, capsule) assert sym_key == sym_key_from_capsule
def test_cheating_ursula_replays_old_reencryption(N, M): priv_key_alice = keys.UmbralPrivateKey.gen_key() pub_key_alice = priv_key_alice.get_pubkey() priv_key_bob = keys.UmbralPrivateKey.gen_key() pub_key_bob = priv_key_bob.get_pubkey() sym_key_alice1, capsule_alice1 = pre._encapsulate(pub_key_alice.point_key) sym_key_alice2, capsule_alice2 = pre._encapsulate(pub_key_alice.point_key) kfrags = pre.split_rekey(priv_key_alice, pub_key_bob, M, N) cfrags, metadata = [], [] for i, kfrag in enumerate(kfrags): # Example of potential metadata to describe the re-encryption request metadata_i = "This is an example of metadata for re-encryption request #{}" metadata_i = metadata_i.format(i).encode() if i == 0: # Let's put the re-encryption of a different Alice ciphertext cfrag = pre.reencrypt(kfrag, capsule_alice2, metadata=metadata_i) else: cfrag = pre.reencrypt(kfrag, capsule_alice1, metadata=metadata_i) capsule_alice1.attach_cfrag(cfrag) cfrags.append(cfrag) # Let's activate the capsule capsule_alice1._reconstruct_shamirs_secret(pub_key_alice, priv_key_bob) with pytest.raises(pre.GenericUmbralError): sym_key = pre._decapsulate_reencrypted(pub_key_bob.point_key, priv_key_bob.bn_key, pub_key_alice.point_key, capsule_alice1) assert not cfrags[0].verify_correctness( capsule_alice1, pub_key_alice, pub_key_bob, ) # The response of cheating Ursula is in cfrags[0], # so the rest of CFrags should be correct: for cfrag_i, metadata_i in zip(cfrags[1:], metadata[1:]): assert cfrag_i.verify_correctness( capsule_alice1, pub_key_alice, pub_key_bob, ) # Alternatively, we can try to open the capsule directly. # We should get an exception with an attached list of incorrect cfrags with pytest.raises(pre.UmbralCorrectnessError) as exception_info: _ = pre._open_capsule(capsule_alice1, priv_key_bob, pub_key_alice) correctness_error = exception_info.value assert cfrags[0] in correctness_error.offending_cfrags assert len(correctness_error.offending_cfrags) == 1
def test_cheating_ursula_replays_old_reencryption(N, M): priv_key_alice = keys.UmbralPrivateKey.gen_key() pub_key_alice = priv_key_alice.get_pubkey() priv_key_bob = keys.UmbralPrivateKey.gen_key() pub_key_bob = priv_key_bob.get_pubkey() sym_key_alice1, capsule_alice1 = pre._encapsulate(pub_key_alice.point_key) sym_key_alice2, capsule_alice2 = pre._encapsulate(pub_key_alice.point_key) kfrags = pre.split_rekey(priv_key_alice, pub_key_bob, M, N) cfrags, challenges = [], [] for index, kfrag in enumerate(kfrags): if index == 0: # Let's put the re-encryption of a different Alice ciphertext cfrag = pre.reencrypt(kfrag, capsule_alice2) else: cfrag = pre.reencrypt(kfrag, capsule_alice1) metadata = ("Challenge metadata: index {}".format(index)).encode() challenge = pre._challenge(kfrag, capsule_alice1, cfrag, metadata) capsule_alice1.attach_cfrag(cfrag) challenges.append(challenge) cfrags.append(cfrag) # Let's activate the capsule capsule_alice1._reconstruct_shamirs_secret(pub_key_alice, priv_key_bob) with pytest.raises(pre.GenericUmbralError): sym_key = pre._decapsulate_reencrypted(pub_key_bob.point_key, priv_key_bob.bn_key, pub_key_alice.point_key, capsule_alice1) metadata = b"Challenge metadata: index 0" assert not pre._check_challenge(capsule_alice1, cfrags[0], challenges[0], pub_key_alice.point_key, pub_key_bob.point_key, metadata ) # The response of cheating Ursula is in capsules[0], # so the rest of challenges chould be correct: for i, challenge in enumerate(challenges[1:], 1): cfrag = cfrags[i] metadata = ("Challenge metadata: index {}".format(i)).encode() assert pre._check_challenge(capsule_alice1, cfrag, challenge, pub_key_alice.point_key, pub_key_bob.point_key, metadata )
def test_wrong_N_M_in_split_rekey(N, M, alices_keys, bobs_keys): delegating_privkey, signing_privkey = alices_keys signer = Signer(signing_privkey) _receiving_privkey, receiving_pubkey = bobs_keys with pytest.raises(ValueError): _kfrags = pre.split_rekey(delegating_privkey, signer, receiving_pubkey, M, N)
def __setup(): delegating_privkey, signer, receiving_pubkey, ciphertext, capsule = __standard_encryption_api( ) kfrags = pre.split_rekey(delegating_privkey, signer, receiving_pubkey, m, n) one_kfrag, *remaining_kfrags = kfrags args, kwargs = tuple(), {"kfrag": one_kfrag, "capsule": capsule}, return args, kwargs
def kfrags(alices_keys, bobs_keys): delegating_privkey, signing_privkey = alices_keys delegating_pubkey = delegating_privkey.get_pubkey() signer_alice = Signer(signing_privkey) receiving_privkey, receiving_pubkey = bobs_keys yield pre.split_rekey(delegating_privkey, signer_alice, receiving_pubkey, 6, 10)
def test_cheating_ursula_replays_old_reencryption(N, M): priv_key_alice = keys.UmbralPrivateKey.gen_key() pub_key_alice = priv_key_alice.get_pubkey() priv_key_bob = keys.UmbralPrivateKey.gen_key() pub_key_bob = priv_key_bob.get_pubkey() sym_key_alice1, capsule_alice1 = pre._encapsulate(pub_key_alice.point_key) sym_key_alice2, capsule_alice2 = pre._encapsulate(pub_key_alice.point_key) kfrags = pre.split_rekey(priv_key_alice, pub_key_bob, M, N) cfrags, challenges, metadata = [], [], [] for i, kfrag in enumerate(kfrags): if i == 0: # Let's put the re-encryption of a different Alice ciphertext cfrag = pre.reencrypt(kfrag, capsule_alice2) else: cfrag = pre.reencrypt(kfrag, capsule_alice1) # Example of potential metadata to describe the challenge request metadata_i = { 'ursula_id': i, 'timestamp': time.time(), 'capsule': bytes(capsule_alice1), 'cfrag': bytes(cfrag) } metadata.append(str(metadata_i).encode()) challenge = pre._challenge(kfrag, capsule_alice1, cfrag, metadata[i]) capsule_alice1.attach_cfrag(cfrag) challenges.append(challenge) cfrags.append(cfrag) # Let's activate the capsule capsule_alice1._reconstruct_shamirs_secret(pub_key_alice, priv_key_bob) with pytest.raises(pre.GenericUmbralError): sym_key = pre._decapsulate_reencrypted(pub_key_bob.point_key, priv_key_bob.bn_key, pub_key_alice.point_key, capsule_alice1) assert not pre._check_challenge(capsule_alice1, cfrags[0], challenges[0], pub_key_alice.point_key, pub_key_bob.point_key, metadata[0]) # The response of cheating Ursula is in capsules[0], # so the rest of challenges should be correct: for i, challenge in enumerate(challenges[1:], 1): cfrag = cfrags[i] assert pre._check_challenge(capsule_alice1, cfrag, challenge, pub_key_alice.point_key, pub_key_bob.point_key, metadata[i])
def reencrypt(self, receiver_public_key: bytes) -> List[pre.KFrag]: receiver_pubkey = keys.UmbralPublicKey.from_bytes(receiver_public_key) kfrags = pre.split_rekey(delegating_privkey=self.private_key, signer=self.signer, receiving_pubkey=receiver_pubkey, threshold=10, N=20) return kfrags
def test_bad_capsule_fails_reencryption(alices_keys): priv_key_alice, pub_key_alice = alices_keys kfrags = pre.split_rekey(priv_key_alice, pub_key_alice, 1, 2) bollocks_capsule = Capsule(point_e=Point.gen_rand(), point_v=Point.gen_rand(), bn_sig=CurveBN.gen_rand()) with pytest.raises(Capsule.NotValid): pre.reencrypt(kfrags[0], bollocks_capsule)
def encrypt_message(receiver_pub_key, plaintext, sender_priv_key): ciphertext, capsule = pre.encrypt(receiver_pub_key, plaintext) kfrags = pre.split_rekey(sender_priv_key, receiver_pub_key, 10, 20) for k in kfrags: cfrag = pre.reencrypt(kfrag, capsule) capsule.attach_cfrag(cfrag) return ciphertext, capsule
def test_cheating_ursula_replays_old_reencryption(N, M): priv_key_alice = keys.UmbralPrivateKey.gen_key() pub_key_alice = priv_key_alice.get_pubkey() priv_key_bob = keys.UmbralPrivateKey.gen_key() pub_key_bob = priv_key_bob.get_pubkey() sym_key_alice1, capsule_alice1 = pre._encapsulate(pub_key_alice.point_key) sym_key_alice2, capsule_alice2 = pre._encapsulate(pub_key_alice.point_key) k_frags = pre.split_rekey(priv_key_alice, pub_key_bob, M, N) c_frags, challenges = [], [] for index, k_frag in enumerate(k_frags): if index == 0: # Let's put the re-encryption of a different Alice ciphertext c_frag = pre.reencrypt(k_frag, capsule_alice2) else: c_frag = pre.reencrypt(k_frag, capsule_alice1) challenge = pre.challenge(k_frag, capsule_alice1, c_frag) capsule_alice1.attach_cfrag(c_frag) challenges.append(challenge) c_frags.append(c_frag) capsule_alice1._reconstruct_shamirs_secret() # activate capsule with pytest.raises(pre.GenericUmbralError): sym_key = pre.decapsulate_reencrypted(pub_key_bob.point_key, priv_key_bob.bn_key, pub_key_alice.point_key, capsule_alice1) assert not sym_key == sym_key_alice1 assert not pre.check_challenge( capsule_alice1, c_frags[0], challenges[0], pub_key_alice.point_key, pub_key_bob.point_key, ) # The response of cheating Ursula is in capsules[0], # so the rest of challenges chould be correct: for (c_frag, ch) in zip(c_frags[1:], challenges[1:]): assert pre.check_challenge( capsule_alice1, c_frag, ch, pub_key_alice.point_key, pub_key_bob.point_key, )