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 coincurve
import pytest
from coincurve import PublicKey
from cryptography.hazmat.backends.openssl import backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
from eth_tester.exceptions import TransactionFailed
from eth_utils import to_normalized_address
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_SHA256 = 1
@ -53,26 +53,25 @@ def test_recover(testerchain, signature_verifier):
# Generate Umbral key and extract "address" from the public key
umbral_privkey = UmbralPrivateKey.gen_key()
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:])
# Sign message using SHA-256 hash (because only 32 bytes hash can be used in the `ecrecover` method)
cryptography_priv_key = umbral_privkey.to_cryptography_privkey()
signature_der_bytes = cryptography_priv_key.sign(message, ec.ECDSA(hashes.SHA256()))
signature = Signature.from_bytes(signature_der_bytes, der_encoded=True)
# Sign message
signer = Signer(umbral_privkey)
signature = signer(message)
# 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
# Only the correct v will match the correct public key
# First try v = 0
recoverable_signature = bytes(signature) + bytes([0])
pubkey_bytes = coincurve.PublicKey.from_signature_and_message(recoverable_signature, message_hash, hasher=None)\
.format(compressed=False)
pubkey = PublicKey.from_signature_and_message(recoverable_signature, message_hash, hasher=None)
pubkey_bytes = pubkey.format(compressed=False)
if pubkey_bytes != umbral_pubkey_bytes:
# Extracted public key is not ours, that means v = 1
recoverable_signature = bytes(signature) + bytes([1])
pubkey_bytes = coincurve.PublicKey.from_signature_and_message(recoverable_signature, message_hash, hasher=None)\
.format(compressed=False)
pubkey = PublicKey.from_signature_and_message(recoverable_signature, message_hash, hasher=None)
pubkey_bytes = pubkey.format(compressed=False)
# Check that recovery was ok
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())
# 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(
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):
# Generate Umbral key and extract "address" from the public key
umbral_privkey = UmbralPrivateKey.gen_key()
umbral_pubkey_bytes = umbral_privkey.get_pubkey().to_bytes(is_compressed=False)
signer_address = bytearray(testerchain.interface.w3.solidityKeccak(['bytes32'], [umbral_pubkey_bytes[1:]]))
umbral_pubkey_bytes = umbral_privkey.get_pubkey().to_bytes(is_compressed=False)[1:]
signer_address = keccak_digest(umbral_pubkey_bytes)
signer_address = to_normalized_address(signer_address[12:])
# 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)
@ -131,9 +130,8 @@ def test_verify(testerchain, signature_verifier):
umbral_pubkey_bytes = umbral_privkey.get_pubkey().to_bytes(is_compressed=False)
# Sign message using SHA-256 hash
cryptography_priv_key = umbral_privkey.to_cryptography_privkey()
signature_der_bytes = cryptography_priv_key.sign(message, ec.ECDSA(hashes.SHA256()))
signature = Signature.from_bytes(signature_der_bytes, der_encoded=True)
signer = Signer(umbral_privkey)
signature = signer(message)
# Prepare message hash
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
# First try v = 0
recoverable_signature = bytes(signature) + bytes([0])
pubkey_bytes = coincurve.PublicKey.from_signature_and_message(recoverable_signature, message_hash, hasher=None) \
.format(compressed=False)
pubkey = PublicKey.from_signature_and_message(recoverable_signature, message_hash, hasher=None)
pubkey_bytes = pubkey.format(compressed=False)
if pubkey_bytes != umbral_pubkey_bytes:
# Extracted public key is not ours, that means v = 1
recoverable_signature = bytes(signature) + bytes([1])
# Verify signature
assert signature_verifier.functions.\
verify(message, recoverable_signature, umbral_pubkey_bytes[1:], ALGORITHM_SHA256).call()
assert signature_verifier.functions.verify(message,
recoverable_signature,
umbral_pubkey_bytes[1:],
ALGORITHM_SHA256).call()
# Verify signature using wrong key
umbral_privkey = UmbralPrivateKey.gen_key()
umbral_pubkey_bytes = umbral_privkey.get_pubkey().to_bytes(is_compressed=False)
assert not signature_verifier.functions.\
verify(message, recoverable_signature, umbral_pubkey_bytes[1:], ALGORITHM_SHA256).call()
assert not signature_verifier.functions.verify(message,
recoverable_signature,
umbral_pubkey_bytes[1:],
ALGORITHM_SHA256).call()