def test_serialization(self): """ Tests that serialize/deserialize are inverse operations """ signature = "A" * 128 vk = "A" * 64 seal = Seal.create(signature=signature, verifying_key=vk) seal_clone = Seal.from_bytes(seal.serialize()) self.assertEqual(seal, seal_clone)
def test_eq(self): """ tests __eq__ """ signature = "A" * 128 vk = "A" * 64 seal = Seal.create(signature=signature, verifying_key=vk) seal2 = Seal.create(signature=signature, verifying_key=vk) self.assertEqual(seal, seal2)
def create_from_message(cls, message: MessageBase, signing_key: str, verifying_key: str = None, uuid: int = -1): assert issubclass( type(message), MessageBase), "message arg must be a MessageBase subclass" assert type(message) in MessageBase.registry, "Message type {} not found in registry {}"\ .format(type(message), MessageBase.registry) # TODO -- verify sk (valid hex, 128 char) # Create MessageMeta t = MessageBase.registry[type(message)] timestamp = str(time.time()) meta = MessageMeta.create(type=t, timestamp=timestamp, uuid=uuid) # Create Seal if not verifying_key: verifying_key = Constants.Protocol.Wallets.get_vk(signing_key) seal_sig = EnvelopeAuth.seal(signing_key=signing_key, meta=meta, message=message) seal = Seal.create(signature=seal_sig, verifying_key=verifying_key) # Create Envelope obj = cls.create_from_objects(seal=seal, meta=meta, message=message.serialize()) set_lazy_property(obj, 'message', message) return obj
def create_from_message(cls, message: MessageBase, signing_key: str, verifying_key: str=None, uuid: int=-1): """ Creates an Envelope to package a MessageBase instance :param message: The MessageBase instance to create an envelope for :param signing_key: The sender's signing key, which is used to create the Seal. :param verifying_key: The sender's verifying key. This should be passed in for computational efficiency, but can be computed from the signing key if it is ommited :param uuid: The UUID to use for the Envelope's MessageMeta. If -1, a random UUID will be generated. :return: An Envelope instance """ assert issubclass(type(message), MessageBase), "message arg must be a MessageBase subclass" assert type(message) in MessageBase.registry, "Message type {} not found in registry {}"\ .format(type(message), MessageBase.registry) # TODO -- verify sk (valid hex, 128 char) # Create MessageMeta t = MessageBase.registry[type(message)] timestamp = str(time.time()) meta = MessageMeta.create(type=t, timestamp=timestamp, uuid=uuid) # Create Seal if not verifying_key: verifying_key = Constants.Protocol.Wallets.get_vk(signing_key) seal_sig = EnvelopeAuth.seal(signing_key=signing_key, meta=meta, message=message) seal = Seal.create(signature=seal_sig, verifying_key=verifying_key) # Create Envelope obj = cls._create_from_objects(seal=seal, meta=meta, message=message.serialize()) set_lazy_property(obj, 'message', message) return obj
def _default_seal(self): """ Helper method to build a Seal :return: a Seal instance """ sig = 'A' * 128 vk = 'A' * 68 return Seal.create(signature=sig, verifying_key=vk)
def test_create(self): """ Tests creating a seal produces a Seal object with the expected properties """ signature = "A" * 128 vk = "A" * 64 seal = Seal.create(signature=signature, verifying_key=vk) self.assertEqual(seal.signature, signature) self.assertEqual(seal.verifying_key, vk)
def test_validate_bad_metadata(self): meta = b'lol' message = self._default_msg() sk, vk = W.new() sk2, vk2 = W.new() signature = EnvelopeAuth.seal(signing_key=sk, meta=meta, message=message) seal = Seal.create(signature=signature, verifying_key=vk2) self.assertRaises(Exception, Envelope.create_from_objects, seal, meta, message.serialize())
def test_validate_bad_seal(self): meta = self._default_meta() message = self._default_msg() sk, vk = W.new() sk2, vk2 = W.new() signature = EnvelopeAuth.seal(signing_key=sk, meta=meta, message=message) seal = Seal.create(signature=signature, verifying_key=vk2) env = Envelope.create_from_objects(seal=seal, meta=meta, message=message.serialize()) self.assertFalse(env.verify_seal())
def test_verify_seal(self): """ Tests verify seal with a valid signature """ meta = self._default_meta() message = self._default_msg() sk, vk = W.new() signature = EnvelopeAuth.seal(signing_key=sk, meta=meta, message=message) seal = Seal.create(signature=signature, verifying_key=vk) env = Envelope.create_from_message(message=message, signing_key=sk, verifying_key=vk) self.assertTrue(env.verify_seal())
def test_validate_envelope(self): """ Tests validate envelope function """ meta = self._default_meta() message = self._default_msg() sk, vk = W.new() signature = EnvelopeAuth.seal(signing_key=sk, meta=meta, message=message) seal = Seal.create(signature=signature, verifying_key=vk) env = Envelope.create_from_objects(seal=seal, meta=meta, message=message.serialize()) env.validate()
def test_verify_seal_invalid(self): """ Tests verifying a seal with an invalid signature """ meta = self._default_meta() message = self._default_msg() sk, vk = W.new() sk_prime = 'A' * 64 signature = EnvelopeAuth.seal(signing_key=sk_prime, meta=meta, message=message) seal = Seal.create(signature=signature, verifying_key=vk) env = Envelope.create_from_objects(seal=seal, meta=meta, message=message.serialize()) env.verify_seal()
def seal(self) -> Seal: return Seal.from_data(self._data.seal)
from cilantro import Constants from cilantro.utils import lazy_property, set_lazy_property from cilantro.messages import MessageMeta, MessageBase, Seal from cilantro.protocol.structures import EnvelopeAuth from cilantro.utils import Hasher # Just for debugging (used in __repr__) import time import capnp import envelope_capnp """ An envelope is a structure that encapsulates all messages passed between nodes on the cilantro network An envelope consists of the following types: Seal (args: private key, public key) Metadata (args: type, timestamp, uuid) Message (binary field) An envelope's metadata UUID is using to match REQ/REP sockets and route packets to the correct party on the network """ class Envelope(MessageBase): @classmethod def _deserialize_data(cls, data: bytes): return envelope_capnp.Envelope.from_bytes_packed(data) @classmethod def from_bytes(cls, data: bytes, validate=True, cache_binary=True): env = super().from_bytes(data=data, validate=validate) if cache_binary: set_lazy_property(env, 'serialize', data)