github.com/trustbloc/kms-go@v1.1.2/crypto/tinkcrypto/primitive/secp256k1/subtle/secp256k1.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/elliptic"
    11  	"errors"
    12  	"fmt"
    13  	"math/big"
    14  
    15  	"github.com/btcsuite/btcd/btcec/v2"
    16  
    17  	secp256k1pb "github.com/trustbloc/kms-go/crypto/tinkcrypto/primitive/proto/secp256k1_go_proto"
    18  )
    19  
    20  var errUnsupportedEncoding = errors.New("secp256k1: unsupported encoding")
    21  
    22  // Secp256k1Signature is a struct holding the r and s values of an secp256k1 signature.
    23  type Secp256k1Signature struct {
    24  	R, S *big.Int
    25  }
    26  
    27  // NewSecp256K1Signature creates a new Secp256k1Signature instance.
    28  func NewSecp256K1Signature(r, s *big.Int) *Secp256k1Signature {
    29  	return &Secp256k1Signature{R: r, S: s}
    30  }
    31  
    32  // EncodeSecp256K1Signature converts the signature to the given encoding format.
    33  func (sig *Secp256k1Signature) EncodeSecp256K1Signature(encoding, curveName string) ([]byte, error) {
    34  	var (
    35  		enc []byte
    36  		err error
    37  	)
    38  
    39  	switch encoding {
    40  	case secp256k1pb.Secp256K1SignatureEncoding_Bitcoin_IEEE_P1363.String():
    41  		enc, err = ieeeP1363Encode(sig, curveName)
    42  	case secp256k1pb.Secp256K1SignatureEncoding_Bitcoin_DER.String():
    43  		enc, err = asn1encode(sig)
    44  	default:
    45  		err = errUnsupportedEncoding
    46  	}
    47  
    48  	if err != nil {
    49  		return nil, fmt.Errorf("secp256k1: can't convert secp256k1 signature to %s encoding: %w", encoding, err)
    50  	}
    51  
    52  	return enc, nil
    53  }
    54  
    55  // DecodeSecp256K1Signature creates a new secp256k1 signature using the given byte slice.
    56  // The function assumes that the byte slice is the concatenation of the BigEndian
    57  // representation of two big integer r and s.
    58  func DecodeSecp256K1Signature(encodedBytes []byte, encoding string) (*Secp256k1Signature, error) {
    59  	var (
    60  		sig *Secp256k1Signature
    61  		err error
    62  	)
    63  
    64  	switch encoding {
    65  	case secp256k1pb.Secp256K1SignatureEncoding_Bitcoin_IEEE_P1363.String():
    66  		sig, err = ieeeP1363Decode(encodedBytes)
    67  	case secp256k1pb.Secp256K1SignatureEncoding_Bitcoin_DER.String():
    68  		sig, err = asn1decode(encodedBytes)
    69  	default:
    70  		err = errUnsupportedEncoding
    71  	}
    72  
    73  	if err != nil {
    74  		return nil, fmt.Errorf("secp256k1: %w", err)
    75  	}
    76  
    77  	return sig, nil
    78  }
    79  
    80  // ValidateSecp256K1Params validates secp256k1 parameters.
    81  // The hash's strength must not be weaker than the curve's strength.
    82  // DER and IEEE_P1363 encodings are supported.
    83  func ValidateSecp256K1Params(hashAlg, curve, encoding string) error {
    84  	switch encoding {
    85  	case secp256k1pb.Secp256K1SignatureEncoding_Bitcoin_DER.String():
    86  	case secp256k1pb.Secp256K1SignatureEncoding_Bitcoin_IEEE_P1363.String():
    87  	default:
    88  		return errUnsupportedEncoding
    89  	}
    90  
    91  	switch curve {
    92  	case secp256k1pb.BitcoinCurveType_SECP256K1.String():
    93  		if hashAlg != "SHA256" {
    94  			return errors.New("invalid hash type, expect SHA-256")
    95  		}
    96  	default:
    97  		return fmt.Errorf("unsupported curve: %s", curve)
    98  	}
    99  
   100  	return nil
   101  }
   102  
   103  // GetCurve returns the curve object that corresponds to the given curve type.
   104  // It returns null if the curve type is not supported.
   105  func GetCurve(curve string) elliptic.Curve {
   106  	switch curve {
   107  	case secp256k1pb.BitcoinCurveType_SECP256K1.String():
   108  		return btcec.S256()
   109  	default:
   110  		return nil
   111  	}
   112  }