1
0
mirror of https://github.com/bitcoin/bips.git synced 2026-02-09 15:23:09 +00:00

BIP-374: use tagged_hash and xor_bytes routines from secp256k1lab

This commit is contained in:
Sebastian Falbesoner 2026-01-15 00:56:13 +01:00
parent 459d977d9b
commit 436a3dd1fa
2 changed files with 7 additions and 20 deletions

View File

@ -2,13 +2,12 @@
"""Generate the BIP-0374 test vectors."""
import csv
from pathlib import Path
import sys
from reference import (
TaggedHash,
dleq_generate_proof,
dleq_verify_proof,
)
from secp256k1lab.secp256k1 import G as GENERATOR, GE
from secp256k1lab.util import tagged_hash
NUM_SUCCESS_TEST_VECTORS = 8
@ -19,12 +18,12 @@ FILENAME_VERIFY_PROOF_TEST = Path(__file__).parent / 'test_vectors_verify_proof.
def random_scalar_int(vector_i, purpose):
rng_out = TaggedHash(DLEQ_TAG_TESTVECTORS_RNG, purpose.encode() + vector_i.to_bytes(4, 'little'))
rng_out = tagged_hash(DLEQ_TAG_TESTVECTORS_RNG, purpose.encode() + vector_i.to_bytes(4, 'little'))
return int.from_bytes(rng_out, 'big') % GE.ORDER
def random_bytes(vector_i, purpose):
rng_out = TaggedHash(DLEQ_TAG_TESTVECTORS_RNG, purpose.encode() + vector_i.to_bytes(4, 'little'))
rng_out = tagged_hash(DLEQ_TAG_TESTVECTORS_RNG, purpose.encode() + vector_i.to_bytes(4, 'little'))
return rng_out

View File

@ -2,7 +2,6 @@
"""Reference implementation of DLEQ BIP for secp256k1 with unit tests."""
from hashlib import sha256
from pathlib import Path
import random
import sys
@ -11,6 +10,7 @@ import unittest
# Prefer the vendored copy of secp256k1lab
sys.path.insert(0, str(Path(__file__).parent / "secp256k1lab/src"))
from secp256k1lab.secp256k1 import G, GE
from secp256k1lab.util import tagged_hash, xor_bytes
DLEQ_TAG_AUX = "BIP0374/aux"
@ -18,18 +18,6 @@ DLEQ_TAG_NONCE = "BIP0374/nonce"
DLEQ_TAG_CHALLENGE = "BIP0374/challenge"
def TaggedHash(tag: str, data: bytes) -> bytes:
ss = sha256(tag.encode()).digest()
ss += ss
ss += data
return sha256(ss).digest()
def xor_bytes(lhs: bytes, rhs: bytes) -> bytes:
assert len(lhs) == len(rhs)
return bytes([lhs[i] ^ rhs[i] for i in range(len(lhs))])
def dleq_challenge(
A: GE, B: GE, C: GE, R1: GE, R2: GE, m: bytes | None, G: GE,
) -> int:
@ -37,7 +25,7 @@ def dleq_challenge(
assert len(m) == 32
m = bytes([]) if m is None else m
return int.from_bytes(
TaggedHash(
tagged_hash(
DLEQ_TAG_CHALLENGE,
A.to_bytes_compressed()
+ B.to_bytes_compressed()
@ -63,9 +51,9 @@ def dleq_generate_proof(
assert len(m) == 32
A = a * G
C = a * B
t = xor_bytes(a.to_bytes(32, "big"), TaggedHash(DLEQ_TAG_AUX, r))
t = xor_bytes(a.to_bytes(32, "big"), tagged_hash(DLEQ_TAG_AUX, r))
m_prime = bytes([]) if m is None else m
rand = TaggedHash(
rand = tagged_hash(
DLEQ_TAG_NONCE, t + A.to_bytes_compressed() + C.to_bytes_compressed() + m_prime
)
k = int.from_bytes(rand, "big") % GE.ORDER