def test_sign_verify(self, sk_ilp, vk_ilp): message = b'Hello World!' sk = SigningKey(sk_ilp['b58']) vk = VerifyingKey(vk_ilp['b58']) assert vk.verify(message, sk.sign(message)) is True assert vk.verify(message, sk.sign(message + b'dummy')) is False assert vk.verify(message + b'dummy', sk.sign(message)) is False vk = VerifyingKey(vk_ilp[2]['b64'], encoding='base64') assert vk.verify(message, sk.sign(message)) is False
def test_generate_sign_verify(self, vk_ilp): sk_b58, vk_b58 = ed25519_generate_key_pair() sk = SigningKey(sk_b58) vk = VerifyingKey(vk_b58) message = b'Hello World!' assert vk.verify(message, sk.sign(message)) is True assert vk.verify(message, sk.sign(message + b'dummy')) is False assert vk.verify(message + b'dummy', sk.sign(message)) is False vk = VerifyingKey(vk_ilp[2]['b64'], encoding='base64') assert vk.verify(message, sk.sign(message)) is False
def test_deserialize_unsigned_dict_to_fulfillment(self, vk_ilp): fulfillment = ThresholdSha256Fulfillment(threshold=1) fulfillment.add_subfulfillment( Ed25519Fulfillment(public_key=VerifyingKey(vk_ilp['b58']))) fulfillment.add_subfulfillment( Ed25519Fulfillment(public_key=VerifyingKey(vk_ilp['b58']))) parsed_fulfillment = fulfillment.from_dict(fulfillment.to_dict()) assert parsed_fulfillment.condition.serialize_uri( ) == fulfillment.condition.serialize_uri() assert parsed_fulfillment.to_dict() == fulfillment.to_dict()
def test_deteministic_key_pair_is_same(self): seed = b'm\xea#\xbb\xady\xea\xf5Y\x1fz\xe5\xd0\x9d\x0f&\xee\xfb=$u\x08\x80\x04\xcf\xf1\x14*\xc9\x0e<g' sk_b58, vk_b58 = ed25519_generate_key_pair(seed) sk_2_b58, vk_2_b58 = ed25519_generate_key_pair(seed) assert len(base58.b58decode(sk_b58)) == 32 assert len(base58.b58decode(vk_b58)) == 32 assert SigningKey(sk_b58).encode() == sk_b58 assert VerifyingKey(vk_b58).encode() == vk_b58 assert len(base58.b58decode(sk_2_b58)) == 32 assert len(base58.b58decode(vk_2_b58)) == 32 assert SigningKey(sk_2_b58).encode() == sk_2_b58 assert VerifyingKey(vk_2_b58).encode() == vk_2_b58 assert sk_b58 == sk_2_b58 assert vk_b58 == vk_2_b58
def test_to_bytes(self, sk_ilp, vk_ilp): sk = SigningKey(sk_ilp['b58']) assert sk.encode(encoding='base58') == sk_ilp['b58'] assert sk.encode(encoding='base64') == sk_ilp['b64'] vk = VerifyingKey(vk_ilp['b58']) assert vk.encode(encoding='base58') == vk_ilp['b58'] assert vk.encode(encoding='base64') == vk_ilp['b64']
def create_fulfillment_ed25519sha256(self, sk_ilp, vk_ilp): sk = SigningKey(sk_ilp['b58']) vk = VerifyingKey(vk_ilp['b58']) fulfillment = Ed25519Fulfillment(public_key=vk) fulfillment.sign(MESSAGE, sk) return fulfillment
def test_valid_condition_invalid_signature_ilp(self, vk_ilp, signature): vk = VerifyingKey(vk_ilp[2]['b64'], encoding='base64') msg = base64.b64decode(signature['msg']) assert vk.verify(msg, signature['msg'], encoding='base64') is False assert vk.verify(msg, binascii.hexlify(base64.b64decode(signature['msg'])), encoding='hex') is False assert vk.verify( msg, base64.b64decode(signature['msg']), encoding='bytes') is False
def test_ilp_keys(self, sk_ilp, vk_ilp): sk = SigningKey(sk_ilp['b58']) assert sk.encode(encoding='base64') == sk_ilp['b64'] assert binascii.hexlify( sk.encode(encoding='bytes')[:32]) == sk_ilp['hex'] vk = VerifyingKey(vk_ilp['b58']) assert vk.encode(encoding='base64') == vk_ilp['b64'] assert binascii.hexlify(vk.encode(encoding='bytes')) == vk_ilp['hex']
def test_serialize_deserialize_condition(self, vk_ilp): vk = VerifyingKey(vk_ilp['b58']) fulfillment = Ed25519Fulfillment(public_key=vk) condition = fulfillment.condition deserialized_condition = Condition.from_uri(condition.serialize_uri()) assert deserialized_condition.bitmask == condition.bitmask assert deserialized_condition.hash == condition.hash assert deserialized_condition.max_fulfillment_length == condition.max_fulfillment_length assert deserialized_condition.serialize_uri( ) == condition.serialize_uri()
def parse_dict(self, data): """ Generate fulfillment payload from a dict Args: data (dict): description of the fulfillment Returns: Fulfillment """ self.public_key = VerifyingKey(data['public_key']) self.signature = base58.b58decode( data['signature']) if data['signature'] else None
def parse_payload(self, reader, *args): """ Parse the payload of an Ed25519 fulfillment. Read a fulfillment payload from a Reader and populate this object with that fulfillment. Args: reader (Reader): Source to read the fulfillment payload from. """ self.public_key = VerifyingKey( base58.b58encode( reader.read_octet_string(Ed25519Fulfillment.PUBKEY_LENGTH))) self.signature = reader.read_octet_string( Ed25519Fulfillment.SIGNATURE_LENGTH)
def test_serialize_unsigned_dict_to_fulfillment(self, vk_ilp): fulfillment = ThresholdSha256Fulfillment(threshold=1) fulfillment.add_subfulfillment( Ed25519Fulfillment(public_key=VerifyingKey(vk_ilp['b58']))) fulfillment.add_subfulfillment( Ed25519Fulfillment(public_key=VerifyingKey(vk_ilp['b58']))) assert fulfillment.to_dict() == \ {'bitmask': 41, 'subfulfillments': [{'bitmask': 32, 'public_key': 'Gtbi6WQDB6wUePiZm8aYs5XZ5pUqx9jMMLvRVHPESTjU', 'signature': None, 'type': 'fulfillment', 'type_id': 4, 'weight': 1}, {'bitmask': 32, 'public_key': 'Gtbi6WQDB6wUePiZm8aYs5XZ5pUqx9jMMLvRVHPESTjU', 'signature': None, 'type': 'fulfillment', 'type_id': 4, 'weight': 1}], 'threshold': 1, 'type': 'fulfillment', 'type_id': 2}
def test_weak_public_keys(self): """reproduce the problem in https://github.com/bigchaindb/bigchaindb/issues/617 This problem is due to weak keys, specially in this case the key and signature when decoded from base58 correspond to a key and a signature that are zero. In this case its possible to come up with messages that would verify. Libraries like libsodium check for these weak keys and return a BadSignature error if weak keys are being used. More details here: https://github.com/jedisct1/libsodium/issues/112 """ vk_b58 = VerifyingKey('1' * 32) message = b'age=33&name=luo&title=architecture' signature = b'1' * 64 assert vk_b58.verify(message, signature) == False
def __init__(self, public_key=None): """ ED25519: Ed25519 signature condition. This condition implements Ed25519 signatures. ED25519 is assigned the type ID 4. It relies only on the ED25519 feature suite which corresponds to a bitmask of 0x20. Args: public_key (VerifyingKey): Ed25519 publicKey """ if public_key and isinstance(public_key, (str, bytes)): public_key = VerifyingKey(public_key) if public_key and not isinstance(public_key, VerifyingKey): raise TypeError self.public_key = public_key self.signature = None
def test_serialize_deserialize_fulfillment(self, sk_ilp, vk_ilp): sk = SigningKey(sk_ilp['b58']) vk = VerifyingKey(vk_ilp['b58']) fulfillment = Ed25519Fulfillment(public_key=vk) fulfillment.sign(MESSAGE, sk) assert fulfillment.validate(MESSAGE) deserialized_fulfillment = Fulfillment.from_uri( fulfillment.serialize_uri()) assert isinstance(deserialized_fulfillment, Ed25519Fulfillment) assert deserialized_fulfillment.serialize_uri( ) == fulfillment.serialize_uri() assert deserialized_fulfillment.condition.serialize_uri( ) == fulfillment.condition.serialize_uri() assert deserialized_fulfillment.public_key.encode(encoding='bytes') == \ fulfillment.public_key.encode(encoding='bytes') assert deserialized_fulfillment.validate(MESSAGE)
def test_serialize_condition_and_validate_fulfillment( self, sk_ilp, vk_ilp, fulfillment_ed25519): sk = SigningKey(sk_ilp['b58']) vk = VerifyingKey(vk_ilp['b58']) fulfillment = Ed25519Fulfillment(public_key=vk) assert fulfillment.condition.serialize_uri( ) == fulfillment_ed25519['condition_uri'] assert binascii.hexlify(fulfillment.condition.hash ) == fulfillment_ed25519['condition_hash'] # ED25519-SHA256 condition not fulfilled assert fulfillment.validate() == False # Fulfill an ED25519-SHA256 condition fulfillment.sign(MESSAGE, sk) assert fulfillment.serialize_uri( ) == fulfillment_ed25519['fulfillment_uri'] assert fulfillment.validate(MESSAGE)
def test_fulfillment_didnt_reach_threshold(self, vk_ilp, fulfillment_ed25519): ilp_fulfillment = Fulfillment.from_uri( fulfillment_ed25519['fulfillment_uri']) threshold = 10 # Create a threshold condition fulfillment = ThresholdSha256Fulfillment(threshold=threshold) for i in range(threshold - 1): fulfillment.add_subfulfillment(ilp_fulfillment) with pytest.raises(KeyError): fulfillment.serialize_uri() assert fulfillment.validate(MESSAGE) is False fulfillment.add_subfulfillment(ilp_fulfillment) fulfillment_uri = fulfillment.serialize_uri() assert fulfillment.validate(MESSAGE) deserialized_fulfillment = Fulfillment.from_uri(fulfillment_uri) assert isinstance(deserialized_fulfillment, ThresholdSha256Fulfillment) assert deserialized_fulfillment.threshold == threshold assert len([ f for f in deserialized_fulfillment.subconditions if f['type'] == 'fulfillment' ]) == threshold assert len(deserialized_fulfillment.subconditions) == threshold assert deserialized_fulfillment.serialize_uri() == fulfillment_uri assert deserialized_fulfillment.validate(MESSAGE) fulfillment.add_subfulfillment( Ed25519Fulfillment(public_key=VerifyingKey(vk_ilp['b58']))) assert fulfillment.validate(MESSAGE) == True
def test_verifying_key_init(self, vk_ilp): vk = VerifyingKey(vk_ilp['b58']) assert vk.encode(encoding='base64') == vk_ilp['b64'] assert vk.encode(encoding='bytes') == vk_ilp['byt']
def test_verifying_key_decode(self, vk_ilp): vk = VerifyingKey(vk_ilp['b58']) public_value = vk.encode(encoding='base64') assert public_value == vk_ilp['b64']
def test_create(self, vk_ilp): fulfillment1 = Ed25519Fulfillment(public_key=vk_ilp['b58']) fulfillment2 = Ed25519Fulfillment(VerifyingKey(vk_ilp['b58'])) assert fulfillment1.condition.serialize_uri( ) == fulfillment2.condition.serialize_uri()
def test_get_verifying_key(self, sk_ilp, vk_ilp): sk = SigningKey(sk_ilp['b58']) vk = VerifyingKey(vk_ilp['b58']) vk_from_sk = sk.get_verifying_key() assert vk.encode(encoding='bytes') == vk_from_sk.encode( encoding='bytes')
def test_generate_key_pair(self): sk_b58, vk_b58 = ed25519_generate_key_pair() assert len(base58.b58decode(sk_b58)) == 32 assert len(base58.b58decode(vk_b58)) == 32 assert SigningKey(sk_b58).encode() == sk_b58 assert VerifyingKey(vk_b58).encode() == vk_b58