2

I need an algorithm for translating a 12-word phrase to BTC SegWit bech32 P2WPKH addresses.

I wrote a function in Python that returns a seed, but I don't understand what to do next. Here when entering a 12 word phrase the seed is shown, then, if I select the BIP84 derivation path tab, the address I need is displayed in the table of derived addresses in item m/84'/0'/0'/0/0. Same with ether address, but on the BIP44 tab, and item m/44'/60'/0'/0/0.

I roughly understand that this is a tree-like derivation of some keys from others, but I don’t know what algorithms are needed and how to hash the keys to get the final addresses.

Example: I need this:

absent project job apart fault staff age cycle option pulp direct rail

convert to this:

BTC: bc1q57gu73qnxw3we7h7k9zrg2v5cvg5d7j0g5y6d4

I already have a function to get the seed:

59dc4d5348b364f9024e2af7d6bcd6fd115a95a5dfe33b213ddac6d1ed4b77175b05e727605c62c98bd110d0952dcb38de9f16c94e55b82603af77d5226be5f5

Please explain what I need to do next.

1

1 Answer 1

2

To get from the seed to the BIP84 address (intended for the P2WPKH), you must follow the derivation path defines in BIP84 standard and apply the appropriate derivation operation.

The derivation path defined in this standard is: m/84'/0'/0'/0/0 where m stands for the master key, the sign / denotes the level of the tree and the number between the / denote the index of key in that level. With the ' sign, it is indicated that the key was of hardened type (hardened derivation was applied). If there is no such sign, the key a result of the normal derivation.

So first what we need to do is to get the master key from the seed. To do this, we follow the BIP32 section for the master key generation. It says that after generating the seed, we need to use the HMAC-SHA512 function where the key is Bitcoin seed and the data is the seed. In our case:

KEY: Bitcoin seed
DATA: 59dc4d5348b364f9024e2af7d6bcd6fd115a95a5dfe33b213ddac6d1ed4b77175b05e727605c62c98bd110d0952dcb38de9f16c94e55b82603af77d5226be5f5

For this purpose, you can use an online tool like this. Set the values as I did in the following image. I keep mentioning online tools (it was easier for me to use them when writing the answer), however, you can also use well-tested programming libraries in different programming languages.

enter image description here

The result is the following:

f36ab72ee8ddc6c9288a3a26dc5f1009198bd37169dfb6ddc93b7c237b63b231c547d66d20e80779c2b7a48e9d59f989ae8c3e2bf3e8eb752aae9fb555ad5123

Left 32 bytes represent master/root private key and the right 32 bytes represent master/root chain code. Thus:

MASTER PRIVATE KEY: f36ab72ee8ddc6c9288a3a26dc5f1009198bd37169dfb6ddc93b7c237b63b231
MASTER CHAIN CODE: c547d66d20e80779c2b7a48e9d59f989ae8c3e2bf3e8eb752aae9fb555ad5123

On the site you provided they represent BIP32 Root Key as a zprv base58check encoded extended private key. But that's just a way of presenting it, nothing else.

