1
0
mirror of https://github.com/bitcoin/bips.git synced 2026-09-21 19:04:28 +00:00

BIP-374: treat challenge hash result e as scalar, bump to version 0.3.0

Note that the purpose of this change is primarily to improve clarity
for implementers and consistency with existing BIPs like BIP-340 and
BIP-327. Under the assumption that reaching a challenge hash with
`e >= n` is negligible, the newly introduced test vectors in the next
commit would also fail without the new rejection branch.
This commit is contained in:
Sebastian Falbesoner
2026-08-19 15:35:48 +02:00
parent 857a7debc6
commit c88e295d92
2 changed files with 9 additions and 5 deletions

View File

@@ -11,7 +11,7 @@
License: BSD-2-Clause
Discussion: https://gist.github.com/andrewtoth/df97c3260cc8d12f09d3855ee61322ea
https://groups.google.com/g/bitcoindev/c/MezoKV5md7s
Version: 0.2.0
Version: 0.3.0
</pre>
== Introduction ==
@@ -79,7 +79,7 @@ The algorithm ''GenerateProof(a, B, r, G, m)'' is defined as:
* Fail if ''k = 0''.
* Let ''R<sub>1</sub> = k⋅G''.
* Let ''R<sub>2</sub> = k⋅B''.
* Let ''e = int(hash<sub>BIP0374/challenge</sub>(cbytes(A) || cbytes(B) || cbytes(C) || cbytes(G) || cbytes(R<sub>1</sub>) || cbytes(R<sub>2</sub>) || m'))''.
* Let ''e = int(hash<sub>BIP0374/challenge</sub>(cbytes(A) || cbytes(B) || cbytes(C) || cbytes(G) || cbytes(R<sub>1</sub>) || cbytes(R<sub>2</sub>) || m')) mod n''.
* Let ''s = (k + e⋅a) mod n''.
* Let ''proof = bytes(32, e) || bytes(32, s)''.
* If ''VerifyProof(A, B, C, proof, G, m)'' (see below) returns failure, abort.
@@ -99,14 +99,14 @@ Input:
The algorithm ''VerifyProof(A, B, C, proof, G, m)'' is defined as:
* Fail if any of ''is_infinite(A)'', ''is_infinite(B)'', ''is_infinite(C)'', ''is_infinite(G)''
* Let ''e = int(proof[0:32])''.
* Let ''e = int(proof[0:32])''; fail if ''e &ge; n''.
* Let ''s = int(proof[32:64])''; fail if ''s &ge; n''.
* Let ''R<sub>1</sub> = s⋅G - e⋅A''.
* Fail if ''is_infinite(R<sub>1</sub>)''.
* Let ''R<sub>2</sub> = s⋅B - e⋅C''.
* Fail if ''is_infinite(R<sub>2</sub>)''.
* Let ''m' = m if m is provided, otherwise an empty byte array''.
* Fail if ''e ≠ int(hash<sub>BIP0374/challenge</sub>(cbytes(A) || cbytes(B) || cbytes(C) || cbytes(G) || cbytes(R<sub>1</sub>) || cbytes(R<sub>2</sub>) || m'))''.
* Fail if ''e ≠ int(hash<sub>BIP0374/challenge</sub>(cbytes(A) || cbytes(B) || cbytes(C) || cbytes(G) || cbytes(R<sub>1</sub>) || cbytes(R<sub>2</sub>) || m')) mod n''.
* Return success iff no failure occurred before reaching this point.
==Backwards Compatibility==
@@ -124,6 +124,8 @@ Test vectors can be generated by running <code>./bip-0374/gen_test_vectors.py</c
== Changelog ==
* 0.3.0 (2026-08-19):
** Treat the challenge ''e'' as a scalar (reduced modulo the curve order) and reject proofs with ''e &ge; n''
* 0.2.0 (2025-02-27):
** Add the message to the rand computation
* 0.1.0 (2024-12-26):

View File

@@ -36,7 +36,7 @@ def dleq_challenge(
+ m,
),
"big",
)
) % GE.ORDER
def dleq_generate_proof(
@@ -76,6 +76,8 @@ def dleq_verify_proof(
return False
assert len(proof) == 64
e = int.from_bytes(proof[:32], "big")
if e >= GE.ORDER:
return False
s = int.from_bytes(proof[32:], "big")
if s >= GE.ORDER:
return False