def decode(b58: str) -> bytes: partial_sum = 0 exponent = 0 for digit in reversed(b58): try: partial_sum += ALPHABET.index(digit) * BASE**exponent except ValueError: raise Base58DecodeError('Bad Byte') from None exponent += 1 return int_to_bytes(partial_sum)
def var_int(n): if n < 0xfd: return int_to_bytes(n) elif n <= 0xffff: return b'\xfd' + pad(n, 2)[::-1] elif n <= 0xffffffff: return b'\xfe' + pad(n, 4)[::-1] elif n <= 0xffffffffffffffff: return b'\xff' + pad(n, 8)[::-1] else: raise ValueError('Data too long for var_int')
def child(self, i: int) -> 'Xprv': hardened = i >= 1 << 31 if hardened: I = hmac.new(key=self.code, msg=self.keydata() + int_to_bytes(i).rjust(32, b'\x00'), digestmod=hashlib.sha512).digest() else: I = hmac.new(key=self.code, msg=self.key.to_public().encode(compressed=True) + int_to_bytes(i).rjust(32, b'\x00'), digestmod=hashlib.sha512).digest() I_L, I_R = bytes_to_int(I[:32]), I[32:] key = I_L + self.key.int() % CURVE.N if I_L >= CURVE.N or key == 0: return self.child(i + 1) ret_code = I_R return Xprv(key, ret_code, depth=self.depth + 1, i=i)
def child(self, i: int) -> 'Xpub': hardened = i >= 1 << 31 if hardened: raise KeyDerivationError( 'Cannot derive a hardened key from a Public key') I = hmac.new(key=self.code, msg=self.keydata() + int_to_bytes(i).rjust(32, b'\x00')) I_L, I_R = I[:32], I[32:] key = PrivateKey(I_L).to_public().point + self.key.point ret_code = I_R # TODO add point at infinity check return Xpub(key, ret_code, depth=self.depth + 1, i=i)
def witness_byte(witver: int) -> bytes: assert 0 <= witver <= 16, "Witness version must be between 0-16" return int_to_bytes(witver + 0x50 if witver > 0 else 0)
def byte(self): return int_to_bytes(self.value)