From f7b78df0244f8383ee5a0a1b43399b026d750f4f Mon Sep 17 00:00:00 2001 From: Novo Date: Sun, 25 Oct 2026 18:01:56 +0100 Subject: [PATCH 1/2] BIP352: validate control block size in reference impl --- bip-0352/reference.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/bip-0352/reference.py b/bip-0352/reference.py index c334d328..b38a29e5 100755 --- a/bip-0352/reference.py +++ b/bip-0352/reference.py @@ -32,6 +32,10 @@ from bitcoin_utils import ( K_max = 2323 # per-group recipient limit NUMS_H = 0x50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0 +TAPROOT_CONTROL_BASE_SIZE = 33 +TAPROOT_CONTROL_NODE_SIZE = 32 +TAPROOT_CONTROL_MAX_NODE_COUNT = 128 +TAPROOT_CONTROL_MAX_SIZE = TAPROOT_CONTROL_BASE_SIZE + TAPROOT_CONTROL_NODE_SIZE * TAPROOT_CONTROL_MAX_NODE_COUNT def get_pubkey_from_input(vin: VinInfo) -> GE: @@ -79,6 +83,9 @@ def get_pubkey_from_input(vin: VinInfo) -> GE: # Script-path spend control_block = witnessStack[-1] # control block is <32 byte internal key> and 0 or more <32 byte hash> + assert len(control_block) >= TAPROOT_CONTROL_BASE_SIZE + assert len(control_block) <= TAPROOT_CONTROL_MAX_SIZE + assert (len(control_block) - TAPROOT_CONTROL_BASE_SIZE) % TAPROOT_CONTROL_NODE_SIZE == 0 internal_key = control_block[1:33] if (internal_key == NUMS_H.to_bytes(32, 'big')): # Skip if NUMS_H From bbb2794d9ea616cde9a4ceb0efb6184831b0681f Mon Sep 17 00:00:00 2001 From: Novo Date: Mon, 26 Oct 2026 14:49:58 +0100 Subject: [PATCH 2/2] BIP352: add consensus validity scanning requirements Silent Payments transaction scanning assumes that the transaction is consensus-valid. The test vectors do not include consensus-invalid transactions. --- bip-0352.mediawiki | 1 + 1 file changed, 1 insertion(+) diff --git a/bip-0352.mediawiki b/bip-0352.mediawiki index a369555d..6c2ae67a 100644 --- a/bip-0352.mediawiki +++ b/bip-0352.mediawiki @@ -190,6 +190,7 @@ Future silent payments versions will use the following scheme: For silent payments v0 a transaction MUST be scanned if and only if all of the following are true: +* The transaction is consensus-valid * The transaction contains at least one BIP341 taproot output (note: spent transactions optionally can be skipped by only considering transactions with at least one unspent taproot output) * The transaction has at least one input from the ''[[#inputs-for-shared-secret-derivation|Inputs For Shared Secret Derivation]]'' list * The transaction does not spend an output with SegWit version > 1'''Why skip transactions that spend SegWit version > 1?''' Skipping transactions that spend unknown output scripts allows us to have a clean upgrade path for silent payments by avoiding the need to scan the same transaction multiple times with different rule sets. If a new SegWit version is added in the future and silent payments v1 is released with support, we would want to avoid having to first scan the transaction with the silent payment v0 rules and then again with the silent payment v1 rules. Note: this restriction only applies to the inputs of a transaction.