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.
# 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):