mirror of
https://github.com/tendermint/tendermint.git
synced 2026-01-03 03:35:19 +00:00
crypto: Remove build flags from secp256k1 (#8051)
Manual backport of #7823. * remove cgo build flags * remove nocgo file
This commit is contained in:
@@ -122,6 +122,26 @@ func GenPrivKeySecp256k1(secret []byte) PrivKey {
|
|||||||
return PrivKey(privKey32)
|
return PrivKey(privKey32)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// used to reject malleable signatures
|
||||||
|
// see:
|
||||||
|
// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/signature_nocgo.go#L90-L93
|
||||||
|
// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/crypto.go#L39
|
||||||
|
var secp256k1halfN = new(big.Int).Rsh(secp256k1.S256().N, 1)
|
||||||
|
|
||||||
|
// Sign creates an ECDSA signature on curve Secp256k1, using SHA256 on the msg.
|
||||||
|
// The returned signature will be of the form R || S (in lower-S form).
|
||||||
|
func (privKey PrivKey) Sign(msg []byte) ([]byte, error) {
|
||||||
|
priv, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey)
|
||||||
|
|
||||||
|
sig, err := priv.Sign(crypto.Sha256(msg))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sigBytes := serializeSig(sig)
|
||||||
|
return sigBytes, nil
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
|
|
||||||
var _ crypto.PubKey = PubKey{}
|
var _ crypto.PubKey = PubKey{}
|
||||||
@@ -171,3 +191,47 @@ func (pubKey PubKey) Equals(other crypto.PubKey) bool {
|
|||||||
func (pubKey PubKey) Type() string {
|
func (pubKey PubKey) Type() string {
|
||||||
return KeyType
|
return KeyType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VerifySignature verifies a signature of the form R || S.
|
||||||
|
// It rejects signatures which are not in lower-S form.
|
||||||
|
func (pubKey PubKey) VerifySignature(msg []byte, sigStr []byte) bool {
|
||||||
|
if len(sigStr) != 64 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
pub, err := secp256k1.ParsePubKey(pubKey, secp256k1.S256())
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse the signature:
|
||||||
|
signature := signatureFromBytes(sigStr)
|
||||||
|
// Reject malleable signatures. libsecp256k1 does this check but btcec doesn't.
|
||||||
|
// see: https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/signature_nocgo.go#L90-L93
|
||||||
|
if signature.S.Cmp(secp256k1halfN) > 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return signature.Verify(crypto.Sha256(msg), pub)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read Signature struct from R || S. Caller needs to ensure
|
||||||
|
// that len(sigStr) == 64.
|
||||||
|
func signatureFromBytes(sigStr []byte) *secp256k1.Signature {
|
||||||
|
return &secp256k1.Signature{
|
||||||
|
R: new(big.Int).SetBytes(sigStr[:32]),
|
||||||
|
S: new(big.Int).SetBytes(sigStr[32:64]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Serialize signature to R || S.
|
||||||
|
// R, S are padded to 32 bytes respectively.
|
||||||
|
func serializeSig(sig *secp256k1.Signature) []byte {
|
||||||
|
rBytes := sig.R.Bytes()
|
||||||
|
sBytes := sig.S.Bytes()
|
||||||
|
sigBytes := make([]byte, 64)
|
||||||
|
// 0 pad the byte arrays from the left if they aren't big enough.
|
||||||
|
copy(sigBytes[32-len(rBytes):32], rBytes)
|
||||||
|
copy(sigBytes[64-len(sBytes):64], sBytes)
|
||||||
|
return sigBytes
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,76 +0,0 @@
|
|||||||
//go:build !libsecp256k1
|
|
||||||
// +build !libsecp256k1
|
|
||||||
|
|
||||||
package secp256k1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math/big"
|
|
||||||
|
|
||||||
secp256k1 "github.com/btcsuite/btcd/btcec"
|
|
||||||
|
|
||||||
"github.com/tendermint/tendermint/crypto"
|
|
||||||
)
|
|
||||||
|
|
||||||
// used to reject malleable signatures
|
|
||||||
// see:
|
|
||||||
// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/signature_nocgo.go#L90-L93
|
|
||||||
// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/crypto.go#L39
|
|
||||||
var secp256k1halfN = new(big.Int).Rsh(secp256k1.S256().N, 1)
|
|
||||||
|
|
||||||
// Sign creates an ECDSA signature on curve Secp256k1, using SHA256 on the msg.
|
|
||||||
// The returned signature will be of the form R || S (in lower-S form).
|
|
||||||
func (privKey PrivKey) Sign(msg []byte) ([]byte, error) {
|
|
||||||
priv, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey)
|
|
||||||
|
|
||||||
sig, err := priv.Sign(crypto.Sha256(msg))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
sigBytes := serializeSig(sig)
|
|
||||||
return sigBytes, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// VerifySignature verifies a signature of the form R || S.
|
|
||||||
// It rejects signatures which are not in lower-S form.
|
|
||||||
func (pubKey PubKey) VerifySignature(msg []byte, sigStr []byte) bool {
|
|
||||||
if len(sigStr) != 64 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
pub, err := secp256k1.ParsePubKey(pubKey, secp256k1.S256())
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse the signature:
|
|
||||||
signature := signatureFromBytes(sigStr)
|
|
||||||
// Reject malleable signatures. libsecp256k1 does this check but btcec doesn't.
|
|
||||||
// see: https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/signature_nocgo.go#L90-L93
|
|
||||||
if signature.S.Cmp(secp256k1halfN) > 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return signature.Verify(crypto.Sha256(msg), pub)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read Signature struct from R || S. Caller needs to ensure
|
|
||||||
// that len(sigStr) == 64.
|
|
||||||
func signatureFromBytes(sigStr []byte) *secp256k1.Signature {
|
|
||||||
return &secp256k1.Signature{
|
|
||||||
R: new(big.Int).SetBytes(sigStr[:32]),
|
|
||||||
S: new(big.Int).SetBytes(sigStr[32:64]),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Serialize signature to R || S.
|
|
||||||
// R, S are padded to 32 bytes respectively.
|
|
||||||
func serializeSig(sig *secp256k1.Signature) []byte {
|
|
||||||
rBytes := sig.R.Bytes()
|
|
||||||
sBytes := sig.S.Bytes()
|
|
||||||
sigBytes := make([]byte, 64)
|
|
||||||
// 0 pad the byte arrays from the left if they aren't big enough.
|
|
||||||
copy(sigBytes[32-len(rBytes):32], rBytes)
|
|
||||||
copy(sigBytes[64-len(sBytes):64], sBytes)
|
|
||||||
return sigBytes
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user