diff --git a/README.mediawiki b/README.mediawiki index 403d852c22..5b2b9aaf9f 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1513,6 +1513,13 @@ users (see also: [https://en.bitcoin.it/wiki/Economic_majority economic majority | bubb1es, haris | Specification | Draft +|- +| [[bip-0461.md|461]] +| Applications +| Deterministic ECDSA Signatures +| Liam Gilligan +| Specification +| Draft |} diff --git a/bip-0461.md b/bip-0461.md new file mode 100644 index 0000000000..444db94711 --- /dev/null +++ b/bip-0461.md @@ -0,0 +1,251 @@ +``` + BIP: 461 + Layer: Applications + Title: Deterministic ECDSA Signatures + Authors: Liam Gilligan + Status: Draft + Type: Specification + Assigned: 2026-08-12 + License: CC0-1.0 + Discussion: 2026-06-09: https://groups.google.com/g/bitcoindev/c/boEZRlqczvw +``` + +## Abstract + +This document specifies an ECDSA signing algorithm whose output is fully determined by the secret key and the message being signed. Its signatures are at most 70 bytes when DER encoded, rather than 72 for an arbitrary valid ECDSA signature. + +## Motivation + +Under current consensus rules, a valid ECDSA signature of any message under any key has two degrees of freedom: the signer's free choice of nonce fixes *r*[^rchoice], and two possible values of *s* follow from a specific *r*. A malicious signer can exploit that freedom to generate signatures that leak key material[^darkskippy], but a standardized, deterministic signing algorithm removes that freedom. Signers expected to comply with such an algorithm cannot leak key material without risking detection: a key holder can load the same secret key into two independent signers, sign the same message on both, and compare the results, as any difference reveals that at least one signer is not following this specification. + +The standardization of the deterministic algorithm is what enables leak detection, as a nonstandard algorithm has no other implementations to cross-check against. + +## Definitions + +- The value *(n - 1) / 2* is the **half curve order**, where *n* is the order of the secp256k1 curve. +- A given signature *(r, s)* is considered **low-*r*** when *r < 2255*, and is otherwise considered **high-*r***. +- A given signature *(r, s)* is considered **low-*s*** when *s* is less than or equal to the half curve order, and is otherwise considered **high-*s***. +- **Low-*r* grinding** is the process of regenerating a signature with a new nonce until it is a low-*r* signature. +- **Low-*s* normalization** is the process of replacing a signature *(r, s)* with the equivalent signature *(r, n - s)* if *(r, s)* is high-*s*.[^lowsnormalization] + +## Specification + +### Notation + +The following conventions are used, with constants as defined for [secp256k1](https://www.secg.org/sec2-v2.pdf). + +- Lowercase variables represent integers, byte arrays, or signatures: + + - The constant *p* refers to the field size, *0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F*. + - The constant *n* refers to the curve order, *0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141*. + - The constant *half_order* refers to the half curve order, *(n - 1) / 2*. + - The constant *empty_bytestring* refers to the byte array of length zero. + - An ECDSA signature *sig* can be represented literally by an integer pair *(r, s)*, with *0 < r, s < n*. + +- Points on the curve with equation *y2 = x3 + 7* over the integers modulo *p*: + + - The point at infinity is the identity element of the curve group, and is the only point without X and Y coordinates. + - The function *is_infinite(P)* returns whether or not *P* is the point at infinity. + - *x(P)* and *y(P)* are integers in the range *0..p-1* and refer to the X and Y coordinates of a point *P* (assuming it is not infinity). + - The constant *G* refers to the base point, for which *x(G) = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798* and *y(G) = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8*. + - Addition of points refers to the usual [elliptic curve group operation](https://en.wikipedia.org/wiki/Elliptic_curve#The_group_law). + - [Multiplication (⋅) of an integer and a point](https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication) refers to the repeated application of the group operation. + +- Functions and operations: + + - *||* refers to byte array concatenation. + - The function *int(x)*, where *x* is a 32-byte array, returns the 256-bit unsigned integer whose most significant byte first encoding is *x*. + - The function *bytes(l, x)*, where *x* is an integer, returns the *l*-byte encoding of *x*, most significant byte first. + - The function *bytes_le(l, x)*, where *x* is an integer, returns the *l*-byte encoding of *x*, least significant byte first. + - The function *fill_bytes(l, x)*, where *x* is a byte, returns the length *l* byte array in which every byte is *x*. + - The function *hmac(k, m)*, where *k* and *m* are byte arrays, returns HMAC-SHA256[^hmac] with key *k* over message *m*. + - *x-1* refers to the modular multiplicative inverse of the integer *x* modulo *n*. + +### Algorithms + +This section specifies the following algorithms: + +- *nonce_rfc6979(sk, msghash, extra, count)* derives a nonce deterministically. +- *sign(sk, msghash, extra)* produces an ECDSA signature under a given additional data input. +- *verify(sig, P, msghash)* checks an ECDSA signature. +- *DeterministicSign(sk, msghash)* grinds *sign* until *r* is low and normalizes *s*. + +#### Nonce Derivation + +Input: + +- The secret key *sk*: a 32-byte array +- The message hash *msghash*: a 32-byte array +- The additional data *extra*: a byte array, possibly empty +- The attempt counter *count*: an integer, *count >= 0* + +The algorithm *nonce_rfc6979(sk, msghash, extra, count)* is defined as:[^kv] + +- Let *h = bytes(32, int(msghash) mod n)*[^bits2octets] +- Let *V = fill_bytes(32, 0x01)* +- Let *K = fill_bytes(32, 0x00)* +- Let *K = hmac(K, V || 0x00 || sk || h || extra)* +- Let *V = hmac(K, V)* +- Let *K = hmac(K, V || 0x01 || sk || h || extra)* +- Let *V = hmac(K, V)* +- Let *V = hmac(K, V)* +- For *j = 1, ..., count*: + - Let *K = hmac(K, V || 0x00)* + - Let *V = hmac(K, V)* + - Let *V = hmac(K, V)* +- Return *V* + +#### ECDSA Signing + +Input: + +- The secret key *sk*: a 32-byte array +- The message hash *msghash*: a 32-byte array +- The additional data *extra*: a byte array, possibly empty + +The algorithm *sign(sk, msghash, extra)* is defined as: + +- Let *d = int(sk)* +- Fail if *d = 0* or *d >= n* +- For *count = 0, 1, ..., 232 - 1*:[^attempt] + - Let *nonce = nonce_rfc6979(sk, msghash, extra, count)* + - Let *k = int(nonce)* + - Continue if *k = 0* or *k >= n* + - Let *R = k⋅G* + - Let *r = x(R) mod n* + - Continue if *r = 0* + - Let *s = k-1 * (d * r + int(msghash)) mod n* + - Continue if *s = 0* + - Return *(r, s)* +- Fail + +#### ECDSA Verification + +Input: + +- The signature *sig*: *(r, s)* +- The public key *P*: a point +- The message hash *msghash*: a 32-byte array + +The algorithm *verify(sig, P, msghash)* is defined as: + +- If *is_infinite(P)*: + - Return *false* +- If *y(P)2 ≠ x(P)3 + 7 mod p*: + - Return *false* +- Let *(r, s) = sig* +- If *r = 0* or *r >= n*: + - Return *false* +- If *s = 0* or *s >= n*: + - Return *false* +- Let *w = s-1* +- Let *u1 = w * int(msghash) mod n* +- Let *u2 = w * r mod n* +- Let *R = u1⋅G + u2⋅P* +- If *is_infinite(R)*: + - Return *false* +- If *x(R) mod n ≠ r*: + - Return *false* +- Return *true* + +#### Deterministic Signing + +Input: + +- The secret key *sk*: a 32-byte array +- The message hash *msghash*: a 32-byte array + +The algorithm *DeterministicSign(sk, msghash)* is defined as follows. The **grind counter** is *0* for the initial call to *sign*, which supplies no additional data, and takes the value of the loop variable *i* for every subsequent call. + +- Fail if *int(sk) = 0* or *int(sk) >= n* +- Let *(r, s) = sign(sk, msghash, empty_bytestring)*[^ndata] +- Let *i = 1* +- While *r >= 2255*:[^geometric] + - If *i >= 232*: + - Fail + - Let *extra = bytes_le(4, i) || fill_bytes(28, 0x00)*[^core] + - Let *(r, s) = sign(sk, msghash, extra)* + - Let *i = i + 1* +- If *s > half_order*:[^lows] + - Let *s = n - s* +- Let *P = int(sk)⋅G* +- If *verify((r, s), P, msghash)* returns *false*, abort[^verifysign] +- Return *(r, s)* + +The predicate *r >= 2255* is equivalent to testing that the most significant byte of *bytes(32, r)* is greater than or equal to *0x80*. + +## Rationale + +Bitcoin encodes ECDSA signatures in a strict DER form with an additional 1-byte sighash flag, which serializes *r* and *s* as arbitrary-length big-endian signed integers[^bip66]. Their encoding being signed means that even though every value of *r* and *s* can be encoded in 32 bytes or less as an unsigned integer, a null byte must be prepended if the most significant bit is set, raising the maximum size to 33 bytes each. The maximum size of a DER encoded ECDSA signature is 72 bytes, or 73 with the sighash flag. + +The signing algorithm as specified makes use of low-*r* grinding and low-*s* normalization[^lowspolicy] to exclusively produce low-*r* and low-*s* signatures. This produces signatures with a maximum DER encoding size of 70 bytes, or 71 with the sighash flag.[^bip62size] Against a signer that normalizes *s* but does not grind, low-*r* grinding saves on average 0.5 vbytes per signature in legacy inputs and 0.125 vbytes in v0 segwit inputs.[^optech] In 2-of-3 P2SH inputs it saves 2.5 vbytes on average, as a single high-*r* signature pushes the input script's length indicator from one byte to three. The cost is rather cheap: low-*r* grinding requires an additional signing operation and low-*s* normalization requires a scalar subtraction. Uniform adoption is worthwhile independently of the savings, as a signer that does not grind is identifiable on-chain by its high-*r* signatures.[^review] + +### Low-*r* Grinding + +#### Why RFC 6979 + +Grinding requires a nonce derivation that is deterministic in the secret key and message, and that additionally accepts a counter, so that a fresh and unrelated nonce can be derived for the same key and message.[^noncereq] RFC 6979 provides exactly this: it is the IETF's standard deterministic nonce derivation for ECDSA, and its section 3.6 admits an additional data input, for which it names a signature counter as an example:[^rfc6979] + +> It suffices that the additional data k' is non-repeating (e.g., a signature counter or a monotonic clock) to ensure "random-looking" signatures are indistinguishable, in a cryptographic way, from plain (EC)DSA signatures. + +#### Potential Alternate Grinding Methods + +**A fresh random nonce on each attempt.** Drawing each candidate nonce from a cryptographically secure random source also yields unrelated nonces, and is a valid means of producing low-*r* signatures. Such a method is not adopted because the resulting signatures are not reproducible, which reopens the exfiltration problem described in the Motivation. Randomness would buy some protection against fault injection, which is why [BIP 340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki) recommends it for Schnorr signatures. Deterministic derivation is nonetheless established practice for ECDSA in Bitcoin, as RFC 6979 is libsecp256k1's default nonce function and Bitcoin Core requests it explicitly.[^deterministictoday] + +**Grinding for smaller *r*.** In order for a lower *r* value to save any space, it must be an entire byte smaller, and thus must have the leading 9 bits unset rather than just the leading bit. Computing such an *r* value would take 512 signing operations on average, as opposed to the two of regular low-*r* grinding.[^geometric] Grinding for a smaller *r* was deemed too expensive to be adopted widely. Because few signers would do so, the signers that did would be identifiable on-chain.[^pr13666] + +**Speeding up grinding with the *λ* endomorphism.** It was suggested to use secp256k1's *λ* endomorphism to quickly compute alternative nonces.[^endomorphism] Low-*r* grinding as specified takes only two point multiplications on average. The added complexity of using the *λ* endomorphism cannot meaningfully improve on that.[^endospeedup] + +## Backward Compatibility + +Signatures generated under this specification are normal valid signatures and will verify under existing consensus rules, and thus are fully backward compatible. + +## Copyright + +This BIP is licensed under the CC0-1.0 license. + +[^rchoice]: Technically a signer selects a nonce *k*, from which *r = x(k⋅G) mod n* follows. It cannot target a particular *r* without solving the discrete logarithm problem, and only about half the integers modulo *n* occur as an *r* at all, since *r* must be the x-coordinate of a curve point. What the signer has is free choice of *k*, and so free choice among the *r* values that result. + +[^darkskippy]: [Dark Skippy](https://darkskippy.com/) is a method by which malicious signing device firmware embeds seed material in the nonces of otherwise valid signatures, from which an attacker who observes those signatures on-chain can recover the seed. Raised in the context of this document by Craig Raw; see [this comment](https://github.com/bitcoin/bips/pull/2224#issuecomment-5114943404). + +[^lowsnormalization]: Low-*s* normalization preserves signature validity: Let *(r, s)* be a high-*s* signature that *verify* accepts for a public key *P* and message hash *msghash*. Let *(r, s')* be a low-*s* signature with *s' = n - s*, and let us consider whether *verify* will accept it under *P* and *msghash*. The checks on *P*, *msghash*, and *r* do not involve *s* and are unchanged, and *s'* passes the range check because *0 < s < n* implies *0 < n - s < n*. Since *s' ≡ -s (mod n)*, *w' = -w*, so *u1' = -u1*, *u2' = -u2*, and consequently *R' = -R*. The x-coordinate of a finite point is invariant under negation, so *x(R') mod n = r*, and thus *verify* accepts *(r, n - s)* and low-*s* normalization preserves validity. + +[^hmac]: [RFC 2104: HMAC: Keyed-Hashing for Message Authentication](https://www.rfc-editor.org/rfc/rfc2104), instantiated with SHA-256 as specified in [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf). + +[^kv]: *K* and *V* are the internal state variables of the HMAC-based generator specified in [RFC 6979 section 3.2](https://www.rfc-editor.org/rfc/rfc6979#section-3.2), and carry its names. Both are 32-byte arrays rather than curve points, and *K* is unrelated to the nonce *k*. + +[^bits2octets]: This reduction is RFC 6979's *bits2octets(h1)*, required by [section 3.2d](https://www.rfc-editor.org/rfc/rfc6979#section-3.2). It has no effect unless *int(msghash) >= n*, which occurs with probability about 1.27 · 2-128. libsecp256k1 performs it as `msgmod32` in `nonce_function_rfc6979`; see [libsecp256k1 `src/secp256k1.c`](https://github.com/bitcoin-core/secp256k1/blob/master/src/secp256k1.c). Bitcoin Core acquired the reduction in v24.0, having fed the unreduced hash from v0.17.0 through v23.0. + +[^attempt]: *count* advances the RFC 6979 generator without changing *extra*, and is distinct from the grind counter *i*. libsecp256k1 increments the same counter whenever the derived nonce falls outside *[1, n-1]*, or the resulting *r* or *s* is zero; see `secp256k1_ecdsa_sign_inner` in [libsecp256k1 `src/secp256k1.c`](https://github.com/bitcoin-core/secp256k1/blob/master/src/secp256k1.c), which retries in both cases rather than failing. Each of those conditions has probability on the order of 2-128 or less, so *count* is 0 for every signature produced in practice. Because *sign* rejects an out-of-range secret key, and *DeterministicSign* rejects one before the loop is entered, no secret key makes every attempt fail, so the loop's *Fail* branch is unreachable in practice. An implementation may therefore omit the retry and fail on the first unusable nonce instead. Retrying is recommended and costs nothing, and neither choice affects the test vectors or interoperability. + +[^ndata]: Omitting the additional data makes RFC 6979 hash a 64-byte seed rather than a 96-byte one, so grind counter *0* does not produce the nonce that 32 null bytes would. See [libsecp256k1 `src/secp256k1.c`](https://github.com/bitcoin-core/secp256k1/blob/master/src/secp256k1.c), `nonce_function_rfc6979`, which notes that the argument mixtures have distinct lengths and so cannot emulate one another. + +[^geometric]: For an event of probability *q*, the expected number of attempts before the first success is 1/*q*. A low *r* arises with probability approximately 1/2, so grinding as specified takes two attempts on average, needs more than *j* attempts with probability 2-j, and terminates with probability 1; Bitcoin Core allots a 32-bit counter, which cannot be exhausted in practice. Grinding for an *r* a whole byte smaller instead has *q* = 2-9, giving 512 attempts on average. That threshold is nine bits rather than eight because DER restores the padding byte whenever the leading content byte has its most significant bit set, so *r* must fall below 2247 rather than 2248. + +[^core]: The little-endian counter is an artifact of `CKey::Sign` writing the counter into a 32-byte entropy buffer with `WriteLE32`; see [Bitcoin Core `src/key.cpp`](https://github.com/bitcoin/bitcoin/blob/master/src/key.cpp). + +[^lows]: [libsecp256k1 `src/ecdsa_impl.h`](https://github.com/bitcoin-core/secp256k1/blob/master/src/ecdsa_impl.h), `secp256k1_ecdsa_sig_sign`: `high = secp256k1_scalar_is_high(sigs); secp256k1_scalar_cond_negate(sigs, high);` + +[^verifysign]: Verifying the signature before leaving the signer prevents random or attacker provoked computation errors. This prevents publishing invalid signatures which may leak information about the secret key. It is recommended, but can be omitted if the computation cost is prohibitive, at the cost of detecting faults in the signing computation. The preceding wording is taken from the equivalent step in the signing algorithm of [BIP 340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki), which is licensed under BSD-2-Clause. Bitcoin Core performs the check unconditionally in [`CKey::Sign`](https://github.com/bitcoin/bitcoin/blob/master/src/key.cpp). Because the check cannot alter the returned signature, omitting it affects neither the test vectors nor interoperability. + +[^bip66]: [BIP 66: Strict DER signatures](https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki). + +[^lowspolicy]: Note that transactions with high-*s* signatures are valid but currently will not be relayed based on standard policy: see [Bitcoin Core `src/policy/policy.h`](https://github.com/bitcoin/bitcoin/blob/master/src/policy/policy.h). + +[^bip62size]: A signer that normalizes *s* but does not grind falls between the two bounds, at 71 bytes of DER. [BIP 62](https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki), "DER encoding", gives that case as "the total signature size being at most 72 bytes (and on average 71.494 bytes)", counting the sighash flag. The average falls slightly below 71.5 because *r* occasionally encodes in fewer than 32 bytes. + +[^optech]: [Bitcoin Optech: Low-r grinding](https://bitcoinops.org/en/topics/low-r-grinding/). + +[^review]: See, e.g., [this comment](https://github.com/bitcoin/bitcoin/pull/13666#issuecomment-406053492) and the surrounding discussion in the pull request that introduced grinding to Bitcoin Core. + +[^noncereq]: Two published signatures whose nonces stand in a relation an attacker can find will leak the secret key. Neither the intermediate attempts of a grind nor the counter that produced the successful one is published, so the constraint binds across messages rather than within a single grind loop; RFC 6979 satisfies it in both directions in any case. A fresh nonce from a cryptographically secure random source on each attempt also satisfies it, though the resulting signatures are not reproducible. + +[^rfc6979]: [RFC 6979: Deterministic Usage of the Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA)](https://www.rfc-editor.org/rfc/rfc6979). The additional data input and the non-repetition requirement are given in [section 3.6](https://www.rfc-editor.org/rfc/rfc6979#section-3.6). + +[^deterministictoday]: `secp256k1_nonce_function_default` is `nonce_function_rfc6979`; see [libsecp256k1 `src/secp256k1.c`](https://github.com/bitcoin-core/secp256k1/blob/master/src/secp256k1.c). Bitcoin Core passes `secp256k1_nonce_function_rfc6979` to `secp256k1_ecdsa_sign` in [`CKey::Sign`](https://github.com/bitcoin/bitcoin/blob/master/src/key.cpp). + +[^pr13666]: [Bitcoin Core PR #13666, "Always create signatures with Low R values"](https://github.com/bitcoin/bitcoin/pull/13666), released in [Bitcoin Core v0.17.0](https://bitcoincore.org/en/releases/0.17.0/). The review discussion also considered grinding for even smaller *r* values; see [this comment](https://github.com/bitcoin/bitcoin/pull/13666#issuecomment-405116700). + +[^endomorphism]: [Suggested during review of the pull request that introduced grinding to Bitcoin Core](https://github.com/bitcoin/bitcoin/pull/13666#issuecomment-405116700); the replies that follow discuss the nonce distribution it would produce. + +[^endospeedup]: A single point multiplication for the nonce *k* also yields the *r* values belonging to *λk* and *λ*2*k*, where *λ* is a primitive cube root of unity modulo the group order; see [libsecp256k1 `src/scalar_impl.h`](https://github.com/bitcoin-core/secp256k1/blob/master/src/scalar_impl.h), `secp256k1_const_lambda`. Since a signer must compute one point multiplication in any case, this saves at most one per signature, and capturing it requires curve arithmetic outside the signing routine.