ecc: allow tests to disable ecdsa R-value grinding
see https://github.com/spesmilo/electrum/pull/7453#issuecomment-912594926
This commit is contained in:
@@ -41,6 +41,11 @@ from .ecc_fast import _libsecp256k1, SECP256K1_EC_UNCOMPRESSED
|
|||||||
_logger = get_logger(__name__)
|
_logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
# Some unit tests need to create ECDSA sigs without grinding the R value (and just use RFC6979).
|
||||||
|
# see https://github.com/bitcoin/bitcoin/pull/13666
|
||||||
|
ENABLE_ECDSA_R_VALUE_GRINDING = True
|
||||||
|
|
||||||
|
|
||||||
def string_to_number(b: bytes) -> int:
|
def string_to_number(b: bytes) -> int:
|
||||||
return int.from_bytes(b, byteorder='big', signed=False)
|
return int.from_bytes(b, byteorder='big', signed=False)
|
||||||
|
|
||||||
@@ -463,11 +468,12 @@ class ECPrivkey(ECPubkey):
|
|||||||
return r, s
|
return r, s
|
||||||
|
|
||||||
r, s = sign_with_extra_entropy(extra_entropy=None)
|
r, s = sign_with_extra_entropy(extra_entropy=None)
|
||||||
counter = 0
|
if ENABLE_ECDSA_R_VALUE_GRINDING:
|
||||||
while r >= 2**255: # grind for low R value https://github.com/bitcoin/bitcoin/pull/13666
|
counter = 0
|
||||||
counter += 1
|
while r >= 2**255: # grind for low R value https://github.com/bitcoin/bitcoin/pull/13666
|
||||||
extra_entropy = counter.to_bytes(32, byteorder="little")
|
counter += 1
|
||||||
r, s = sign_with_extra_entropy(extra_entropy=extra_entropy)
|
extra_entropy = counter.to_bytes(32, byteorder="little")
|
||||||
|
r, s = sign_with_extra_entropy(extra_entropy=extra_entropy)
|
||||||
|
|
||||||
sig_string = sig_string_from_r_and_s(r, s)
|
sig_string = sig_string_from_r_and_s(r, s)
|
||||||
self.verify_message_hash(sig_string, msg_hash)
|
self.verify_message_hash(sig_string, msg_hash)
|
||||||
|
|||||||
@@ -86,6 +86,24 @@ def needs_test_with_all_chacha20_implementations(func):
|
|||||||
return run_test
|
return run_test
|
||||||
|
|
||||||
|
|
||||||
|
def disable_ecdsa_r_value_grinding(func):
|
||||||
|
"""Function decorator to run a unit test with ecdsa R-value grinding disabled.
|
||||||
|
This is used when we want to pass test vectors that were created without R-value grinding.
|
||||||
|
(see https://github.com/bitcoin/bitcoin/pull/13666 )
|
||||||
|
|
||||||
|
NOTE: this is inherently sequential;
|
||||||
|
tests running in parallel would break things
|
||||||
|
"""
|
||||||
|
def run_test(*args, **kwargs):
|
||||||
|
is_grinding = ecc.ENABLE_ECDSA_R_VALUE_GRINDING
|
||||||
|
try:
|
||||||
|
ecc.ENABLE_ECDSA_R_VALUE_GRINDING = False
|
||||||
|
func(*args, **kwargs)
|
||||||
|
finally:
|
||||||
|
ecc.ENABLE_ECDSA_R_VALUE_GRINDING = is_grinding
|
||||||
|
return run_test
|
||||||
|
|
||||||
|
|
||||||
class Test_bitcoin(ElectrumTestCase):
|
class Test_bitcoin(ElectrumTestCase):
|
||||||
|
|
||||||
def test_libsecp256k1_is_available(self):
|
def test_libsecp256k1_is_available(self):
|
||||||
@@ -221,6 +239,12 @@ class Test_bitcoin(ElectrumTestCase):
|
|||||||
sig2 = eckey2.sign_transaction(bfh('642a2e66332f507c92bda910158dfe46fc10afbf72218764899d3af99a043fac'))
|
sig2 = eckey2.sign_transaction(bfh('642a2e66332f507c92bda910158dfe46fc10afbf72218764899d3af99a043fac'))
|
||||||
self.assertEqual('30440220618513f4cfc87dde798ce5febae7634c23e7b9254a1eabf486be820f6a7c2c4702204fef459393a2b931f949e63ced06888f35e286e446dc46feb24b5b5f81c6ed52', sig2.hex())
|
self.assertEqual('30440220618513f4cfc87dde798ce5febae7634c23e7b9254a1eabf486be820f6a7c2c4702204fef459393a2b931f949e63ced06888f35e286e446dc46feb24b5b5f81c6ed52', sig2.hex())
|
||||||
|
|
||||||
|
@disable_ecdsa_r_value_grinding
|
||||||
|
def test_sign_transaction_without_ecdsa_r_value_grinding(self):
|
||||||
|
eckey1 = ecc.ECPrivkey(bfh('7e1255fddb52db1729fc3ceb21a46f95b8d9fe94cc83425e936a6c5223bb679d'))
|
||||||
|
sig1 = eckey1.sign_transaction(bfh('5a548b12369a53faaa7e51b5081829474ebdd9c924b3a8230b69aa0be254cd94'))
|
||||||
|
self.assertEqual('3045022100902a288b98392254cd23c0e9a49ac6d7920f171b8249a48e484b998f1874a2010220723d844826828f092cf400cb210c4fa0b8cd1b9d1a7f21590e78e022ff6476b9', sig1.hex())
|
||||||
|
|
||||||
@needs_test_with_all_aes_implementations
|
@needs_test_with_all_aes_implementations
|
||||||
def test_aes_homomorphic(self):
|
def test_aes_homomorphic(self):
|
||||||
"""Make sure AES is homomorphic."""
|
"""Make sure AES is homomorphic."""
|
||||||
|
|||||||
Reference in New Issue
Block a user