def capsule_side_channel(enacted_policy): signing_keypair = SigningKeypair() data_source = DataSource(policy_pubkey_enc=enacted_policy.public_key, signing_keypair=signing_keypair) message_kit, _signature = data_source.encapsulate_single_message( b"Welcome to the flippering.") return message_kit, data_source
class PublicEdekProtectedEpisode(object): """Keeps the individual episode label, data and policy configuration. Data is encrypted so it's absolutely secure to keep it public Attributes: label: public unencrypted label used in search on Ursulas policy: policy on Ursula (provisione for each episode) data_source: the decryption abstraction, see pyUmbral docs episode_message_kit: the capsule providing the reencryption capabilities, see pyUmbral docs """ def __init__(self, label, raw_episode, author, n=3, m=2): self.n = n self.m = m policy_end_datetime = maya.now() + datetime.timedelta(days=365) self.label = label self.author = author self.policy = self.author.grant(self.author, self.label, m=m, n=n, expiration=policy_end_datetime) self.data_source = DataSource(policy_pubkey_enc=self.policy.public_key, label=self.label) self.data_source_public_key = bytes(self.data_source.stamp) self.episode_message_kit, self.episode_signature = self.data_source.encapsulate_single_message(raw_episode) def grant(self, subscriber, hours=1): """Access can be granted on per-subscriber per-episode basis with time limits. 1 hour by default which is pretty enough for streaming app""" policy_end_datetime = maya.now() + datetime.timedelta(hours=hours) self.author.grant(subscriber, self.label, m=self.m, n=self.n, expiration=policy_end_datetime) print("DDRM:Stream:Episode: access granted for the subscriber {} for {} hours".format(subscriber,hours))
def deliver_purchase(self, to): policy_end_datetime = maya.now() + datetime.timedelta(days=5) policy = author.character.grant(first_buyer.character, self.book.label, m=m, n=n, expiration=policy_end_datetime) author_pubkey = bytes(self.author.character.stamp) data_source = DataSource(policy_pubkey_enc=policy.public_key) message_kit, _signature = data_source.encapsulate_single_message( self.book.content) data_source_public_key = bytes(data_source.stamp) return (author_pubkey, policy.public_key, data_source_public_key, self.book.label, message_kit)
def encrypt_for_policy(self, policy_pubkey: UmbralPublicKey, plaintext: bytes): """ Encrypt data for a Policy :param policy_pubkey: Policy public key :param plaintext: Plaintext bytes to encrypt :return: data_source, message_kit, _signature """ # First we make a DataSource for this policy data_source = DataSource(policy_pubkey_enc=policy_pubkey) # Generate a MessageKit for the policy message_kit, _signature = data_source.encapsulate_single_message( plaintext) return data_source, message_kit, _signature
# Now Alice has set a Policy and Bob has joined it. # You're ready to make some DataSources and encrypt for Bob. # It may also be helpful to imagine that you have multiple Bobs, # multiple Labels, or both. # First we make a DataSource for this policy. data_source = DataSource(policy_pubkey_enc=policy.public_key) # Here's how we generate a MessageKit for the Policy. We also get a signature # here, which can be passed via a side-channel (or posted somewhere public as # testimony) and verified if desired. In this case, the plaintext is a # single passage from James Joyce's Finnegan's Wake. # The matter of whether encryption makes the passage more or less readable # is left to the reader to determine. message_kit, _signature = data_source.encapsulate_single_message(plaintext) # The DataSource will want to be able to be verified by Bob, so it leaves # its Public Key somewhere. data_source_public_key = bytes(data_source.stamp) # It can save the MessageKit somewhere (IPFS, etc) and then it too can # choose to disappear (although it may also opt to continue transmitting # as many messages as may be appropriate). del data_source ############### # Back to Bob # ############### # Bob needs to reconstruct the DataSource.
print("**************James Joyce's Finnegan's Wake**************") print() print("---------------------------------------------------------") for counter, plaintext in enumerate(finnegans_wake): ######################### # Enrico, the Encryptor # ######################### enciro = Enrico(policy_pubkey_enc=policy.public_key) # In this case, the plaintext is a # single passage from James Joyce's Finnegan's Wake. # The matter of whether encryption makes the passage more or less readable # is left to the reader to determine. single_passage_ciphertext, _signature = enciro.encapsulate_single_message( plaintext) data_source_public_key = bytes(enciro.stamp) del enciro ############### # Back to Bob # ############### enrico_as_understood_by_bob = Enrico.from_public_keys( policy_public_key=policy.public_key, datasource_public_key=data_source_public_key, label=label) # Now Bob can retrieve the original message. alice_pubkey_restored_from_ancient_scroll = UmbralPublicKey.from_bytes( alices_pubkey_bytes_saved_for_posterity)
def test_bob_joins_policy_and_retrieves( federated_alice, federated_ursulas, certificates_tempdir, ): # Let's partition Ursulas in two parts a_couple_of_ursulas = list(federated_ursulas)[:2] rest_of_ursulas = list(federated_ursulas)[2:] # Bob becomes bob = Bob( federated_only=True, start_learning_now=True, network_middleware=MockRestMiddleware(), known_certificates_dir=certificates_tempdir, abort_on_learning_error=True, known_nodes=a_couple_of_ursulas, ) # Bob only knows a couple of Ursulas initially assert len(bob.known_nodes) == 2 # Alice creates a policy granting access to Bob # Just for fun, let's assume she distributes KFrags among Ursulas unknown to Bob n = DEFAULT_NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK - 2 label = b'label://' + os.urandom(32) contract_end_datetime = maya.now() + datetime.timedelta(days=5) policy = federated_alice.grant( bob=bob, label=label, m=3, n=n, expiration=contract_end_datetime, handpicked_ursulas=set(rest_of_ursulas), ) assert bob == policy.bob assert label == policy.label # Now, Bob joins the policy bob.join_policy( label=label, alice_pubkey_sig=federated_alice.stamp, ) # In the end, Bob should know all the Ursulas assert len(bob.known_nodes) == len(federated_ursulas) # DataSource becomes data_source = DataSource(policy_pubkey_enc=policy.public_key, signing_keypair=SigningKeypair(), label=label) plaintext = b"What's your approach? Mississippis or what?" message_kit, _signature = data_source.encapsulate_single_message(plaintext) alices_verifying_key = federated_alice.stamp.as_umbral_pubkey() # Bob takes the message_kit and retrieves the message within delivered_cleartexts = bob.retrieve( message_kit=message_kit, data_source=data_source, alice_verifying_key=alices_verifying_key) assert plaintext == delivered_cleartexts[0]