summaryrefslogtreecommitdiff
path: root/cli/vendor/github.com/btcsuite/btcd/btcec/v2/ecdsa/signature.go
diff options
context:
space:
mode:
Diffstat (limited to 'cli/vendor/github.com/btcsuite/btcd/btcec/v2/ecdsa/signature.go')
-rw-r--r--cli/vendor/github.com/btcsuite/btcd/btcec/v2/ecdsa/signature.go240
1 files changed, 240 insertions, 0 deletions
diff --git a/cli/vendor/github.com/btcsuite/btcd/btcec/v2/ecdsa/signature.go b/cli/vendor/github.com/btcsuite/btcd/btcec/v2/ecdsa/signature.go
new file mode 100644
index 0000000..092e4ce
--- /dev/null
+++ b/cli/vendor/github.com/btcsuite/btcd/btcec/v2/ecdsa/signature.go
@@ -0,0 +1,240 @@
+// 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 + <byte> + 0x2 + 0x01 + <byte>
+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 <length of whole message> <0x02> <length of R> <R> 0x2
+ // <length of S> <S>.
+
+ 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, <len> <s>
+ // 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><padded bytes for signature S>
+// 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)
+}