crypto: add DecompressPubkey, VerifySignature (#15615)
We need those operations for p2p/enr. Also upgrade github.com/btcsuite/btcd/btcec to the latest version and improve BenchmarkSha3. The benchmark printed extra output that confused tools like benchstat and ignored N.
This commit is contained in:
@ -21,11 +21,14 @@ package crypto
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
)
|
||||
|
||||
// Ecrecover returns the uncompressed public key that created the given signature.
|
||||
func Ecrecover(hash, sig []byte) ([]byte, error) {
|
||||
pub, err := SigToPub(hash, sig)
|
||||
if err != nil {
|
||||
@ -35,6 +38,7 @@ func Ecrecover(hash, sig []byte) ([]byte, error) {
|
||||
return bytes, err
|
||||
}
|
||||
|
||||
// SigToPub returns the public key that created the given signature.
|
||||
func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) {
|
||||
// Convert to btcec input format with 'recovery id' v at the beginning.
|
||||
btcsig := make([]byte, 65)
|
||||
@ -71,6 +75,33 @@ func Sign(hash []byte, prv *ecdsa.PrivateKey) ([]byte, error) {
|
||||
return sig, nil
|
||||
}
|
||||
|
||||
// VerifySignature checks that the given public key created signature over hash.
|
||||
// The public key should be in compressed (33 bytes) or uncompressed (65 bytes) format.
|
||||
// The signature should have the 64 byte [R || S] format.
|
||||
func VerifySignature(pubkey, hash, signature []byte) bool {
|
||||
if len(signature) != 64 {
|
||||
return false
|
||||
}
|
||||
sig := &btcec.Signature{R: new(big.Int).SetBytes(signature[:32]), S: new(big.Int).SetBytes(signature[32:])}
|
||||
key, err := btcec.ParsePubKey(pubkey, btcec.S256())
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return sig.Verify(hash, key)
|
||||
}
|
||||
|
||||
// DecompressPubkey parses a public key in the 33-byte compressed format.
|
||||
func DecompressPubkey(pubkey []byte) (*ecdsa.PublicKey, error) {
|
||||
if len(pubkey) != 33 {
|
||||
return nil, errors.New("invalid compressed public key length")
|
||||
}
|
||||
key, err := btcec.ParsePubKey(pubkey, btcec.S256())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return key.ToECDSA(), nil
|
||||
}
|
||||
|
||||
// S256 returns an instance of the secp256k1 curve.
|
||||
func S256() elliptic.Curve {
|
||||
return btcec.S256()
|
||||
|
Reference in New Issue
Block a user