// Copyright (c) 2013-2014 The btcsuite developers
// Copyright (c) 2015-2024 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 (
	

	
)

// References:
//   [GECC]: Guide to Elliptic Curve Cryptography (Hankerson, Menezes, Vanstone)
//
//   [ISO/IEC 8825-1]: Information technology — ASN.1 encoding rules:
//     Specification of Basic Encoding Rules (BER), Canonical Encoding Rules
//     (CER) and Distinguished Encoding Rules (DER)
//
//   [SEC1]: Elliptic Curve Cryptography (May 31, 2009, Version 2.0)
//     https://www.secg.org/sec1-v2.pdf

var (
	// zero32 is an array of 32 bytes used for the purposes of zeroing and is
	// defined here to avoid extra allocations.
	zero32 = [32]byte{}

	// orderAsFieldVal is the order of the secp256k1 curve group stored as a
	// field value.  It is provided here to avoid the need to create it multiple
	// times.
	orderAsFieldVal = func() secp256k1.FieldVal {
		var  secp256k1.FieldVal
		.SetByteSlice(secp256k1.Params().N.Bytes())
		return 
	}()
)

const (
	// asn1SequenceID is the ASN.1 identifier for a sequence and is used when
	// parsing and serializing signatures encoded with the Distinguished
	// Encoding Rules (DER) format per section 10 of [ISO/IEC 8825-1].
	asn1SequenceID = 0x30

	// asn1IntegerID is the ASN.1 identifier for an integer and is used when
	// parsing and serializing signatures encoded with the Distinguished
	// Encoding Rules (DER) format per section 10 of [ISO/IEC 8825-1].
	asn1IntegerID = 0x02
)

// Signature is a type representing an ECDSA signature.
type Signature struct {
	r secp256k1.ModNScalar
	s secp256k1.ModNScalar
}

// NewSignature instantiates a new signature given some r and s values.
func (,  *secp256k1.ModNScalar) *Signature {
	return &Signature{*, *}
}

// R returns the r value of the signature.
func ( *Signature) () secp256k1.ModNScalar {
	return .r
}

// S returns the s value of the signature.
func ( *Signature) () secp256k1.ModNScalar {
	return .s
}

// Serialize returns the ECDSA signature in the Distinguished Encoding Rules
// (DER) format per section 10 of [ISO/IEC 8825-1] and such that the S component
// of the signature is less than or equal to the half order of the group.
//
// Note that the serialized bytes returned do not include the appended hash type
// used in Decred signature scripts.
func ( *Signature) () []byte {
	// The format of a DER encoded signature is as follows:
	//
	// 0x30 <total length> 0x02 <length of R> <R> 0x02 <length of S> <S>
	//   - 0x30 is the ASN.1 identifier for a sequence.
	//   - Total length is 1 byte and specifies length of all remaining data.
	//   - 0x02 is the ASN.1 identifier that specifies an integer follows.
	//   - Length of R is 1 byte and specifies how many bytes R occupies.
	//   - R is the arbitrary length big-endian encoded number which
	//     represents the R value of the signature.  DER encoding dictates
	//     that the value must be encoded using the minimum possible number
	//     of bytes.  This implies the first byte can only be null if the
	//     highest bit of the next byte is set in order to prevent it from
	//     being interpreted as a negative number.
	//   - 0x02 is once again the ASN.1 integer identifier.
	//   - Length of S is 1 byte and specifies how many bytes S occupies.
	//   - S is the arbitrary length big-endian encoded number which
	//     represents the S value of the signature.  The encoding rules are
	//     identical as those for R.

	// Ensure the S component of the signature is less than or equal to the half
	// order of the group because both S and its negation are valid signatures
	// modulo the order, so this forces a consistent choice to reduce signature
	// malleability.
	 := new(secp256k1.ModNScalar).Set(&.s)
	if .IsOverHalfOrder() {
		.Negate()
	}

	// Serialize the R and S components of the signature into their fixed
	// 32-byte big-endian encoding.  Note that the extra leading zero byte is
	// used to ensure it is canonical per DER and will be stripped if needed
	// below.
	var ,  [33]byte
	.r.PutBytesUnchecked([1:33])
	.PutBytesUnchecked([1:33])

	// Ensure the encoded bytes for the R and S components are canonical per DER
	// by trimming all leading zero bytes so long as the next byte does not have
	// the high bit set and it's not the final byte.
	,  := [:], [:]
	for len() > 1 && [0] == 0x00 && [1]&0x80 == 0 {
		 = [1:]
	}
	for len() > 1 && [0] == 0x00 && [1]&0x80 == 0 {
		 = [1:]
	}

	// Total length of returned signature is 1 byte for each magic and length
	// (6 total), plus lengths of R and S.
	 := 6 + len() + len()
	 := make([]byte, 0, )
	 = append(, asn1SequenceID)
	 = append(, byte(-2))
	 = append(, asn1IntegerID)
	 = append(, byte(len()))
	 = append(, ...)
	 = append(, asn1IntegerID)
	 = append(, byte(len()))
	 = append(, ...)
	return 
}

