def subkey_secret_exponent_chain_code_pair(
secret_exponent, chain_code_bytes, i, is_hardened, public_pair=None):
"""
Yield info for a child node for this node.
secret_exponent:
base secret exponent
chain_code:
base chain code
i:
the index for this node.
is_hardened:
use "hardened key derivation". The public version of this node cannot calculate this child.
public_pair:
the public_pair for the given secret exponent. If you leave it None, it's calculated for you
(but then it's slower)
Returns a pair (new_secret_exponent, new_chain_code)
"""
i_as_bytes = struct.pack(">L", i)
if is_hardened:
data = b'\0' + to_bytes_32(secret_exponent) + i_as_bytes
else:
if public_pair is None:
public_pair = ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, secret_exponent)
sec = public_pair_to_sec(public_pair, compressed=True)
data = sec + i_as_bytes
I64 = hmac.HMAC(key=chain_code_bytes, msg=data, digestmod=hashlib.sha512).digest()
I_left_as_exponent = from_bytes_32(I64[:32])
if I_left_as_exponent >= ORDER:
logger.critical(_SUBKEY_VALIDATION_LOG_ERR_FMT)
raise DerivationError('I_L >= {}'.format(ORDER))
new_secret_exponent = (I_left_as_exponent + secret_exponent) % ORDER
if new_secret_exponent == 0:
logger.critical(_SUBKEY_VALIDATION_LOG_ERR_FMT)
raise DerivationError('k_{} == 0'.format(i))
new_chain_code = I64[32:]
return new_secret_exponent, new_chain_code
评论列表
文章目录