From b0a4abd79a2ffc80ad09c77aa0741cc2d24a35f4 Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Sun, 28 Jan 2024 14:03:12 +0000 Subject: [PATCH] bip_hd,ecc: compatibility fixes (libsecp256k1, Python 3.9) --- extmod/secp256k1mod.c | 15 +++++++++++---- mmgen/bip_hd/__init__.py | 21 ++++++++++++--------- mmgen/data/version | 2 +- test/include/ecc.py | 2 +- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/extmod/secp256k1mod.c b/extmod/secp256k1mod.c index efd38c32..b1e27b5b 100755 --- a/extmod/secp256k1mod.c +++ b/extmod/secp256k1mod.c @@ -16,6 +16,12 @@ this program. If not, see . */ +/* + NOTE: deprecated context flags SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY + must be used for now instead of SECP256K1_CONTEXT_NONE (see libsecp256k1 CHANGELOG) + for backward compatibility with libsecp256k1 #include @@ -84,9 +90,8 @@ static PyObject * pubkey_gen(PyObject *self, PyObject *args) { size_t pubkey_bytes_len = compressed == 1 ? 33 : 65; unsigned char pubkey_bytes[pubkey_bytes_len]; secp256k1_pubkey pubkey; - /* use deprecated context flags (see libsecp256k1 CHANGELOG) for backward compatibility (pre-bookworm) */ + /* see NOTE */ secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - /* secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); */ /* for bookworm and later */ if (ctx == NULL) { PyErr_SetString(PyExc_RuntimeError, "Context initialization failed"); return NULL; @@ -115,7 +120,8 @@ static PyObject * pubkey_tweak_add(PyObject *self, PyObject *args) { PyErr_SetString(PyExc_ValueError, "Unable to parse extension mod arguments"); return NULL; } - secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); + /* see NOTE */ + secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); secp256k1_pubkey pubkey; if (!pubkey_parse_with_check(ctx, &pubkey, pubkey_bytes, pubkey_bytes_len)) { return NULL; @@ -148,7 +154,8 @@ static PyObject * pubkey_check(PyObject *self, PyObject *args) { PyErr_SetString(PyExc_ValueError, "Unable to parse extension mod arguments"); return NULL; } - secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); + /* see NOTE */ + secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); secp256k1_pubkey pubkey; if (!pubkey_parse_with_check(ctx, &pubkey, pubkey_bytes, pubkey_bytes_len)) { return NULL; diff --git a/mmgen/bip_hd/__init__.py b/mmgen/bip_hd/__init__.py index 31c605f4..d70aa5b6 100644 --- a/mmgen/bip_hd/__init__.py +++ b/mmgen/bip_hd/__init__.py @@ -80,7 +80,7 @@ class Bip32ExtendedKey(Lockable): bipnum, cp_entry = parse_version_bytes(ver_hex) public = ver_hex == cp_entry.vb_pub - idx_raw = int.from_bytes(key[9:13]) + idx_raw = int.from_bytes(key[9:13], byteorder='big') self.base58 = key_b58 self.ver_bytes = key[:4] @@ -182,7 +182,7 @@ class MasterNode(Lockable): self.public = False self.base_cfg = base_cfg - check_privkey(int.from_bytes(self.key)) + check_privkey(int.from_bytes(self.key, byteorder='big')) def init_cfg(self, coin=None, network=None, addr_type=None, from_path=False, no_path_checks=False): @@ -295,9 +295,12 @@ class BipHDNode(Lockable): raise ValueError('cannot create extended private key for public node!') ret = b58chk_encode( bytes.fromhex(get_version_bytes(self.cfg.bip_proto, self.cfg.base_cfg.coin, public)) - + int.to_bytes(self.depth, length=1) + + int.to_bytes(self.depth, length=1, byteorder='big') + self.par_print - + int.to_bytes(self.idx + (hardened_idx0 if self.hardened and self.depth else 0), length=4) + + int.to_bytes( + self.idx + (hardened_idx0 if self.hardened and self.depth else 0), + length = 4, + byteorder = 'big') + self.chaincode + (self.pubkey_bytes if public else b'\x00' + self.key) ) @@ -333,7 +336,7 @@ class BipHDNode(Lockable): I = hmac.digest( self.chaincode, - key_in + ((hardened_idx0 if new.hardened else 0) + new.idx).to_bytes(length=4), + key_in + ((hardened_idx0 if new.hardened else 0) + new.idx).to_bytes(length=4, byteorder='big'), 'sha512') pk_addend_bytes = I[:32] @@ -342,11 +345,11 @@ class BipHDNode(Lockable): if new.public: new.key = pubkey_tweak_add(key_in, pk_addend_bytes) # checks range of pk_addend else: - pk_addend = int.from_bytes(pk_addend_bytes) + pk_addend = int.from_bytes(pk_addend_bytes, byteorder='big') check_privkey(pk_addend) - key_int = (int.from_bytes(self.key) + pk_addend) % secp256k1_order + key_int = (int.from_bytes(self.key, byteorder='big') + pk_addend) % secp256k1_order check_privkey(key_int) - new.key = int.to_bytes(key_int, length=32) + new.key = int.to_bytes(key_int, length=32, byteorder='big') new._lock() return new @@ -396,7 +399,7 @@ class BipHDNode(Lockable): if xk.public: pubkey_check(xk.key) else: - check_privkey(int.from_bytes(xk.key)) + check_privkey(int.from_bytes(xk.key, byteorder='big')) addr_types = { 84: 'bech32', diff --git a/mmgen/data/version b/mmgen/data/version index ea667bcd..7996f928 100644 --- a/mmgen/data/version +++ b/mmgen/data/version @@ -1 +1 @@ -14.1.dev6 +14.1.dev7 diff --git a/test/include/ecc.py b/test/include/ecc.py index 4fae1675..6c5c2ce4 100755 --- a/test/include/ecc.py +++ b/test/include/ecc.py @@ -32,7 +32,7 @@ def pubkey_check_pyecdsa(vk_bytes): _check_pub_point(_pubkey_to_pub_point(vk_bytes), vk_bytes) def pubkey_tweak_add_pyecdsa(vk_bytes,pk_addend_bytes): - pk_addend = int.from_bytes(pk_addend_bytes) + pk_addend = int.from_bytes(pk_addend_bytes, byteorder='big') point_sum = ( _pubkey_to_pub_point(vk_bytes) + ecdsa.SigningKey.from_secret_exponent(pk_addend, curve=ecdsa.SECP256k1).verifying_key.pubkey.point