ebellocchia / bip_utils

Generation of mnemonics, seeds, private/public keys and addresses for different types of cryptocurrencies

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.