eoscanada / eos-go

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

ecc privatekey signature error #205

Closed oldkingnearby closed 1 year ago

oldkingnearby commented 1 year ago
package eos

import (
    "encoding/hex"
    "log"

    "github.com/eoscanada/eos-go/ecc"
    secp256k1 "github.com/uuosio/go-secp256k1"
)

func TestSign() (err error) {
    privateKey := "5JWuxonweDjwWFuXRwt4sqj5YriEc8ehZh6EKszYYcf3Puh6gAa"
    hash, err := hex.DecodeString("aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906")
    eccPrivKey, err := ecc.NewPrivateKey(privateKey)
    eccSig, err := eccPrivKey.Sign(hash)
    log.Println("ecc sign:", eccPrivKey.PublicKey().String(), eccSig.String())
    uuosioPrivKey, err := secp256k1.NewPrivateKeyFromBase58(privateKey)
    uuosioSig, err := uuosioPrivKey.Sign(hash)
    log.Println("uuo sign:", uuosioPrivKey.GetPublicKey().StringEOS(), uuosioSig.String())
    return
}

output:

2023/03/13 btcec.go:16: ecc sign: EOS6u3S5RbCxVrCE2sW7yBQLZ7fftaupqB85BLDeuV9j4eTBGCKX1 SIG_K1_Juzw36zdpKsus1ZHzRK6breTfs5S7mxwXJCz9HUrahsyPvEMcMStvEL4ou3co2UuuJ43rjs4HzTbTtMFbB51gPGfVRCCef 2023/03/13 btcec.go:19: uuo sign: EOS6u3S5RbCxVrCE2sW7yBQLZ7fftaupqB85BLDeuV9j4eTBGCKX1 SIG_K1_K7YM1SYUEmt2hB7JUhETr58wk6Kn5bm89AneufBbwX1KaojdRDXGtEWrfDUyWqo1W3vSzqLNTpxH3ZmJsoitkyqAC5Fn7T

The correct signature is "SIG_K1_K7YM1SYUEmt2hB7JUhETr58wk6Kn5bm89AneufBbwX1KaojdRDXGtEWrfDUyWqo1W3vSzqLNTpxH3ZmJsoitkyqAC5Fn7T".

pnx commented 1 year ago

Signatures may be different but still valid. always recover the public key and validate. simply comparing two signature values is not enough.

package main

import (
    "encoding/hex"
    "fmt"
    "log"

    secp256k1 "github.com/uuosio/go-secp256k1"
)

func validateSignature(hash []byte, sig *secp256k1.Signature, pubkey *secp256k1.PublicKey) bool {
    // Recover public key from signature.
    recovered, err := secp256k1.Recover(hash, sig)
    if err != nil {
        return false
    }

    // Check if the provided pubkey is the same as the recovered one.
    return pubkey.Data == recovered.Data
}

func main() {
    hash, err := hex.DecodeString("aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906")
    if err != nil {
        log.Fatal(err)
    }

    pubkey, err := secp256k1.NewPublicKeyFromBase58("EOS6u3S5RbCxVrCE2sW7yBQLZ7fftaupqB85BLDeuV9j4eTBGCKX1")
    if err != nil {
        log.Fatal(err)
    }

    sig1, err := secp256k1.NewSignatureFromBase58("SIG_K1_Juzw36zdpKsus1ZHzRK6breTfs5S7mxwXJCz9HUrahsyPvEMcMStvEL4ou3co2UuuJ43rjs4HzTbTtMFbB51gPGfVRCCef")
    if err != nil {
        log.Fatal(err)
    }

    sig2, err := secp256k1.NewSignatureFromBase58("SIG_K1_K7YM1SYUEmt2hB7JUhETr58wk6Kn5bm89AneufBbwX1KaojdRDXGtEWrfDUyWqo1W3vSzqLNTpxH3ZmJsoitkyqAC5Fn7T")
    if err != nil {
        log.Fatal(err)
    }

    if validateSignature(hash, sig1, pubkey) {
        fmt.Println("sig1: valid")
    } else {
        fmt.Println("sig1: NOT valid")
    }

    if validateSignature(hash, sig2, pubkey) {
        fmt.Println("sig2: valid")
    } else {
        fmt.Println("sig2: NOT valid")
    }
}

for reference: https://github.com/eoscanada/eos-go/issues/49#issuecomment-426076376 https://github.com/EOSIO/eosjs-ecc/issues/20#issuecomment-413650338

maoueh commented 1 year ago

@pnx Thanks for jumping in, missed that one.