#!/usr/bin/env python3
from bip_utils import Bip84, Bip84Coins, Bip44Changes
from mnemonic import Mnemonic
import hmac, hashlib
from ecdsa import SECP256k1, SigningKey
mn = Mnemonic("english")
mnemonic_str = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
seed = mn.to_seed(mnemonic_str)
bip84 = Bip84.FromSeed(seed, Bip84Coins.BITCOIN)
account = bip84.Purpose().Coin().Account(acc_idx=0)
chain = account.Change(Bip44Changes.CHANGE_EXTERNAL)
addr_obj = chain.AddressIndex(0)
priv_key = bytes(addr_obj.PrivateKey().Raw())
print("bip-utils final priv key:", priv_key.hex())
sk = SigningKey.from_string(priv_key, curve=SECP256k1)
vk = sk.verifying_key
pub_uncompressed = vk.to_string()
y = int.from_bytes(pub_uncompressed, "big")
prefix = 0x02 if y % 2 == 0 else 0x03
pub_compressed = bytes([prefix]) + pub_uncompressed[:32]
print("Computed pubkey:", pub_compressed.hex())
def hash160(data):
h = hashlib.new("ripemd160")
h.update(hashlib.sha256(data).digest())
return h.digest()
h160 = hash160(pub_compressed)
print("H160:", h160.hex())
bech32_obj = addr_obj.ToBech32()
addr = bech32_obj.Payload()
print("\nbip-utils address:", addr)
def bech32_encode(hrp, data_bytes):
charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
def convertbits(data, frombits, tobits, pad=True):
acc = 0
bits = 0
ret = []
maxv = (1 << tobits) - 1
for v in data:
acc = (acc << frombits) | v
bits += frombits
while bits >= tobits:
bits -= tobits
ret.append((acc >> bits) & maxv)
if pad and bits:
ret.append((acc << (tobits - bits)) & maxv)
return ret
def polymod(values):
GEN = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3]
res = 1
for v in values:
b = res >> 25
res = ((res & 0x1ffffff) << 5) ^ v
for i in range(5):
res ^= GEN[i] if ((b >> i) & 1) else 0
return res ^ 1
data5 = convertbits([0x00] + list(data_bytes), 8, 5)
payload = [0x00] + data5
checksum = polymod([0] + [ord(c) for c in hrp] + [0] + payload + [0]*6)
for i in range(6):
payload.append((checksum >> (5 * (5 - i))) & 0x1f)
return hrp + "1" + "".join(charset[d] for d in payload)
my_addr = bech32_encode("bc", h160)
print("My bech32: ", my_addr)
print()
print("MATCH:", my_addr == addr)