-
Notifications
You must be signed in to change notification settings - Fork 410
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
why not add leading zero bytes to make childkey 32 bytes long? #172
Comments
We only ever need to pad the private key bytes when further deriving a child extended key. This is already taken care of here: btcutil/hdkeychain/extendedkey.go Lines 250 to 258 in 4649e4b
The other thing we care about is whether the integer corresponding to the private child key bytes is valid for the secp256k1 elliptic curve. Here it doesn't matter if the serialization was done in 32 bytes or less, as long as the underlying crypto library can convert it to a Note that the Let me know if this answers your question. Otherwise, if you can provide a failing test case, I'll gladly take a look. |
From my point of view, this implementatin might get a wrong result in some case. As the BIP32 said, in the case of computing a child extended hardened private key from the parent private key, I = HMAC-SHA512(Key = cpar, Data = 0x00 || ser256(kpar) || ser32(i)). btcutil/hdkeychain/extendedkey.go Lines 250 to 272 in 4649e4b
If the length of k.key is less than 32, for example 31, then the Data = 0x00 || 31 bytes || 0x00 || ser32(i). ser256(kpar) just performs like another key leading with this 31 bytes and followed one 0x00. This is not consistent with the regulations of BIP32. Here is a test vector. Seed(Hex): 1cae71ac5ed584ff88a078a119512d12bb61e5398521785e123b6d08809d44b2
In Chain m/44'/0', this implementaion gets a wrong result. This is because the length of the serialization of its parant private key is 31 and we are deriving a hardened child private key. I tried to fix this bug with leading 0x00 and got another result. Seed(Hex): 1cae71ac5ed584ff88a078a119512d12bb61e5398521785e123b6d08809d44b2
I got the same result on bip32.org. As the result shows, this implementation might calculate a child key different from the one specified in BIP32 in some scenarios. As for the official BIP-0032 test vectors, the length of the serialization of their private key are all 32. |
@silencer-Tsai good case👍 |
fixes issue btcsuite#172
@ksedgwic just ran into this issue, and I noticed that there is this already open issue. I submitted a PR just now, linked above. |
I try to replace the original code with the following code. Hope to help. btcutil/hdkeychain/extendedkey.go Line 257 in 4649e4b
copy(data[keyLen-len(k.key):], k.key) |
@silencer-Tsai if you haven't already, please submit it to BIP32 with the correct result? People randomly implementing and copy/pasting fixtures might run into it then. Plus a note to explain what to look for if it fails? :) Always thought it'd be cool to write a standard testing interface for bitcoin libraries, implement the interface for each lib, then test against vectors in the suite. This kind of bug (non-portable results due to implementation quirks) sucks and can be hard to detect for a long time if you always use the same software.. I can imagine a lot of stress trying to find out why electrum shows an empty balance but the servers say otherwise! |
Is this issue resolved? |
This has been resolved. |
…allet go-ethereum-hdwallet is a relatively straightforward wrapper around bip39 and btc hd wallet libraries. in the past, there was an issue in btc hd wallet libraries where they got derivation wrong with zero padding on the most significant byte side. btcsuite/btcutil#172 the way go-ethereum-hdwallet fixed this seems... wrong. miguelmota/go-ethereum-hdwallet#21 unfortunately, the issue was closed because the library was archived. so instead of using a questionable archived library for a few things, let's just use its libraries directly Change-Id: I418f07bc1763f52579afc4f58451de79d2194b88
See extendedkey.go:297
The bytes length may be smaller than 32. Is there any bug when deriving hardened private key?
The derived key with padding differs.
The text was updated successfully, but these errors were encountered: