Repository navigation
doc: document bounded30 usage-dependent security margin and raw-key counter limits - #264
Merged
Merged
Conversation
…mits Add a non-normative note, doc/reference/p2mr-signature-security.md, on how the SLH-DSA-SHA2-128s-bounded30 security margin depends on the number of signatures per key. FORS+C still gives k*a = 128 bits for a single use, because verification rejects a nonzero compressed index. The standard SPHINCS+ few-time FORS bound gives the full 128-bit level up to about 2^26.6 signatures and about 118 bits at the 2^30 limit. The note includes a script that reproduces these figures. Make the signrawtransactionwithkey, descriptorprocesspsbt and importdescriptors help say that PQC signature counts for caller-supplied keys are not tracked across calls, so the caller is responsible for the 2^30-per-key limit. In P2MR v1 section 9, separate wallet-held keys, whose counters enforce the contract, from caller-supplied keys. Add cross-references from the user, wallet, PSBT, descriptor and RPC-delta docs. No consensus, signature-format or counter-behaviour change. Refs #261 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Member
Author
|
@codex review |
|
Codex Review: Didn't find any major issues. You're on a roll. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
23 of 30 tasks
5 of 9 tasks
kiwidream
added a commit
that referenced
this pull request
Nov 2, 2026
Fold the release-notes fragments of #264, #265, #266 and #268 into doc/release-notes-1.0.1.md and delete them, and write the #263 entry from its pull request. #263's new P2MR stack-byte standardness rule is also listed under the behavior changes. Correct claims these merges made stale: - the fuzz-evidence limitation said later changes touch no fuzzed code; #263 and #265 change the interpreter that p2mr_script runs, and #268 replaces the library that pqc and p2mr_script call, so fresh evidence on the release source is now required before tagging; - the #162 entry said data signatures are unchanged (#265 caches them); - the no-measurement line now points to #268's library cost figures; - the #252 entry now notes the later #264 and #263 profile edits. Also correct the #183 entry, which said every other encryptwallet failure returns -16; some return -4 or -8. Record the deferred items under Known limitations: the consensus stack-byte cap (#257), uncached failed PQC signature checks (#259), and the remaining AuxPoW limits and open review notes from #266 (#258). Refs #174. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kiwidream
added a commit
that referenced
this pull request
Nov 2, 2026
Release notes: - add an Updated RPCs section: bumpfee rejects a replacement whose signer changed anything but input signatures, and revalidates the replacement at commit time (#167, which shipped the unmerged #146); send entries can omit vout, address and label (#150); list the new bumpfee failures under the behavior changes as well; - restate #268's cost from the release review's measurements, with the SHA backends they cover; - add Known limitations for per-descriptor PQC signature counters, the qbit-qt Send dialog signing while it prepares, and the platforms on which the libbitcoinpqc stack-wipe depth is verified. doc/consensus/p2mr-v1.md: correct the non-normative section 9 sentence from #264, which implied wallet-wide per-key counting. Wallet counters enforce the 2^30 contract per descriptor and per wallet copy. No normative text changes, but the specification bytes do, so the P2MR v1 consensus review must cite a commit that contains this change. share/examples/qbit.conf: show the -fallbackfee default from #151, as contrib/devtools/gen-qbit-conf.sh generates it. The generator's other difference, the lock debug category, appears only in Debug builds and is left out. Refs #174. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Refs #261.
Targets the v1.0.1 release line (
1.x.x).1.x.xis frozen for v1.0.1 (#181), so a maintainer must lift the freeze before merging, and the v1.0.1 release notes in #181 need this entry (fragment:doc/release-notes-264.md).Docs and RPC help only. No consensus, signature-format, or counter-behaviour change.
1. Usage-dependent security margin. New non-normative note
doc/reference/p2mr-signature-security.md:crypto_sign_verifyrejects any digest whose compressed (8th) tree index is not 0, so a forger must also meet that2^-16condition. Single-use bound isk·a = 128bits.H_msgquery,Σ_r Poisson(r; q/2^30) · 2^-16 · (1 − (1 − 2^-16)^r)^7, with a stdlib-only Python script and its output (reproduced below).2^26signatures per key (exact crossover2^26.64;2^26is the rounded-down planning figure), about 118 bits at the2^30cap; rotate high-volume keys well before2^30.(tree, leaf)pairs are expected (50% at ~38.6k signatures) and share a hypertree path by design; maps the walletwarning/criticalthresholds onto the curve; tabulates which signing paths track the2^30counter (wallet-held keys,signrawtransactionwithkey,descriptorprocesspsbt, copies/backups, external signers).Short cross-references were added to
doc/user/bitcoin-core-differences.md(which now also states that the2^30limit is a signer-side contract that consensus does not enforce),doc/user/wallet/p2mr-wallets.md,doc/user/wallet/psbt.md,doc/user/wallet/descriptors.md,doc/integration/rpc-delta-reference.md(Raw Transaction Signing and PSBT Handling), anddoc/reference/README.md.2. Raw-key RPC help.
signrawtransactionwithkeyanddescriptorprocesspsbtnow say PQC signature counts for keys passed to them are not tracked across calls (each call treats every key as unused) and the caller is responsible for keeping each key within the1073741824-signature limit.importdescriptorsnow says imported keys' counters do not include signatures the same keys made outside this wallet.utxoupdatepsbthides secrets;signmessagewithprivkeyis legacy-only and disabled on P2MR-only chains).ParseDescriptorPQCPrivateKeymergesexpanded_keys.pqc_sig_counters, butExpandPrivatenever populates it, so every raw-key call starts from 0.rpc-docs.jsonis generated from the binary by therpcdocs-jsontarget; there are no checked-in per-release help snapshots or annotations for these RPCs, so nothing needed regenerating. I builtrpcdocs-jsonand confirmed the new text is present.3.
doc/consensus/p2mr-v1.md§9. The line "qbit wallet signing counters enforce the2^30contract operationally" now distinguishes wallet-held keys (enforced by wallet counters) from caller-supplied keys signed outside a wallet (caller's responsibility), without naming specific RPCs in the normative profile, and a one-paragraph pointer to the non-normative note was added. No MUST/SHOULD text and no §10 text changed (§10 belongs to #257). Binding check:p2mr_v1_manifest.jsonnames the spec by path only;ci/release/verify_p2mr_v1_conformance.pyreads the spec blob from the signed tag target and requires it to be unchanged since the reviewedspecification_commit. Edits are therefore allowed on this line, but release review evidence must cover the final §9 text (as it must for #252/#257). The analysis itself lives outside the normative spec.4. Upstream note (no qbit file changed). The vendored parameter explorer
src/libbitcoinpqc/docs/sphincs-parameter-explorer.htmlscores security ask·aonly, ignoring the usage-dependent FORS term. That fix belongs upstream inQbit-Org/qbit-libbitcoinpqc.src/libbitcoinpqcis untouched.Reproduced table
Model: per-key, per-
H_msg-query forgery probabilityeps(q) = Σ_{r≥1} Poisson(r; q/2^30) · 2^-16 · (1 − (1 − 2^-16)^r)^7; bits =−log2 eps(q). Poisson matches exactBinomial(q, 2^-30)to 4 decimal places at every row.The 16-byte hash output still caps the overall level at about 128 bits, so figures above 128 are model output only.
Testing
cmake --build build -j12, RelWithDebInfo, wallet, tests, bench).Exact checks:
build/bin/test_qbit(full unit suite): passed, "No errors detected".test/functional/test_runner.py rpc_help.py rpc_signrawtransactionwithkey.py wallet_importdescriptors.py rpc_psbt.py: 4/4 passed.test/lint/lint-qbit-public-docs.py: passed.test/lint/check-doc.py,test/lint/lint-files.py: passed.python3 -m unittest ci.release.test_verify_p2mr_v1_conformance: 31 tests OK (includesCheckedInP2MRIntegrationMatrixTestfrom the public-docs-lint job).cmake --build build --target rpcdocs-json, then confirmed the new help text appears inbuild/doc/rpc/rpc-docs.json.test/rpc_docs/test_*.py: all OK (1 skipped: mkdocs is not installed locally).2^30 − 2^24→ 118.3 bits), and the birthday figure (38,581).help signrawtransactionwithkey,help descriptorprocesspsbt, andhelp importdescriptorson regtest.lint-spelling.py(codespell is not installed on the host);ctest(host-memory restriction, see release-gate rules).Target Branch
mainor a maintainer-requested release branch such as0.1.x.Targets
1.x.x(v1.0.1 release line), base4fb9dbeac3.Risk / Review Notes
Notes: The only code changes are RPC help strings. The security statement is a judgment call, so reviewers should check the model, not just the arithmetic.
Engineering practices applied:
ParseExplicitPQCSecret,ParseDescriptorPQCPrivateKey,FlatSigningProvider::SignPQC, walletm_map_pqc_sig_counters). The help now matches the contract all of those paths actually implement. No serialized or RPC result format changed.Docs / Process Impact
libbitcoinpqc Subtree Checklist (if
src/libbitcoinpqcchanged)Not applicable:
src/libbitcoinpqcis unchanged.🤖 Generated with Claude Code