eoscanada / eos-go

EOS.IO Go API library
MIT License
563 stars 217 forks source link

Got an error when trying to import PVT_K1 format private key #168

Open cream-cheeze opened 2 years ago

cream-cheeze commented 2 years ago

When I'm trying to import PVT_K1 format private key I got the error: "malformed private key".

keyBag := &eos.KeyBag{}
err := keyBag.ImportPrivateKey(context.Background(), pk)

With old PK format works fine.

maoueh commented 2 years ago

Could you provide a dummy private key that exhibits the problem? Do not post your own private keys! (Sorry for this over caution comment)

cream-cheeze commented 2 years ago

The format I had issues with is like this: PVT_K1_ZZZZZZZZZZZ555555555555. With a format like EOS5WZZZZZZZZZZZZZ5555555 it works fine.

maoueh commented 2 years ago

@cream-cheeze The EOS5WZZZZZZZZZZZZZ5555555 is the format of the public key, and it's not a private key. I just added a test https://github.com/eoscanada/eos-go/commit/25569fc708280b5237ebc11f74e28a970e7298c5 which is

func TestPrefixedK1PrivateToPublic(t *testing.T) {
    wif := "PVT_K1_5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss"
    privKey, err := NewPrivateKey(wif)
    require.NoError(t, err)

    pubKey := privKey.PublicKey()

    pubKeyString := pubKey.String()
    assert.Equal(t, PublicKeyPrefixCompat+"859gxfnXyUriMgUeThh1fWv3oqcpLFyHa3TfFYC4PK2HqhToVM", pubKeyString)
}

And this pass. if I use PVT_K1_ZZZZZZZZZZZ555555555555, it doesn't work because it's a malformed private key:

--- FAIL: TestPrefixedK1PrivateToPublic (0.00s)
    crypto_test.go:26:
            Error Trace:    crypto_test.go:26
            Error:          Received unexpected error:
                            malformed private key
            Test:           TestPrefixedK1PrivateToPublic
            Messages:       private key "PVT_K1_ZZZZZZZZZZZ555555555555"

Would you have one that was is valid and was not working as expected?

cream-cheeze commented 2 years ago

You are right, sorry for misleading you. I provided you with the wrong examples.

Actually, I did not try to use a public key in my code - the key I've used and which was OK is of such format: 6YHa4...aRyt The private key that didn't work for me was of format like I've specified before - PVT_K1_2Cvew4...FEW - it is not malformed, it's just an example, because as you said I will not give you a real PK.

cream-cheeze commented 2 years ago

Try this one: PVT_K1_6AcEnhoMbeiCUa53Kkly79XvAgOPdNwWBuNY6qhhrb55EH1iUC - I've just modified some symbols of one of the existing PKs - the length is the same. Such PKs are used in the Proton chain.

maoueh commented 2 years ago

I should have been clearer about the "dummy" key, meant a valid one that is not working that can be publicly shared.

I tried the provided 6AcEnhoMbeiCUa53Kkly79XvAgOPdNwWBuNY6qhhrb55EH1iUC just as-is and it's still says malformed private (even without the actual prefix).

I get that you cannot share the private key that you initially had problem with. How did you generate it do you remember?

cream-cheeze commented 2 years ago

I've just created an account with Proton Wallet (WebAuth.com) - it generated PK for me. OK, I will generate a new one and will post it here in a while.

cream-cheeze commented 2 years ago

Here you go: PVT_K1_3mP9KLWYvrZtreadWBGGV1ZGu8L6EJ1JryJjFoxzGPeP5AxCX - it is the real one not used anywhere. It is successfully reading with the Anchor wallet, for example.

maoueh commented 2 years ago

Ok so even with 3mP9KLWYvrZtreadWBGGV1ZGu8L6EJ1JryJjFoxzGPeP5AxCX it still says malformed private key. I get though that's it's a valid key that can be imported in Anchor Wallet.

How it was generated, I would like to know to better find why the key is malformed according to the crypto lib we use.

cream-cheeze commented 2 years ago

This is the problem - that the lib recognizes the key as malformed.

It was created by WebAuth.com (Proton) mobile wallet.

maoueh commented 2 years ago

But is it a WebAuthn key? If it's a WebAuth key, then it's normal that it doesn't work, WebAuthn has not the same format and payload info as a K1 key.

maoueh commented 2 years ago

To be honest, I did not investigate the WebAuthn private key part, I did the public key portion but not the private key part. So I'm wondering if it's prefixed with PVT_K1 but it's actually in another format.

Not clear.

maoueh commented 2 years ago

When I registered on WebAuth.com, I did get a PVT_WA_... key, how did you get the PVT_K1_ one?

cream-cheeze commented 2 years ago

But is it a WebAuthn key? If it's a WebAuth key, then it's normal that it doesn't work, WebAuthn has not the same format and payload info as a K1 key.

But how does Anchor understand this key with no problem?

There is a note on the protonscan.io about public keys:

Screenshot 2022-01-20 at 18 20 16

I assume the same is true for private keys. If so, it looks like it is just another format of writing a key.

For example, for public keys I can see both versions:

Screenshot 2022-01-20 at 18 24 56 Screenshot 2022-01-20 at 18 25 03
cream-cheeze commented 2 years ago

When I registered on WebAuth.com, I did get a PVT_WA_... key, how did you get the PVT_K1_ one?

I've meant the WebAuth.com mobile wallet - I've created an account in there.

maoueh commented 2 years ago

So if I use their converter to convert from PVT_K1_... to old format, then use the converted key, it works as expected.

Now what I'm wondering is how to handle them. Our current code is simply removing the PVT_K1_ prefix and then use the reminder as the private key.

Two possibilities:

I think the first bullet makes more sense, but I'll need to perform extra testing.

maoueh commented 2 years ago

I checked with eos-ecc library and indeed, the PVT_K1_ format is quite different than just removing the prefix.

The PUB_K1_ and EOS however is the exact same and I assume we actually simply ported the logic over to PVT_K1_ but it's quite wrong.

I should be able to fix that.