WifDecoder throws error when presented with the Optional 0x01 suffix for a privatekey with a compressed public key
Anynomouss opened this issue · comments
When testing some implementation for BIP38 where I want both derivation for compressed and uncompressed public keys, I encountered this error:
When entering a WIF private-key with the optional 0x01
suffix, the decoder throws an error. Now, indeed the prefix is Optional, but it is good practice to use the suffix and it would be better to add support to the decoder and encoder for private-keys.
For explanation on WIF private-keys and suffixes:
https://learnmeabitcoin.com/technical/wif
Example for reproduction, a WIF key generated using iancolman too:
WifDecoder.Decode('6PRWGLWiYnnextD6uzpud3ttQMNc8RdMswUB7WSuV4UWZzumhKJJWiTTTL')
Hi,
the compressed/uncompressed public key is already supported by WIF. You can set the WifPubKeyModes
when encoding, and the same is returned when decoding.
enc = WifEncoder.Encode(
BytesUtils.FromHexString("e2668903ef6d0fec071c5e912ad506e804c95e6950bfc0f098edb7d56c581fb0"),
pub_key_mode=WifPubKeyModes.UNCOMPRESSED
)
# Print: 5KXzgLt48zbV83EXhjeo6xfGXggD9M8N7GNYytgheioLA8Md3RG
print(enc)
dec, mode = WifDecoder.Decode(enc)
# Print: e2668903ef6d0fec071c5e912ad506e804c95e6950bfc0f098edb7d56c581fb0 P2PKHPubKeyModes.UNCOMPRESSED
print(dec.hex(), mode)
The same for BIP38, you can specify the public key mode when encoding and getting it back when decoding.
You cannot decode an encrypted key like 6PRWGLWiYnnextD6uzpud3ttQMNc8RdMswUB7WSuV4UWZzumhKJJWiTTTL
with the WIF decoder, you should decode it using BIP38 giving the passphrase. If BIP38 gives error when decoding you can write me the example with the related passphrase.
Regards
Emanuele
Thanks, I understand now a bit better. But how do you get the public key and adresses then for a bip38 encrypted private-key? Basically I want to go from seed and path to get all information such as private-keys, public_keys and addresses assuming someone used bip38 encryption for the privatekeys.
You decrypt the private key with BIP38 and you use it to construct a BIP44 object with FromPrivateKey
method, then you can derive path and addresses as usual
Ok, but what I do not understand is that if you have a wallet without bip38 encryption, it has different public key and addresses, when testing this with:
https://iancoleman.io/bip39/
I also assumed it would be a normal wallet, with only the privatkey encrypted as extra protection, but this appears not to be the case, at least not in the implementation from Ian Coleman.
You should give me an example.
Anyway, it clearly depends what private key you are encrypting. If you encrypt the master key, then you should derive the complete path. If you encrypt a private key related to an address (like the tool), you should set the correct depth when constructing the BIP44 object so that it can derive the correct keys.
I think I might have found it:
When I compare the public-key in hex encryption is 130 long in Ian Coleman's tool when using BIP38, and only 66 characters long without using BIP38 encryption for the private-key. Maybe he by accident switches to using an uncompressed public key, because the privatekey starts with 6PR
(compressed form of an uncompressed key), while the keys generated with bip_utils start with 6PY
(compressed).
I do not know if this should be considered a mistake in his implementation, I think it is since it is strange to suddenly without user interaction switch between compressed or uncompressed mode. I will try using the uncompressed mode, see if it matches with his public-keys and addresses.
The issue is not with bip_utils, but a bit unexpected behavior of so I close this issue. to switch from compressed to uncompressed public keys when enabling BIP38 encryption. I will close this issue.