pyUmbral/docs/examples/umbral_simple_api.py

113 lines
4.1 KiB
Python

import random
from umbral import (
SecretKey, Signer, CapsuleFrag,
encrypt, generate_kfrags, reencrypt, decrypt_original, decrypt_reencrypted)
# Generate an Umbral key pair
# ---------------------------
# First, Let's generate two asymmetric key pairs for Alice:
# A delegating key pair and a Signing key pair.
alices_secret_key = SecretKey.random()
alices_public_key = alices_secret_key.public_key()
alices_signing_key = SecretKey.random()
alices_verifying_key = alices_signing_key.public_key()
alices_signer = Signer(alices_signing_key)
# Encrypt some data for Alice
# ---------------------------
# Now let's encrypt data with Alice's public key.
# Invocation of `pre.encrypt` returns both the `ciphertext`,
# and a `capsule`. Anyone with Alice's public key can perform
# this operation.
plaintext = b'Proxy Re-encryption is cool!'
capsule, ciphertext = encrypt(alices_public_key, plaintext)
print(ciphertext)
# Decrypt data for Alice
# ----------------------
# Since data was encrypted with Alice's public key,
# Alice can open the capsule and decrypt the ciphertext with her private key.
cleartext = decrypt_original(alices_secret_key, capsule, ciphertext)
print(cleartext)
# Bob Exists
# -----------
bobs_secret_key = SecretKey.random()
bobs_public_key = bobs_secret_key.public_key()
# Bob receives a capsule through a side channel (s3, ipfs, Google cloud, etc)
bob_capsule = capsule
# Attempt Bob's decryption (fail)
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.
# Bob must gather at least `threshold` `cfrags` in order to open the capsule.
cfrags = list() # Bob's cfrag collection
for kfrag in kfrags:
cfrag = reencrypt(capsule=capsule, kfrag=kfrag)
cfrags.append(cfrag) # Bob collects a cfrag
assert len(cfrags) == 10
# Bob checks the capsule fragments
# --------------------------------
# If Bob received the capsule fragments in serialized form,
# he can verify that they are valid and really originate from Alice,
# using Alice's public keys.
suspicious_cfrags = [CapsuleFrag.from_bytes(bytes(cfrag)) for cfrag in cfrags]
cfrags = [cfrag.verify(capsule,
verifying_pk=alices_verifying_key,
delegating_pk=alices_public_key,
receiving_pk=bobs_public_key,
)
for cfrag in suspicious_cfrags]
# Bob opens the capsule
# ------------------------------------
# Finally, Bob decrypts the re-encrypted ciphertext using his key.
bob_cleartext = decrypt_reencrypted(receiving_sk=bobs_secret_key,
delegating_pk=alices_public_key,
capsule=bob_capsule,
verified_cfrags=cfrags,
ciphertext=ciphertext)
print(bob_cleartext)
assert bob_cleartext == plaintext