aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/secp256k1/secp256.go
diff options
context:
space:
mode:
authorFelix Lange <fjl@users.noreply.github.com>2017-12-06 23:07:08 +0800
committerGitHub <noreply@github.com>2017-12-06 23:07:08 +0800
commite85b68ef53e80eb66c7ab394c57e9eb146a60b91 (patch)
tree92a728f14c9a0d42b50f2410d3c67a46795364d6 /crypto/secp256k1/secp256.go
parent6e613cf3de6ebfd14edd5a332baf6e4079c1c86f (diff)
downloadgo-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.go29
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