Browse Source

bip_hd,ecc: compatibility fixes (libsecp256k1, Python 3.9)

The MMGen Project 3 months ago
parent
commit
b0a4abd79a
4 changed files with 25 additions and 15 deletions
  1. 11 4
      extmod/secp256k1mod.c
  2. 12 9
      mmgen/bip_hd/__init__.py
  3. 1 1
      mmgen/data/version
  4. 1 1
      test/include/ecc.py

+ 11 - 4
extmod/secp256k1mod.c

@@ -16,6 +16,12 @@
   this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
+/*
+   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 <v0.2.0 (i.e. pre-bookworm distros).
+*/
+
 #define PY_SSIZE_T_CLEAN
 #include <Python.h>
 #include <secp256k1.h>
@@ -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;

+ 12 - 9
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',

+ 1 - 1
mmgen/data/version

@@ -1 +1 @@
-14.1.dev6
+14.1.dev7

+ 1 - 1
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