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  }