我有一个签名:
3044022014d647cd08f1ea5b31d1e6539b6cbceb9182f6e7b2e29fb969354ef7e3434923022028bb4eda36af410149baa936322e7c0e46cc5540a3aa89c811bc3c360028bfd301
哈希
f27c6c3aa42563c958292922be1e53fe107f4db0dfadba11122f0b12bf77f3ab
和一个公钥
04b0bd634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e6537a576782eba668a7ef8bd3b3cfb1edb7117ab65129b8a2e681f3c1e0908ef7b
下面是我的Go代码以验证签名,但失败!我得到的信息是,这三个部分应该可以验证,并且其他人已经以其他方式对其进行了验证。因此,我想知道该Go代码中的错误使我得到了错误的结果。
如果您需要更多信息,此链接是关于我如何建立我的签名以及某人说他是否以其他方式进行验证的链接。我现在感到无助: 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\n", ecdsa.Verify(&rawPubKey, hash[:], &r, &s))
}
答案 0 :(得分:1)
您正在尝试使用错误的曲线。 P-256,也称为secp256r1,与secp256k1比特币中使用的曲线不相同。您的公钥与P-256上的一个点不对应(可以用curve.IsOnCurve(&x, &y)
进行检查),但是它 是secp256k1上的一个点。
Golang不支持比特币曲线,因此您需要找到一个使用它进行ECDSA的库。
如果使用正确的曲线,我可以确认签名确实可以验证该密钥的数据。