diff options
author | Felix Lange <fjl@users.noreply.github.com> | 2017-12-06 23:07:08 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-06 23:07:08 +0800 |
commit | e85b68ef53e80eb66c7ab394c57e9eb146a60b91 (patch) | |
tree | 92a728f14c9a0d42b50f2410d3c67a46795364d6 /crypto/secp256k1/secp256.go | |
parent | 6e613cf3de6ebfd14edd5a332baf6e4079c1c86f (diff) | |
download | go-tangerine-e85b68ef53e80eb66c7ab394c57e9eb146a60b91.tar go-tangerine-e85b68ef53e80eb66c7ab394c57e9eb146a60b91.tar.gz go-tangerine-e85b68ef53e80eb66c7ab394c57e9eb146a60b91.tar.bz2 go-tangerine-e85b68ef53e80eb66c7ab394c57e9eb146a60b91.tar.lz go-tangerine-e85b68ef53e80eb66c7ab394c57e9eb146a60b91.tar.xz go-tangerine-e85b68ef53e80eb66c7ab394c57e9eb146a60b91.tar.zst go-tangerine-e85b68ef53e80eb66c7ab394c57e9eb146a60b91.zip |
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.
Diffstat (limited to 'crypto/secp256k1/secp256.go')
-rw-r--r-- | crypto/secp256k1/secp256.go | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/crypto/secp256k1/secp256.go b/crypto/secp256k1/secp256.go index 0ffa04fe0..00a1f8aaa 100644 --- a/crypto/secp256k1/secp256.go +++ b/crypto/secp256k1/secp256.go @@ -38,6 +38,7 @@ import "C" import ( "errors" + "math/big" "unsafe" ) @@ -55,6 +56,7 @@ var ( ErrInvalidSignatureLen = errors.New("invalid signature length") ErrInvalidRecoveryID = errors.New("invalid signature recovery id") ErrInvalidKey = errors.New("invalid private key") + ErrInvalidPubkey = errors.New("invalid public key") ErrSignFailed = errors.New("signing failed") ErrRecoverFailed = errors.New("recovery failed") ) @@ -119,6 +121,33 @@ func RecoverPubkey(msg []byte, sig []byte) ([]byte, error) { return pubkey, nil } +// VerifySignature checks that the given pubkey created signature over message. +// The signature should be in [R || S] format. +func VerifySignature(pubkey, msg, signature []byte) bool { + if len(msg) != 32 || len(signature) != 64 || len(pubkey) == 0 { + return false + } + sigdata := (*C.uchar)(unsafe.Pointer(&signature[0])) + msgdata := (*C.uchar)(unsafe.Pointer(&msg[0])) + keydata := (*C.uchar)(unsafe.Pointer(&pubkey[0])) + return C.secp256k1_ecdsa_verify_enc(context, sigdata, msgdata, keydata, C.size_t(len(pubkey))) != 0 +} + +// DecompressPubkey parses a public key in the 33-byte compressed format. +// It returns non-nil coordinates if the public key is valid. +func DecompressPubkey(pubkey []byte) (X, Y *big.Int) { + if len(pubkey) != 33 { + return nil, nil + } + buf := make([]byte, 65) + bufdata := (*C.uchar)(unsafe.Pointer(&buf[0])) + pubkeydata := (*C.uchar)(unsafe.Pointer(&pubkey[0])) + if C.secp256k1_decompress_pubkey(context, bufdata, pubkeydata) == 0 { + return nil, nil + } + return new(big.Int).SetBytes(buf[1:33]), new(big.Int).SetBytes(buf[33:]) +} + func checkSignature(sig []byte) error { if len(sig) != 65 { return ErrInvalidSignatureLen |