def test_wrong_num_kfrags(alices_keys, bobs_keys): delegating_sk, signing_sk = alices_keys _receiving_sk, receiving_pk = bobs_keys # Trying to create less kfrags than the threshold with pytest.raises(ValueError): generate_kfrags(delegating_sk=delegating_sk, signer=Signer(signing_sk), receiving_pk=receiving_pk, threshold=3, num_kfrags=2)
def test_open_reencrypted(alices_keys, bobs_keys): threshold = 6 shares = 10 delegating_sk, signing_sk = alices_keys receiving_sk, receiving_pk = bobs_keys signer = Signer(signing_sk) delegating_pk = delegating_sk.public_key() capsule, key = Capsule.from_public_key(delegating_pk) kfrags = generate_kfrags(delegating_sk=delegating_sk, signer=signer, receiving_pk=receiving_pk, threshold=threshold, shares=shares) cfrags = [reencrypt(capsule, kfrag).cfrag for kfrag in kfrags] key_back = capsule.open_reencrypted(receiving_sk, delegating_pk, cfrags[:threshold]) assert key_back == key # No cfrags at all with pytest.raises(ValueError, match="Empty CapsuleFrag sequence"): capsule.open_reencrypted(receiving_sk, delegating_pk, []) # Not enough cfrags with pytest.raises(ValueError, match="Internal validation failed"): capsule.open_reencrypted(receiving_sk, delegating_pk, cfrags[:threshold - 1]) # Repeating cfrags with pytest.raises(ValueError, match="Some of the CapsuleFrags are repeated"): capsule.open_reencrypted(receiving_sk, delegating_pk, [cfrags[0]] + cfrags[:threshold - 1]) # Mismatched cfrags kfrags2 = generate_kfrags(delegating_sk=delegating_sk, signer=signer, receiving_pk=receiving_pk, threshold=threshold, shares=shares) cfrags2 = [reencrypt(capsule, kfrag).cfrag for kfrag in kfrags2] with pytest.raises(ValueError, match="CapsuleFrags are not pairwise consistent"): capsule.open_reencrypted(receiving_sk, delegating_pk, [cfrags2[0]] + cfrags[:threshold - 1])
def kfrags(alices_keys, bobs_keys): delegating_sk, signing_sk = alices_keys receiving_sk, receiving_pk = bobs_keys yield generate_kfrags(delegating_sk=delegating_sk, signer=Signer(signing_sk), receiving_pk=receiving_pk, threshold=6, num_kfrags=10)
def test_simple_api(num_kfrags, threshold): """ This test models the main interactions between actors (i.e., Alice, Bob, Data Source, and Ursulas) and artifacts (i.e., public and private keys, ciphertexts, capsules, KFrags, CFrags, etc). The test covers all the main stages of data sharing: key generation, delegation, encryption, decryption by Alice, re-encryption by Ursula, and decryption by Bob. """ # Key Generation (Alice) delegating_sk = SecretKey.random() delegating_pk = delegating_sk.public_key() signing_sk = SecretKey.random() signer = Signer(signing_sk) verifying_pk = signing_sk.public_key() # Key Generation (Bob) receiving_sk = SecretKey.random() receiving_pk = receiving_sk.public_key() # Encryption by an unnamed data source plaintext = b'peace at dawn' capsule, ciphertext = encrypt(delegating_pk, plaintext) # Decryption by Alice plaintext_decrypted = decrypt_original(delegating_sk, capsule, ciphertext) assert plaintext_decrypted == plaintext # Split Re-Encryption Key Generation (aka Delegation) kfrags = generate_kfrags(delegating_sk=delegating_sk, receiving_pk=receiving_pk, signer=signer, threshold=threshold, num_kfrags=num_kfrags) # Bob requests re-encryption to some set of M ursulas cfrags = [reencrypt(capsule, kfrag) for kfrag in kfrags] # Decryption by Bob plaintext_reenc = decrypt_reencrypted( receiving_sk=receiving_sk, delegating_pk=delegating_pk, capsule=capsule, verified_cfrags=cfrags[:threshold], ciphertext=ciphertext, ) assert plaintext_reenc == plaintext
def __produce_kfrags_and_capsule( m: int, n: int) -> Tuple[List[umbral.KeyFrag], umbral.Capsule]: delegating_sk = umbral.SecretKey.random() delegating_pk = delegating_sk.public_key() signing_sk = umbral.SecretKey.random() signer = umbral.Signer(signing_sk) receiving_sk = umbral.SecretKey.random() receiving_pk = receiving_sk.public_key() plain_data = os.urandom(32) capsule, ciphertext = umbral.encrypt(delegating_pk, plain_data) kfrags = umbral.generate_kfrags(delegating_sk, receiving_pk, signer, m, n) return kfrags, capsule
try: fail_decrypted_data = decrypt_original(bobs_secret_key, bob_capsule, ciphertext) except ValueError: print("Decryption failed! Bob doesn't has access granted yet.") # Alice grants access to Bob by generating kfrags # ----------------------------------------------- # When Alice wants to grant Bob access to open her encrypted messages, # she creates *threshold split re-encryption keys*, or *"kfrags"*, # which are next sent to N proxies or *Ursulas*. # She uses her private key, and Bob's public key, and she sets a minimum # threshold of 10, for 20 total shares kfrags = generate_kfrags(delegating_sk=alices_secret_key, receiving_pk=bobs_public_key, signer=alices_signer, threshold=10, num_kfrags=20) # Ursulas perform re-encryption # ------------------------------ # Bob asks several Ursulas to re-encrypt the capsule so he can open it. # Each Ursula performs re-encryption on the capsule using the `kfrag` # provided by Alice, obtaining this way a "capsule fragment", or `cfrag`. # Let's mock a network or transport layer by sampling `threshold` random `kfrags`, # one for each required Ursula. kfrags = random.sample(kfrags, # All kfrags from above 10) # M - Threshold # Bob collects the resulting `cfrags` from several Ursulas.
######### # SETUP # ######### # We create also some Umbral objects for later delegating_sk = SecretKey.random() receiving_sk = SecretKey.random() signing_sk = SecretKey.random() verifying_pk = signing_sk.public_key() delegating_pk = delegating_sk.public_key() receiving_pk = receiving_sk.public_key() kfrags = generate_kfrags(delegating_sk=delegating_sk, receiving_pk=receiving_pk, signer=Signer(signing_sk), threshold=6, shares=10, ) plain_data = b'peace at dawn' capsule, ciphertext = encrypt(delegating_pk, plain_data) cfrag = CapsuleFrag.from_bytes(bytes(reencrypt(capsule, kfrags[0]))) points = [capsule.point_e, cfrag.point_e1, cfrag.proof.point_e2, capsule.point_v, cfrag.point_v1, cfrag.proof.point_v2, cfrag.proof.kfrag_commitment, cfrag.proof.kfrag_pok] z = cfrag.proof.signature