aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/signature_nocgo.go
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/signature_nocgo.go')
-rw-r--r--crypto/signature_nocgo.go31
1 files changed, 31 insertions, 0 deletions
diff --git a/crypto/signature_nocgo.go b/crypto/signature_nocgo.go
index a022eef9a..17fd613b2 100644
--- a/crypto/signature_nocgo.go
+++ b/crypto/signature_nocgo.go
@@ -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()