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.""" """Generate the BIP-0374 test vectors."""
import csv import csv
from pathlib import Path from pathlib import Path
import sys
from reference import ( from reference import (
TaggedHash,
dleq_generate_proof, dleq_generate_proof,
dleq_verify_proof, dleq_verify_proof,
) )
from secp256k1lab.secp256k1 import G as GENERATOR, GE from secp256k1lab.secp256k1 import G as GENERATOR, GE
from secp256k1lab.util import tagged_hash
NUM_SUCCESS_TEST_VECTORS = 8 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): 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 return int.from_bytes(rng_out, 'big') % GE.ORDER
def random_bytes(vector_i, purpose): 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 return rng_out

View File

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