github.com/trustbloc/kms-go@v1.1.2/crypto/tinkcrypto/primitive/secp256k1/subtle/encoding.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 "bytes" 11 "encoding/asn1" 12 "fmt" 13 "math/big" 14 15 "github.com/btcsuite/btcd/btcec/v2" 16 ) 17 18 // asn1encode encodes the given ECDSA signature using ASN.1 encoding. 19 func asn1encode(sig *Secp256k1Signature) ([]byte, error) { 20 ret, err := asn1.Marshal(*sig) 21 if err != nil { 22 return nil, fmt.Errorf("asn.1 encoding failed") 23 } 24 25 return ret, nil 26 } 27 28 var errAsn1Decoding = fmt.Errorf("asn.1 decoding failed") 29 30 // asn1decode verifies the given ECDSA signature and decodes it if it is valid. 31 // Since asn1.Unmarshal() doesn't do a strict verification on its input, it will 32 // accept signatures with trailing data. Therefore, we add an additional check to make sure 33 // that the input follows strict DER encoding: after unmarshalling the signature bytes, 34 // we marshal the obtained signature object again. Since DER encoding is deterministic, 35 // we expect that the obtained bytes would be equal to the input. 36 func asn1decode(b []byte) (*Secp256k1Signature, error) { 37 sig := new(Secp256k1Signature) 38 39 _, err := asn1.Unmarshal(b, sig) // der encoding does not work for Secp256k1 keys. 40 if err != nil { 41 return nil, errAsn1Decoding 42 } 43 44 // encode the signature again 45 encoded, err := asn1.Marshal(*sig) 46 if err != nil { 47 return nil, errAsn1Decoding 48 } 49 50 if !bytes.Equal(b, encoded) { 51 return nil, errAsn1Decoding 52 } 53 54 return sig, nil 55 } 56 57 func ieeeSignatureSize(curveName string) (int, error) { 58 switch curveName { 59 case btcec.S256().Params().Name: 60 return 64, nil //nolint:gomnd 61 default: 62 return 0, fmt.Errorf("ieeeP1363 unsupported curve name: %q", curveName) 63 } 64 } 65 66 func ieeeP1363Encode(sig *Secp256k1Signature, curveName string) ([]byte, error) { 67 two := 2 68 69 sigSize, err := ieeeSignatureSize(curveName) 70 if err != nil { 71 return nil, err 72 } 73 74 enc := make([]byte, sigSize) 75 76 // sigR and sigS must be half the size of the signature. If not, we need to pad them with zeros. 77 offset := 0 78 if len(sig.R.Bytes()) < (sigSize / two) { 79 offset += (sigSize / two) - len(sig.R.Bytes()) 80 } 81 82 // Copy sigR after any zero-padding. 83 copy(enc[offset:], sig.R.Bytes()) 84 85 // Skip the bytes of sigR. 86 offset = sigSize / two 87 if len(sig.S.Bytes()) < (sigSize / two) { 88 offset += (sigSize / two) - len(sig.S.Bytes()) 89 } 90 91 // Copy sigS after sigR and any zero-padding. 92 copy(enc[offset:], sig.S.Bytes()) 93 94 return enc, nil 95 } 96 97 func ieeeP1363Decode(encodedBytes []byte) (*Secp256k1Signature, error) { 98 if len(encodedBytes) == 0 || len(encodedBytes) > 132 || len(encodedBytes)%2 != 0 { 99 return nil, fmt.Errorf("ecdsa: Invalid IEEE_P1363 encoded bytes") 100 } 101 102 r := new(big.Int).SetBytes(encodedBytes[:len(encodedBytes)/2]) 103 s := new(big.Int).SetBytes(encodedBytes[len(encodedBytes)/2:]) 104 105 return &Secp256k1Signature{R: r, S: s}, nil 106 }