I have a signature:
3044022014d647cd08f1ea5b31d1e6539b6cbceb9182f6e7b2e29fb969354ef7e3434923022028bb4eda36af410149baa936322e7c0e46cc5540a3aa89c811bc3c360028bfd301
a hash
f27c6c3aa42563c958292922be1e53fe107f4db0dfadba11122f0b12bf77f3ab
and a pubkey
04b0bd634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e6537a576782eba668a7ef8bd3b3cfb1edb7117ab65129b8a2e681f3c1e0908ef7b
Below is my Go code to verify the signature but it fails! I have information that the three pieces should validate OK and some other person has verified them in other ways. So I want to kown what mistake in this Go code make me get the false result.
if you want more information,this link is about how i build my signature and how someone say he success verify in other ways. I feel helpless now: https://bitcointalk.org/index.php?topic=4879014.msg43992837#msg43992837
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"encoding/hex"
"fmt"
"math/big"
)
func main() {
pubkey, err := hex.DecodeString("b0bd634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e6537a576782eba668a7ef8bd3b3cfb1edb7117ab65129b8a2e681f3c1e0908ef7b")
if err != nil {
panic(err)
}
curve := elliptic.P256()
// length
keyLen := len(pubkey)
x := big.Int{}
y := big.Int{}
x.SetBytes(pubkey[:(keyLen / 2)])
y.SetBytes(pubkey[(keyLen / 2):])
rawPubKey := ecdsa.PublicKey{curve, &x, &y}
// hash
hash, err := hex.DecodeString("f27c6c3aa42563c958292922be1e53fe107f4db0dfadba11122f0b12bf77f3ab")
if err != nil {
panic(err)
}
r := big.Int{}
s := big.Int{}
rr, err := hex.DecodeString("14d647cd08f1ea5b31d1e6539b6cbceb9182f6e7b2e29fb969354ef7e3434923")
if err != nil {
panic(err)
}
ss, err := hex.DecodeString("28bb4eda36af410149baa936322e7c0e46cc5540a3aa89c811bc3c360028bfd3")
if err != nil {
panic(err)
}
r.SetBytes(rr)
s.SetBytes(ss)
fmt.Printf("%v
", ecdsa.Verify(&rawPubKey, hash[:], &r, &s))
}
You are trying to use the wrong curve. P-256, also known as secp256r1, is not the same as the curve used in Bitcoin, which is secp256k1. Your public key doesn’t correspond to a point on P-256 (you can check with curve.IsOnCurve(&x, &y)
), but it is a point on secp256k1.
Golang doesn’t include support for the Bitcoin curve, so you will need to find a library that does ECDSA using it.
I can confirm that signature does verify that data for that key if you use the correct curve.