// zeroArray32 zeroes the provided 32-byte buffer.
func zeroArray32( *[32]byte) {
	copy([:], zero32[:])
}

// fieldToModNScalar converts a field value to scalar modulo the group order and
// returns the scalar along with either 1 if it was reduced (aka it overflowed)
// or 0 otherwise.
//
// Note that a bool is not used here because it is not possible in Go to convert
// from a bool to numeric value in constant time and many constant-time
// operations require a numeric value.
func fieldToModNScalar( *secp256k1.FieldVal) (secp256k1.ModNScalar, uint32) {
	var  [32]byte
	.PutBytes(&)
	var  secp256k1.ModNScalar
	 := .SetBytes(&)
	zeroArray32(&)
	return , 
}

// modNScalarToField converts a scalar modulo the group order to a field value.
func modNScalarToField( *secp256k1.ModNScalar) secp256k1.FieldVal {
	var  [32]byte
	.PutBytes(&)
	var  secp256k1.FieldVal
	.SetBytes(&)
	return 
}

// Verify returns whether or not the signature is valid for the provided hash
// and secp256k1 public key.
func ( *Signature) ( []byte,  *secp256k1.PublicKey) bool {
	// The algorithm for verifying an ECDSA signature is given as algorithm 4.30
	// in [GECC].
	//
	// The following is a paraphrased version for reference:
	//
	// G = curve generator
	// N = curve order
	// Q = public key
	// m = message
	// R, S = signature
	//
	// 1. Fail if R and S are not in [1, N-1]
	// 2. e = H(m)
	// 3. w = S^-1 mod N
	// 4. u1 = e * w mod N
	//    u2 = R * w mod N
	// 5. X = u1G + u2Q
	// 6. Fail if X is the point at infinity
	// 7. x = X.x mod N (X.x is the x coordinate of X)
	// 8. Verified if x == R
	//
	// However, since all group operations are done internally in Jacobian
	// projective space, the algorithm is modified slightly here in order to
	// avoid an expensive inversion back into affine coordinates at step 7.
	// Credits to Greg Maxwell for originally suggesting this optimization.
	//
	// Ordinarily, step 7 involves converting the x coordinate to affine by
	// calculating x = x / z^2 (mod P) and then calculating the remainder as
	// x = x (mod N).  Then step 8 compares it to R.
	//
	// Note that since R is the x coordinate mod N from a random point that was
	// originally mod P, and the cofactor of the secp256k1 curve is 1, there are
	// only two possible x coordinates that the original random point could have
	// been to produce R: x, where x < N, and x+N, where x+N < P.
	//
	// This implies that the signature is valid if either:
	// a) R == X.x / X.z^2 (mod P)
	//    => R * X.z^2 == X.x (mod P)
	// --or--
	// b) R + N < P && R + N == X.x / X.z^2 (mod P)
	//    => R + N < P && (R + N) * X.z^2 == X.x (mod P)
	//
	// Therefore the following modified algorithm is used:
	//
	// 1. Fail if R and S are not in [1, N-1]
	// 2. e = H(m)
	// 3. w = S^-1 mod N
	// 4. u1 = e * w mod N
	//    u2 = R * w mod N
	// 5. X = u1G + u2Q
	// 6. Fail if X is the point at infinity
	// 7. z = (X.z)^2 mod P (X.z is the z coordinate of X)
	// 8. Verified if R * z == X.x (mod P)
	// 9. Fail if R + N >= P
	// 10. Verified if (R + N) * z == X.x (mod P)

	// Step 1.
	//
	// Fail if R and S are not in [1, N-1].
	if .r.IsZero() || .s.IsZero() {
		return false
	}

	// Step 2.
	//
	// e = H(m)
	var  secp256k1.ModNScalar
	.SetByteSlice()

	// Step 3.
	//
	// w = S^-1 mod N
	 := new(secp256k1.ModNScalar).InverseValNonConst(&.s)

	// Step 4.
	//
	// u1 = e * w mod N
	// u2 = R * w mod N
	 := new(secp256k1.ModNScalar).Mul2(&, )
	 := new(secp256k1.ModNScalar).Mul2(&.r, )

	// Step 5.
	//
	// X = u1G + u2Q
	var , , ,  secp256k1.JacobianPoint
	.AsJacobian(&)
	secp256k1.ScalarBaseMultNonConst(, &)
	secp256k1.ScalarMultNonConst(, &, &)
	secp256k1.AddNonConst(&, &, &)

	// Step 6.
	//
	// Fail if X is the point at infinity
	if (.X.IsZero() && .Y.IsZero()) || .Z.IsZero() {
		return false
	}

	// Step 7.
	//
	// z = (X.z)^2 mod P (X.z is the z coordinate of X)
	 := new(secp256k1.FieldVal).SquareVal(&.Z)

	// Step 8.
	//
	// Verified if R * z == X.x (mod P)
	 := modNScalarToField(&.r)
	 := new(secp256k1.FieldVal).Mul2(&, ).Normalize()
	if .Equals(&.X) {
		return true
	}

	// Step 9.
	//
	// Fail if R + N >= P
	if .IsGtOrEqPrimeMinusOrder() {
		return false
	}

	// Step 10.
	//
	// Verified if (R + N) * z == X.x (mod P)
	.Add(&orderAsFieldVal)
	.Mul2(&, ).Normalize()
	return .Equals(&.X)
}

