Every captured commit receives deterministic security triage and a separate communication-quality score. Security candidates and broader second-pass signals receive full-patch Ollama analysis.
Message quality measures whether a commit identifies its scope, purpose, rationale, testing, and supporting references. It does not change the security-severity score.
This commit fixes a cache-key collision bug in Elements' range-proof and surjection-proof validation caches. Previously, the cache key was built by simply concatenating raw bytes, so two different sets of inputs could accidentally produce …
Cache key collision resistance hardened by length-prefixing all fieldsSurjection-proof cache key now includes vTags, fixing a missing-input vulnerabilityNew runtime option to disable range-proof cache without recompilation
This commit adds a new command-line option `-norangeproofcache` that lets node operators turn off an internal performance cache used when validating confidential transaction range proofs. It is a debug/test option, not a security fix. Ther…
No security-relevant signal in commit message or diffNew debug/test startup option onlyNo validation logic change; only cache lookup/store paths are bypassed
This commit fixes a cache-key collision bug in Elements' proof verification caches. Previously, the cache key for range proofs and surjection proofs was built by simply concatenating raw bytes, so two different sets of inputs could acciden…
Cache-key collision in proof verification cache could allow bypass of cryptographic verificationRaw concatenation of variable-length fields in cache-key constructionMissing input (vTags) in surjection-proof cache key
This update fixes several ways that malformed transaction data could crash Elements nodes or trick wallet users into signing bad transactions. The main changes turn internal 'assert' crashes into proper error returns when creating confiden…
assert-to-error conversion in rangeproof generationPSBT explicit output data now required before signing blinded outputspeg-in witness stack length and deserialization hardening
This merge commit fixes several security and robustness bugs in Elements' confidential-transaction blinding code and in its dynamic-federated (dynafed) header handling. The most user-visible issues are in 'blindpsbt': malformed PSET inputs…
Replacement of assertion failures with recoverable error returns in attacker-influenced PSET blinding pathsOut-of-bounds read prevention by requiring 33-byte Pedersen commitments before passing buffers to libsecp256k1Range-proof equality verification now checks both min and max bounds, closing a proof-forgery window
This commit only updates test scripts to fix flaky automated tests. It changes how test code calculates expected pegin subsidy values and how test nodes bind to network ports when using Bitcoin Core as a parent chain. No production node co…
No changes to production source codeChanges limited to test/functional/ Python test scriptsTest assertion hardening: dynamic subsidy computation instead of hardcoded constants
This commit hardens how Elements handles 'peg-in' transactions—transfers of assets from a parent blockchain into a sidechain. It adds size checks for witness data fields and wraps decoding in error handling so malformed inputs are rejected…
Out-of-bounds array access fixed in PSBT peg-in setupMissing length validation added for pegin witness stack elementsException handling added around deserialization of pegin witness components
This commit fixes a security bug in how the Elements wallet signs partially-signed Bitcoin transactions (PSBTs) for confidential (blinded) payments. Previously, a malicious counterparty could remove the plain-text amount and asset fields f…
Missing input validation on attacker-controlled PSBT dataBlinding proof verification relied on explicit fields that could be omitted by a counterpartyAssertions replaced with safe error returns for off-host data
This commit fixes a crash bug in the Elements blockchain wallet software. When creating a confidential (blinded) transaction, the code could hit an internal 'assert' and abort the program if it tried to generate a rangeproof for a zero-amo…
Removal of assert() on cryptographic operation result in transaction blinding codeConversion of abort-on-failure into error-return for rangeproof generation failuresNew explicit validation rejecting zero-amount spendable outputs in PSBT blinding
This commit fixes a denial-of-service bug in Elements' confidential asset handling. Previously, a malformed transaction file (PSET) could trigger a hard program crash (assert/abort) by feeding in mismatched cryptographic tags. The patch tu…
assert-to-error conversiondenial-of-service vector from untrusted PSET inputsurjection proof failure on attacker-chosen tags/generators
This commit fixes a crash/undefined-behavior bug in the Elements wallet's confidential-transaction blinding code. When processing a specially crafted Partially Signed Elements Transaction (PSET), the software would blindly use an output am…
Undefined behavior from dereferencing a disengaged std::optionalMissing input validation on optional PSET fieldPotential denial-of-service/crash via crafted PSET
This commit fixes a bug in how Elements nodes temporarily store block headers during initial sync. The node was stripping out Elements-specific fields (block height, proof, dynamic federation parameters, and signblock witness) when compres…
Header integrity loss in sync path: reconstructed header hash would not match received headerLoss of proof and signblock witness data needed for signed/dynafed validationPotential denial-of-service via sync failure or validation rejection of otherwise valid headers
This commit fixes a bug in how Elements verifies confidential transaction value proofs. Previously, the software only checked the lower bound of a mathematical range proof against the amount shown in a transaction. That meant a proof could…
Understated output values in PSET blind value proofsIncomplete range-proof bound verificationConfidential transaction amount mismatch risk
This patch fixes a bug in the Elements blockchain where dynamic-federation (dynafed) block headers could contain an incorrect block height and still be accepted, and where stored header records could be rebuilt with a different hash than t…
Header hash mismatch between accepted and reconstructed dynafed headers when legacy option disabledMissing height validation for dynafed headers when -con_blockheightinheader option is offPotential for accepting dynafed headers with incorrect block_height
This commit fixes a crash bug in Elements' confidential-transaction blinding code for PSBTs (Partially Signed Bitcoin Transactions). A malformed, attacker-chosen 'blinding public key' that is not actually a valid point on the cryptographic…
Off-curve / invalid elliptic-curve public key reaches ECDHAssertion abort (DoS / process termination) via crafted inputMissing input validation in PSBT blinding path compared to non-PSBT path
This commit fixes a voting threshold bug in Elements' dynamic federation (dynafed) feature. The code was supposed to require at least 80% (four-fifths) of recent blocks to approve a change to federation parameters, but due to integer divis…
Consensus threshold under-approximation due to integer floor divisionPotential for dynafed parameter transition with less than intended 80% block approvalOverflow-safe ceiling formula used as remediation
This commit fixes a bug in the way confidential transaction value proofs are validated. Previously, the code accepted an explicit 9-byte value or an empty field where a 33-byte cryptographic commitment was expected. It then passed that sho…
Out-of-bounds read in cryptographic proof verificationInsufficient input validation before passing buffer to libsecp256k1Confidential value/asset commitment type confusion
This commit only adds a new test to the project's test suite. It checks that the wallet's default signing behavior correctly includes (or excludes) a special 'rangeproof' flag depending on whether a network upgrade called 'dynafed' is acti…
Adds functional test coverage for SIGHASH_RANGEPROOF default behaviorVerifies pre-dynafed wallet default does not set SIGHASH_RANGEPROOF bitNo modification to signing, consensus, or mempool code
This commit changes the Elements wallet so that, when a newer consensus feature called 'DynaFed' is active, any transaction the wallet signs without an explicit signature mode will automatically include the transaction's confidential outpu…
Fixes a known malleability vector: pre-Taproot rangeproof/witness malleabilityChanges wallet default sighash only when dynafed is activeDoes not override explicit user sighash choices
This commit changes how the Elements blockchain software creates and checks digital signatures for raw transactions. Once a network upgrade called 'dynafed' is active, the software now defaults to a signature type that also commits to conf…
New consensus-relevant sighash default gated by dynafed activationVerification flag added to accept previously rejected signature typeRaw transaction signing behavior change for RPC callers
target is **master** branch, cherry-picked commits from #1600
Switch the range-proof and surjection-proof cache hashers from raw CSHA256 concatenation to CHashWriter . This length-prefixes every field, so distinct argument tuples with byte-identical raw concatenations no longer collide to the same cache key.
Both caches retain per-process salted midstates with distinct domain separators ('r' / 's').
Also adds a -norangeproofcache startup option to disable the range proof cache without recompiling.
ACKs for top commit: tomt1664: ACK 53167b1f452f9cdf96b1ec4af7fed613ba772c95 tested locally
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification✓ Links an issue, advisory, or supporting reference
Why it was queued
defensive validationconsensus or confidential-proof validationmerge-commit duplicate discount
AI analysis · Moderate 64/100
This commit fixes a cache-key collision bug in Elements' range-proof and surjection-proof validation caches. Previously, the cache key was built by simply concatenating raw bytes, so two different sets of inputs could accidentally produce the same key. If that happened, a node might skip verification and accept a proof it had never actually checked. The patch switches to length-prefixed hashing so distinct inputs always get distinct keys, adds the missing vTags data to the surjection-proof key, and adds a startup option to disable the range-proof cache. It also adds unit tests to prevent regressions.
init: add -norangeproofcache startup option to disable range proof cache
Add -norangeproofcache startup option. InitRangeproofCache() early-returns (allocating nothing) when the flag is set. VerifyRangeProof reads the flag on each call and bypasses both the Get and Set paths, so cache behaviour is fully skipped without restarting.
(cherry picked from commit 19d704279b3197af16ac52d910a915225505fe61)
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Why it was queued
consensus or confidential-proof validation
AI analysis · Informational 18/100
This commit adds a new command-line option `-norangeproofcache` that lets node operators turn off an internal performance cache used when validating confidential transaction range proofs. It is a debug/test option, not a security fix. There is no evidence in the commit or supplied references that this change addresses a vulnerability or that disabling the cache is security-relevant.
sigcache: harden proof cache keys with length-prefixed hashing
Switch range-proof and surjection-proof cache hashers from raw CSHA256 concatenation to CHashWriter (SER_GETHASH). This serializes each field with a length prefix, so distinct argument tuples with byte-identical raw concatenations no longer collide to the same cache key.
A cache entry is a positive verification result; a collision would let an attacker bypass verification. The fix affects two caches:
Both caches retain the per-process 64-byte salted midstate (nonce || PADDING_RANGE_PROOF / PADDING_SURJECTION_PROOF) for domain separation between the two proof types.
Expose thin test-only hooks (TestComputeEntryRangeProof / TestComputeEntrySurjectionProof) so unit tests can reach the anonymous-namespace cache internals.
(cherry picked from commit 94000967f6dc05b1afd435e79b1bbc597e29f816)
83/100 · StrongMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification
Why it was queued
explicit security languagedefensive validationconsensus or confidential-proof validation
AI analysis · Moderate 68/100
This commit fixes a cache-key collision bug in Elements' proof verification caches. Previously, the cache key for range proofs and surjection proofs was built by simply concatenating raw bytes, so two different sets of inputs could accidentally produce the same key. Because a cache hit means 'this proof was already verified, skip checking it again,' an attacker who could trigger such a collision could potentially make the node accept an invalid proof. The fix switches to length-prefixed serialization so distinct inputs can no longer collide, and also adds a missing input (vTags) to the surjection-proof cache key. The commit message explicitly calls this a hardening fix against verification bypass.
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode✓ Mentions testing or verification✓ Links an issue, advisory, or supporting reference
Why it was queued
signing boundaryconsensus or confidential-proof validationsigning or wallet pathmerge-commit duplicate discount
AI analysis · Moderate 59/100
This update fixes several ways that malformed transaction data could crash Elements nodes or trick wallet users into signing bad transactions. The main changes turn internal 'assert' crashes into proper error returns when creating confidential range proofs, add checks for missing or tampered PSBT output data, reject peg-in witness data that is the wrong size or badly encoded, enforce that peg-out outputs must not hide their asset type, and prevent a bad federation script from causing an assertion failure. One change also adds a startup warning about a known limitation with signed-blocks parent chains.
c26d719c29a40da280a825b25657e9c3d8bc7d99 fix: range proof cache bind to asset and scriptpubkey (Byron Hambly) b0aba619b6ff2846617b285274a954e0404137f5 blindpsbt: return error instead of asserting on surjection proof failure (Byron Hambly) f634a3a4635550b881d3db3376c42d614ea1d9b4 blindpsbt: reject off-curve blinding pubkey before ECDH (Byron Hambly) 066ecf6eb3bc54e6135d79864b969ac6ad84795e blindpsbt: refuse to blind a PSET output with no amount (Byron Hambly) fef1a30b62374d06e29bc8617dcf415c37993ffa headerssync: retain Elements identity and proof fields (Byron Hambly) bdedb12ee3996adab4959b63b51ccbe9575284bf dynafed: require at least four-fifths approval for parameter transition (Byron Hambly) c7ec63c58312c4581c763f02f4aa31ef608e12a8 validation: always validate and retain dynafed header block_height (Byron Hambly) 34be37f34d25fde692d6c5559ee0ca13b1c48654 blindpsbt: require both range bounds to match claim in VerifyBlindValueProof (Byron Hambly) 6f1a51310b85e8072e7ffe0983b515a86f397411 blindpsbt: require genuine commitments in VerifyBlindValueProof (Byron Hambly) a7a88214f740a23b49aec0a7b1125e03ac9227a4 blind: reject empty surjection-target set in SurjectOutput (Byron Hambly)
Pull request description:
Fixes a number of small issues picked up during LLM scans
ACKs for top commit: tomt1664: ACK c26d719c29a40da280a825b25657e9c3d8bc7d99 tested locally.
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification✓ Links an issue, advisory, or supporting reference
Why it was queued
signing boundarydefensive validationconsensus or confidential-proof validationsigning or wallet pathmerge-commit duplicate discount
AI analysis · High 72/100
This merge commit fixes several security and robustness bugs in Elements' confidential-transaction blinding code and in its dynamic-federated (dynafed) header handling. The most user-visible issues are in 'blindpsbt': malformed PSET inputs could previously crash the node (assertion failures), read memory out of bounds, or trick a verifier into accepting a wrong amount. Other changes stop a zero-input transaction from crashing during surjection-proof creation, make the range-proof cache depend on more data so it cannot return a wrong 'already verified' answer, and ensure dynafed block headers always carry and validate their height even when a legacy option is off. The pull request says the issues were 'picked up during LLM scans' and does not claim any are already exploited in the wild.
Merge ElementsProject/elements#1576: Fix intermittent failure in feature_pegin_subsidy.py
45fd28fca72b19fcc2db9d5fa013aee16febf75b test: fix fedpeg test to work with bitcoind parent (Byron Hambly) 22bb277474e10d02a2a30ad0d02ab03f59762b23 test: fix pegin subsidy test to work with bitcoind parent (Byron Hambly) c6692e16c724ce3854b9c34fb49c86e7a7d44ab5 Fix intermittent failure in feature_pegin_subsidy.py (Tom Trevethan)
Pull request description:
feature_pegin_subsidy.py has several assertions comparing the burn subsidy against hardcoded constants assumed fixed-length witness (t * 72 bytes per signature), but the actual subsidy is computed by the node from the parent-chain deposit transaction's real fee and vsize. DER-signature lengths on the parent-chain transaction vary by a byte or two causing a rare intermittent failure.
Replaced hardcoded subsidy values with a Python function that replicates `CheckPeginSubsidyAndMinimum`'s computation.
ACKs for top commit: delta1: ACK 45fd28fca72b19fcc2db9d5fa013aee16febf75b; tested locally
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification✓ Links an issue, advisory, or supporting reference✓ Names security-relevant behavior explicitly
Why it was queued
signing boundarymerge-commit duplicate discount
AI analysis · Informational 15/100
This commit only updates test scripts to fix flaky automated tests. It changes how test code calculates expected pegin subsidy values and how test nodes bind to network ports when using Bitcoin Core as a parent chain. No production node code is modified, so this does not create or fix any security vulnerability in the Elements software itself.
Security candidateReturn error for psbt if explicit amounts/assets deletedby Tom Trevethan · 3a8dec12 · Sep 1, 2026 · 3 filesMessage 50 · ThinHigh 72Details
Commit message · Tom Trevethan
Return error for psbt if explicit amounts/assets deleted
50/100 · ThinMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component! No meaningful explanatory body
Why it was queued
signing boundarysigning or wallet path
AI analysis · High 72/100
This commit fixes a security bug in how the Elements wallet signs partially-signed Bitcoin transactions (PSBTs) for confidential (blinded) payments. Previously, a malicious counterparty could remove the plain-text amount and asset fields from a transaction output before asking the wallet to sign. The wallet would then unblind the output and blindly trust whatever hidden value the counterparty had committed to, potentially allowing the wallet to sign away funds without knowing the real amount or asset type. The patch now refuses to sign if those explicit fields are missing, and replaces internal 'this can never happen' crash assertions with proper error returns, because the transaction data comes from outside the wallet.
Security candidateblindpsbt: require both range bounds to match claim in VerifyBlindValueProofby Byron Hambly · 34be37f3 · Sep 1, 2026 · 1 fileMessage 85 · StrongHigh 74Details
Commit message · Byron Hambly
blindpsbt: require both range bounds to match claim in VerifyBlindValueProof
A range-membership proof whose lower bound equalled the displayed PSET amount was accepted even when the committed value was larger, because only min_value was compared. Require both verified bounds to equal the claimed amount so a proof can no longer understate an output's value.
85/100 · StrongMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode
Why it was queued
signing boundarysigning or wallet path
AI analysis · High 74/100
This commit fixes a bug in how Elements verifies confidential transaction value proofs. Previously, the software only checked the lower bound of a mathematical range proof against the amount shown in a transaction. That meant a proof could truthfully prove the hidden amount was at least the displayed value, while the actual hidden amount was larger. This could let someone understate the value of an output in a partially-signed transaction (PSET). The fix now requires both the lower and upper bounds to equal the claimed amount, turning the range proof into a proper equality proof.
headerssync: retain Elements identity and proof fields
CompressedHeader kept only the Bitcoin PoW fields and GetFullHeader() reconstructed only those. In the low-work headers presync/redownload path Elements headers were therefore rebuilt without block_height, proof, dynafed params, or the signblock witness, so the reconstructed header's hash no longer matched what was received and the fields signed/dynafed validation needs were dropped.
Retain block_height, proof, m_dynafed_params, and m_signblock_witness in CompressedHeader and reconstruct them in GetFullHeader(). This enlarges the per-header redownload buffer footprint (previously assumed to be 48 bytes); the comment and static_assert are updated accordingly. No consensus rule changes: the reconstructed header now matches the header that was received.
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Why it was queued
consensus or confidential-proof validation
AI analysis · Moderate 63/100
This commit fixes a bug in how Elements nodes temporarily store block headers during initial sync. The node was stripping out Elements-specific fields (block height, proof, dynamic federation parameters, and signblock witness) when compressing headers for memory efficiency. When it later rebuilt the full header, those fields were missing, so the rebuilt header's hash no longer matched the original header that was received. This could cause sync failures or validation problems for Elements nodes, but it does not change any consensus rules.
Security candidatedynafed: require at least four-fifths approval for parameter transitionby Byron Hambly · bdedb12e · Sep 1, 2026 · 1 fileMessage 78 · AdequateModerate 60Details
Commit message · Byron Hambly
dynafed: require at least four-fifths approval for parameter transition
NextBlockIsParameterTransition computed the approval threshold as (epoch_length*4)/5, which floor-divides. For epoch lengths not divisible by 5 this is below the intended at-least-four-fifths rule, so a transition could pass with fewer than 80% of the epoch's blocks voting for it.
Use the overflow-safe ceiling N - N/5 (== ceil(N*4/5)). This is a no-op for epoch lengths divisible by 5 (the only currently deployed case) and only corrects the under-approximation for non-divisible epoch lengths.
78/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Names security-relevant behavior explicitly
Why it was queued
memory safety
AI analysis · Moderate 60/100
This commit fixes a voting threshold bug in Elements' dynamic federation (dynafed) feature. The code was supposed to require at least 80% (four-fifths) of recent blocks to approve a change to federation parameters, but due to integer division rounding down, it could approve changes with slightly less than 80% support when the voting epoch length was not evenly divisible by 5. The fix changes the math so the threshold is always rounded up to the next whole number, ensuring the true 80% requirement is met. Currently deployed systems use epoch lengths divisible by 5, so this is a no-op for them, but it corrects the behavior for other configurations.
validation: always validate and retain dynafed header block_height
A dynafed header always serializes block_height as part of its identity (CBlockHeader::Serialize/GetHash), independent of the legacy -con_blockheightinheader option. Previously the height was only validated in ContextualCheckBlockHeader and only reconstructed in CBlockIndex/CDiskBlockIndex::GetBlockHeader when that option was on, so a dynafed header with a mismatched height could be accepted, and a header rebuilt from an accepted index no longer matched the accepted header's hash when the option was off.
Validate and reconstruct block_height for all dynafed headers regardless of the option. Non-dynafed headers keep the legacy option behaviour. This does not change any consensus rule: the height was already part of every dynafed header's hash.
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Why it was queued
defensive validationconsensus or confidential-proof validation
AI analysis · Low 48/100
This patch fixes a bug in the Elements blockchain where dynamic-federation (dynafed) block headers could contain an incorrect block height and still be accepted, and where stored header records could be rebuilt with a different hash than the original accepted header. The fix ensures dynafed headers always validate and preserve their block height, even when an older compatibility option is turned off. It is a consistency and integrity fix rather than a change to consensus rules.
blindpsbt: require genuine commitments in VerifyBlindValueProof
An explicit 9-byte value (or a null field) passed the IsNull() check and its buffer was then parsed as a 33-byte Pedersen commitment, reading past the end. Require IsCommitment() on both the value and asset fields so the parser's length precondition holds and the out-of-bounds read is avoided.
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Why it was queued
signing boundarysigning or wallet path
AI analysis · Moderate 62/100
This commit fixes a bug in the way confidential transaction value proofs are validated. Previously, the code accepted an explicit 9-byte value or an empty field where a 33-byte cryptographic commitment was expected. It then passed that shorter buffer to a library that always reads 33 bytes, causing it to read past the end of the data. The fix now requires both the value and asset fields to be genuine 33-byte commitments before handing them to the parser, preventing an out-of-bounds read.
blindpsbt: return error instead of asserting on surjection proof failure
CreateAssetSurjectionProof asserted on secp256k1_surjectionproof_generate and _verify failure. A crafted PSET can supply unrelated tags/generators with no known discrete-log relationship, causing generation to fail and the assert to abort the process. Make these recoverable errors by returning false.
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Why it was queued
signing boundaryconsensus or confidential-proof validationsigning or wallet path
AI analysis · High 74/100
This commit fixes a denial-of-service bug in Elements' confidential asset handling. Previously, a malformed transaction file (PSET) could trigger a hard program crash (assert/abort) by feeding in mismatched cryptographic tags. The patch turns that crash into a normal, recoverable error so the process stays alive and simply rejects the bad input.
blindpsbt: reject off-curve blinding pubkey before ECDH
BlindPSBT passed the blinding pubkey straight to CKey::ECDH, whose only validation is an assert on the peer key, so a crafted off-curve pubkey (reaching IsBlinded() but failing IsFullyValid()) aborted the process. Mirror the non-PSET path and return BlindingStatus::INVALID_BLINDER when the pubkey is not fully valid.
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Why it was queued
signing boundarysigning or wallet path
AI analysis · Moderate 62/100
This commit fixes a crash bug in Elements' confidential-transaction blinding code for PSBTs (Partially Signed Bitcoin Transactions). A malformed, attacker-chosen 'blinding public key' that is not actually a valid point on the cryptographic curve could slip through earlier checks and reach a low-level ECDH key-exchange routine. That routine only had an internal assertion for validation, so the invalid key would trigger an assertion failure and abort the running process. The fix adds an explicit validity check and returns a controlled error instead of crashing.
Security candidateblindpsbt: refuse to blind a PSET output with no amountby Byron Hambly · 066ecf6e · Sep 1, 2026 · 1 fileMessage 73 · AdequateModerate 62Details
Commit message · Byron Hambly
blindpsbt: refuse to blind a PSET output with no amount
BlindPSBT dereferenced output.amount without a nullopt check. A crafted v0 PSET output (m_blinder_index set, amount absent) reached the blinding loop and dereferenced a disengaged std::optional, which is undefined behaviour. Refuse such outputs with BlindingStatus::INVALID_BLINDER.
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Why it was queued
signing boundarysigning or wallet path
AI analysis · Moderate 62/100
This commit fixes a crash/undefined-behavior bug in the Elements wallet's confidential-transaction blinding code. When processing a specially crafted Partially Signed Elements Transaction (PSET), the software would blindly use an output amount that might not exist, which can crash the program or cause unpredictable behavior. The fix now checks whether the amount is present and refuses to blind the output if it is missing.
Extend feature_sighash_rangeproof.py with a case asserting that the wallet's default sign path (no explicit sighash arg) produces signatures that commit to output rangeproofs once dynafed is active.
95/100 · StrongMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Uses a recognizable type or scope✓ Provides detailed explanatory context✓ Mentions testing or verification
Why it was queued
signing boundary
AI analysis · Informational 12/100
This commit only adds a new test to the project's test suite. It checks that the wallet's default signing behavior correctly includes (or excludes) a special 'rangeproof' flag depending on whether a network upgrade called 'dynafed' is active. There is no change to wallet, node, or consensus code—only a new automated test is introduced.
Security candidaterpc: default raw signing to rangeproof-committing sighash when dynafed activeby Byron Hambly · f5e2b1f5 · Aug 26, 2026 · 4 filesMessage 73 · AdequateLow 33Details
Commit message · Byron Hambly
rpc: default raw signing to rangeproof-committing sighash when dynafed active
Default the raw signing RPCs to commit to output rangeproofs when dynafed is active at the current tip. The SignTransaction util gains a sighash_rangeproof_active parameter and, when no sighash is supplied, resolves the default via DefaultSighashType. Wire this through signrawtransactionwithkey and descriptorprocesspsbt using DeploymentActiveAfter(DEPLOYMENT_DYNA_FED) for tip activation. Explicit user-supplied sighash types are left untouched.
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Why it was queued
signing boundarysigning or wallet path
AI analysis · Low 33/100
This commit changes how the Elements blockchain software creates and checks digital signatures for raw transactions. Once a network upgrade called 'dynafed' is active, the software now defaults to a signature type that also commits to confidential transaction rangeproofs. It also fixes verification so signatures using that new default are accepted instead of rejected. The change is a protocol-alignment fix; it does not appear to introduce a security vulnerability, but it prevents a functional break where valid wallet signatures would be considered invalid.
Security candidatewallet: default to rangeproof-committing sighash when dynafed activeby Byron Hambly · ce342f58 · Aug 26, 2026 · 3 filesMessage 73 · AdequateModerate 64Details
Commit message · Byron Hambly
wallet: default to rangeproof-committing sighash when dynafed active
Change the wallet's default pre-Taproot sighash to commit to output rangeproofs when dynafed is active at the current tip, closing the pre-Taproot rangeproof (witness) malleability gap. Route the default through DefaultSighashType(chain().isSighashRangeproofActive()) in CWallet::SignTransaction and in the signrawtransactionwithwallet / walletprocesspsbt RPCs when the caller does not supply a sighash. Explicit user-supplied sighash types are left untouched.
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Why it was queued
signing boundarysigning or wallet path
AI analysis · Moderate 64/100
This commit changes the Elements wallet so that, when a newer consensus feature called 'DynaFed' is active, any transaction the wallet signs without an explicit signature mode will automatically include the transaction's confidential output proofs ('rangeproofs') in the signature. Previously, those proofs could be changed by a third party after the transaction was signed, which could let someone mangle a transaction's witness data without invalidating the signature. The fix only changes the default behavior; users who explicitly pick a signature mode are unaffected.
Add a Chain interface method that reports whether SIGHASH_RANGEPROOF is active for signing at the current chain tip, mirroring the mempool standardness check (DeploymentActiveAfter for DEPLOYMENT_DYNA_FED). This is the live-tip gating source used by the wallet and wallet-backed RPC to decide the default pre-Taproot sighash.
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Why it was queued
signing boundary
AI analysis · Informational 17/100
This commit adds a small internal helper that lets the wallet ask the node whether a particular Elements feature (SIGHASH_RANGEPROOF) is active at the current chain tip. It is purely an exposure of existing chain-state information through a programming interface; it does not change consensus rules, transaction validation, or network behavior. There is no obvious security bug here.
Security candidatescript: add SIGHASH_ALL_WITH_RANGEPROOF and DefaultSighashType; strip rangeproof bit for Taproot signingby Byron Hambly · 6a531c26 · Aug 18, 2026 · 4 filesMessage 73 · AdequateLow 35Details
Commit message · Byron Hambly
script: add SIGHASH_ALL_WITH_RANGEPROOF and DefaultSighashType; strip rangeproof bit for Taproot signing
Add a named default constant SIGHASH_ALL_WITH_RANGEPROOF (SIGHASH_ALL | SIGHASH_RANGEPROOF) and a DefaultSighashType() helper that selects the default pre-Taproot sighash based on whether SIGHASH_RANGEPROOF is active for the target chain.
Strip the 0x40 (SIGHASH_RANGEPROOF) bit when computing Schnorr signatures, since the BIP341-style sighash always commits to rangeproofs and rejects the bit. This keeps SIGHASH_ALL_WITH_RANGEPROOF a valid universal default for both pre-Taproot and Taproot signing.
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Why it was queued
signing boundarysigning or wallet path
AI analysis · Low 35/100
This commit adds a new default signature mode for the Elements sidechain that includes 'rangeproof' data in signatures for older-style (pre-Taproot) transactions. It also makes sure that when Taproot/Schnorr signing is used, the extra rangeproof bit is stripped away because Taproot already commits to rangeproofs in a different way and would reject the bit. The change is defensive: it closes a 'rangeproof malleability gap' where transaction witnesses could potentially be altered without invalidating signatures, but only on chains where the relevant feature (dynafed) is active. It is not a fix for an active exploit, but a hardening/correctness improvement.
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification✓ Links an issue, advisory, or supporting reference✓ Names security-relevant behavior explicitly
Why it was queued
signing boundarycryptography-sensitive pathseed or entropy pathsigning or wallet pathboot or update pathauthentication pathparser or protocol path
AI analysis · Moderate 63/100
This commit is a large subtree update that pulls in many upstream secp256k1-zkp changes. The most security-relevant parts are fixes for two cryptographic proof modules used in Elements' confidential transactions: surjection proofs and range proofs. The commit message says the fixes prevent reusing random-looking proof values ('s-values' and nonces) across different proof statements, which is a known way cryptographic proofs can be forged or leak secrets. However, the actual code changes for those fixes are not shown in the supplied diff; only repository-wide metadata and build/CI file changes are visible. So while the topic is security-sensitive, we cannot directly verify the cryptographic details from the materials provided.
Security candidatefix: range proof cache bind to asset and scriptpubkeyby Byron Hambly · c26d719c · Aug 3, 2026 · 2 filesMessage 62 · AdequateCritical 87Details
Commit message · Byron Hambly
fix: range proof cache bind to asset and scriptpubkey
62/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Uses a recognizable type or scope! No meaningful explanatory body
Why it was queued
consensus or confidential-proof validation
AI analysis · Critical 87/100
This commit changes how Elements (the software behind the Liquid sidechain) remembers whether it has already checked a 'range proof'—a cryptographic receipt that helps keep transaction amounts private. Previously, the cache key was built only from the proof and the value commitment. The patch adds the asset commitment and the output's scriptPubKey to that key. An independent researcher argues that an earlier version of this same fix introduced a cache-key collision that was exploited to withdraw roughly 4,000 BTC from Liquid's federation wallet. The commit itself is a narrow code change; the exploit claim comes from outside analysis, not from the commit message or a vendor root-cause report.
✓ Subject identifies a change✓ Uses a recognizable type or scope! No meaningful explanatory body
Why it was queued
signing or wallet pathauthentication pathparser or protocol path
AI analysis · Informational 15/100
This commit is a routine cleanup titled 'Fix: linter errors'. It removes trailing whitespace, fixes typos in comments and strings, corrects indentation, removes unused include directives, and deletes a large number of stale test files under test/bitcoin_functional/functional. There is no functional code change that affects how the software behaves or processes untrusted data.
Bitcoin Core defaults to accepting any fee-bumping replacement regardless of signaling (full-RBF). Revert this for Elements: only replace mempool transactions that explicitly opt in via BIP125 nSequence signaling (or TRUC), and report fullrbf=false in getmempoolinfo.
Update feature_rbf.py accordingly, and add a regression test for CVE-2021-31876 confirming that inherited signaling from an unconfirmed parent does not make a non-signaling child replaceable.
91/100 · StrongMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification✓ Links an issue, advisory, or supporting reference
Why it was queued
explicit security languagefuzzing or regression evidence
AI analysis · Moderate 50/100
This commit changes how Elements' mempool handles transaction replacements. It disables 'full-RBF' (where any transaction can be replaced by a higher-fee version even without signaling) and requires explicit BIP125 opt-in signaling for replacements. It also adds a regression test for CVE-2021-31876, confirming that a transaction cannot be replaced just because one of its unconfirmed parents signaled replaceability. This is a defensive policy change to protect merchants and users who rely on first-seen mempool behavior from unexpected transaction replacements.
Security candidaterpc: fix fields type in man in 'decodepsbt'by Ruslan Kasheparov · ef1d2673 · Jun 24, 2026 · 1 fileMessage 45 · ThinInformational 15Details
Commit message · Ruslan Kasheparov
rpc: fix fields type in man in 'decodepsbt'
45/100 · ThinMessage clarity
✓ Descriptive subject✓ Names a concrete action or component! No meaningful explanatory body
Why it was queued
signing boundarysigning or wallet path
AI analysis · Informational 15/100
This commit corrects a documentation-only error in the help text for the 'decodepsbt' RPC command. The two fields 'inputs_modifiable' and 'outputs_modifiable' were incorrectly listed as numeric (NUM) types when they are actually boolean (BOOL) values. No code behavior changes, so there is no security impact.