def test_session_key_derivation(initiator_private_key, recipient_private_key, id_nonce): initiator_private_key_object = PrivateKey(initiator_private_key) recipient_private_key_object = PrivateKey(recipient_private_key) initiator_public_key = initiator_private_key_object.public_key.to_bytes() recipient_public_key = recipient_private_key_object.public_key.to_bytes() initiator_node_id = keccak( initiator_private_key_object.public_key.to_bytes()) recipient_node_id = keccak( recipient_private_key_object.public_key.to_bytes()) initiator_session_keys = V4IdentityScheme.compute_session_keys( local_private_key=initiator_private_key, remote_public_key=recipient_public_key, local_node_id=initiator_node_id, remote_node_id=recipient_node_id, id_nonce=id_nonce, is_locally_initiated=True, ) recipient_session_keys = V4IdentityScheme.compute_session_keys( local_private_key=recipient_private_key, remote_public_key=initiator_public_key, local_node_id=recipient_node_id, remote_node_id=initiator_node_id, id_nonce=id_nonce, is_locally_initiated=False, ) assert initiator_session_keys.auth_response_key == recipient_session_keys.auth_response_key assert initiator_session_keys.encryption_key == recipient_session_keys.decryption_key assert initiator_session_keys.decryption_key == recipient_session_keys.encryption_key
def test_enr_public_key(): private_key = PrivateKey(b"\x11" * 32) public_key = private_key.public_key.to_compressed_bytes() unsigned_enr = UnsignedENR(0, { b"id": b"v4", b"secp256k1": public_key, b"key1": b"value1", }) enr = unsigned_enr.to_signed_enr(private_key.to_bytes()) assert V4IdentityScheme.extract_public_key(unsigned_enr) == public_key assert V4IdentityScheme.extract_public_key(enr) == public_key
def test_enr_signature_validation(): private_key = PrivateKey(b"\x11" * 32) unsigned_enr = UnsignedENR( 0, { b"id": b"v4", b"secp256k1": private_key.public_key.to_compressed_bytes(), b"key1": b"value1", }) enr = unsigned_enr.to_signed_enr(private_key.to_bytes()) V4IdentityScheme.validate_enr_signature(enr) forged_enr = ENR(enr.sequence_number, dict(enr), b"\x00" * 64) with pytest.raises(ValidationError): V4IdentityScheme.validate_enr_signature(forged_enr)
def test_valid_id_nonce_signature_validation(private_key, id_nonce, ephemeral_key): ephemeral_public_key = PrivateKey(ephemeral_key).public_key.to_bytes() signature = V4IdentityScheme.create_id_nonce_signature( id_nonce=id_nonce, private_key=private_key, ephemeral_public_key=ephemeral_public_key, ) public_key = PrivateKey(private_key).public_key.to_compressed_bytes() V4IdentityScheme.validate_id_nonce_signature( id_nonce=id_nonce, ephemeral_public_key=ephemeral_public_key, signature=signature, public_key=public_key, )
def test_official_auth_header_packet_preparation(tag, auth_tag, id_nonce, encoded_message, local_private_key, auth_response_key, encryption_key, ephemeral_public_key, auth_message_rlp): message_type_id = encoded_message[0] message_type = default_message_type_registry[message_type_id] message = rlp.decode(encoded_message[1:], message_type) assert message.to_bytes() == encoded_message id_nonce_signature = V4IdentityScheme.create_id_nonce_signature( id_nonce=id_nonce, ephemeral_public_key=ephemeral_public_key, private_key=local_private_key, ) packet = AuthHeaderPacket.prepare( tag=tag, auth_tag=auth_tag, id_nonce=id_nonce, message=message, initiator_key=encryption_key, id_nonce_signature=id_nonce_signature, auth_response_key=auth_response_key, enr=None, ephemeral_public_key=ephemeral_public_key, ) packet_wire_bytes = packet.to_wire_bytes() assert packet_wire_bytes == auth_message_rlp
def test_official_id_nonce_signature(id_nonce, ephemeral_public_key, local_secret_key, id_nonce_signature): created_signature = V4IdentityScheme.create_id_nonce_signature( id_nonce=id_nonce, ephemeral_public_key=ephemeral_public_key, private_key=local_secret_key, ) assert created_signature == id_nonce_signature
def test_id_nonce_signing(private_key, id_nonce, ephemeral_key): ephemeral_public_key = PrivateKey(ephemeral_key).public_key.to_bytes() signature = V4IdentityScheme.create_id_nonce_signature( id_nonce=id_nonce, private_key=private_key, ephemeral_public_key=ephemeral_public_key, ) signature_object = NonRecoverableSignature(signature) message_hash = sha256(ID_NONCE_SIGNATURE_PREFIX + id_nonce + ephemeral_public_key).digest() assert signature_object.verify_msg_hash(message_hash, PrivateKey(private_key).public_key)
def test_enr_node_id(): private_key = PrivateKey(b"\x11" * 32) unsigned_enr = UnsignedENR( 0, { b"id": b"v4", b"secp256k1": private_key.public_key.to_compressed_bytes(), b"key1": b"value1", }) enr = unsigned_enr.to_signed_enr(private_key.to_bytes()) node_id = V4IdentityScheme.extract_node_id(enr) assert node_id == keccak(private_key.public_key.to_bytes())
def test_enr_signing(): private_key = PrivateKey(b"\x11" * 32) unsigned_enr = UnsignedENR( 0, { b"id": b"v4", b"secp256k1": private_key.public_key.to_compressed_bytes(), b"key1": b"value1", }) signature = V4IdentityScheme.create_enr_signature(unsigned_enr, private_key.to_bytes()) message_hash = keccak(unsigned_enr.get_signing_message()) assert private_key.public_key.verify_msg_hash( message_hash, NonRecoverableSignature(signature))
def test_official_auth_response_encryption(secret_key, id_nonce, enr, auth_response_key, ephemeral_public_key, auth_cipher_text): id_nonce_signature = V4IdentityScheme.create_id_nonce_signature( id_nonce=id_nonce, private_key=secret_key, ephemeral_public_key=ephemeral_public_key, ) assert compute_encrypted_auth_response( auth_response_key=auth_response_key, id_nonce_signature=id_nonce_signature, enr=enr, ) == auth_cipher_text
def test_invalid_id_nonce_signature_validation(): id_nonce = b"\xff" * 10 private_key = b"\x11" * 32 ephemeral_public_key = b"\x22" * 64 signature = V4IdentityScheme.create_id_nonce_signature( id_nonce=id_nonce, ephemeral_public_key=ephemeral_public_key, private_key=private_key, ) public_key = PrivateKey(private_key).public_key.to_compressed_bytes() different_public_key = PrivateKey(b"\x22" * 32).public_key.to_compressed_bytes() different_id_nonce = b"\x00" * 10 different_ephemeral_public_key = b"\x00" * 64 assert different_public_key != public_key assert different_id_nonce != id_nonce with pytest.raises(ValidationError): V4IdentityScheme.validate_id_nonce_signature( id_nonce=id_nonce, ephemeral_public_key=ephemeral_public_key, signature=signature, public_key=different_public_key, ) with pytest.raises(ValidationError): V4IdentityScheme.validate_id_nonce_signature( id_nonce=different_id_nonce, ephemeral_public_key=ephemeral_public_key, signature=signature, public_key=public_key, ) with pytest.raises(ValidationError): V4IdentityScheme.validate_id_nonce_signature( id_nonce=id_nonce, ephemeral_public_key=different_ephemeral_public_key, signature=signature, public_key=public_key, )
def test_handshake_public_key_validation_invalid(public_key): with pytest.raises(ValidationError): V4IdentityScheme.validate_handshake_public_key(public_key)
def test_handshake_public_key_validation_valid(public_key): V4IdentityScheme.validate_handshake_public_key(public_key)
def test_handshake_key_generation(): private_key, public_key = V4IdentityScheme.create_handshake_key_pair() V4IdentityScheme.validate_uncompressed_public_key(public_key) V4IdentityScheme.validate_handshake_public_key(public_key) assert PrivateKey(private_key).public_key.to_bytes() == public_key