Touchups to test_signature_verifier

pull/947/head
David Núñez 2019-05-01 12:37:10 +02:00
parent 33bc11a17c
commit 3316315b93
1 changed files with 27 additions and 25 deletions

View File

@ -18,17 +18,17 @@ along with nucypher. If not, see <https://www.gnu.org/licenses/>.
import os import os
import coincurve
import pytest import pytest
from coincurve import PublicKey
from cryptography.hazmat.backends.openssl import backend from cryptography.hazmat.backends.openssl import backend
from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
from eth_tester.exceptions import TransactionFailed from eth_tester.exceptions import TransactionFailed
from eth_utils import to_normalized_address from eth_utils import to_normalized_address
from umbral.keys import UmbralPrivateKey from umbral.keys import UmbralPrivateKey
from umbral.signing import Signature from umbral.signing import Signer
from nucypher.crypto.api import keccak_digest
ALGORITHM_KECCAK256 = 0 ALGORITHM_KECCAK256 = 0
ALGORITHM_SHA256 = 1 ALGORITHM_SHA256 = 1
@ -53,26 +53,25 @@ def test_recover(testerchain, signature_verifier):
# Generate Umbral key and extract "address" from the public key # Generate Umbral key and extract "address" from the public key
umbral_privkey = UmbralPrivateKey.gen_key() umbral_privkey = UmbralPrivateKey.gen_key()
umbral_pubkey_bytes = umbral_privkey.get_pubkey().to_bytes(is_compressed=False) umbral_pubkey_bytes = umbral_privkey.get_pubkey().to_bytes(is_compressed=False)
signer_address = bytearray(testerchain.interface.w3.solidityKeccak(['bytes32'], [umbral_pubkey_bytes[1:]])) signer_address = keccak_digest(umbral_pubkey_bytes[1:])
signer_address = to_normalized_address(signer_address[12:]) signer_address = to_normalized_address(signer_address[12:])
# Sign message using SHA-256 hash (because only 32 bytes hash can be used in the `ecrecover` method) # Sign message
cryptography_priv_key = umbral_privkey.to_cryptography_privkey() signer = Signer(umbral_privkey)
signature_der_bytes = cryptography_priv_key.sign(message, ec.ECDSA(hashes.SHA256())) signature = signer(message)
signature = Signature.from_bytes(signature_der_bytes, der_encoded=True)
# Get recovery id (v) before using contract # Get recovery id (v) before using contract
# If we don't have recovery id while signing than we should try to recover public key with different v # If we don't have recovery id while signing than we should try to recover public key with different v
# Only the correct v will match the correct public key # Only the correct v will match the correct public key
# First try v = 0 # First try v = 0
recoverable_signature = bytes(signature) + bytes([0]) recoverable_signature = bytes(signature) + bytes([0])
pubkey_bytes = coincurve.PublicKey.from_signature_and_message(recoverable_signature, message_hash, hasher=None)\ pubkey = PublicKey.from_signature_and_message(recoverable_signature, message_hash, hasher=None)
.format(compressed=False) pubkey_bytes = pubkey.format(compressed=False)
if pubkey_bytes != umbral_pubkey_bytes: if pubkey_bytes != umbral_pubkey_bytes:
# Extracted public key is not ours, that means v = 1 # Extracted public key is not ours, that means v = 1
recoverable_signature = bytes(signature) + bytes([1]) recoverable_signature = bytes(signature) + bytes([1])
pubkey_bytes = coincurve.PublicKey.from_signature_and_message(recoverable_signature, message_hash, hasher=None)\ pubkey = PublicKey.from_signature_and_message(recoverable_signature, message_hash, hasher=None)
.format(compressed=False) pubkey_bytes = pubkey.format(compressed=False)
# Check that recovery was ok # Check that recovery was ok
assert umbral_pubkey_bytes == pubkey_bytes assert umbral_pubkey_bytes == pubkey_bytes
@ -81,7 +80,7 @@ def test_recover(testerchain, signature_verifier):
signature_verifier.functions.recover(message_hash, recoverable_signature).call()) signature_verifier.functions.recover(message_hash, recoverable_signature).call())
# Also numbers 27 and 28 can be used for v # Also numbers 27 and 28 can be used for v
recoverable_signature = recoverable_signature[0:-1] + bytes([recoverable_signature[-1] + 27]) recoverable_signature = recoverable_signature[:-1] + bytes([recoverable_signature[-1] + 27])
assert signer_address == to_normalized_address( assert signer_address == to_normalized_address(
signature_verifier.functions.recover(message_hash, recoverable_signature).call()) signature_verifier.functions.recover(message_hash, recoverable_signature).call())
@ -100,12 +99,12 @@ def test_recover(testerchain, signature_verifier):
def test_address(testerchain, signature_verifier): def test_address(testerchain, signature_verifier):
# Generate Umbral key and extract "address" from the public key # Generate Umbral key and extract "address" from the public key
umbral_privkey = UmbralPrivateKey.gen_key() umbral_privkey = UmbralPrivateKey.gen_key()
umbral_pubkey_bytes = umbral_privkey.get_pubkey().to_bytes(is_compressed=False) umbral_pubkey_bytes = umbral_privkey.get_pubkey().to_bytes(is_compressed=False)[1:]
signer_address = bytearray(testerchain.interface.w3.solidityKeccak(['bytes32'], [umbral_pubkey_bytes[1:]])) signer_address = keccak_digest(umbral_pubkey_bytes)
signer_address = to_normalized_address(signer_address[12:]) signer_address = to_normalized_address(signer_address[12:])
# Check extracting address in library # Check extracting address in library
result_address = signature_verifier.functions.toAddress(umbral_pubkey_bytes[1:]).call() result_address = signature_verifier.functions.toAddress(umbral_pubkey_bytes).call()
assert signer_address == to_normalized_address(result_address) assert signer_address == to_normalized_address(result_address)
@ -131,9 +130,8 @@ def test_verify(testerchain, signature_verifier):
umbral_pubkey_bytes = umbral_privkey.get_pubkey().to_bytes(is_compressed=False) umbral_pubkey_bytes = umbral_privkey.get_pubkey().to_bytes(is_compressed=False)
# Sign message using SHA-256 hash # Sign message using SHA-256 hash
cryptography_priv_key = umbral_privkey.to_cryptography_privkey() signer = Signer(umbral_privkey)
signature_der_bytes = cryptography_priv_key.sign(message, ec.ECDSA(hashes.SHA256())) signature = signer(message)
signature = Signature.from_bytes(signature_der_bytes, der_encoded=True)
# Prepare message hash # Prepare message hash
hash_ctx = hashes.Hash(hashes.SHA256(), backend=backend) hash_ctx = hashes.Hash(hashes.SHA256(), backend=backend)
@ -143,18 +141,22 @@ def test_verify(testerchain, signature_verifier):
# Get recovery id (v) before using contract # Get recovery id (v) before using contract
# First try v = 0 # First try v = 0
recoverable_signature = bytes(signature) + bytes([0]) recoverable_signature = bytes(signature) + bytes([0])
pubkey_bytes = coincurve.PublicKey.from_signature_and_message(recoverable_signature, message_hash, hasher=None) \ pubkey = PublicKey.from_signature_and_message(recoverable_signature, message_hash, hasher=None)
.format(compressed=False) pubkey_bytes = pubkey.format(compressed=False)
if pubkey_bytes != umbral_pubkey_bytes: if pubkey_bytes != umbral_pubkey_bytes:
# Extracted public key is not ours, that means v = 1 # Extracted public key is not ours, that means v = 1
recoverable_signature = bytes(signature) + bytes([1]) recoverable_signature = bytes(signature) + bytes([1])
# Verify signature # Verify signature
assert signature_verifier.functions.\ assert signature_verifier.functions.verify(message,
verify(message, recoverable_signature, umbral_pubkey_bytes[1:], ALGORITHM_SHA256).call() recoverable_signature,
umbral_pubkey_bytes[1:],
ALGORITHM_SHA256).call()
# Verify signature using wrong key # Verify signature using wrong key
umbral_privkey = UmbralPrivateKey.gen_key() umbral_privkey = UmbralPrivateKey.gen_key()
umbral_pubkey_bytes = umbral_privkey.get_pubkey().to_bytes(is_compressed=False) umbral_pubkey_bytes = umbral_privkey.get_pubkey().to_bytes(is_compressed=False)
assert not signature_verifier.functions.\ assert not signature_verifier.functions.verify(message,
verify(message, recoverable_signature, umbral_pubkey_bytes[1:], ALGORITHM_SHA256).call() recoverable_signature,
umbral_pubkey_bytes[1:],
ALGORITHM_SHA256).call()