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 }