Now that we have our master private key, we need to generate its child keys. Looking at the derivation path, we can see that next what we need to generate is the 85th key at the second level. The hardened derivation is used (it has the sign ').

Before we continue, it's important to note that the indexes for hardened children start at 2^31. So the index for the 85th hardened child is actually 2147483732 (hex: 80000054). For the 1st child it would be 2147483648 (hex: 80000000).

So to get the 85th hardened child, following the BIP32 section to derive the hardened child private key from the parent's private key, the first thing we need to do is use the HMAC-SHA512 function where the key is the parent's chain code and the date is the concatenation of 0x00, the parent's private key and child index. So the inputs for the HMAC-SHA512 are:

KEY: c547d66d20e80779c2b7a48e9d59f989ae8c3e2bf3e8eb752aae9fb555ad5123
DATA: 00f36ab72ee8ddc6c9288a3a26dc5f1009198bd37169dfb6ddc93b7c237b63b23180000054

You can again use the same online tool. The result is:

4eb98f36d3bd9c27c2d74ae497e2dba29e3af8365b1de8fc29dd2f39b8111017841d3b7767023d0d985618d4a6b8d466aaac220155cb1fb18739836a86f2c223

Next, following BIP32, the right 32 bytes represent the child's chain key, and to get the child's private key, the next thing we need to do is add the left half of the result (4eb98f36d3bd9c27c2d74ae497e2dba29e3af8365b1de8fc29dd2f39b8111017) and the parent's private key (f36ab72ee8ddc6c9288a3a26dc5f1009198bd37169dfb6ddc93b7c237b63b231). Also, the MOD operation should be performed on the obtained result. The secp256k1 elliptic curve order is used for this. Order of the secp256k1 elliptic curve is FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141. Next two pictures show how to do this using this online tool.

enter image description here

enter image description here

So, the 85th hardened child private key and its chain code are:

CHILD PRIVATE KEY: 42244665bc9b62f0eb61850b7441ebacfd17eec115b4ff9e33464cd0633e8107
CHILD CHAIN CODE: 841d3b7767023d0d985618d4a6b8d466aaac220155cb1fb18739836a86f2c223

Absolutely the same mechanism is used to get the next two children in the BIP84 derivation path. The only difference is that the index of the child is 0, that is 2147483648 (hex: 80000000) since it is a hardened derivation. That's why I will write only the results.

m/84'/0'

CHILD PRIVATE KEY: 68155c2b225b592f73e2f812a307d9a15f4cb352cf3fc12e80fea185c63a176e
CHILD CHAIN CODE: 52da1bc66383744a78001a8b504d5d28c1fea7b98a95c361a8d8cc23fb371345

m/84'/0'/0'

CHILD PRIVATE KEY: f4f8cb21aae3e6b3df7acee3f65bb592824b770ecbbc6ebe1efa4479d4950978
CHILD CHAIN CODE: f871e9c89e2ad059573dbd49bc14f6d1d2b1d444027ec12c23d2ede7b921175f

The remaining two children we need to find (m/84'/0'/0'/0 and m/84'/0'/0'/0/0) are derived using non-hardened (normal) derivation. The procedure is more or less the same, with the fact that in the HMAC-SHA512 function, the private key is not forwarded, but the public key. Therefore, based on the private key, it is first necessary to find its public key. I will not go into the details of this.

To find a public key from a private key, you can use this online tool.

So, for the private key f4f8cb21aae3e6b3df7acee3f65bb592824b770ecbbc6ebe1efa4479d4950978, the corresponding uncompressed public key is:

04576DF6CA4FA6D5347899277169CD38646F74E35A391F85DBDAFD3DE697F106979CDEA7B904A7B6F254BD3635ABEDCB140CBBDBBC2A81E7CB7223259B846E7BB2

The problem here is that we need a compressed public key, so we can again use one of the online tool. So the compressed public key is:

PRIVATE KEY: f4f8cb21aae3e6b3df7acee3f65bb592824b770ecbbc6ebe1efa4479d4950978
PUBLIC KEY: 02576df6ca4fa6d5347899277169cd38646f74e35a391f85dbdafd3de697f10697

Now we have everything we need to find a non-hardened child private key. BIP32 says that we need to use HMAC-SHA512 function where the key is parent chain code, and the date is the concatenation of the (now) parent public key and the child index. So the inputs to the HMAC-SHA512 are:

KEY: f871e9c89e2ad059573dbd49bc14f6d1d2b1d444027ec12c23d2ede7b921175f
DATA: 02576df6ca4fa6d5347899277169cd38646f74e35a391f85dbdafd3de697f1069700000000

The further process is exactly the same as with hardened derivation. The left half of the result is added with the parent's private key, and then the MOD operation is performed. In this way, the child's private key is obtained. The right side of the result represents the chain code of the child. Thus:

RESULT: ef2ca2404a289aefb8ed2327215ed0660524d470394e06d4c6cd665e23191ffd1ba81f4c432bba50b8c1089b4030e4edf71ada1ac83962f745dc3769525d004c
CHILD PRIVATE KEY: e4256d61f50c81a39867f20b17ba85f9ccc16e9855c1d55725f54c4b2777e834
CHILD CHAIN CODE: 1ba81f4c432bba50b8c1089b4030e4edf71ada1ac83962f745dc3769525d004c

And for the last child (m/84'/0'/0'/0/0):

PARENT PRIVATE KEY: e4256d61f50c81a39867f20b17ba85f9ccc16e9855c1d55725f54c4b2777e834
PARENT PUBLIC KEY: 03ad87f5eb4b30ba3aa1b4713cacb4d722b47d729ac0b24c4c9810d4d2d11981ed
CHILD PRIVATE KEY: 879bef1ec302343d2c722fbfbd313165f2e1ef4828b0e74249bcef6e15ec55db
CHILD CHAIN CODE: f0aebf37903b4bd76d90456771c6673ff2b09bbd58435d54afb69089e30791ca
CHILD PUBLIC KEY: 0299c5b020a59dbe0059292b9c78f869ed82768de29184cd60feafd33db3f4e0e2

And that is that. We have received the public key for the path m/84'/0'/0'/0/0. The only thing left is to calculate the address and encode it with bech32. To get a P2WPKH address in Bitcoin, you need to do RIPEMD160 (SHA256 (public key)). So we have the following:

PUBLIC KEY: 0299c5b020a59dbe0059292b9c78f869ed82768de29184cd60feafd33db3f4e0e2
SHA256(PUBLIC KEY): 2152377138127c59daf69fc627325d1b1b76c775a3c1e5063dd6f265cf7bb4b1
RIPEMD160(SHA256(PUBLIC KEY)): a791cf441333a2ecfafeb144342994c31146fa4f

At the end we just need to encode a791cf441333a2ecfafeb144342994c31146fa4f in bech32. For that, we can use this online tool.

This way we get the address you asked for (bc1q57gu73qnxw3we7h7k9zrg2v5cvg5d7j0g5y6d4).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.