Robert Johnstone
Robert Johnstone

Reputation: 5371

Going from BIP39 (mnemonic) to BIP32 (public/private keys)

I'm looking to develop some code, that creates Bitcoin private and public keys from a mnemonic. My current understanding of this process is:

entropy > nmemonic > seed > public/private keys > public address

I am using Trezor's nmemonic library and moneywagon in my code.

import string
from random import SystemRandom, randrange
from binascii import hexlify, unhexlify
from moneywagon import generate_keypair
from mnemonic import mnemonic

def gen_rand():
    foo = SystemRandom()
    length = 32
    chars = string.hexdigits
    return ''.join(foo.choice(chars) for _ in range(length))

mnemo = mnemonic.Mnemonic('english')

entropy = gen_rand()
# entropy = '00000000000000000000000000000000'

words = mnemo.to_mnemonic(unhexlify(entropy))
seed = hexlify(mnemo.to_seed(words, passphrase='apassphrase'))
address = generate_keypair('btc', seed)

print(words)  
print(seed)
print(address['public']['address'])
print(address['private']['hex'])

If you comment out the above entropy line, and run the code, you get:

abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about
b'05de15fb96dc0ab9f03c9d411bf84c586c72e7c30bddd413a304896f9f994ea65e7fcafd2c6b796141e310850e5f30b6abc2e6aec79a8ff81f4ba38fde81c403'
15GyM1xxxxxxxxxxxxxxxxxxxxxxTXrrvG
8ede10xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxcae501

My problem is none of this is reflected in iancoleman.io/bip39 or bip32jp.github.io for generating mnemonic codes and public/private keys.

Where am I going wrong?

Upvotes: 8

Views: 5911

Answers (2)

Volodymyr Prokopyuk
Volodymyr Prokopyuk

Reputation: 353

Have a look at

https://github.com/volodymyrprokopyuk/go-wallet

A guided design and implementation of a BIP-32 HD wallet in Go with a convenient CLI for easy experimentation using Nushell.

A guided design and implementation of a HD wallet in Go with a convenient CLI for easy experimentation using Nushell (or any other shell). The wallet CLI exposes an easy to use and experiment CLI tools to generate BIP-39 mnemonics for a HD wallet, derive extended private and public keys for a BIP-32 HD wallet, encode and decode derived keys into different formats e.g. xprv, xpub. The wallet CLI also provides tools to generate secp256k1 key pairs, ESDSA sign transactions and verify signatures. The wallet CLI exposes tools to encode and decode data using the bsae58 and base58check encoding, as well as encode an Ethereum address using the ERC-55 address encoding.

Upvotes: 0

jan.vogt
jan.vogt

Reputation: 1817

Both sites generate the same seed as you, given your mnemonic:

abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about

Also https://bip32jp.github.io/english/ gives this specific mnemonic given your forced entropy of

entropy = '00000000000000000000000000000000'

(you have to choose base 16 encoding, since your call to unhexlify interprets this string as such)

The first site https://iancoleman.io/bip39/#english seems to heuristically determine the string encoding for the entropy and recognising it as binary. This yields consequently to another result.

The values for

address['public']['address']
address['private']['hex']

differ from yours on both pages, since these pages use different derivation algorithms than moneywagon does. Moneywagon uses BIP38 a discouraged algorithm. I assume that is the reason for both sites not to offer it.

Upvotes: 1

Related Questions