github.com/trustbloc/kms-go@v1.1.2/crypto/tinkcrypto/primitive/secp256k1/subtle/secp256k1_verifier.go (about) 1 /* 2 Copyright SecureKey Technologies Inc. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package subtle 8 9 import ( 10 "crypto/ecdsa" 11 "errors" 12 "fmt" 13 "hash" 14 "math/big" 15 16 "github.com/google/tink/go/subtle" 17 ) 18 19 var errInvalidSecp256K1Signature = errors.New("secp256k1_verifier: invalid signature") 20 21 // ECDSAVerifier is an implementation of Verifier for ECDSA. 22 // At the moment, the implementation only accepts signatures with strict DER encoding. 23 type ECDSAVerifier struct { 24 publicKey *ecdsa.PublicKey 25 hashFunc func() hash.Hash 26 encoding string 27 } 28 29 // NewSecp256K1Verifier creates a new instance of Secp256K1Verifier. 30 func NewSecp256K1Verifier(hashAlg, curve, encoding string, x, y []byte) (*ECDSAVerifier, error) { 31 publicKey := &ecdsa.PublicKey{ 32 Curve: GetCurve(curve), 33 X: new(big.Int).SetBytes(x), 34 Y: new(big.Int).SetBytes(y), 35 } 36 37 return NewSecp256K1VerifierFromPublicKey(hashAlg, encoding, publicKey) 38 } 39 40 // NewSecp256K1VerifierFromPublicKey creates a new instance of ECDSAVerifier. 41 func NewSecp256K1VerifierFromPublicKey(hashAlg, encoding string, publicKey *ecdsa.PublicKey) (*ECDSAVerifier, error) { 42 if publicKey.Curve == nil { 43 return nil, errors.New("ecdsa_verifier: invalid curve") 44 } 45 46 curve := ConvertCurveName(publicKey.Curve.Params().Name) 47 if err := ValidateSecp256K1Params(hashAlg, curve, encoding); err != nil { 48 return nil, fmt.Errorf("ecdsa_verifier: %w", err) 49 } 50 51 hashFunc := subtle.GetHashFunc(hashAlg) 52 53 return &ECDSAVerifier{ 54 publicKey: publicKey, 55 hashFunc: hashFunc, 56 encoding: encoding, 57 }, nil 58 } 59 60 // Verify verifies whether the given signature is valid for the given data. 61 // It returns an error if the signature is not valid; nil otherwise. 62 func (e *ECDSAVerifier) Verify(signatureBytes, data []byte) error { 63 signature, err := DecodeSecp256K1Signature(signatureBytes, e.encoding) 64 if err != nil { 65 return fmt.Errorf("secp256k1_verifier: %w", err) 66 } 67 68 hashed, err := subtle.ComputeHash(e.hashFunc, data) 69 if err != nil { 70 return err 71 } 72 73 valid := ecdsa.Verify(e.publicKey, hashed, signature.R, signature.S) 74 if !valid { 75 return errInvalidSecp256K1Signature 76 } 77 78 return nil 79 }