Quantum-Ineffective Bitcoin: A Script-Level, Hash-Anchored Defence Against Hypothetical Quantum Key Recovery
Rendering Shor-enabled theft economically futile through value fragmentation and mandatory hash preimages in standard Bitcoin Script
Keywords: Bitcoin, digital cash, micropayments, quantum attacker, Shor, Grover, ECDSA, SHA-256, preimage security, Script, OP_SHA256, OP_HASH256, OP_CHECKSIG, UTXO fragmentation, economic model
Thesis statement: Even if a fault-tolerant quantum computer could recover ECDSA private keys once a public key is exposed, Bitcoin remains secure as a digital cash system by (i) fragmenting value across many low-value UTXOs and (ii) requiring, in Script, that spends reveal committed hash preimages in addition to a signature. Signatures are quantum-fragile; modern hashes are not—quantum algorithms offer at most a square-root speed-up for preimage search—so per-UTXO hash secrets plus strict value caps force negative expected value for attackers and render key-recovery theft ineffective.
Section 1 — Scope and terminology
Scope. The objective is to design and analyse a spend script that remains effective against a hypothetical quantum adversary by eliminating any advantage gained from key recovery. The script binds each spend to secrets proven by hash preimages and, where useful, arithmetic relations so that recovering a private key alone is insufficient to satisfy the lock. All baseline Script opcodes are admissible; every hash opcode is viable and may be combined freely. Arithmetic, including multiplication via OP_MUL, is available to compose numeric predicates that must also hold at spend time. The focus is a script-level defence that stands on hash hardness and explicit conditions enforced on the stack, not on any post-2010 mechanisms or indirections.
Terminology. A UTXO is a discrete coin identified by its originating transaction hash and output index; it is encumbered by a locking program called the scriptPubKey. A spending input provides an unlocking program called the scriptSig. The unlocking program executes first, leaving data on the stack; the locking program then executes and consumes that data. Evaluation succeeds only if all VERIFY checks pass and the final stack value is true. A commitment is the pair (H, s) where H = Hash(s) under a named hash function; spending requires revealing the committed preimage s. A preimage is any s such that Hash(s) = H. A second preimage is any s ≠ s₀ such that Hash(s) = Hash(s₀) for a fixed s₀. A collision is a pair a ≠ b with Hash(a) = Hash(b). The hash opcodes available are OP_RIPEMD160, OP_SHA1, OP_SHA256, OP_HASH160, and OP_HASH256, with the conventional definitions HASH160(x) = RIPEMD-160(SHA-256(x)) and HASH256(x) = SHA-256(SHA-256(x)). Signature verification uses ECDSA over secp256k1 via OP_CHECKSIG; signatures authenticate intent but do not, by themselves, satisfy the additional hash or arithmetic predicates. Stack manipulation and arithmetic opcodes are used as needed, including OP_DUP, OP_SWAP, OP_EQUAL, OP_EQUALVERIFY, OP_VERIFY, OP_ADD, OP_SUB, and OP_MUL for composing checks that the spender must meet in the same unlocking sequence.
Threat model. The adversary possesses a fault-tolerant quantum device capable of deriving an ECDSA private key from a known public key after some non-zero latency and cost (Shor-level capability). The adversary can observe broadcasts, copy any values revealed by the spender (including public keys and preimages), and attempt a same-height conflicting spend. The adversary has no super-polynomial advantage against the hash functions enforced by the script; for preimage and second-preimage problems on an n-bit hash, known quantum speed-ups are at most quadratic, leaving effective work on the order of 2^(n/2) oracle evaluations. Under this model, signatures alone are fragile once a public key is exposed; scripts that demand specific hash preimages and optional arithmetic invariants ensure that key recovery is insufficient to pass the lock.
Section 2 — What quantum breaks and what it does not
Shor versus signatures
Shor’s algorithm gives a polynomial-time method for the discrete logarithm on elliptic curves. With ECDSA, once a public key is visible, a quantum adversary can, in principle, derive the corresponding private key after a non-zero cost and latency. This capability targets signature algebra specifically; it does not generalise to one-way hash functions.
Grover versus hashes
For an n-bit hash, the strongest known generic quantum speed-up for preimage and second-preimage search is quadratic: classical ≈ 2^n trials becomes ≈ 2^(n/2) oracle queries with Grover-type amplitude amplification. There is no known quantum algorithm that does substantially better for generic preimage problems on well-designed hashes. For SHA-256, a preimage requires about 2^128 quantum queries, which is beyond practicality once error-correction overheads and circuit depth are included. Double hashing (HASH256) preserves this preimage hardness and removes length-extension artefacts.
Collisions are a different game
Collision search asks for a ≠ b with Hash(a) = Hash(b). Quantum algorithms can reduce the classical birthday scale ≈ 2^(n/2) to roughly 2^(n/3). Our construction does not ask for “any” colliding pair; it requires a specific preimage s of a fixed commitment H. Collision shortcuts therefore do not open a path to spend.
Multi-target effects do not rescue the attacker
Against T independent hash commitments of equal strength, amplitude amplification yields at most a square-root batching effect: expected work per successful preimage remains ≈ 2^(n/2)/√T. At n = 256, even extremely large T leaves the total cost far outside usefulness.
Opcode set: all hash opcodes remain viable
OP_RIPEMD160, OP_SHA1, OP_SHA256, OP_HASH160, and OP_HASH256 remain suitable for Script predicates. For address/key binding, HASH160 is fine. For spend-authorising secrets, commit with SHA-256 or HASH256 to keep an effective quantum preimage margin near 2^128. Arithmetic (including OP_MUL) and stack operators can be combined with these hash checks to enforce additional invariants without weakening the hash predicate.
Practical consequence for script design
Signatures alone are fragile once a public key is exposed (Shor). Hash-anchored conditions are not: a spend that demands “reveal s such that SHA-256(s) = H” (or HASH256) forces the attacker into a preimage problem with ≈ 2^128 quantum cost per output. Hence, signatures authenticate intent, but the hash preimage is what removes the quantum advantage from theft.
Section 3 — Economic model: why “lots of small keys” neutralises theft
Define the attacker’s per-key recovery cost as C_shor (all-in: hardware amortisation, error-correction overhead, energy, labour, time value). Define a hard per-output cap V_max set by wallet policy, and let V_i ≤ V_max be the value of a specific target output. Ignoring everything else, the attacker’s per-target profit is π_i = V_i − C_shor. If V_max < C_shor then π_i < 0 for every target; scaling the number of targets or running attacks in parallel multiplies losses linearly and never flips the sign.
Include the reality of a mempool race. Let q be the probability the attacker’s conflicting spend confirms first (0 < q < 1). Let F_att be the transaction fee the attacker must pay for a competitive confirmation. If the attack fails (probability 1 − q), the attacker usually loses F_att as sunk cost. The per-target expected profit becomes
E[π] = q·(V_i − F_att) − C_shor − (1 − q)·F_att = q·V_i − C_shor − F_att.
Break-even requires q·V_i = C_shor + F_att, i.e.
V_i ≥ V* where V* = (C_shor + F_att) / q.
A defender guarantees negative expected value by enforcing V_max < V*.
This inequality is robust to throughput and batching. Attacking N independent outputs yields E[Π_N] = N·E[π]. If E[π] < 0, then E[Π_N] < 0 for all N; parallelism merely accelerates the burn rate. There is no portfolio effect that rescues a negative per-trial drift because each output is locked by an independent key.
Illustrative numbers in prose make the point concrete. If C_shor = 12 and the wallet caps outputs at V_max = 5, then even with q = 1 and F_att = 0 the attacker burns 7 per attempt; any realistic q < 1 only worsens it. If outputs are 50 and C_shor = 80, each cracked output loses 30 before fees or race failure. If C_shor dropped to 1, setting V_max in the cents range drives E[π] strongly negative: with q = 0.7 and F_att = 0.01, the threshold is V* ≈ (1 + 0.01)/0.7 ≈ 1.44; capping outputs at 0.02 makes every trial a ≈ 1.42 loss in expectation. In all cases, aggregating meaningful value demands thousands to millions of independent key recoveries; the attacker’s total expected loss scales linearly with the number of cracks attempted.
The best possible attacker response—cherry-picking larger outputs—fails when the wallet never creates them. The defence therefore reduces to a simple policy knob: maintain V_max well below the moving break-even V* = (C_shor + F_att)/q. As long as V_max tracks beneath that threshold, “lots of small keys” makes key-recovery theft a strictly negative-EV strategy, regardless of the attacker’s speed or scale.
Section 4 — Timing surface: exposure, races, and practical latency
Public key exposure defines the only realistic window. When value is locked to a public-key hash, the public key is not visible until the spend is broadcast. Before that moment a quantum adversary has nothing to feed into a key-recovery routine. The window opens at broadcast, when the unlocking data reveals the public key (and any hash preimages the script requires), and it closes at confirmation when a miner includes the honest spend in a block. The attacker’s path therefore begins no earlier than first observation of the broadcast, never at output creation.
The attacker’s sequence has three latency gates. First, observation and extraction of the revealed data occur at network propagation speed; this is effectively seconds to reach most well-connected nodes. Second, the adversary must complete key recovery with a Shor-style routine; denote its all-in runtime per key as τ_shor, which includes error-correction overheads and device scheduling. Third, the adversary must assemble and propagate a conflicting transaction that spends the same input with a valid signature and the same required preimage(s), and must have that conflicting transaction win miner selection before the honest one confirms; denote this end-to-end craft-and-propagate time as τ_craft+prop. The honest transaction confirms after a stochastic delay whose realised value we call Δ_confirm from first broadcast to inclusion in a block. A necessary condition for successful theft is τ_shor + τ_craft+prop < Δ_confirm, together with miners actually choosing the conflicting spend over the honest spend they already saw.
Hash-anchored conditions choke the race at the start line. The script demands, in addition to a valid signature, a specific preimage s for a published commitment H (for example, SHA-256(s) = H or HASH256(s) = H). Before the honest broadcast, s is unknown on the network; the attacker cannot pre-spend by preparing a transaction that satisfies the hash predicate. After the honest broadcast, s becomes observable, but the attacker still lacks the private key until Shor completes. Copying s is trivial, but useless without a signature produced by the recovered key. The race therefore reduces to a pure latency contest between τ_shor + τ_craft+prop and Δ_confirm, with no way to start earlier, because neither the public key nor the preimage is available beforehand.
Miner selection dynamics further compress the feasible window. Nodes usually relay and miners typically favour the first fully valid spend they receive for a given input; a later conflicting spend must either reach miners that never saw the original or must do so under conditions where those miners choose it instead. That requires extra fee, privileged connectivity, or both, which increases the attacker’s cost and does not relax the inequality τ_shor + τ_craft+prop < Δ_confirm. In practical networks the propagation of the honest spend reaches the majority of hash-power rapidly, so the attacker’s conflicting transaction must reach enough miners fast enough after τ_shor elapses to overturn the honest lead; this is a second, independent latency hurdle on top of quantum runtime.
Key-reuse collapses the defender’s timing advantage and must be eliminated. If the same public key appears earlier on chain, the attacker can begin key recovery long before the wallet spends the target output, making τ_shor effectively front-loaded. The remedy is simple and absolute: one key per output and never reuse. With key reuse banned, the attacker can never begin τ_shor before the honest broadcast reveals the public key.
Value fragmentation narrows the attacker’s viable Δ_confirm budget in aggregate. Each additional input guarded by an independent key forces another quantum recovery. If a payment aggregates k inputs, the attacker’s total quantum runtime becomes roughly k·τ_shor before they can sign a conflicting spend that covers them all. Unless Δ_confirm is implausibly long, k·τ_shor + τ_craft+prop exceeds the available window. Fragmentation therefore not only makes theft economically pointless in expectation; it also makes the timing geometry hostile to any real-time attack.
Operational practice tightens Δ_confirm while leaving script semantics unchanged. Fast relay to well-connected miners, adequate fees, and immediate broadcast shorten the honest Δ_confirm path and widen the margin by which τ_shor + τ_craft+prop must fail. None of this relies on non-standard mechanics; it simply reduces dwell time in the network, squeezing the attacker’s only window.
The structural conclusion is that a hash-anchored, key-once spend reveals everything the attacker needs only at broadcast, and then forces them to finish quantum key recovery, craft a conflict, and outrun network propagation before confirmation. With realistic quantum latencies and ordinary propagation, that compound requirement is not met. The race is therefore lost in design, not merely in parameter tuning.
Section 5 — Core defence: enforce committed hash preimages in Script (hardened)
The lock must make key recovery alone useless. The spender must reveal one or more committed preimages and only then pass a signature check. The following Forth-style scripts strengthen the basic idea in three ways: (1) keep the public key hidden until spend, (2) require the same secret to satisfy multiple independent hash predicates, and (3) optionally demand a second secret plus a simple arithmetic latch using OP_MUL. All opcodes are standard; no post-2010 mechanisms are invoked.
A. Multi-hash, key-once lock (P2PKH + triple hash on one secret)
scriptPubKey
OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY # verify pubkey
OP_TOALTSTACK # save <PubKey> off the main stack
OP_DUP OP_SIZE 32 OP_EQUALVERIFY # require s to be exactly 32 bytes
OP_DUP OP_SHA256 <H_sha256> OP_EQUALVERIFY # SHA-256(s) == H_sha256
OP_DUP OP_HASH160 <H_hash160> OP_EQUALVERIFY # HASH160(s) == H_hash160
OP_RIPEMD160 <H_ripemd160> OP_EQUALVERIFY # RIPEMD160(s) == H_ripemd160
OP_DROP # drop the original s
OP_FROMALTSTACK OP_CHECKSIG # verify signature with saved pubkey
scriptSig
<Sig> <s> <PubKey>
Semantics. The public key is proven first, then parked off-stack. The same 32-byte secret s must simultaneously satisfy SHA-256, HASH160, and RIPEMD-160 commitments. Only after all three pass is the signature checked. Copying the signature is impossible without the private key; copying s is useless without also producing a valid signature. Requiring three independent hashes eliminates reliance on a single primitive and blocks “second preimage” games across hash domains.
B. Bare single-key form (compact, no pubkey hash)
scriptPubKey
OP_DUP OP_SIZE 32 OP_EQUALVERIFY
OP_DUP OP_SHA256 <H_sha256> OP_EQUALVERIFY
OP_DUP OP_HASH160 <H_hash160> OP_EQUALVERIFY
OP_RIPEMD160 <H_ripemd160> OP_EQUALVERIFY
OP_DROP
<PubKey> OP_CHECKSIG
scriptSig
<Sig> <s>
Semantics. This is the most compact hardened lock when address-style key hiding is not required. It retains the triple-hash commitment to one 32-byte secret.
C. Dual-secret with arithmetic latch (adds OP_MUL check)
This variant demands two independent secrets with distinct commitments and a small numeric latch that must also be satisfied. The latch is not a cryptographic primitive; it is an inexpensive invariant that catches script mangling and forces the attacker to supply exactly the wallet’s chosen numbers as well.
scriptPubKey
OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY # prove pubkey, then stash it
OP_TOALTSTACK
# Stack (after saving pubkey): [ <Sig> <t> <s> ]
OP_SWAP # reorder to [ <Sig> <s> <t> ]
# Secret s checks
OP_DUP OP_SIZE 32 OP_EQUALVERIFY
OP_SHA256 <H_s_sha256> OP_EQUALVERIFY
# Bring t on top and check its commitments
OP_SWAP
OP_DUP OP_SIZE 24 OP_GREATERTHANOREQUALVERIFY # t must be at least 24 bytes (tunable)
OP_SHA1 <H_t_sha1> OP_EQUALVERIFY
# Arithmetic latch: require n1 * n2 == Prod
# (n1 and n2 are pushed in the unlocking script as minimally-encoded integers)
<nProd>
OP_TOALTSTACK # save Prod
OP_SWAP # [ <Sig> <n2> <n1> ] will be provided by scriptSig; swap to get n1,n2 order right
OP_MUL # compute n1 * n2
OP_FROMALTSTACK OP_EQUALVERIFY
# Finish with signature
OP_FROMALTSTACK OP_CHECKSIG # restore pubkey and verify signature
scriptSig
<Sig> <n2> <n1> <t> <s> <PubKey>
Semantics. The spender reveals two secrets: s committed via SHA-256 and t committed via SHA-1 (hash choices are deliberate to diversify). Length checks reject malformed encodings before hashing. The latch enforces that two small integers n1 and n2 multiply to a pre-committed product <nProd>. Because n1 and n2 are part of the satisfaction, any replay must reproduce them exactly as minimally encoded integers; accidental or malicious rewrites fail cleanly. The cryptographic hardness still rests on the preimages; the latch is an additional, low-cost invariant that uses OP_MUL as requested.
D. Why these are materially more robust
The public key is hidden until spend, minimising the time during which a key-recovery device can even begin. A single revealed secret must satisfy multiple independent hash predicates, so any weakness or structural quirk in one hash does not admit a path to spend. Optional dual-secret mode forces an attacker to know two unrelated preimages; learning only one (for example, from an earlier spend of a different output) does not help. The arithmetic latch, while not a cryptographic barrier, is a deterministic check that resists sloppy or adversarial stack manipulation and proves the unlocking data matches the wallet’s exact choices. All checks are enforced before signature verification finishes, so failure aborts immediately. The result is a spend condition where recovering a private key confers no advantage without also producing the committed preimage(s) and passing the extra invariant, which a quantum device does not accelerate.
Section 6 — Optional second secret: tunable margin (enhanced, with advanced opcodes)
Variant A — Dual-secret with triple commitment and concatenation check (uses OP_CAT)
scriptPubKey
# Expect stack from scriptSig: [ <Sig> <t> <s> <PubKey> ]
OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY # prove pubkey
OP_TOALTSTACK # stash pubkey
# s: exact length + SHA-256 commit
OP_DUP OP_SIZE 32 OP_EQUALVERIFY
OP_DUP OP_SHA256 <H1_sha256> OP_EQUALVERIFY
# bring t to top, check SHA-256 commit (t length is policy-tunable)
OP_SWAP
OP_DUP OP_SIZE 24 OP_GREATERTHANOREQUALVERIFY # example floor; adjust as desired
OP_DUP OP_SHA256 <H2_sha256> OP_EQUALVERIFY
# joint binding: check SHA-256(s || t)
OP_2DUP OP_CAT OP_SHA256 <H12_cat_sha256> OP_EQUALVERIFY
# clean and verify signature
OP_DROP OP_DROP
OP_FROMALTSTACK OP_CHECKSIG
scriptSig
<Sig> <t> <s> <PubKey>
Notes. One revealed secret is not enough; both must satisfy their own SHA-256 commitments and the concatenation commitment. Any attempt to substitute (s', t') that collide in one domain fails the other domains.
Variant B — Dual-secret with position constraint (uses OP_SUBSTR)
Purpose: enforce that s appears inside t at a fixed offset k, binding structure as well as value.
scriptPubKey
# Expect: [ <Sig> <t> <s> <PubKey> ]
OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY
OP_TOALTSTACK
# Commit to s and t individually
OP_DUP OP_SHA256 <H1_sha256> OP_EQUALVERIFY # s
OP_SWAP
OP_DUP OP_SHA256 <H2_sha256> OP_EQUALVERIFY # t
# Verify that t[k : k+|s|] == s
# Stack now: [ <Sig> <s> <t> ]
OP_2DUP # [ <Sig> <s> <t> <s> <t> ]
OP_SWAP # [ <Sig> <s> <t> <t> <s> ]
<k> # push offset k
OP_SIZE # compute |s|
OP_SUBSTR # take t[k : k+|s|]
OP_EQUALVERIFY # substring equals s
# Finish
OP_DROP OP_DROP
OP_FROMALTSTACK OP_CHECKSIG
scriptSig
<Sig> <t> <s> <PubKey>
Notes. The substring constraint prevents splicing arbitrary (s, t) that match only by hash; the structure of t is fixed by k and |s|.
Variant C — Dual-secret plus arithmetic latch (uses OP_MUL)
Purpose: add an inexpensive numeric invariant that must match a pre-committed product P = n1 · n2.
scriptPubKey
# Expect: [ <Sig> <n2> <n1> <t> <s> <PubKey> ]
OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY
OP_TOALTSTACK
# s
OP_DUP OP_SHA256 <H1_sha256> OP_EQUALVERIFY
# swap to t
OP_SWAP OP_SWAP
OP_DUP OP_SHA256 <H2_sha256> OP_EQUALVERIFY
# arithmetic latch: n1 * n2 == P
# bring n1,n2 to top in correct order
OP_ROT OP_ROT # [ <Sig> <n2> <n1> ... ] -> move n1,n2 up
OP_SWAP # [ <Sig> <n1> <n2> ... ]
OP_MUL # compute n1*n2
<P_prod> OP_NUMEQUALVERIFY
# clean and finish
OP_DROP OP_DROP # drop t, s (kept untouched)
OP_FROMALTSTACK OP_CHECKSIG
scriptSig
<Sig> <n2> <n1> <t> <s> <PubKey>
Notes. The latch is not a cryptographic barrier; it forces exact, minimally-encoded integers chosen by the wallet, tightening satisfaction to a unique witness.
Variant D — Dual-secret with mixed-hash diversity and length discipline
Goal: diversify primitives and enforce strict encodings before hashes are evaluated.
scriptPubKey
# Expect: [ <Sig> <t> <s> <PubKey> ]
OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY
OP_TOALTSTACK
# s: exact size + dual commitments
OP_DUP OP_SIZE 32 OP_EQUALVERIFY
OP_DUP OP_SHA256 <H1_sha256> OP_EQUALVERIFY
OP_DUP OP_HASH160 <H1_hash160> OP_EQUALVERIFY
# t: minimum size + dual commitments
OP_SWAP
OP_DUP OP_SIZE 40 OP_GREATERTHANOREQUALVERIFY
OP_DUP OP_RIPEMD160 <H2_rmd160> OP_EQUALVERIFY
OP_DUP OP_SHA1 <H2_sha1> OP_EQUALVERIFY
# optional cross-commit: HASH160(s || t)
OP_2DUP OP_CAT OP_HASH160 <Hst_hash160> OP_EQUALVERIFY
# finish
OP_DROP OP_DROP
OP_FROMALTSTACK OP_CHECKSIG
scriptSig
<Sig> <t> <s> <PubKey>
Notes. Multiple, independent hash families (SHA-2, RIPEMD-160, SHA-1) must all agree; any isolated weakness in one domain does not grant a spend.
Variant E — Three-way binding: per-secret commits, concatenation, and interleave (uses OP_CAT)
Purpose: require s‖t, t‖s, and an interleaving to all match pre-committed digests.
scriptPubKey
# Expect: [ <Sig> <t> <s> <PubKey> ]
OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY
OP_TOALTSTACK
# individual commits
OP_DUP OP_SHA256 <H1_sha256> OP_EQUALVERIFY
OP_SWAP
OP_DUP OP_SHA256 <H2_sha256> OP_EQUALVERIFY
# s||t
OP_2DUP OP_CAT OP_SHA256 <Hst_sha256> OP_EQUALVERIFY
# t||s
OP_SWAP OP_2DUP OP_CAT OP_SHA256 <Hts_sha256> OP_EQUALVERIFY
OP_DROP OP_DROP
# interleave: build i = s[0] || t[0] || s[1] || t[1] || ...
# (performed in scriptSig to avoid loops; we verify only)
<i_commit_sha256> OP_SWAP OP_EQUALVERIFY # scriptSig pushes pre-built interleave 'i' before <t>
OP_FROMALTSTACK OP_CHECKSIG
scriptSig
<Sig> <i> <t> <s> <PubKey>
Notes. The interleave value i is constructed off-chain and committed on-chain. Verification is a simple equality, keeping the lock loop-free while binding a more complex relation between s and t.
Selection guidance
Use Variant A as the baseline: compact, strong, and fast;
OP_CATbinds joint structure.Add Variant C when a numeric latch (using
OP_MUL) is desirable to make the witness uniquely shaped.Prefer Variant D when primitive diversity is a priority.
Use Variant B to freeze
s’s position insidetviaOP_SUBSTR.Combine patterns when needed: e.g., A + C to require
s,t,s‖t, and the product latch.
Section 7 — Wallet-side algorithm: enforcing economic fragmentation and per-UTXO secrets
Policy goal. Make key-recovery useless and unprofitable by ensuring every spend must supply exact preimages bound to that specific coin, while keeping each coin’s value below a strict ceiling so no single target is worth the attacker’s effort. Large payments are executed as a series of small transactions (“send many”), never by merging coins first.
7.1 Receive pipeline (fan-out and encumbrance)
Per-output ceiling. Fix a hard ceiling
V_max(in satoshis). Any single output created by the wallet must satisfyvalue < V_max.Fan-out. On receipt of amount
A, decompose intok = ⌈A / V_max⌉outputs: push as many full-V_maxoutputs as needed; the final output equals the exact remainder (which is still< V_max).Fresh materials per output. For each output
u:
Derive a new keypair.
Draw a fresh secret
s_u(32 bytes). Optionally draw a second secrett_u(policy: ≥ 24 bytes).Compute commitments required by the selected lock (examples from §5–6):
H1_u = SHA-256(s_u);H2_u = SHA-256(t_u); optional cross-commitments such asH_st_u = SHA-256(s_u || t_u); optional mixed-family digests (e.g.,HASH160(s_u),RIPEMD160(s_u)).If using an arithmetic latch, choose small integers
n1_u,n2_uand recordP_u = n1_u * n2_u(checked withOP_MUL).Build the locking program for this output (choose one hardened template from §5–6; default is key-hidden, multi-hash on
s_u; dual-secret for elevated assurance).
Metadata (encrypted at rest). For each output store: derivation path, public key, script-template ID, all on-chain digests, any latch constants (
P_u), and a unique nonceu_nonce. Secrets are either stored encrypted or deterministically derived as:
s_u = HMAC-SHA-256(K_master, "s" || u_nonce)
t_u = HMAC-SHA-256(K_master, "t" || u_nonce) # when used
Cleartext secrets exist only in RAM during script construction and signing and are then zeroised.
7.2 Spend pipeline (send-many; no consolidation)
Partition a large payment into multiple transactions. Choose per-transaction limits:
I_max: maximum inputs per transaction.O_max: maximum new outputs per transaction (recipient + change), with each new output< V_max.
Split the payment into a sequence so every transaction respects both limits. There is no preliminary merge; fragmentation is preserved.
Input selection (per transaction). Choose the smallest-cardinality set of inputs that covers the transaction’s slice plus fee, subject to
count ≤ I_maxand each input’s value< V_max. When several choices tie, prefer diverse ages and denominations to reduce pattern leakage. Inputs whose use would force a later merge are avoided; if more value is needed, open another transaction in the sequence.Unlocking data assembly (per input). For the chosen template:
Push required preimages (e.g.,
s_u, andt_uif present).Push any structured bytes the lock binds (e.g., concatenations for
OP_CATvariants, interleave strings when used).Push arithmetic-latch integers (
n1_u,n2_u) as minimally encoded Script integers if the lock checksOP_MUL.Push the public key if the lock proves a public-key hash.
Produce the signature last, after every pushed byte is final, so the signed serialization matches what will be broadcast.
Preflight verification (wallet-side). Before signing:
Re-hash
s_u(andt_u) and recompute all cross-digests; compare to the output’s recorded digests.Recompute
n1_u * n2_uand compare toP_uif an arithmetic latch is present.Verify all integers are minimally encoded.
Refuse to proceed if any check fails; discard that input’s secrets and select a replacement coin with fresh secrets.
Broadcast (per transaction). Transmit immediately with a fee rate that targets rapid inclusion. Relay through well-connected peers and direct miner channels when available. Repeat for each transaction in the sequence. Public keys first appear only in the unlocking program; the lock demands exact preimages as well as a signature, so key recovery alone does not enable a conflicting spend.
Change policy. Any change created by a transaction is immediately split into outputs strictly
< V_max, each with fresh keypair, fresh secrets, fresh digests, and a hardened lock. No key, no secret, and no digest is ever reused. No later merge is performed; future payments simply open additional small transactions.Failure handling. If a transaction is rejected or withdrawn:
Mark every secret placed into its unlocking data as permanently retired.
Zeroise RAM copies.
Rebuild with different inputs and new secrets.
Do not “resubmit” with the same secrets.
Audit and restore. At intervals:
Re-derive deterministic secrets from
K_masterandu_nonce; confirm hashing them reproduces stored digests for every unspent coin.On mismatch, lock spending until corrected.
Restore reconstructs key hierarchy and, if deterministic mode is enabled, re-derives
s_u/t_ufor every coin and checks them against the on-chain digests before enabling spends.
7.3 Worked example A — Receive fan-out (integers; no remainders)
Parameters: V_max = 2,000,000 sat. Incoming amount A = 13,745,000 sat.
Decomposition:
Emit 6 outputs of
2,000,000 sat(total12,000,000 sat).Final output is
1,745,000 sat(still< V_max).
For each of the 7 outputs {u0 … u6}:
Generate keypair_uN
s_uN = HMAC-SHA-256(K_master, "s" || u_nonce_N)
H1_uN = SHA-256(s_uN)
# Optionally:
t_uN = HMAC-SHA-256(K_master, "t" || u_nonce_N)
H2_uN = SHA-256(t_uN)
H_st_uN = SHA-256(s_uN || t_uN)
# Optional arithmetic latch:
Choose n1_uN, n2_uN; P_uN = n1_uN * n2_uN
Construct scriptPubKey_uN using the chosen hardened template
Persist encrypted metadata: {path, pubkey, template_ID, H1/H2/H_st, P, u_nonce_N}
Every output now requires its own preimages (and possibly latch integers) plus a valid signature to spend; no single output is worth a key-recovery attempt.
7.4 Worked example B — Large payment via send-many
Parameters: V_max = 2,000,000 sat, I_max = 8, O_max = 6. Payment target: A_pay = 25,000,000 sat to one recipient (who will accept multiple outputs).
Plan: open four transactions.
Tx1: inputs ≤ 8 coins whose sum covers
6,250,000 sat + fee. Recipient outputs:2,000,000 + 2,000,000 + 2,000,000 + 250,000(all< V_max). Change: split< V_maxwith fresh secrets.Tx2: same plan for the next
6,250,000 sat.Tx3: same plan for the next
6,250,000 sat.Tx4: final
6,250,000 satwith outputs2,000,000 + 2,000,000 + 2,000,000 + 250,000.
For each input of each transaction, the unlocking data is assembled according to its lock. Example (key-hidden triple-hash-on-s from §5):
scriptSig: <Sig> <s_u> <PubKey_u>
Stack flow (per input):
Prove
HASH160(PubKey_u)equals the locked value.Park
PubKey_u.Check
OP_SIZE(s_u) == 32.Check
SHA-256(s_u) == H_sha256_u.Check
HASH160(s_u) == H_hash160_u.Check
RIPEMD160(s_u) == H_ripemd160_u.Verify signature with the parked
PubKey_u.
If the output was created with the dual-secret + concatenation lock (§6 Variant A), the unlocking data is:
scriptSig: <Sig> <t_u> <s_u> <PubKey_u>
and the lock additionally checks SHA-256(s_u || t_u) == H_st_u. If an arithmetic latch was included, the unlocking data includes <n2_u> <n1_u> (in the order the lock expects), and the lock enforces OP_MUL equals the precommitted product.
Each transaction is broadcast immediately on construction. The recipient will end up with multiple outputs, each < V_max, all independently protected. At no time is value merged into a larger coin.
7.5 Why this removes the attacker’s advantage
Preimages first. The lock demands exact preimages (and optional structured/arithmetical conditions) before it accepts the signature. Recovering a key does not satisfy the lock.
Key exposure window is short. Public keys appear only in the unlocking program, at broadcast. There is no pre-broadcast target.
Fragmentation multiplies cost and time. A conflicting spend of a transaction with
minputs requiresmkey recoveries and the correct preimages (which are not accelerated by a quantum device). Splitting a large payment into multiple transactions repeats that burden independently per transaction.No consolidation. The wallet never creates large, attractive targets. Every coin remains below
V_max, so any per-key attack is negative expected value (§3).
7.6 Parameters and defaults
V_max: set strictly below the moving break-even(C_shor + F_att) / q.I_max,O_max: bound per-transaction size to keep race windows short and uniform.Secret lengths:
|s| = 32bytes;|t| ≥ 24bytes when used; enforced byOP_SIZEchecks in the lock.Default lock: key-hidden, multi-hash on
s(triple-hash).Elevated lock (optional): dual-secret with
SHA-256(s),SHA-256(t), andSHA-256(s || t); addOP_MULlatch when a uniquely shaped stack is desired.Deterministic derivation:
HMAC-SHA-256withK_masterandu_noncefor exact restore; secrets never reused.
Under this algorithm, coins are always small, always independently bound to secrets the attacker cannot compute, and payments are carried by many small transactions instead of merges. Key recovery alone never suffices to spend.
Section 7b — HMAC-anchored hash chain (10,000+-step epochs) for one-time tokens
This construction derives a public, auditable chain of one-time secrets from a single master key and binds each spend to exactly one unused element of that chain. A new chain is rotated in after every 10,000+ uses. The guarantees are: a spender can reveal the next token and satisfy the Script; an observer can verify that each revealed token links to the published epoch anchor and ultimately to the master commitment; no outsider can compute unrevealed tokens; and any reuse is detectable and fails by policy.
Master. Choose a 32-byte master key K. Fix HMAC-SHA-256 as the PRF: HMAC(k, m). Publish a master commitment M = SHA-256(HMAC(K, "master")). M never changes and is the root of audit.
Epoch derivation and 10,000-step chain. Number epochs e = 0, 1, 2, …. For epoch e, derive a seed S_e = HMAC(K, "epoch" || e). Form a reverse hash chain of length L = 10,000 by first computing a private tail value y_{e,L} = HMAC(K, "tail" || S_e) and then, for i = L−1 … 0, computing y_{e,i} = SHA-256(y_{e,i+1}). Publish the epoch anchor A_e = y_{e,0} and the linkage commitment C_e = SHA-256(S_e). Anyone later given S_e can recompute the entire chain and confirm A_e. The wallet reveals tokens in order y_{e,1}, y_{e,2}, …, y_{e,L}; each token hashes forward to the public anchor: SHA-256^i(y_{e,i}) = A_e. After i = L is consumed, increment e and repeat.
On-chain binding per UTXO. Each output that consumes a token commits to that token and binds it to its epoch and index. The Script does not loop; the membership check against A_e is audited off-chain. On-chain, the lock verifies that the exact (e, i, y_{e,i}) triple intended for this coin is presented and that the signature matches the key.
Forth script: epoch-bound, index-bound token (P2PKH style; binds (e, i, y))
scriptPubKey
OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY # prove pubkey; keep it hidden until spend
OP_TOALTSTACK
# Expect stack from scriptSig: [ <Sig> <i> <e> <y> ]
# 1) Structural checks (sizes are policy-tunable)
OP_DUP OP_SIZE 32 OP_EQUALVERIFY # y must be 32 bytes
# 2) Bind (e || i || y) to a commitment D_{e,i}
# D_{e,i} = SHA-256( e_bytes || i_bytes || y )
# e_bytes and i_bytes are minimally-encoded integers pushed by the spender
OP_ROT OP_ROT # stack: [ <Sig> <y> <i> <e> ]
OP_SWAP OP_CAT # build: (e || i)
OP_SWAP OP_CAT # build: (e || i || y)
OP_SHA256 <D_ei> OP_EQUALVERIFY # D_ei is precommitted in the output
# 3) Optional cross-bind: SHA-256(y) equals the per-UTXO simple commitment H_i
OP_DUP OP_SHA256 <H_i> OP_EQUALVERIFY # H_i = SHA-256(y_{e,i})
# 4) Finish with signature
OP_DROP # drop y
OP_FROMALTSTACK OP_CHECKSIG
scriptSig
<Sig> <i> <e> <y> <PubKey>
Semantics. The wallet precomputes (e, i, y) and installs <D_ei> = SHA-256(e || i || y) and <H_i> = SHA-256(y) in the output. To spend, the wallet reveals the next unused token y = y_{e,i}, along with e and i. The Script checks the binding to (e, i) and also the simple SHA-256(y) commitment. The signature is then verified against the hidden public key. Because each (e, i) is unique and monotone within an epoch, reuse of a token is detectable: a second spend with the same (e, i, y) cannot occur because the first spend’s UTXO has been consumed, and a contradictory (e, i, y') fails both commitments.
Audit path to the master. Anyone holding (M, A_e, C_e) and later S_e can verify SHA-256(S_e) = C_e and recompute y_{e,0} … y_{e,L} to confirm y_{e,0} = A_e. Every revealed (e, i, y) seen on-chain is checked by hashing y forward i steps to recover A_e; mismatches indicate tampering. The chain is rotated after exactly 10,000 spends by incrementing e and publishing the new A_{e+1} and C_{e+1}; the master M remains constant.
Wallet lifecycle. At output creation time, the wallet advances a per-epoch counter i and selects y = y_{e,i}. It writes <H_i> and <D_ei> into the locking script, stores (e, i) in the metadata, and marks i as reserved. At spend time, it pushes <i> <e> <y> in the unlocking program. After confirmation it records i as consumed. When i = L is consumed, it increments e, derives S_{e+1} from the master key with HMAC, publishes A_{e+1} and C_{e+1}, and resets i to 0.
Stronger binding with concatenation to the public anchor (uses OP_CAT). Some deployments prefer to bind the token directly to the public epoch anchor without loops by committing E_e = SHA-256(A_e || e) and checking that (A_e || e || i || y) matches a precommitted digest.
Alternative scriptPubKey (anchor-bound digest)
OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY
OP_TOALTSTACK
# Build (A_e || e || i || y) and check digest Q_{e,i}
<A_e> OP_SWAP OP_CAT # (A_e || y)
OP_ROT OP_CAT # (A_e || y || e)
OP_ROT OP_CAT # (A_e || y || e || i)
OP_SHA256 <Q_ei> OP_EQUALVERIFY # Q_ei = SHA-256(A_e || y || e || i)
OP_FROMALTSTACK OP_CHECKSIG
scriptSig
<Sig> <i> <e> <y> <PubKey>
This variant ties each witness to the publicly known A_e, making cross-epoch or cross-wallet rebinds impossible without changing the digest. It remains one-time because each (e, i) appears at most once.
Security properties. Preimage hardness protects unrevealed tokens. The HMAC derivations ensure tokens are pseudorandom under a single master key and unique across epochs and indices. One-time use is enforced by UTXO consumption plus unique (e, i) bindings; any duplicate is evident and fails the digest checks. The audit trail flows y → A_e → M, and rotation every 10,000 tokens prevents unbounded counter growth while preserving continuity under the fixed master.
Section 8 — Quantitative demonstration in words: negative expected value at small denominations
Start from the simple fact that a quantum attacker must pay a real, non-zero cost each time they derive one private key after seeing its public key. Call that cost “the per-key recovery cost”. Against that you place the face value of a single coin. If the face value is smaller than the per-key cost, every attempt loses money even before counting fees or failures. Splitting value into many low-value coins therefore forces the attacker into a loss on each crack and scales their total loss linearly with the number of coins they try. Now add the script requirement: every spend must also present exact hash preimages that were committed at lock-time. Quantum speed-ups do not give a practical way to discover those preimages; the best known methods still leave preimage search effectively around two to the power of one hundred and twenty-eight steps for SHA-256. So recovering a key alone achieves nothing; without the preimage the lock does not open, and by the time a preimage is revealed by an honest spend the attacker still has to out-run network propagation and miner selection on a very short clock.
Case A: per-key cost ten, coins worth five. Imagine a pool of one million coins, each worth five. The attacker’s machine can, in principle, derive one private key at a real marginal expense of ten. Each crack ends five in the red before they even try to publish a conflicting transaction. Publishing that conflict consumes a fee and very often loses the miner race, which means the fee is burned as well. Running this a million times simply multiplies the loss: roughly five million lost to key recovery plus a very large burn in fees on the many conflicts that never confirm. Parallelising does not rescue the economics; doing ten thousand cracks at once merely loses money faster. Splitting value across one million such coins turns the attacker’s shiny device into a heat source that converts capital into waste.
Case B: per-key cost forty, coins worth fifty. On paper, this looks profitable if one imagines that recovering a key is enough. It is not. The lock demands a specific preimage s for a published commitment, for example “show s such that SHA-256(s) equals H”. There is no practical quantum shortcut to invent s from H. The only way the attacker ever sees s is when an honest spend presents it in the unlocking data. At that moment the attacker still has no signature unless their key-recovery routine has already finished; so they must now complete key recovery, manufacture a conflicting transaction that also includes s, push it across the network, and persuade miners to include it ahead of the honest spend they already saw. In ordinary networks that window is short; propagation of the honest spend reaches most hash-power rapidly, and miners typically prefer the first valid spend they receive. Even if we imagine a world where the attacker sometimes wins that race, they only earn the ten of headroom on those rare wins and still pay forty on every key they attempt. On the majority of attempts they lose fees and gain nothing. Worse for them, real payments are executed as a series of small transactions using many inputs; to beat one such transaction they must complete key recovery for every one of its inputs before they can even sign a conflicting version. If there are six inputs, they need six recoveries within the same short interval, and they still need the preimage s (and any second secret t) for the lock. The practical result is that the apparent ten of headroom is theoretical; in reality the hash-preimage requirement removes the “opportunistic theft” path and the race dynamics erase most of the wins.
Case C: per-key cost one, coins worth two hundredths. This is the micropayment regime. Each crack loses ninety-eight hundredths before fees or failures. Publishing a conflicting spend still burns fees and usually loses the race. The attacker can throw parallel hardware at the problem, but the arithmetic never flips: every attempt loses most of a unit, a million attempts lose close to a million units, and nothing about scale or speed changes that direction. In fact, fragmentation helps the defender twice here. First, it cements the negative cash flow on every key recovery. Second, by sending many small transactions rather than one big one, each transaction is insulated by its own brief propagation window, so the attacker cannot concentrate effort on a single large, slow target.
Why parallelism and throughput do not help the attacker. Key recovery is per key. The script’s preimage is per coin. The race must be won per transaction. None of these compose into a super-linear advantage for the attacker. Running more machines increases burn rate; it does not convert losses into gains. Even the illusion of batching falls apart, because each coin in a transaction still needs its own recovered key, and the transaction cannot be signed until all of those keys are in hand and the exact preimages are known.
Why “waiting for the preimage” does not help either. The only time a preimage s appears on the network is when the rightful owner spends the coin. Seeing s in that moment gives the attacker no ability to sign unless the key was already recovered. If the key was not already recovered, they must finish recovery and broadcast a conflict after the honest spend is already racing across the network; miners have usually seen the original first. If the key was recovered earlier, that required an earlier public key exposure, which well-designed policy prevents by never reusing keys and by keeping public keys hidden until spend.
Why the conclusion holds as conditions move. If the per-key cost rises, the defender can raise the per-output ceiling slightly and still keep the attack unprofitable on every trial. If the per-key cost falls, the defender lowers the ceiling and leans even harder into small denominations and send-many execution. In every regime the hash-preimage requirement remains the same: there is no practical quantum path to invent s from H, so there is no way to grab coins “for free” when value caps are respected.
Putting the three cases side by side makes the invariants obvious. With coins worth five and per-key cost ten, every attempt loses five and the total loss scales with the number of targets. With coins worth fifty and per-key cost forty, the only way to see any gain would be to both recover keys fast enough across all inputs and beat the already-propagating honest spends; in practice the hash-preimage requirement removes the easy path and the race removes most of the rest. With coins worth two hundredths and per-key cost one, every attempt is a near-total loss; multiplying attempts multiplies losses. The general rule is simple and stable: keep the face value of each coin below the realistic per-key recovery cost, and bind every spend to exact preimages. Under that rule, a quantum device designed to recover keys becomes economically ineffective, and fragmentation converts the attacker’s budget into heat.
Section 9 — Adversarial composition and edge cases
Adversary model (composed)
The attacker can derive a private key from a revealed public key using a Shor-capable machine, but only after some non-zero runtime and cost per key. The attacker can read everything in a broadcast transaction, including the input’s unlocking program. The attacker cannot efficiently compute a preimage of a 256-bit hash; the fastest generic quantum method leaves preimage search at about 2^128 steps. Miners accept the first fully valid spend they see for a given input; later conflicts must either outpace propagation or persuade enough miners to choose them instead, typically by paying more.
Key recovered after broadcast, but preimage unknown
If a key is recovered in the interval between broadcast and confirmation while the secret s has not yet been revealed on-chain, the attacker still cannot pass the lock. The locking program demands a specific preimage (e.g., SHA-256(s) = H) before the signature check finalises. Without s, possession of the key alone is useless.
Learning s by observing the honest spend
When the honest input is broadcast, s becomes visible in its unlocking program. Copying s is trivial. What is not trivial is replacing the spend: the attacker must also produce a signature with the recovered key and get a conflicting transaction chosen first by miners. That requires (a) finishing key recovery fast enough across every input of the target transaction, (b) assembling a conflicting transaction that exactly reproduces all required unlocking data in the right order, and (c) out-propagating or out-paying the already-seen honest transaction. Any shortfall on (a)–(c) ends in failure.
Multi-input transactions are multiplicative hurdles
With m inputs, the attacker must finish m separate key recoveries in time to sign the conflict. If any one input is not ready, the conflict is invalid. The per-input hash condition compounds the work: each input has its own s (and optionally t) and, in hardened templates, cross-commitments like SHA-256(s || t). There is no batching shortcut: each input is a separate gate that must be satisfied exactly.
“Wait and snipe” does not create a free ride
“Wait for s, copy it, publish a conflict” sounds easy. In practice:
The honest transaction has already reached a large fraction of miners before the attacker even sees it.
The attacker still needs valid signatures for all inputs; if key recovery was not already complete at broadcast, they are now behind.
Miner selection is path-dependent: the first valid spend seen tends to be favoured; a late conflict must overcome both propagation and policy.
The result is that copyingsafter the fact does not convert the lock into a trivial target.
High-value outputs as selective targets
Targeting only unusually large outputs is defeated by policy. The wallet never creates outputs above the ceiling V_max. If the recipient requires a large total, the wallet emits many small outputs and, where necessary, many small transactions. There is no fat target to snipe.
Network latency and propagation games
An adversary might try to exploit geography or topology to reach a subset of miners first. The wallet trims the broadcast-to-confirmation window by using adequate fees, submitting directly to well-connected miners where available, and avoiding any delays between assembly and broadcast. None of these operational choices weaken the hash requirement; they simply compress the only window in which a conflict could, in principle, succeed.
Reorganisations and miner collusion
Even if a miner (or colluding set) tries to include a conflict in a later block or private re-organisation, the same facts hold: a valid conflict must satisfy the exact hash preimage conditions and signatures for all inputs. There is no path that bypasses the preimage checks; without s (and t if present), the script remains unsatisfied, regardless of who proposes the block.
Key reuse as a structural risk (eliminated by policy)
If a public key appears earlier on-chain, an attacker could start key recovery before the target spend, stretching the timing window. The wallet removes this lever by never reusing keys. With key-once hygiene, there is nothing to feed a recovery machine until the spend itself, at which point the race still requires the hash preimages.
Secret reuse as a structural risk (eliminated by policy)
Reusing s (or t) across outputs would create a “collect once, steal many” condition if a secret is ever revealed. The wallet generates fresh secrets per output and marks any revealed secret as permanently retired. Cross-output reuse is forbidden; change outputs receive new secrets.
Encoding and stack-shaping attacks
Alternate numeric encodings and stack reorderings are common sources of accidental acceptance. Locks enforce sizes and equality with explicit checks:
OP_SIZEons(andt) to fix lengths.Multi-hash commitments on the same
s(e.g.,SHA-256,HASH160,RIPEMD-160) to defeat domain quirks.Optional arithmetic latch (
OP_MULthenOP_NUMEQUALVERIFY) with minimally encoded integers to make the unlocking sequence uniquely shaped.Cross-commitments like
SHA-256(s || t)to bind structure, not just values.
Collision-finding does not help with fixed preimages
The lock demands “this exact s,” not “any pair that collides.” Even with quantum improvements to collision search, that capability does not produce a specific preimage for a fixed digest. The only generic path to s remains preimage search, which stays at about 2^128 quantum effort for 256-bit hashes.
Partial leakage of secrets
If s (or t) leaks off-chain before broadcast, the affected output is no longer protected by its hash condition; however, leakage does not generalise: each output has independent secrets. Operationally, the wallet treats any suspected leak as a trigger to move funds immediately using fresh secrets and, critically, still below V_max. The policy ensures the worst case is bounded by the face value of a single coin.
Hash-chain tokens (integration with Section 7b)
When per-output secrets are drawn from an HMAC-anchored hash chain, each token is single-use by construction. The lock binds (epoch, index, y) to the coin; reusing a token is impossible because the original coin is consumed on first success, and attempting a different y′ fails the digest checks. Auditors can verify y → A_e → M without seeing the master.
Template downgrades and replay
An attacker might prefer a weaker template (e.g., single hash only) and attempt to replay an old unlocking program. This is defused by binding every coin to its chosen template via specific digests and, where used, specific arithmetic constants. Replay across templates fails because the expected stack shape and digest set are different; the equality checks do not line up.
Cross-transaction mix-and-match
Taking s from one transaction and a signature from another does not help. Each input’s lock is bound to its own commitments; moving bytes between inputs fails size and digest checks. In dual-secret designs, cross-mixing s and t from different outputs is also rejected by the SHA-256(s || t) check.
Parameter drift and adaptive defence
If the per-key recovery cost falls, the wallet lowers V_max and leans further into send-many execution; the economics remain negative for the attacker (see Section 8). If propagation becomes slower, the wallet raises fees and uses more direct submission paths; the timing window remains short. None of these adjustments touch the core hash requirement.
What has to go wrong for the attacker to win
All of the following would need to align in the attacker’s favour:
Every input’s public key is recovered in time.
Every input’s preimage requirements are satisfied (i.e.,
sandtare in hand or broken by impossible preimage search).The conflict reaches miners fast enough and is chosen over the honest spend.
The design ensures (2) blocks the door: without the secrets, (1) and (3) are irrelevant. With secrets generated per coin and never reused, and with keys hidden until spend, there is no scalable way around the lock.
Bottom line
Recovering a key is not enough. The lock demands exact preimages; the network favours the first valid spend; and the wallet never creates large targets or reusable secrets. Composed together, these properties make quantum key recovery economically and practically ineffective across all of the edge cases above.
Section 10 — Engineering notes and compatibility within base Script
Goals
Portability and reliability across common node policies. The constructions here:
Use only baseline Script opcodes and simple stack manipulation (
OP_DUP,OP_SWAP,OP_ROT,OP_TOALTSTACK,OP_FROMALTSTACK,OP_2DUP).Use the full hash set (
OP_SHA256,OP_HASH160,OP_RIPEMD160,OP_SHA1,OP_HASH256) and arithmetic where helpful (OP_MUL,OP_NUMEQUALVERIFY).Optionally use structural helpers such as
OP_CATandOP_SUBSTRwhere they are available.Do not rely on timelocks or covenant-like mechanisms.
Keep sizes and encodings conservative so default relays accept them; where a miner policy is stricter, large payers coordinate acceptance out of band. At the consensus layer the scripts evaluate cleanly.
Opcode profile
Hash ops:
OP_SHA256,OP_HASH256,OP_HASH160,OP_RIPEMD160,OP_SHA1.Stack/flow:
OP_DUP,OP_SWAP,OP_ROT,OP_2DUP,OP_TOALTSTACK,OP_FROMALTSTACK,OP_DROP,OP_EQUAL,OP_EQUALVERIFY,OP_VERIFY.Signatures:
OP_CHECKSIG.Arithmetic (optional latch):
OP_MUL,OP_NUMEQUALVERIFY.Structural (optional):
OP_CAT,OP_SUBSTR.
No disabled or stateful features are required; no loops; straight-line evaluation.
Encoding rules that keep you out of trouble
Pushes: use minimal push opcodes for constants and digests.
Integers: minimally encoded, no leading zero bytes, negative zero forbidden.
Lengths: enforce with
OP_SIZEbefore hashing (for example,smust be exactly 32 bytes;tat least a floor you choose).Signatures: canonical DER; create the signature after every byte of unlocking data is final.
Public keys: use one format per wallet (compressed 33-byte or uncompressed 65-byte) and commit to it everywhere.
Size budgets (typical; comfortably inside common relays)
Triple-hash, key-hidden
scriptPubKey(Section 5 A): ≈ 110–140 bytes (20-byte pubkey hash + three digest constants + opcodes).Dual-secret, key-hidden with
s‖tbinding (Section 6 A): ≈ 150–190 bytes.Unlocking data per input:
Single-secret:
<Sig> <s> <PubKey>≈ 72 + 32 + 33/65 bytes.Dual-secret: add
t(policy floor ≥ 24 bytes).Arithmetic latch: add two small integers (typically 1–3 bytes each).
Keep each input well under typical standard transaction limits with wide safety margins.
Malleability and build order
Because the unlocking program is part of the signed serialization, build in this order per input:
Push all required bytes for secrets (
s,t), structured values (e.g., concatenations), and any latch integers.Push the public key if the lock proves a pubkey hash.
Produce the signature last.
Any change to what you push changes the signed message; signing last avoids accidental invalidation.
Baseline example (key-hidden, multi-hash on one secret)
scriptPubKey
OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY
OP_TOALTSTACK
OP_DUP OP_SIZE 32 OP_EQUALVERIFY
OP_DUP OP_SHA256 <H_sha256> OP_EQUALVERIFY
OP_DUP OP_HASH160 <H_hash160> OP_EQUALVERIFY
OP_RIPEMD160 <H_ripemd160> OP_EQUALVERIFY
OP_DROP
OP_FROMALTSTACK OP_CHECKSIG
unlocking (input)
<Sig> <s> <PubKey>
Why it ports: only baseline ops; no structural or arithmetic opcodes; digest constants are compact; stack usage is simple.
Hardened example (dual-secret with concatenation binding)
scriptPubKey
OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY
OP_TOALTSTACK
OP_DUP OP_SIZE 32 OP_EQUALVERIFY
OP_DUP OP_SHA256 <H1_sha256> OP_EQUALVERIFY # s
OP_SWAP
OP_DUP OP_SIZE 24 OP_GREATERTHANOREQUALVERIFY
OP_DUP OP_SHA256 <H2_sha256> OP_EQUALVERIFY # t
OP_2DUP OP_CAT OP_SHA256 <H_st_cat> OP_EQUALVERIFY # bind s||t
OP_DROP OP_DROP
OP_FROMALTSTACK OP_CHECKSIG
unlocking
<Sig> <t> <s> <PubKey>
Why it ports: adds only OP_CAT where available; still straight-line; all constants pushed minimally.
Arithmetic latch add-on (when unique stack shape is desirable)
Append to either of the above, just before OP_FROMALTSTACK OP_CHECKSIG:
# integers n1, n2 will be pushed in the unlocking data
<nProd> OP_TOALTSTACK
OP_SWAP # bring n1,n2 into order expected
OP_MUL
OP_FROMALTSTACK OP_NUMEQUALVERIFY
unlocking augmentation
... <n2> <n1> ...
Why it ports: uses only OP_MUL and numeric equality; integers must be minimally encoded.
Miner relay acceptance
Keep
scriptPubKeysizes modest (examples above) and avoid exotic, oversized constants.Keep unlocking data per input predictable and compact; avoid gigantic
tvalues unless you’ve cleared policy.If a relay policy flags “non-standard”, large payers coordinate with miners (direct submission, pre-whitelisting script templates). The constructions evaluate to true/false deterministically; acceptance is policy, not consensus, and is solved by business coordination.
Node/resource hygiene
Sigops: one
OP_CHECKSIGper input keeps per-transaction sigop counts well within typical budgets.Runtime: no loops, no data-dependent repetition; hashing is constant count per input.
Memory: stack bounded; move the pubkey to altstack, consume temps with
OP_DROP.
Off-chain preflight (must-pass checks before you sign)
Recompute every on-chain digest:
SHA-256(s),SHA-256(t),SHA-256(s||t)if used, and mixed-family variants.Verify
OP_SIZEconstraints with exact byte counts.Verify latch equality:
n1 * n2 == nProd.Verify minimal integer encodings (no leading zeroes; zero is empty vector).
Refuse to sign if any check fails; regenerate fresh secrets for that coin.
Key and secret hygiene
No key reuse: one keypair per output; a key appears on-chain only once, at spend.
No secret reuse:
sandtare unique per output; once revealed, they are retired forever.Deterministic recovery: derive
s/tfrom a master key and per-output nonce via HMAC-SHA-256, or store encrypted; in both cases verify by hashing to the recorded digests.
Monitoring and roll-forward
Maintain a small registry of approved script templates (by literal byte image) and reject any deviation.
Track miner policy shifts; if a template is ever rate-limited by relays, switch to the compact baseline (triple-hash single-secret) for new outputs while you coordinate acceptance for the larger variant.
Rotation of parameters (for example, raising the minimum length of
t) is done by minting new outputs under the new template; old outputs remain spendable under their original locks.
Privacy notes
Vary denominations below
V_maxto avoid trivially identical fan-outs.Prefer diverse ages and face values in input selection to minimise deterministic linkage.
Keep unlocking data consistent within a template so parsers cannot distinguish “user cohorts” by small stack shape differences.
What not to depend on
No timelocks, relative or absolute, are required for the defence.
No covenant-like opcodes or template matching opcodes are required.
No extra-protocol signalling (other than business coordination for policy acceptance when needed).
Bottom line
These locks run entirely on baseline Script, keep sizes and encodings conservative, and avoid brittle dependencies. If a relay policy is stricter than your chosen template, coordinate miner acceptance; at the execution layer the programs are valid, straight-line, and deterministic. Operational hygiene—no key reuse, no secret reuse, fresh per-output randomness—completes the compatibility picture.
Section 11 — Security parameters and recommended defaults
Hash suite (commitments and checks)
Primary commitment: SHA-256. For each coin bind a secret
swithH_s = SHA-256(s).Strengthening (recommended): add independent checks on the same
swithHASH160(s)andRIPEMD-160(s). This diversifies hash families without changing the spend flow.Dual-secret mode (optional): bind a second secret
twithH_t = SHA-256(t)and add a cross-bindingH_st = SHA-256(s || t). For maximal rigidity you may also precommitH_ts = SHA-256(t || s); verification remains straight-line.Double hashing: where a simple
SHA-256(·)is used for cross-bindings,HASH256(·)is also acceptable.
Secret lengths and encoding
s: exactly 32 bytes. Enforce withOP_SIZE 32 OP_EQUALVERIFYbefore hashing.t(if used): minimum 40 bytes. Enforce withOP_SIZE 40 OP_GREATERTHANOREQUALVERIFYbefore hashing.All pushed integers (for any arithmetic latches): minimally encoded (no leading zero bytes; zero is the empty vector).
Secret generation and recovery
Random mode: draw
s(andt) from a cryptographically secure generator at creation time.Deterministic mode (recommended for restore): maintain a 32-byte master key
K_masterand a unique per-coin nonceu_nonce(≥ 16 bytes). Derives = HMAC-SHA-256(K_master, "s" || u_nonce)t = HMAC-SHA-256(K_master, "t" || u_nonce)(when used).
Storeu_nonceand the on-chain digests; never stores/tin clear at rest.At restore, re-derive
s/tfromK_masterandu_nonceand verify by hashing to the recorded digests before enabling spends.
Script templates (defaults)
Baseline (single secret, multi-hash): key-hidden (public-key hash proved first), then
OP_SIZEons, thenSHA-256(s),HASH160(s),RIPEMD-160(s), then signature.
Rationale: one secret, three independent hash families, public key only revealed at spend.Elevated (dual secret): key-hidden,
OP_SIZEonsandt,SHA-256(s),SHA-256(t),SHA-256(s || t), then signature.
Rationale: two secrets and a structural binding close “mix-and-match” attempts.
Arithmetic latch (optional, using OP_MUL)
Pick two small positive integers
n1,n2(8–16-bit each). PrecomputeP = n1 * n2and requireOP_MULto equalP(OP_NUMEQUALVERIFY).Purpose: a low-cost invariant that fixes stack shape and encoding; not relied upon for cryptographic strength.
Value ceiling and transaction shaping
Per-output ceiling
V_max: choose strictly below a conservative lower bound for the attacker’s per-key recovery cost. Keep a safety margin; if conditions change, lowerV_max—never raise it casually.Consumer payments: small, fixed denominations in the 5–50 equivalent range keep key-recovery strictly loss-making.
Micropayments: set
V_maxin the cents/sub-unit range.
Send-many execution: large payments are split into multiple small transactions. No merging.
Per-transaction limits:
I_max(inputs): 8–12 by default.O_max(new outputs including change): 4–8 by default.
All new outputs must be< V_max.
Public key handling and reuse policy
One key per coin. A key appears on-chain exactly once, at spend.
Never reuse
sort. Any secret revealed in one spend is permanently retired.
Broadcast and propagation defaults
Assemble unlocking data fully, then produce the signature last.
Broadcast immediately on authorisation; target rapid inclusion with competitive fees.
Use multiple relay paths and direct miner submission where possible to compress the broadcast-to-confirmation window.
Storage, encryption, and zeroisation
Persist per-coin metadata: derivation path, public key, template ID, on-chain digests, any arithmetic constants, and
u_nonce.Encrypt at rest under a strong AEAD key derived from the wallet seed and passphrase.
Keep
s/tin RAM only while building a spend; zeroise buffers after signing.
Audit cadence and rotation
Periodically re-derive deterministic
s/tand verify all recorded digests; on any mismatch, lock spending until corrected.Rotate denomination palettes (still
< V_max) to avoid easily recognisable fan-out patterns.If using HMAC-anchored hash chains (Section 7b), fix epochs to 10,000 tokens; publish the new epoch anchor and linkage commitment at rotation.
Size budgets (practical targets)
Baseline key-hidden multi-hash lock: compact; unlocking data ≈ 72 (signature) + 32 (
s) + 33/65 (public key).Dual-secret lock: add
|t|(≥ 40 bytes) and the cross-binding digest constant in the lock.Keep constants minimal; keep per-input programs straight-line with one
OP_CHECKSIG.
Default profile (ready to ship)
Hashes: SHA-256 for commitments; add
HASH160(s)andRIPEMD-160(s)on the sames.Secrets:
|s| = 32bytes;|t| ≥ 40bytes when dual-secret mode is enabled.Locks: key-hidden templates; dual-secret +
SHA-256(s || t)for elevated assurance.Arithmetic latch: off by default; enable per coin when a uniquely shaped unlocking sequence is desired.
V_max: below conservative per-key recovery cost; maintain an explicit safety margin.Execution: send many; never consolidate; one key and fresh secrets per coin; immediate broadcast.
These parameters keep every coin independently bound to secrets a quantum device does not practically recover, keep each target too small to be worth attacking, and keep every transaction short and fast so there is no exploitable timing surface.
Section 12 — Summary of the defence
Core idea. Every coin is locked so that spending it requires two things, not one:
a valid signature, and
exact hash preimages that were committed when the coin was created.
Quantum machines can help with signatures once a public key is visible; they do not make finding specific hash preimages practical. By forcing both conditions, key recovery alone is useless.
Fragmentation makes attacks uneconomic. The wallet never creates large, attractive coins. Value is split across many low-value outputs, each bound to its own secrets. An attacker pays a real per-key cost for every output they try to crack. When each output’s value is capped below that cost, every attempt loses money. Doing more in parallel only burns funds faster.
What the attacker actually faces.
Before spend: the public key is not on-chain; there is nothing to feed into key recovery.
At spend: the unlocking program reveals the public key and the committed preimage(s). Copying the preimage(s) is easy, but without the key the attacker cannot sign; with only the key and without the exact preimage(s), the script still rejects.
To replace the payment: the attacker must finish key recovery for every input in the same short interval, assemble a conflicting transaction with the exact unlocking data, and convince miners to prefer it over the one they saw first. That compound requirement routinely fails.
Wallet policy that enforces the advantage.
One key per coin; keys are never reused.
Fresh secrets per coin; once revealed, never reused.
Strict per-output ceiling
V_max; large payments are sent as many small transactions (“send many”), never by merging coins first.Change is split immediately into fresh coins, each below
V_maxand bound to new secrets.Immediate broadcast with sensible fees and direct submission where available to keep the race window tight.
Script templates that make key recovery insufficient.
Key-hidden, multi-hash on one secret (e.g., size check on
s, thenSHA-256(s),HASH160(s),RIPEMD-160(s), then signature).Elevated dual-secret variants (commit to
s, commit tot, and bind structure withSHA-256(s‖t)), optionally adding a tiny arithmetic check withOP_MULto fix stack shape.
All of these are straight-line, Forth-style programs; no loops, no timelocks, no covenant-style tricks.
Economics in one line. Per-key attack cost > per-coin value ⇒ negative expected value per attempt. Multiply attempts, multiply losses.
Timing in one line. The public key and preimages appear only at broadcast; the attacker must complete multiple key recoveries and win miner selection after that moment. In practice, the honest transaction’s propagation closes the window before the attacker can do both.
Edge cases are closed. Targeting “big coins” fails because the wallet does not create them. Reusing secrets or keys is forbidden by policy. Collision tricks do not help because the lock asks for a specific preimage, not “any colliding pair.” Network-latency games are blunted by immediate broadcast and direct miner submission.
Bottom line. By (1) binding each spend to hash preimages that quantum methods don’t efficiently discover, and (2) keeping every coin too small to justify per-key attacks, the design removes the attacker’s practical and economic paths. Scaling up only scales losses. A hypothetical quantum key-recovery device is therefore ineffective against a wallet that follows this script and policy.
Appendix A — Reference Script templates (Unicode)
All snippets are straight Forth-style Script. Placeholders like <PubKey>, <PubKeyHash>, <H>, <H1>, <H2>, <H_sha256>, etc., are literal data pushes. “scriptSig” is the unlocking program; “scriptPubKey” is the locking program.
A1. Bare hash-locked signature (single secret)
scriptPubKey
OP_SHA256 <H> OP_EQUALVERIFY
<PubKey> OP_CHECKSIG
scriptSig
<Sig> <s>
A2. Hash-augmented P2PKH (keep the public key hidden until spend)
scriptPubKey
OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY
OP_SWAP OP_SHA256 <H> OP_EQUALVERIFY
OP_CHECKSIG
scriptSig
<Sig> <s> <PubKey>
A3. Two-secret variant (bare)
scriptPubKey
OP_SHA256 <H1> OP_EQUALVERIFY
OP_SHA256 <H2> OP_EQUALVERIFY
<PubKey> OP_CHECKSIG
scriptSig
<Sig> <t> <s>
A4. Key-hidden, multi-hash on one secret (triple commitment)
scriptPubKey
OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY
OP_TOALTSTACK
OP_DUP OP_SIZE 32 OP_EQUALVERIFY
OP_DUP OP_SHA256 <H_sha256> OP_EQUALVERIFY
OP_DUP OP_HASH160 <H_hash160> OP_EQUALVERIFY
OP_RIPEMD160 <H_ripemd160> OP_EQUALVERIFY
OP_DROP
OP_FROMALTSTACK OP_CHECKSIG
scriptSig
<Sig> <s> <PubKey>
A5. Dual-secret with concatenation binding (uses OP_CAT)
scriptPubKey
OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY
OP_TOALTSTACK
OP_DUP OP_SIZE 32 OP_EQUALVERIFY
OP_DUP OP_SHA256 <H1_sha256> OP_EQUALVERIFY # s
OP_SWAP
OP_DUP OP_SIZE 24 OP_GREATERTHANOREQUALVERIFY
OP_DUP OP_SHA256 <H2_sha256> OP_EQUALVERIFY # t
OP_2DUP OP_CAT OP_SHA256 <H_st_cat> OP_EQUALVERIFY
OP_DROP OP_DROP
OP_FROMALTSTACK OP_CHECKSIG
scriptSig
<Sig> <t> <s> <PubKey>
A6. Position-constrained dual-secret (uses OP_SUBSTR)
Requires that s appears inside t at fixed offset <k>; also commits individually to s and t.
scriptPubKey
OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY
OP_TOALTSTACK
OP_DUP OP_SHA256 <H1_sha256> OP_EQUALVERIFY # s
OP_SWAP
OP_DUP OP_SHA256 <H2_sha256> OP_EQUALVERIFY # t
OP_2DUP # ... t s t s
OP_SWAP <k> OP_SIZE OP_SUBSTR OP_EQUALVERIFY # t[k : k+|s|] == s
OP_DROP OP_DROP
OP_FROMALTSTACK OP_CHECKSIG
scriptSig
<Sig> <t> <s> <PubKey>
A7. Epoch/index-bound token from an HMAC-anchored chain (see §7b)
Binds (e, i, y) to a per-coin digest <D_ei> = SHA-256(e || i || y) and also to <H_i> = SHA-256(y).
scriptPubKey
OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY
OP_TOALTSTACK
OP_DUP OP_SIZE 32 OP_EQUALVERIFY # y must be 32 bytes
OP_ROT OP_ROT # ... y i e -> bring e,i before y
OP_SWAP OP_CAT # (e || i)
OP_SWAP OP_CAT # (e || i || y)
OP_SHA256 <D_ei> OP_EQUALVERIFY
OP_DUP OP_SHA256 <H_i> OP_EQUALVERIFY
OP_DROP
OP_FROMALTSTACK OP_CHECKSIG
scriptSig
<Sig> <i> <e> <y> <PubKey>
A8. Anchor-bound digest variant (bind to public epoch anchor A_e; uses OP_CAT)
Commits <Q_ei> = SHA-256(A_e || y || e || i) so each token is tied to the published anchor.
scriptPubKey
OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY
OP_TOALTSTACK
<A_e> OP_SWAP OP_CAT # (A_e || y)
OP_ROT OP_CAT # (A_e || y || e)
OP_ROT OP_CAT # (A_e || y || e || i)
OP_SHA256 <Q_ei> OP_EQUALVERIFY
OP_FROMALTSTACK OP_CHECKSIG
scriptSig
<Sig> <i> <e> <y> <PubKey>
A9. Compact bare single-secret, multi-hash (no key hiding)
scriptPubKey
OP_DUP OP_SIZE 32 OP_EQUALVERIFY
OP_DUP OP_SHA256 <H_sha256> OP_EQUALVERIFY
OP_DUP OP_HASH160 <H_hash160> OP_EQUALVERIFY
OP_RIPEMD160 <H_ripemd160> OP_EQUALVERIFY
OP_DROP
<PubKey> OP_CHECKSIG
scriptSig
<Sig> <s>
A10. Minimal single-secret with double-hash (HASH256) and key hiding
scriptPubKey
OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY
OP_TOALTSTACK
OP_DUP OP_SIZE 32 OP_EQUALVERIFY
OP_HASH256 <H_hash256> OP_EQUALVERIFY
OP_DROP
OP_FROMALTSTACK OP_CHECKSIG
scriptSig
<Sig> <s> <PubKey>
Notes for implementers
Enforce sizes with
OP_SIZEbefore hashing (e.g.,sexactly 32 bytes;tat least a floor you choose).Push integers (when used) in minimal Script encoding.
Assemble all unlocking data first; create the signature last so it covers the exact bytes you will publish.
Appendix B — Wallet-side procedure (high-level, non-bullet narrative)
On receipt of funds the wallet immediately decomposes the amount into many outputs so that no single output exceeds the configured ceiling VmaxV_{\max} (expressed in satoshis, enforced in code—not as a mathematical formula). It does not hold a lump sum in one place and it does not create a large target for later convenience. For each output it derives a brand-new keypair and creates brand-new secrets that will be demanded at spend time by the locking program. In the minimal profile there is one 32-byte secret ss; in the stronger profile there is also a second secret tt of policy-defined length. These secrets may be drawn from a cryptographically secure generator, or deterministically derived from a master key with a unique per-output nonce using HMAC-SHA-256 so that a restore can reproduce them exactly. The wallet immediately computes the required commitments—at minimum SHA-256(s), and, in the hardened templates, additional checks on the same s (such as HASH160(s) and RIPEMD-160(s)), or a second commitment SHA-256(t) together with a structural binding like SHA-256(s‖t). If the chosen template includes a small arithmetic latch, the wallet also selects two small positive integers n₁ and n₂, records their product P, and later enforces OP_MUL equals P in the locking program. With those constants in hand, the wallet assembles the scriptPubKey for the output: either a key-hidden, multi-hash script that proves the public-key hash first and then demands the exact secret(s) before it will validate a signature, or a dual-secret script that commits to s and t and binds their concatenation, again before any signature check is considered. Every output receives its own independent key, secrets, and commitments; nothing is ever reused.
All per-output materials are recorded as encrypted metadata: the derivation path, the raw public key, the script template identifier, the full set of on-chain digests, any arithmetic constants, and the per-output nonce used for deterministic derivation if that mode is active. Cleartext secrets exist only in memory during script construction and signing and are wiped with deliberate zeroisation once the transaction is assembled. The public key itself is not placed on-chain at creation; the wallet prefers the key-hidden form, so the first time a public key appears is in the unlocking program of the spend that uses it. This choice shortens the attacker’s theoretical window: there is nothing to feed into a key-recovery routine until broadcast.
When making a payment the wallet never tries to “tidy up” value by merging coins. Instead it executes the amount as a sequence of small transactions (“send many”), each bounded by explicit limits on the number of inputs and outputs and with every new output kept strictly below VmaxV_{\max}. It chooses the first transaction’s inputs as the smallest group of low-value coins that covers the intended slice of the payment and the fee. Where several choices work equally well, it prefers a mix of ages and denominations so repeated use does not leave a mechanical pattern. For each chosen input it prepares the unlocking program in a straight line: it pushes the secret s, and, if the output was created under a dual-secret template, it also pushes t; if the lock binds structure using concatenation or an interleave value, the corresponding byte string (prebuilt by the wallet) is pushed in the exact position the script expects; if an arithmetic latch is present, the two small integers are pushed as minimally encoded Script integers; if the lock proves a public-key hash, the public key is then pushed; and only when every byte that will go onto the stack is final does the wallet produce the signature. Before signing, the wallet performs a pre-flight check for each input: it re-hashes s (and t if present) and recomputes any cross-digests to confirm they match the on-chain commitments, verifies that integer encodings are minimal and that n₁·n₂ equals the recorded product P when such a latch is used, and refuses to proceed if anything is off by even one bit. Any input that fails is replaced with a different coin created with fresh secrets; secrets that appeared in a rejected build are permanently retired within the wallet’s state so they cannot be reintroduced accidentally.
Broadcast happens immediately after assembly. The wallet uses a fee rate intended to minimise dwell time and submits through multiple well-connected peers and, where available, direct miner channels to compress the broadcast-to-confirmation interval. Because the public key appears only now, and because the lock demands exact preimages as well as a valid signature, seeing the transaction in flight does not create a cheap replacement path: copying the secret after broadcast still leaves the would-be thief without the corresponding signature, and recovering a key without the secret still leaves them short of the hash conditions. If the overall payment is larger than one transaction can comfortably carry under the input and output limits, the wallet simply constructs and broadcasts another small transaction, repeating the same procedure, and continues until the requested amount is fully delivered. Each transaction in the series stands on its own and closes quickly; there is never a preparatory merge into a big coin.
Change is treated as a fresh receive rather than a bookkeeping afterthought. Immediately after placing the recipient outputs and the fee, the wallet splits any change into new outputs that are each strictly below VmaxV_{\max}. It derives fresh keypairs and fresh secrets for these change outputs, computes new commitments, and writes new scriptPubKeys. No secret or key is ever recycled; a secret that has been revealed on-chain once can never satisfy any other output anywhere in the wallet. This keeps every coin independent: if any one secret were somehow to leak off-chain, only the single coin encumbered by that secret is at risk, and even then the attacker still needs to defeat both the hash condition and the network race to replace the spend.
If a transaction fails relay or is withdrawn, the wallet does not try to salvage its components. It marks every secret that appeared in that transaction’s unlocking programs as permanently spent from the wallet’s point of view, zeroises any residual copies in memory, and rebuilds a new transaction with different inputs and fresh secrets. This rule prevents subtle reuse and eliminates the chance that a previously exposed byte string could be replayed in a later context. After confirmation the wallet prunes transient state while retaining the encrypted metadata that enables deterministic recovery and audit.
Audit and restore are first-class concerns. At regular intervals the wallet re-derives deterministic secrets from the master key and the stored per-output nonce and re-computes all published digests to confirm that the archive matches reality. Any discrepancy locks spending until it is resolved, so that no malformed unlocking program can be constructed. A restore begins by rebuilding the key hierarchy, then, if deterministic derivation is active, regenerates s (and t) for every unspent coin from its nonce, checks that hashing them reproduces the on-chain commitments, and only then enables spending. Because the commitments are embedded in the locking programs, a restored wallet can verify its reconstruction without revealing the secrets to any third party.
The procedure’s rhythm never changes: split value on receipt into many small coins, bind each coin to its own secrets with hash commitments that a quantum device does not help to invert, hide the public key until the moment of spend, assemble unlocking data exactly as the locking program requires and sign last, broadcast immediately, and treat any change as new coins subject to the same rules. Large payments are carried by many small transactions rather than by creating a single large coin. Under this discipline key recovery alone cannot unlock a coin, and no coin is valuable enough on its own to make that attempt profitable.



Very good. Was this once protected by IP?