mirror of https://github.com/nucypher/nucypher.git
Extract kfrag authorization into a class
parent
e5c0bb079e
commit
8c628da9ea
|
@ -108,7 +108,7 @@ from nucypher.network.nodes import NodeSprout, TEACHER_NODES, Teacher
|
|||
from nucypher.network.protocols import InterfaceInfo, parse_node_uri
|
||||
from nucypher.network.server import ProxyRESTServer, TLSHostingPower, make_rest_app
|
||||
from nucypher.network.trackers import AvailabilityTracker
|
||||
from nucypher.policy.maps import TreasureMap
|
||||
from nucypher.policy.maps import TreasureMap, AuthorizedKeyFrag
|
||||
from nucypher.policy.orders import WorkOrder
|
||||
from nucypher.policy.policies import Policy
|
||||
from nucypher.utilities.logging import Logger
|
||||
|
@ -1737,35 +1737,29 @@ class Ursula(Teacher, Character, Worker):
|
|||
#
|
||||
|
||||
def verify_kfrag_authorization(self,
|
||||
alice: Alice,
|
||||
kfrag: KeyFrag,
|
||||
signed_writ: bytes,
|
||||
work_order: 'WorkOrder'
|
||||
hrac: bytes,
|
||||
author: Alice,
|
||||
publisher: Alice,
|
||||
authorized_kfrag: AuthorizedKeyFrag,
|
||||
) -> VerifiedKeyFrag:
|
||||
from nucypher.policy.orders import WorkOrder # TODO: resolve ciruclar dependency
|
||||
|
||||
writ_hrac, writ_kfrag_checksum, writ_signature = WorkOrder.signed_writ_splitter(signed_writ)
|
||||
reconstructed_writ = writ_hrac + writ_kfrag_checksum
|
||||
# TODO: should it be a method of AuthorizedKeyFrag?
|
||||
|
||||
try:
|
||||
self.verify_from(alice, reconstructed_writ, signature=writ_signature)
|
||||
self.verify_from(publisher, authorized_kfrag.writ, signature=authorized_kfrag.writ_signature)
|
||||
except InvalidSignature:
|
||||
# TODO (#2740): differentiate cases for Policy.Unauthorized
|
||||
raise Policy.Unauthorized # This isn't from Alice (publisher).
|
||||
|
||||
if writ_hrac != work_order.hrac: # Funky Workorder
|
||||
if authorized_kfrag.hrac != hrac: # Funky Workorder
|
||||
raise Policy.Unauthorized # Bob, what the *hell* are you doing?
|
||||
|
||||
kfrag_checksum = keccak_digest(bytes(kfrag))[:WRIT_CHECKSUM_SIZE]
|
||||
if kfrag_checksum != writ_kfrag_checksum:
|
||||
raise Policy.Unauthorized # Bob, Seriously?
|
||||
|
||||
try:
|
||||
verified_kfrag = kfrag.verify(verifying_pk=alice.stamp.as_umbral_pubkey())
|
||||
verified_kfrag = authorized_kfrag.kfrag.verify(verifying_pk=author.stamp.as_umbral_pubkey())
|
||||
except VerificationError:
|
||||
raise Policy.Unauthorized # WTF, Alice did not generate these KFrags.
|
||||
|
||||
if writ_hrac in self.revoked_policies:
|
||||
if authorized_kfrag.hrac in self.revoked_policies:
|
||||
# Note: This is only an off-chain and in-memory check.
|
||||
raise Policy.Unauthorized # Denied
|
||||
|
||||
|
|
|
@ -24,7 +24,10 @@ SIGNATURE_SIZE = 64
|
|||
EIP712_MESSAGE_SIGNATURE_SIZE = 65
|
||||
WRIT_CHECKSUM_SIZE = 32
|
||||
SIGNED_WRIT_SIZE = HRAC_LENGTH + WRIT_CHECKSUM_SIZE + SIGNATURE_SIZE
|
||||
ENCRYPTED_KFRAG_PAYLOAD_LENGTH = 619 # Depends on encryption parameters in Umbral, has to be hardcoded
|
||||
|
||||
# The size of a serialized message kit encrypting an AuthorizedKeyFrag.
|
||||
# Depends on encryption parameters in Umbral, has to be hardcoded.
|
||||
ENCRYPTED_KFRAG_PAYLOAD_LENGTH = 619
|
||||
|
||||
# Digest Lengths
|
||||
KECCAK_DIGEST_LENGTH = 32
|
||||
|
|
|
@ -220,14 +220,21 @@ def _make_rest_app(datastore: Datastore, this_node, domain: str, log: Logger) ->
|
|||
return Response(response="KFrag decryption failed.", status=403) # 403 - Forbidden
|
||||
|
||||
# Verify KFrag Authorization (offchain)
|
||||
signed_writ, kfrag = work_order.kfrag_payload_splitter(plaintext_kfrag_payload)
|
||||
from nucypher.policy.maps import AuthorizedKeyFrag
|
||||
try:
|
||||
verified_kfrag = this_node.verify_kfrag_authorization(
|
||||
alice=policy_publisher,
|
||||
kfrag=kfrag,
|
||||
signed_writ=signed_writ,
|
||||
work_order=work_order
|
||||
)
|
||||
authorized_kfrag = AuthorizedKeyFrag.from_bytes(plaintext_kfrag_payload)
|
||||
except ValueError:
|
||||
message = f'{bob_identity_message} Invalid AuthorizedKeyFrag.'
|
||||
log.info(message)
|
||||
this_node.suspicious_activities_witnessed['unauthorized'].append(message)
|
||||
return Response(message, status=401) # 401 - Unauthorized
|
||||
|
||||
try:
|
||||
verified_kfrag = this_node.verify_kfrag_authorization(hrac=work_order.hrac,
|
||||
author=alice,
|
||||
publisher=policy_publisher,
|
||||
authorized_kfrag=authorized_kfrag)
|
||||
|
||||
except Policy.Unauthorized:
|
||||
message = f'{bob_identity_message} Unauthorized work order.'
|
||||
log.info(message)
|
||||
|
|
|
@ -35,12 +35,68 @@ from nucypher.crypto.constants import HRAC_LENGTH, WRIT_CHECKSUM_SIZE, EIP712_ME
|
|||
from nucypher.crypto.kits import UmbralMessageKit
|
||||
from nucypher.crypto.powers import DecryptingPower, SigningPower
|
||||
from nucypher.crypto.signing import SignatureStamp
|
||||
from nucypher.crypto.splitters import signature_splitter
|
||||
from nucypher.crypto.umbral_adapter import KeyFrag, PublicKey, Signature
|
||||
from nucypher.crypto.splitters import signature_splitter, hrac_splitter, kfrag_splitter
|
||||
from nucypher.crypto.umbral_adapter import KeyFrag, VerifiedKeyFrag, PublicKey, Signature
|
||||
from nucypher.crypto.utils import keccak_digest, encrypt_and_sign, verify_eip_191
|
||||
from nucypher.network.middleware import RestMiddleware
|
||||
|
||||
|
||||
class AuthorizedKeyFrag:
|
||||
|
||||
_splitter = BytestringSplitter(
|
||||
hrac_splitter, # HRAC
|
||||
BytestringSplitter((bytes, WRIT_CHECKSUM_SIZE)), # kfrag checksum
|
||||
signature_splitter, # Publisher's signature
|
||||
kfrag_splitter,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _kfrag_checksum(kfrag: KeyFrag) -> bytes:
|
||||
return keccak_digest(bytes(kfrag))[:WRIT_CHECKSUM_SIZE]
|
||||
|
||||
@classmethod
|
||||
def construct_by_publisher(cls,
|
||||
hrac: bytes,
|
||||
verified_kfrag: VerifiedKeyFrag,
|
||||
publisher_stamp: SignatureStamp,
|
||||
) -> 'AuthorizedKeyFrag':
|
||||
|
||||
# "un-verify" kfrag to keep further logic streamlined
|
||||
kfrag = KeyFrag.from_bytes(bytes(verified_kfrag))
|
||||
|
||||
# Alice makes plain to Ursula that, upon decrypting this message,
|
||||
# this particular KFrag is authorized for use in the policy identified by this HRAC.
|
||||
kfrag_checksum = cls._kfrag_checksum(kfrag)
|
||||
writ = hrac + kfrag_checksum
|
||||
writ_signature = publisher_stamp(writ)
|
||||
|
||||
# The writ and the KFrag together represent a complete kfrag kit: the entirety of
|
||||
# the material needed for Ursula to assuredly service this policy.
|
||||
return cls(hrac, kfrag_checksum, writ_signature, kfrag)
|
||||
|
||||
def __init__(self, hrac: bytes, kfrag_checksum: bytes, writ_signature: Signature, kfrag: KeyFrag):
|
||||
self.hrac = hrac
|
||||
self.kfrag_checksum = kfrag_checksum
|
||||
self.writ = hrac + kfrag_checksum
|
||||
self.writ_signature = writ_signature
|
||||
self.kfrag = kfrag
|
||||
|
||||
def __bytes__(self):
|
||||
return self.writ + bytes(self.writ_signature) + bytes(self.kfrag)
|
||||
|
||||
@classmethod
|
||||
def from_bytes(cls, data: bytes):
|
||||
# TODO: should we check the signature right away here?
|
||||
hrac, kfrag_checksum, writ_signature, kfrag = cls._splitter(data)
|
||||
|
||||
# Check integrity
|
||||
calculated_checksum = cls._kfrag_checksum(kfrag)
|
||||
if calculated_checksum != kfrag_checksum:
|
||||
raise ValueError("Incorrect KeyFrag checksum in the serialized data")
|
||||
|
||||
return cls(hrac, kfrag_checksum, writ_signature, kfrag)
|
||||
|
||||
|
||||
class TreasureMapSplitter(BrandingMixin, VersioningMixin, BytestringKwargifier):
|
||||
pass
|
||||
|
||||
|
@ -214,24 +270,7 @@ class TreasureMap:
|
|||
nodes_as_bytes += (node_id + kfrag)
|
||||
return nodes_as_bytes
|
||||
|
||||
def _make_writ(self, kfrag, publisher_stamp) -> bytes:
|
||||
"""
|
||||
Alice makes plain to Ursula that, upon decrypting this message,
|
||||
this particular KFrag is authorized for use in the policy identified by this HRAC.
|
||||
"""
|
||||
writ = self._hrac + keccak_digest(bytes(kfrag))[:WRIT_CHECKSUM_SIZE]
|
||||
writ_signature = bytes(publisher_stamp(writ))
|
||||
signed_writ = writ + writ_signature
|
||||
return signed_writ
|
||||
|
||||
def _make_kfrag_payload(self, kfrag, publisher_stamp) -> bytes:
|
||||
# The writ and the KFrag together represent a complete kfrag kit: the entirety of
|
||||
# the material needed for Ursula to assuredly service this policy.
|
||||
signed_writ = self._make_writ(kfrag=kfrag, publisher_stamp=publisher_stamp)
|
||||
kfrag_payload = signed_writ + bytes(kfrag)
|
||||
return kfrag_payload
|
||||
|
||||
def add_kfrag(self, ursula, kfrag, publisher_stamp: SignatureStamp) -> None:
|
||||
def add_kfrag(self, ursula, verified_kfrag: VerifiedKeyFrag, publisher_stamp: SignatureStamp) -> None:
|
||||
if self.destinations == NO_DECRYPTION_PERFORMED:
|
||||
# Unsure how this situation can arise, but let's raise an error just in case.
|
||||
raise TypeError("This TreasureMap is encrypted. You can't add another node without decrypting it.")
|
||||
|
@ -242,7 +281,9 @@ class TreasureMap:
|
|||
'Cannot add KFrag to TreasureMap without an HRAC set. Call "derive_hrac" and try again.')
|
||||
|
||||
# Encrypt this kfrag payload for Ursula.
|
||||
kfrag_payload = self._make_kfrag_payload(kfrag=kfrag, publisher_stamp=publisher_stamp)
|
||||
kfrag_payload = bytes(AuthorizedKeyFrag.construct_by_publisher(hrac=self._hrac,
|
||||
verified_kfrag=verified_kfrag,
|
||||
publisher_stamp=publisher_stamp))
|
||||
encrypted_kfrag, _signature = encrypt_and_sign(recipient_pubkey_enc=ursula.public_keys(DecryptingPower),
|
||||
plaintext=kfrag_payload,
|
||||
signer=publisher_stamp)
|
||||
|
@ -295,7 +336,7 @@ class TreasureMap:
|
|||
bob: 'Bob',
|
||||
label: bytes,
|
||||
ursulas: Sequence['Ursula'],
|
||||
kfrags: Sequence[KeyFrag],
|
||||
verified_kfrags: Sequence[VerifiedKeyFrag],
|
||||
m: int
|
||||
) -> 'TreasureMap':
|
||||
"""Create a new treasure map for a collection of ursulas and kfrags."""
|
||||
|
@ -307,9 +348,9 @@ class TreasureMap:
|
|||
label=label)
|
||||
|
||||
# Encrypt each kfrag for an Ursula.
|
||||
for ursula, kfrag in zip(ursulas, kfrags):
|
||||
for ursula, verified_kfrag in zip(ursulas, verified_kfrags):
|
||||
treasure_map.add_kfrag(ursula=ursula,
|
||||
kfrag=kfrag,
|
||||
verified_kfrag=verified_kfrag,
|
||||
publisher_stamp=publisher.stamp)
|
||||
|
||||
# Sign the map if needed before sending it out into the world.
|
||||
|
|
|
@ -31,7 +31,7 @@ from nucypher.crypto.kits import RevocationKit
|
|||
from nucypher.crypto.powers import TransactingPower
|
||||
from nucypher.crypto.splitters import key_splitter
|
||||
from nucypher.crypto.utils import keccak_digest
|
||||
from nucypher.crypto.umbral_adapter import PublicKey, KeyFrag, Signature
|
||||
from nucypher.crypto.umbral_adapter import PublicKey, VerifiedKeyFrag, Signature
|
||||
from nucypher.crypto.utils import construct_policy_id
|
||||
from nucypher.network.middleware import RestMiddleware
|
||||
from nucypher.policy.reservoir import (
|
||||
|
@ -196,7 +196,7 @@ class Policy(ABC):
|
|||
label: bytes,
|
||||
expiration: maya.MayaDT,
|
||||
bob: 'Bob',
|
||||
kfrags: Sequence[KeyFrag],
|
||||
kfrags: Sequence[VerifiedKeyFrag],
|
||||
public_key: PublicKey,
|
||||
m: int,
|
||||
):
|
||||
|
@ -351,7 +351,7 @@ class Policy(ABC):
|
|||
bob=self.bob,
|
||||
label=self.label,
|
||||
ursulas=list(arrangements),
|
||||
kfrags=self.kfrags,
|
||||
verified_kfrags=self.kfrags,
|
||||
m=self.m)
|
||||
return treasure_map
|
||||
|
||||
|
@ -418,7 +418,7 @@ class Policy(ABC):
|
|||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def _make_enactment_payload(self, kfrag: KeyFrag) -> bytes:
|
||||
def _make_enactment_payload(self, kfrag: VerifiedKeyFrag) -> bytes:
|
||||
"""
|
||||
Serializes a given kfrag and policy publication transaction to send to Ursula.
|
||||
"""
|
||||
|
|
|
@ -26,6 +26,7 @@ from nucypher.crypto.kits import PolicyMessageKit
|
|||
from nucypher.crypto.powers import DecryptingPower
|
||||
from nucypher.crypto.umbral_adapter import reencrypt
|
||||
from nucypher.datastore.models import Workorder
|
||||
from nucypher.policy.maps import AuthorizedKeyFrag
|
||||
from tests.utils.middleware import MockRestMiddleware, NodeIsDownMiddleware
|
||||
|
||||
|
||||
|
@ -206,13 +207,16 @@ def test_bob_can_issue_a_work_order_to_a_specific_ursula(enacted_federated_polic
|
|||
|
||||
# Ursula decrypts the encrypted KFrag
|
||||
encrypted_kfrag = enacted_federated_policy.treasure_map.destinations[ursula.checksum_address]
|
||||
alice = Alice.from_public_keys(verifying_key=enacted_federated_policy.publisher_verifying_key)
|
||||
alice = Alice.from_public_keys(verifying_key=federated_alice.stamp.as_umbral_pubkey())
|
||||
plaintext_kfrag_payload = ursula.verify_from(stranger=alice,
|
||||
message_kit=encrypted_kfrag,
|
||||
decrypt=True)
|
||||
_signed_writ, the_kfrag = work_order.kfrag_payload_splitter(plaintext_kfrag_payload)
|
||||
authorized_kfrag = AuthorizedKeyFrag.from_bytes(plaintext_kfrag_payload)
|
||||
verified_kfrag = ursula.verify_kfrag_authorization(hrac=work_order.hrac,
|
||||
author=alice,
|
||||
publisher=alice,
|
||||
authorized_kfrag=authorized_kfrag)
|
||||
|
||||
verified_kfrag = the_kfrag.verify(enacted_federated_policy.publisher_verifying_key)
|
||||
reencrypt(capsule=message_kit.capsule, kfrag=verified_kfrag)
|
||||
|
||||
# Now we'll show that Ursula saved the correct WorkOrder.
|
||||
|
|
|
@ -22,18 +22,18 @@ import pytest
|
|||
|
||||
from nucypher.crypto.powers import DecryptingPower, SigningPower
|
||||
from nucypher.crypto.umbral_adapter import KeyFrag
|
||||
from nucypher.policy.maps import TreasureMap
|
||||
from nucypher.policy.maps import TreasureMap, AuthorizedKeyFrag
|
||||
|
||||
|
||||
def test_complete_treasure_map_journey(federated_alice, federated_bob, federated_ursulas, mocker):
|
||||
def test_complete_treasure_map_journey(federated_alice, federated_bob, federated_ursulas, idle_federated_policy, mocker):
|
||||
|
||||
treasure_map = TreasureMap(m=1)
|
||||
|
||||
bob_encrypting_key = federated_bob.public_keys(DecryptingPower)
|
||||
bob_verifying_key = federated_bob.public_keys(SigningPower)
|
||||
|
||||
mock_kfrag = os.urandom(KeyFrag.serialized_size())
|
||||
make_kfrag_payload_spy = mocker.spy(TreasureMap, '_make_kfrag_payload')
|
||||
kfrag = idle_federated_policy.kfrags[0]
|
||||
make_kfrag_payload_spy = mocker.spy(AuthorizedKeyFrag, '__bytes__')
|
||||
|
||||
treasure_map.derive_hrac(publisher_stamp=federated_alice.stamp,
|
||||
bob_verifying_key=bob_verifying_key,
|
||||
|
@ -41,7 +41,7 @@ def test_complete_treasure_map_journey(federated_alice, federated_bob, federated
|
|||
|
||||
encrypted_kfrags = dict()
|
||||
for ursula in federated_ursulas:
|
||||
treasure_map.add_kfrag(ursula, mock_kfrag, federated_alice.stamp)
|
||||
treasure_map.add_kfrag(ursula, kfrag, federated_alice.stamp)
|
||||
encrypted_kfrags[ursula.checksum_address] = make_kfrag_payload_spy.spy_return
|
||||
|
||||
treasure_map.prepare_for_publication(bob_encrypting_key=bob_encrypting_key,
|
||||
|
@ -51,8 +51,8 @@ def test_complete_treasure_map_journey(federated_alice, federated_bob, federated
|
|||
for ursula_address, encrypted_kfrag in treasure_map.destinations.items():
|
||||
assert ursula_address in ursula_rolodex
|
||||
ursula = ursula_rolodex[ursula_address]
|
||||
mock_kfrag_payload = encrypted_kfrags[ursula.checksum_address]
|
||||
assert mock_kfrag_payload == ursula.verify_from(federated_alice, encrypted_kfrag, decrypt=True) # FIXME: 2203
|
||||
kfrag_payload = encrypted_kfrags[ursula.checksum_address]
|
||||
assert kfrag_payload == ursula.verify_from(federated_alice, encrypted_kfrag, decrypt=True) # FIXME: 2203
|
||||
|
||||
serialized_map = bytes(treasure_map)
|
||||
# ...
|
||||
|
@ -67,16 +67,16 @@ def test_complete_treasure_map_journey(federated_alice, federated_bob, federated
|
|||
|
||||
|
||||
@pytest.mark.skip(reason='Backwards-incompatible with umbral 0.2+')
|
||||
def test_treasure_map_versioning(mocker, federated_alice, federated_bob, federated_ursulas):
|
||||
def test_treasure_map_versioning(mocker, federated_alice, federated_bob, federated_ursulas, idle_federated_policy):
|
||||
# Produced using f04d564a1
|
||||
map_from_previous_version = b'\x87T\x19\xceV_1\x8e\xb0\x87\xf6\xd9\x9d\x80\xba\xaf\xc4\x84\xa1\xd9|P=\x02\x13\xa0r1\x9eB\xf4\xfc\xc6w\xdf\xd1\x88\xc4\x83\x8f \x1c|\xec\xfcnW~k\x95f8\x19\r\xb1\xad\xe9\xa8\xc9\x06\x93j\xaf\xc50&[\xe5Cy\x9cr_R\xcd\xb1\xb1F\xed\x01\x00\x00\x02\xf4\x02][\xb8VP\xfa%D\xc3\xeb\xd4\x8b\xd2SW\x0f\xfe\xe5\x0f\xaa\xe6\x83\x9a\xa1\x91\xf6\x8e\xca\x00\x95\xf9\x90\x02-\x7f\xca\xe8$L\xcd0\x1d\xa1D\x80\xafjY\xea2\xbc\x04\x94\x1c\xd6E\xa4l\x8fu\xdf\x8a#\x04\xe1\x8eKN\xc9Y\xfbB7I\x9b\xa153\xcef\xfd\xb2/9[\x1b^\xe3\xcf\x08/\xf4%k\x06\xf4\xa5\x03\xfa\xf1\xdc\xec\xe1\t\xeb%\x0c\x11{\xbb\xc7Z\xb2^\x1d.\x18\xeaJ\xaa\xa6f\xd8\xb0\x92U\x84;\xbe6\x00\x00\x02m\x89\x97?\xcavL\xa7q\x13\x01\x1e\x1f6\x05)\xc2?\xcd\x96\xafhH/>6\x8d\x1a\xf8\xfd\xd5\x8a\xf9e\xb0\xc5\xa8\xbd(\x86\x9f\xb9L\xb9n=\xcb\xa0\xd2\t\x94\x90l\xc0\xb7\x85\x90N\xe0\xc9M{\x08\xc4\xf5\x80\xb7\xd1\x10\x18P\x8bl\x0f\x87fS\x836\xa6q\'\xabr\xd1l\x1e\xe2\xe7\xce\xccZ1[\x0b\xe7\xaa\x9c\x92Qh"2F\x1f\x9f-7HylC\xad\x03\x8ek_\xb6M\x19\xb2\xef\xde~\xa6\x10F<\xac\x94\xa6e\xc3\xb5\x132\x94\x96\xc4\xd9\'\xf9h\x1c\xe8\xb8Zm\x86M\xed\x00\x86\xc3\xf4\x93\x03/J\x1d6$\x1a\xe5+\xad\xf93\x17n\xc3\x19sQ2C\xaf\x9d\x89p\xb9557O\x9a\xc3O\xf0\x1f\xb3M.\xa9\x89\xeb\xb9\xf6\xe8\xcc@\xb0\\)\x9d\xdb\'\xfc\xc4_\xfd\xe1\xef\x01\xe3\xe7va\xac\xd7y\xb2\xcfm\xda\x85\x06(\x92H\xe2p\xf1\x9aw\xaf\x83\x1c\xd3@a\xaa\xf6\xee\xfc\xae&;\xdd*\x94I\'r1JG\xca\xdb\x9e\xef\x18Z\x9f\x15\x81\xe3\x1c\xcfJ\xd6;2H\xe8\xed\xfc\x98\x8e\xc6\x94\x1f\x1d\x95A\xa5\x8e\xe5\xc6f\x85\xbb\xc3\xd0\x9d\x83\xd3\xdf\x91]\x16\xe6)\xfa\xc0\xf3\xba\x7fAb\x81\xe0\x8f\x1bu0\x0b\x82^\xe9\x16\xf0\xfc\xc3p\xd4\x9f\'\xa6\xe5\xb4\xf7\xe1\x99\xa5\xfe\x12\x0e{L\xb0\xd6\xa1\x049\xcf\xe0\xca\x06\xe3\xd6u\x9e\xb3P\xb7\x1a\xc5X\xb7\xb2\xfa\x1dJ\xe1\xa9Gb\xf6l~DG\x8e5X\xc2^\x87\xac\x89W(\xaf\xd3\x15o\xde\xf7\xe4\x18\xd9\x98\xc3\tcL\xd3\x9dF\x8e3\xe5u\x03\x0b\xe7\tj\xdb\xd3B\xa1\x85\x9d \x9c\xa4{n\x01"\xab\xe1509\xdaoL\xc9\x8d\xc9\xfd"\xad\xd8\xfd\xf5\x14\xa2\xa8N\xf5\xa0\xf4\x04Y\x85i\xe0zj34\xc9\xbd\xac\xb9gn\x19J]\x0eL\x81C\xb9\x95\x86Q,\x81\xdf\xcbh\x13\xae8\xe8\x06y\xd1\xcd\x867\x1a\x1c\xe1\x05\xba\xfaL\x1a\x1f\x9f~\x18O1p@\xee\xee\xc4\xed\x84%\xb4\xb4\x12\xb6\x81\x0c\xcamf.\x9c\xe1\xfe\xc4\x87I\'\xc7e\xc1\x7f\xeb\x9c\xe1\xca\xa5\r.\x15\xa8r\xa8\x82Q\x13\x99K\x12X3\x04\xbc\x99\x96\xf8\xc3\x1es\x0c\x85\x8d\xd3\xee\x1b^\xc8\xf5\x1d^\x1a&6#\xbc\xa8~wp}]8\xb5\xe6v\xa4D\xfe:\xb8<q\xd9\x02\xfa\x7f\xcfWA\xad\xd1#\xac\x8b\xd7\xff\xca\xf7[dm\x9b\x06\xcc\x03\x1b\xfa\xd1\xf6:\xad\x1c\xb6\xb8'
|
||||
|
||||
kfrags = [os.urandom(32) for _ in range(3)]
|
||||
kfrags = idle_federated_policy.kfrags[:3]
|
||||
treasure_map = TreasureMap.construct_by_publisher(publisher=federated_alice,
|
||||
bob=federated_bob,
|
||||
label=b'still Bill',
|
||||
ursulas=list(federated_ursulas)[:len(kfrags)],
|
||||
kfrags=kfrags,
|
||||
verified_kfrags=kfrags,
|
||||
m=2)
|
||||
|
||||
# Good version (baseline)
|
||||
|
|
Loading…
Reference in New Issue