OSDN Git Service

add prune_root_scalar
authorChengcheng Zhang <943420582@qq.com>
Fri, 21 Dec 2018 07:06:38 +0000 (15:06 +0800)
committerChengcheng Zhang <943420582@qq.com>
Fri, 21 Dec 2018 07:06:38 +0000 (15:06 +0800)
app/model/key.py

index 7fe1e23..ed2a284 100644 (file)
@@ -76,6 +76,22 @@ def mnemonic_to_seed(mnemonic_str):
 
     return seed_str
 
+# s_str must be >= 32 bytes long and gets rewritten in place.
+# This is NOT the same pruning as in Ed25519: it additionally clears the third
+# highest bit to ensure subkeys do not overflow the second highest bit.
+def prune_root_scalar(s_str):
+    s_0_int = int.from_bytes(bytes.fromhex(s_str[0:2]), byteorder='big') & 248
+    s_0_str = "%0.2x" % s_0_int
+    new_s_str = s_0_str + s_str[2:]
+    s_31_int = int.from_bytes(bytes.fromhex(new_s_str[62:64]), byteorder='big') & 31
+    s_31_str = "%0.2x" % s_31_int
+    new_s_str = new_s_str[:62] + s_31_str + new_s_str[64:]
+    s_31_int = int.from_bytes(bytes.fromhex(new_s_str[62:64]), byteorder='big') | 64
+    s_31_str = "%0.2x" % s_31_int
+    new_s_str = new_s_str[:62] + s_31_str + new_s_str[64:]
+    
+    return new_s_str
+
 # seed_to_root_xprv create rootxprv from seed
 # seed_str length is 512 bits.
 # root_xprv length is 512 bits.
@@ -91,22 +107,25 @@ def mnemonic_to_seed(mnemonic_str):
 #   root_xprv: a01d6b741b0e74b8d0836ac22b675bbf8e108148ef018d1b000aef1a899a134bd316c0f59e7333520ae1a429504073b2773869e95aa95bb3a4fa0ec76744025c
 def seed_to_root_xprv(seed_str):
     hc_str = hmac.HMAC(b'Root', bytes.fromhex(seed_str), digestmod=hashlib.sha512).hexdigest()
-    hc_0_int = int.from_bytes(bytes.fromhex(hc_str[0:2]), byteorder='big') & 248
-    hc_0_str = "%0.2x" % hc_0_int
-    new_hc_str = hc_0_str + hc_str[2:]
-    hc_31_int = int.from_bytes(bytes.fromhex(new_hc_str[62:64]), byteorder='big') & 31
-    hc_31_str = "%0.2x" % hc_31_int
-    new_hc_str = new_hc_str[:62] + hc_31_str + new_hc_str[64:]
-    hc_31_int = int.from_bytes(bytes.fromhex(new_hc_str[62:64]), byteorder='big') | 64
-    hc_31_str = "%0.2x" % hc_31_int
-    new_hc_str = new_hc_str[:62] + hc_31_str + new_hc_str[64:]
-    root_xprv_str = new_hc_str
+    # hc_0_int = int.from_bytes(bytes.fromhex(hc_str[0:2]), byteorder='big') & 248
+    # hc_0_str = "%0.2x" % hc_0_int
+    # new_hc_str = hc_0_str + hc_str[2:]
+    # hc_31_int = int.from_bytes(bytes.fromhex(new_hc_str[62:64]), byteorder='big') & 31
+    # hc_31_str = "%0.2x" % hc_31_int
+    # new_hc_str = new_hc_str[:62] + hc_31_str + new_hc_str[64:]
+    # hc_31_int = int.from_bytes(bytes.fromhex(new_hc_str[62:64]), byteorder='big') | 64
+    # hc_31_str = "%0.2x" % hc_31_int
+    # new_hc_str = new_hc_str[:62] + hc_31_str + new_hc_str[64:]
+    # root_xprv_str = new_hc_str
+    root_xprv_str = prune_root_scalar(hc_str)
 
     return root_xprv_str
 
+##################################################
 # def xprv_to_xpub(xprv_str):
 # private_key = ed25519.SigningKey(bytes.fromhex(xprv_str[:64]))
 # public_key = private_key.get_verifying_key().to_ascii(encoding='hex')
 # xpub_str = public_key.decode() + xprv_str[64:]
 #     return xpub_str
 
+# def xprv_to_hardened_child(xprv_str):