// IsEqual compares this Signature instance to the one passed, returning true if
// both Signatures are equivalent.  A signature is equivalent to another, if
// they both have the same scalar value for R and S.
func ( *Signature) ( *Signature) bool {
	return .r.Equals(&.r) && .s.Equals(&.s)
}

// ParseDERSignature parses a signature in the Distinguished Encoding Rules
// (DER) format per section 10 of [ISO/IEC 8825-1] and enforces the following
// additional restrictions specific to secp256k1:
//
// - The R and S values must be in the valid range for secp256k1 scalars:
//   - Negative values are rejected
//   - Zero is rejected
//   - Values greater than or equal to the secp256k1 group order are rejected
func ( []byte) (*Signature, error) {
	// The format of a DER encoded signature for secp256k1 is as follows:
	//
	// 0x30 <total length> 0x02 <length of R> <R> 0x02 <length of S> <S>
	//   - 0x30 is the ASN.1 identifier for a sequence
	//   - Total length is 1 byte and specifies length of all remaining data
	//   - 0x02 is the ASN.1 identifier that specifies an integer follows
	//   - Length of R is 1 byte and specifies how many bytes R occupies
	//   - R is the arbitrary length big-endian encoded number which
	//     represents the R value of the signature.  DER encoding dictates
	//     that the value must be encoded using the minimum possible number
	//     of bytes.  This implies the first byte can only be null if the
	//     highest bit of the next byte is set in order to prevent it from
	//     being interpreted as a negative number.
	//   - 0x02 is once again the ASN.1 integer identifier
	//   - Length of S is 1 byte and specifies how many bytes S occupies
	//   - S is the arbitrary length big-endian encoded number which
	//     represents the S value of the signature.  The encoding rules are
	//     identical as those for R.
	//
	// NOTE: The DER specification supports specifying lengths that can occupy
	// more than 1 byte, however, since this is specific to secp256k1
	// signatures, all lengths will be a single byte.
	const (
		// 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>
		 = 8

		// maxSigLen is the maximum length of a DER encoded signature and is
		// when both R and S are 33 bytes each.  It is 33 bytes because a
		// 256-bit integer requires 32 bytes and an additional leading null byte
		// might be required if the high bit is set in the value.
		//
		// 0x30 + <1-byte> + 0x02 + 0x21 + <33 bytes> + 0x2 + 0x21 + <33 bytes>
		 = 72

		// sequenceOffset is the byte offset within the signature of the
		// expected ASN.1 sequence identifier.
		 = 0

		// dataLenOffset is the byte offset within the signature of the expected
		// total length of all remaining data in the signature.
		 = 1

		// rTypeOffset is the byte offset within the signature of the ASN.1
		// identifier for R and is expected to indicate an ASN.1 integer.
		 = 2

		// rLenOffset is the byte offset within the signature of the length of
		// R.
		 = 3

		// rOffset is the byte offset within the signature of R.
		 = 4
	)

	// The signature must adhere to the minimum and maximum allowed length.
	 := len()
	if  <  {
		 := fmt.Sprintf("malformed signature: too short: %d < %d", ,
			)
		return nil, signatureError(ErrSigTooShort, )
	}
	if  >  {
		 := fmt.Sprintf("malformed signature: too long: %d > %d", ,
			)
		return nil, signatureError(ErrSigTooLong, )
	}

	// The signature must start with the ASN.1 sequence identifier.
	if [] != asn1SequenceID {
		 := fmt.Sprintf("malformed signature: format has wrong type: %#x",
			[])
		return nil, signatureError(ErrSigInvalidSeqID, )
	}

	// The signature must indicate the correct amount of data for all elements
	// related to R and S.
	if int([]) != -2 {
		 := fmt.Sprintf("malformed signature: bad length: %d != %d",
			[], -2)
		return nil, signatureError(ErrSigInvalidDataLen, )
	}

	// Calculate the offsets of the elements related to S and ensure S is inside
	// the signature.
	//
	// rLen specifies the length of the big-endian encoded number which
	// represents the R value of the signature.
	//
	// sTypeOffset is the offset of the ASN.1 identifier for S and, like its R
	// counterpart, is expected to indicate an ASN.1 integer.
	//
	// sLenOffset and sOffset are the byte offsets within the signature of the
	// length of S and S itself, respectively.
	 := int([])
	 :=  + 
	 :=  + 1
	if  >=  {
		 := "malformed signature: S type indicator missing"
		return nil, signatureError(ErrSigMissingSTypeID, )
	}
	if  >=  {
		 := "malformed signature: S length missing"
		return nil, signatureError(ErrSigMissingSLen, )
	}

	// The lengths of R and S must match the overall length of the signature.
	//
	// sLen specifies the length of the big-endian encoded number which
	// represents the S value of the signature.
	 :=  + 1
	 := int([])
	if + !=  {
		 := "malformed signature: invalid S length"
		return nil, signatureError(ErrSigInvalidSLen, )
	}

	// R elements must be ASN.1 integers.
	if [] != asn1IntegerID {
		 := fmt.Sprintf("malformed signature: R integer marker: %#x != %#x",
			[], asn1IntegerID)
		return nil, signatureError(ErrSigInvalidRIntID, )
	}

	// Zero-length integers are not allowed for R.
	if  == 0 {
		 := "malformed signature: R length is zero"
		return nil, signatureError(ErrSigZeroRLen, )
	}

	// R must not be negative.
	if []&0x80 != 0 {
		 := "malformed signature: R is negative"
		return nil, signatureError(ErrSigNegativeR, )
	}

	// Null bytes at the start of R are not allowed, unless R would otherwise be
	// interpreted as a negative number.
	if  > 1 && [] == 0x00 && [+1]&0x80 == 0 {
		 := "malformed signature: R value has too much padding"
		return nil, signatureError(ErrSigTooMuchRPadding, )
	}

	// S elements must be ASN.1 integers.
	if [] != asn1IntegerID {
		 := fmt.Sprintf("malformed signature: S integer marker: %#x != %#x",
			[], asn1IntegerID)
		return nil, signatureError(ErrSigInvalidSIntID, )
	}

	// Zero-length integers are not allowed for S.
	if  == 0 {
		 := "malformed signature: S length is zero"
		return nil, signatureError(ErrSigZeroSLen, )
	}

	// S must not be negative.
	if []&0x80 != 0 {
		 := "malformed signature: S is negative"
		return nil, signatureError(ErrSigNegativeS, )
	}

	// Null bytes at the start of S are not allowed, unless S would otherwise be
	// interpreted as a negative number.
	if  > 1 && [] == 0x00 && [+1]&0x80 == 0 {
		 := "malformed signature: S value has too much padding"
		return nil, signatureError(ErrSigTooMuchSPadding, )
	}

	// The signature is validly encoded per DER at this point, however, enforce
	// additional restrictions to ensure R and S are in the range [1, N-1] since
	// valid ECDSA signatures are required to be in that range per spec.
	//
	// Also note that while the overflow checks are required to make use of the
	// specialized mod N scalar type, rejecting zero here is not strictly
	// required because it is also checked when verifying the signature, but
	// there really isn't a good reason not to fail early here on signatures
	// that do not conform to the ECDSA spec.

	// Strip leading zeroes from R.
	 := [ : +]
	for len() > 0 && [0] == 0x00 {
		 = [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  secp256k1.ModNScalar
	if len() > 32 {
		 := "invalid signature: R is larger than 256 bits"
		return nil, signatureError(ErrSigRTooBig, )
	}
	if  := .SetByteSlice();  {
		 := "invalid signature: R >= group order"
		return nil, signatureError(ErrSigRTooBig, )
	}
	if .IsZero() {
		 := "invalid signature: R is 0"
		return nil, signatureError(ErrSigRIsZero, )
	}

	// Strip leading zeroes from S.
	 := [ : +]
	for len() > 0 && [0] == 0x00 {
		 = [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  secp256k1.ModNScalar
	if len() > 32 {
		 := "invalid signature: S is larger than 256 bits"
		return nil, signatureError(ErrSigSTooBig, )
	}
	if  := .SetByteSlice();  {
		 := "invalid signature: S >= group order"
		return nil, signatureError(ErrSigSTooBig, )
	}
	if .IsZero() {
		 := "invalid signature: S is 0"
		return nil, signatureError(ErrSigSIsZero, )
	}

	// Create and return the signature.
	return NewSignature(&, &), nil
}

// 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
// nonce and private key and returns it along with an additional public key
// recovery code and success indicator.  Upon success, the produced signature is
// deterministic (same message, nonce, and key yield the same signature) and
// canonical in accordance with BIP0062.
//
// Note that signRFC6979 makes use of this function as it is the primary ECDSA
// signing logic.  It differs in that it accepts a nonce to use when signing and
// may not successfully produce a valid signature for the given nonce.  It is
// primarily separated for testing purposes.
func sign(,  *secp256k1.ModNScalar,  []byte) (*Signature, byte, bool) {
	// The algorithm for producing an ECDSA signature is given as algorithm 4.29
	// in [GECC].
	//
	// The following is a paraphrased version for reference:
	//
	// G = curve generator
	// N = curve order
	// d = private key
	// m = message
	// r, s = signature
	//
	// 1. Select random nonce k in [1, N-1]
	// 2. Compute kG
	// 3. r = kG.x mod N (kG.x is the x coordinate of the point kG)
	//    Repeat from step 1 if r = 0
	// 4. e = H(m)
	// 5. s = k^-1(e + dr) mod N
	//    Repeat from step 1 if s = 0
	// 6. Return (r,s)
	//
	// This is slightly modified here to conform to RFC6979 and BIP 62 as
	// follows:
	//
	// A. Instead of selecting a random nonce in step 1, use RFC6979 to generate
	//    a deterministic nonce in [1, N-1] parameterized by the private key,
	//    message being signed, and an iteration count for the repeat cases
	// B. Negate s calculated in step 5 if it is > N/2
	//    This is done because both s and its negation are valid signatures
	//    modulo the curve order N, so it forces a consistent choice to reduce
	//    signature malleability

	// NOTE: Step 1 is performed by the caller.
	//
	// Step 2.
	//
	// Compute kG
	//
	// Note that the point must be in affine coordinates.
	 := 
	var  secp256k1.JacobianPoint
	secp256k1.ScalarBaseMultNonConst(, &)
	.ToAffine()

	// Step 3.
	//
	// r = kG.x mod N
	// Repeat from step 1 if r = 0
	,  := fieldToModNScalar(&.X)
	if .IsZero() {
		return nil, 0, false
	}

	// Since the secp256k1 curve has a cofactor of 1, when recovering a
	// public key from an ECDSA signature over it, there are four possible
	// candidates corresponding to the following cases:
	//
	// 1) The X coord of the random point is < N and its Y coord even
	// 2) The X coord of the random point is < N and its Y coord is odd
	// 3) The X coord of the random point is >= N and its Y coord is even
	// 4) The X coord of the random point is >= N and its Y coord is odd
	//
	// Rather than forcing the recovery procedure to check all possible
	// cases, this creates a recovery code that uniquely identifies which of
	// the cases apply by making use of 2 bits.  Bit 0 identifies the
	// oddness case and Bit 1 identifies the overflow case (aka when the X
	// coord >= N).
	//
	// It is also worth noting that making use of Hasse's theorem shows
	// there are around log_2((p-n)/p) ~= -127.65 ~= 1 in 2^127 points where
	// the X coordinate is >= N.  It is not possible to calculate these
	// points since that would require breaking the ECDLP, but, in practice
	// this strongly implies with extremely high probability that there are
	// only a few actual points for which this case is true.
	 := byte(<<1) | byte(.Y.IsOddBit())

	// Step 4.
	//
	// e = H(m)
	//
	// Note that this actually sets e = H(m) mod N which is correct since
	// it is only used in step 5 which itself is mod N.
	var  secp256k1.ModNScalar
	.SetByteSlice()

	// Step 5 with modification B.
	//
	// s = k^-1(e + dr) mod N
	// Repeat from step 1 if s = 0
	// s = -s if s > N/2
	 := new(secp256k1.ModNScalar).InverseValNonConst()
	 := new(secp256k1.ModNScalar).Mul2(, &).Add(&).Mul()
	if .IsZero() {
		return nil, 0, false
	}
	if .IsOverHalfOrder() {
		.Negate()

		// Negating s corresponds to the random point that would have been
		// generated by -k (mod N), which necessarily has the opposite
		// oddness since N is prime, thus flip the pubkey recovery code
		// oddness bit accordingly.
		 ^= 0x01
	}

	// Step 6.
	//
	// Return (r,s)
	return NewSignature(&, ), , true
}

// signRFC6979 generates a deterministic ECDSA signature according to RFC 6979
// and BIP0062 and returns it along with an additional public key recovery code
// for efficiently recovering the public key from the signature.
func signRFC6979( *secp256k1.PrivateKey,  []byte) (*Signature, byte) {
	// The algorithm for producing an ECDSA signature is given as algorithm 4.29
	// in [GECC].
	//
	// The following is a paraphrased version for reference:
	//
	// G = curve generator
	// N = curve order
	// d = private key
	// m = message
	// r, s = signature
	//
	// 1. Select random nonce k in [1, N-1]
	// 2. Compute kG
	// 3. r = kG.x mod N (kG.x is the x coordinate of the point kG)
	//    Repeat from step 1 if r = 0
	// 4. e = H(m)
	// 5. s = k^-1(e + dr) mod N
	//    Repeat from step 1 if s = 0
	// 6. Return (r,s)
	//
	// This is slightly modified here to conform to RFC6979 and BIP 62 as
	// follows:
	//
	// A. Instead of selecting a random nonce in step 1, use RFC6979 to generate
	//    a deterministic nonce in [1, N-1] parameterized by the private key,
	//    message being signed, and an iteration count for the repeat cases
	// B. Negate s calculated in step 5 if it is > N/2
	//    This is done because both s and its negation are valid signatures
	//    modulo the curve order N, so it forces a consistent choice to reduce
	//    signature malleability

	 := &.Key
	var  [32]byte
	.PutBytes(&)
	defer zeroArray32(&)
	for  := uint32(0); ; ++ {
		// Step 1 with modification A.
		//
		// Generate a deterministic nonce in [1, N-1] parameterized by the
		// private key, message being signed, and iteration count.
		 := secp256k1.NonceRFC6979([:], , nil, nil, )

		// Steps 2-6.
		, ,  := sign(, , )
		.Zero()
		if ! {
			continue
		}

		return , 
	}
}

// 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 ( *secp256k1.PrivateKey,  []byte) *Signature {
	,  := signRFC6979(, )
	return 
}

const (
	// compactSigSize is the size of a compact signature.  It consists of a
	// compact signature recovery code byte followed by the R and S components
	// serialized as 32-byte big-endian values. 1+32*2 = 65.
	// for the R and S components. 1+32+32=65.
	compactSigSize = 65

	// compactSigMagicOffset is a value used when creating the compact signature
	// recovery code inherited from Bitcoin and has no meaning, but has been
	// retained for compatibility.  For historical purposes, it was originally
	// picked to avoid a binary representation that would allow compact
	// signatures to be mistaken for other components.
	compactSigMagicOffset = 27

	// compactSigCompPubKey is a value used when creating the compact signature
	// recovery code to indicate the original public key was compressed.
	compactSigCompPubKey = 4

	// pubKeyRecoveryCodeOddnessBit specifies the bit that indicates the oddess
	// of the Y coordinate of the random point calculated when creating a
	// signature.
	pubKeyRecoveryCodeOddnessBit = 1 << 0

	// pubKeyRecoveryCodeOverflowBit specifies the bit that indicates the X
	// coordinate of the random point calculated when creating a signature was
	// >= N, where N is the order of the group.
	pubKeyRecoveryCodeOverflowBit = 1 << 1
)

// SignCompact produces a compact 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 isCompressedKey parameter specifies if the
// produced signature should reference a compressed public key or not.
//
// Compact signature format:
// <1-byte compact sig recovery code><32-byte R><32-byte S>
//
// The compact sig recovery code is the value 27 + public key recovery code + 4
// if the compact signature was created with a compressed public key.
func ( *secp256k1.PrivateKey,  []byte,  bool) []byte {
	// Create the signature and associated pubkey recovery code and calculate
	// the compact signature recovery code.
	,  := signRFC6979(, )
	 := compactSigMagicOffset + 
	if  {
		 += compactSigCompPubKey
	}

	// Output <compactSigRecoveryCode><32-byte R><32-byte S>.
	var  [compactSigSize]byte
	[0] = 
	.r.PutBytesUnchecked([1:33])
	.s.PutBytesUnchecked([33:65])
	return [:]
}

// RecoverCompact attempts to recover the secp256k1 public key from the provided
// compact signature and message hash.  It first verifies the signature, and, if
// the signature matches then the recovered public key will be returned as well
// as a boolean indicating whether or not the original key was compressed.
func (,  []byte) (*secp256k1.PublicKey, bool, error) {
	// The following is very loosely based on the information and algorithm that
	// describes recovering a public key from and ECDSA signature in section
	// 4.1.6 of [SEC1].
	//
	// Given the following parameters:
	//
	// G = curve generator
	// N = group order
	// P = field prime
	// Q = public key
	// m = message
	// e = hash of the message
	// r, s = signature
	// X = random point used when creating signature whose x coordinate is r
	//
	// The equation to recover a public key candidate from an ECDSA signature
	// is:
	// Q = r^-1(sX - eG).
	//
	// This can be verified by plugging it in for Q in the sig verification
	// equation:
	// X = s^-1(eG + rQ) (mod N)
	//  => s^-1(eG + r(r^-1(sX - eG))) (mod N)
	//  => s^-1(eG + sX - eG) (mod N)
	//  => s^-1(sX) (mod N)
	//  => X (mod N)
	//
	// However, note that since r is the x coordinate mod N from a random point
	// that was originally mod P, and the cofactor of the secp256k1 curve is 1,
	// there are four possible points that the original random point could have
	// been to produce r: (r,y), (r,-y), (r+N,y), and (r+N,-y).  At least 2 of
	// those points will successfully verify, and all 4 will successfully verify
	// when the original x coordinate was in the range [N+1, P-1], but in any
	// case, only one of them corresponds to the original private key used.
	//
	// The method described by section 4.1.6 of [SEC1] to determine which one is
	// the correct one involves calculating each possibility as a candidate
	// public key and comparing the candidate to the authentic public key.  It
	// also hints that it is possible to generate the signature in a such a
	// way that only one of the candidate public keys is viable.
	//
	// A more efficient approach that is specific to the secp256k1 curve is used
	// here instead which is to produce a "pubkey recovery code" when signing
	// that uniquely identifies which of the 4 possibilities is correct for the
	// original random point and using that to recover the pubkey directly as
	// follows:
	//
	// 1. Fail if r and s are not in [1, N-1]
	// 2. Convert r to integer mod P
	// 3. If pubkey recovery code overflow bit is set:
	//    3.1 Fail if r + N >= P
	//    3.2 r = r + N (mod P)
	// 4. y = +sqrt(r^3 + 7) (mod P)
	//    4.1 Fail if y does not exist
	//    4.2 y = -y if needed to match pubkey recovery code oddness bit
	// 5. X = (r, y)
	// 6. e = H(m) mod N
	// 7. w = r^-1 mod N
	// 8. u1 = -(e * w) mod N
	//    u2 = s * w mod N
	// 9. Q = u1G + u2X
	// 10. Fail if Q is the point at infinity

	// A compact signature consists of a recovery byte followed by the R and
	// S components serialized as 32-byte big-endian values.
	if len() != compactSigSize {
		 := fmt.Sprintf("malformed signature: wrong size: %d != %d",
			len(), compactSigSize)
		return nil, false, signatureError(ErrSigInvalidLen, )
	}

	// Parse and validate the compact signature recovery code.
	const (
		 = compactSigMagicOffset
		 = compactSigMagicOffset + compactSigCompPubKey + 3
	)
	 := [0]
	if  <  ||  >  {
		 := fmt.Sprintf("invalid signature: public key recovery code %d is "+
			"not in the valid range [%d, %d]", , ,
			)
		return nil, false, signatureError(ErrSigInvalidRecoveryCode, )
	}
	 -= compactSigMagicOffset
	 := &compactSigCompPubKey != 0
	 :=  & 3

	// Step 1.
	//
	// Parse and validate the R and S signature components.
	//
	// Fail if r and s are not in [1, N-1].
	var ,  secp256k1.ModNScalar
	if  := .SetByteSlice([1:33]);  {
		 := "invalid signature: R >= group order"
		return nil, false, signatureError(ErrSigRTooBig, )
	}
	if .IsZero() {
		 := "invalid signature: R is 0"
		return nil, false, signatureError(ErrSigRIsZero, )
	}
	if  := .SetByteSlice([33:]);  {
		 := "invalid signature: S >= group order"
		return nil, false, signatureError(ErrSigSTooBig, )
	}
	if .IsZero() {
		 := "invalid signature: S is 0"
		return nil, false, signatureError(ErrSigSIsZero, )
	}

	// Step 2.
	//
	// Convert r to integer mod P.
	 := modNScalarToField(&)

	// Step 3.
	//
	// If pubkey recovery code overflow bit is set:
	if &pubKeyRecoveryCodeOverflowBit != 0 {
		// Step 3.1.
		//
		// Fail if r + N >= P
		//
		// Either the signature or the recovery code must be invalid if the
		// recovery code overflow bit is set and adding N to the R component
		// would exceed the field prime since R originally came from the X
		// coordinate of a random point on the curve.
		if .IsGtOrEqPrimeMinusOrder() {
			 := "invalid signature: signature R + N >= P"
			return nil, false, signatureError(ErrSigOverflowsPrime, )
		}

		// Step 3.2.
		//
		// r = r + N (mod P)
		.Add(&orderAsFieldVal)
	}
	.Normalize()

	// Step 4.
	//
	// y = +sqrt(r^3 + 7) (mod P)
	// Fail if y does not exist.
	// y = -y if needed to match pubkey recovery code oddness bit
	//
	// The signature must be invalid if the calculation fails because the X
	// coord originally came from a random point on the curve which means there
	// must be a Y coord that satisfies the equation for a valid signature.
	 := &pubKeyRecoveryCodeOddnessBit != 0
	var  secp256k1.FieldVal
	if  := secp256k1.DecompressY(&, , &); ! {
		 := "invalid signature: not for a valid curve point"
		return nil, false, signatureError(ErrPointNotOnCurve, )
	}

	// Step 5.
	//
	// X = (r, y)
	var  secp256k1.JacobianPoint
	.X.Set(&)
	.Y.Set(&)
	.Z.SetInt(1)

	// Step 6.
	//
	// e = H(m) mod N
	var  secp256k1.ModNScalar
	.SetByteSlice()

	// Step 7.
	//
	// w = r^-1 mod N
	 := new(secp256k1.ModNScalar).InverseValNonConst(&)

	// Step 8.
	//
	// u1 = -(e * w) mod N
	// u2 = s * w mod N
	 := new(secp256k1.ModNScalar).Mul2(&, ).Negate()
	 := new(secp256k1.ModNScalar).Mul2(&, )

	// Step 9.
	//
	// Q = u1G + u2X
	var , ,  secp256k1.JacobianPoint
	secp256k1.ScalarBaseMultNonConst(, &)
	secp256k1.ScalarMultNonConst(, &, &)
	secp256k1.AddNonConst(&, &, &)

	// Step 10.
	//
	// Fail if Q is the point at infinity.
	//
	// Either the signature or the pubkey recovery code must be invalid if the
	// recovered pubkey is the point at infinity.
	if (.X.IsZero() && .Y.IsZero()) || .Z.IsZero() {
		 := "invalid signature: recovered pubkey is the point at infinity"
		return nil, false, signatureError(ErrPointNotOnCurve, )
	}

	// Notice that the public key is in affine coordinates.
	.ToAffine()
	 := secp256k1.NewPublicKey(&.X, &.Y)
	return , , nil
}