// Copyright (c) 2013-2017 The btcsuite developers // Copyright (c) 2015-2021 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. package ecdsa import ( "errors" "fmt" "math/big" "github.com/btcsuite/btcd/btcec/v2" secp_ecdsa "github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa" ) // Errors returned by canonicalPadding. var ( errNegativeValue = errors.New("value may be interpreted as negative") errExcessivelyPaddedValue = errors.New("value is excessively padded") ) // Signature is a type representing an ecdsa signature. type Signature = secp_ecdsa.Signature // NewSignature instantiates a new signature given some r and s values. func NewSignature(r, s *btcec.ModNScalar) *Signature { return secp_ecdsa.NewSignature(r, s) } var ( // Used in RFC6979 implementation when testing the nonce for correctness one = big.NewInt(1) // oneInitializer is used to fill a byte slice with byte 0x01. It is provided // here to avoid the need to create it multiple times. oneInitializer = []byte{0x01} ) // MinSigLen is the minimum length of a DER encoded signature and is when both R // and S are 1 byte each. // 0x30 + <1-byte> + 0x02 + 0x01 + + 0x2 + 0x01 + const MinSigLen = 8 // canonicalPadding checks whether a big-endian encoded integer could // possibly be misinterpreted as a negative number (even though OpenSSL // treats all numbers as unsigned), or if there is any unnecessary // leading zero padding. func canonicalPadding(b []byte) error { switch { case b[0]&0x80 == 0x80: return errNegativeValue case len(b) > 1 && b[0] == 0x00 && b[1]&0x80 != 0x80: return errExcessivelyPaddedValue default: return nil } } func parseSig(sigStr []byte, der bool) (*Signature, error) { // Originally this code used encoding/asn1 in order to parse the // signature, but a number of problems were found with this approach. // Despite the fact that signatures are stored as DER, the difference // between go's idea of a bignum (and that they have sign) doesn't agree // with the openssl one (where they do not). The above is true as of // Go 1.1. In the end it was simpler to rewrite the code to explicitly // understand the format which is this: // 0x30 <0x02> 0x2 // . if len(sigStr) < MinSigLen { return nil, errors.New("malformed signature: too short") } // 0x30 index := 0 if sigStr[index] != 0x30 { return nil, errors.New("malformed signature: no header magic") } index++ // length of remaining message siglen := sigStr[index] index++ // siglen should be less than the entire message and greater than // the minimal message size. if int(siglen+2) > len(sigStr) || int(siglen+2) < MinSigLen { return nil, errors.New("malformed signature: bad length") } // trim the slice we're working on so we only look at what matters. sigStr = sigStr[:siglen+2] // 0x02 if sigStr[index] != 0x02 { return nil, errors.New("malformed signature: no 1st int marker") } index++ // Length of signature R. rLen := int(sigStr[index]) // must be positive, must be able to fit in another 0x2, // hence the -3. We assume that the length must be at least one byte. index++ if rLen <= 0 || rLen > len(sigStr)-index-3 { return nil, errors.New("malformed signature: bogus R length") } // Then R itself. rBytes := sigStr[index : index+rLen] if der { switch err := canonicalPadding(rBytes); err { case errNegativeValue: return nil, errors.New("signature R is negative") case errExcessivelyPaddedValue: return nil, errors.New("signature R is excessively padded") } } // Strip leading zeroes from R. for len(rBytes) > 0 && rBytes[0] == 0x00 { rBytes = rBytes[1:] } // R must be in the range [1, N-1]. Notice the check for the maximum number // of bytes is required because SetByteSlice truncates as noted in its // comment so it could otherwise fail to detect the overflow. var r btcec.ModNScalar if len(rBytes) > 32 { str := "invalid signature: R is larger than 256 bits" return nil, errors.New(str) } if overflow := r.SetByteSlice(rBytes); overflow { str := "invalid signature: R >= group order" return nil, errors.New(str) } if r.IsZero() { str := "invalid signature: R is 0" return nil, errors.New(str) } index += rLen // 0x02. length already checked in previous if. if sigStr[index] != 0x02 { return nil, errors.New("malformed signature: no 2nd int marker") } index++ // Length of signature S. sLen := int(sigStr[index]) index++ // S should be the rest of the string. if sLen <= 0 || sLen > len(sigStr)-index { return nil, errors.New("malformed signature: bogus S length") } // Then S itself. sBytes := sigStr[index : index+sLen] if der { switch err := canonicalPadding(sBytes); err { case errNegativeValue: return nil, errors.New("signature S is negative") case errExcessivelyPaddedValue: return nil, errors.New("signature S is excessively padded") } } // Strip leading zeroes from S. for len(sBytes) > 0 && sBytes[0] == 0x00 { sBytes = sBytes[1:] } // S must be in the range [1, N-1]. Notice the check for the maximum number // of bytes is required because SetByteSlice truncates as noted in its // comment so it could otherwise fail to detect the overflow. var s btcec.ModNScalar if len(sBytes) > 32 { str := "invalid signature: S is larger than 256 bits" return nil, errors.New(str) } if overflow := s.SetByteSlice(sBytes); overflow { str := "invalid signature: S >= group order" return nil, errors.New(str) } if s.IsZero() { str := "invalid signature: S is 0" return nil, errors.New(str) } index += sLen // sanity check length parsing if index != len(sigStr) { return nil, fmt.Errorf("malformed signature: bad final length %v != %v", index, len(sigStr)) } return NewSignature(&r, &s), nil } // ParseSignature parses a signature in BER format for the curve type `curve' // into a Signature type, perfoming some basic sanity checks. If parsing // according to the more strict DER format is needed, use ParseDERSignature. func ParseSignature(sigStr []byte) (*Signature, error) { return parseSig(sigStr, false) } // ParseDERSignature parses a signature in DER format for the curve type // `curve` into a Signature type. If parsing according to the less strict // BER format is needed, use ParseSignature. func ParseDERSignature(sigStr []byte) (*Signature, error) { return parseSig(sigStr, true) } // SignCompact produces a compact signature of the data in hash with the given // private key on the given koblitz curve. The isCompressed parameter should // be used to detail if the given signature should reference a compressed // public key or not. If successful the bytes of the compact signature will be // returned in the format: // <(byte of 27+public key solution)+4 if compressed >< padded bytes for signature R> // where the R and S parameters are padde up to the bitlengh of the curve. func SignCompact(key *btcec.PrivateKey, hash []byte, isCompressedKey bool) ([]byte, error) { return secp_ecdsa.SignCompact(key, hash, isCompressedKey), nil } // RecoverCompact verifies the compact signature "signature" of "hash" for the // Koblitz curve in "curve". If the signature matches then the recovered public // key will be returned as well as a boolean if the original key was compressed // or not, else an error will be returned. func RecoverCompact(signature, hash []byte) (*btcec.PublicKey, bool, error) { return secp_ecdsa.RecoverCompact(signature, hash) } // Sign generates an ECDSA signature over the secp256k1 curve for the provided // hash (which should be the result of hashing a larger message) using the // given private key. The produced signature is deterministic (same message and // same key yield the same signature) and canonical in accordance with RFC6979 // and BIP0062. func Sign(key *btcec.PrivateKey, hash []byte) *Signature { return secp_ecdsa.Sign(key, hash) }