github.com/trustbloc/kms-go@v1.1.2/crypto/tinkcrypto/primitive/secp256k1/subtle/secp256k1_signer.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 "crypto/rand" 12 "errors" 13 "fmt" 14 "hash" 15 "math/big" 16 17 "github.com/google/tink/go/subtle" 18 ) 19 20 // Secp256K1Signer is an implementation of Signer for secp256k1 Secp256k2 (Koblitz curve). 21 // At the moment, the implementation only accepts DER encoding. 22 type Secp256K1Signer struct { 23 privateKey *ecdsa.PrivateKey 24 hashFunc func() hash.Hash 25 encoding string 26 } 27 28 // NewSecp256K1Signer creates a new instance of Secp256K1Signer. 29 func NewSecp256K1Signer(hashAlg string, 30 curve string, 31 encoding string, 32 keyValue []byte) (*Secp256K1Signer, error) { 33 privKey := new(ecdsa.PrivateKey) 34 c := GetCurve(curve) 35 privKey.PublicKey.Curve = c 36 privKey.D = new(big.Int).SetBytes(keyValue) 37 privKey.PublicKey.X, privKey.PublicKey.Y = c.ScalarBaseMult(keyValue) 38 39 return NewSecp256K1SignerFromPrivateKey(hashAlg, encoding, privKey) 40 } 41 42 // NewSecp256K1SignerFromPrivateKey creates a new instance of Secp256K1Signer. 43 func NewSecp256K1SignerFromPrivateKey(hashAlg string, encoding string, 44 privateKey *ecdsa.PrivateKey) (*Secp256K1Signer, error) { 45 if privateKey.Curve == nil { 46 return nil, errors.New("secp256k1_signer: privateKey.Curve can't be nil") 47 } 48 49 curve := ConvertCurveName(privateKey.Curve.Params().Name) 50 if err := ValidateSecp256K1Params(hashAlg, curve, encoding); err != nil { 51 return nil, fmt.Errorf("secp256k1_signer: %w", err) 52 } 53 54 hashFunc := subtle.GetHashFunc(hashAlg) 55 56 return &Secp256K1Signer{ 57 privateKey: privateKey, 58 hashFunc: hashFunc, 59 encoding: encoding, 60 }, nil 61 } 62 63 // Sign computes a signature for the given data. 64 func (e *Secp256K1Signer) Sign(data []byte) ([]byte, error) { 65 hashed, err := subtle.ComputeHash(e.hashFunc, data) 66 if err != nil { 67 return nil, err 68 } 69 70 r, s, err := ecdsa.Sign(rand.Reader, e.privateKey, hashed) 71 if err != nil { 72 return nil, fmt.Errorf("secp256k1_signer: signing failed: %w", err) 73 } 74 75 // format the signature 76 sig := NewSecp256K1Signature(r, s) 77 78 ret, err := sig.EncodeSecp256K1Signature(e.encoding, e.privateKey.PublicKey.Curve.Params().Name) 79 if err != nil { 80 return nil, fmt.Errorf("secp256k1_signer: signing failed: %w", err) 81 } 82 83 return ret, nil 84 } 85 86 // ConvertCurveName converts different forms of a curve name to the name that tink recognizes. 87 func ConvertCurveName(name string) string { 88 switch name { 89 case "secp256k1", "secp256K1": 90 return "SECP256K1" 91 default: 92 return "" 93 } 94 }