What changed, and why it matters
This commit lowers the maximum number of Zcash transactions that can be processed in one batch from 40 to 35. It is a small, defensive adjustment to keep memory usage within safe limits on the hardware wallet. There is no direct evidence in the commit that this fixes an active security bug or vulnerability; it appears to be a precautionary resource-limit change.
Treat as a routine hardening change. If Keystone publishes an advisory or explains why 40 was unsafe, re-evaluate. Otherwise, no urgent action is required beyond normal review and regression testing of Zcash batch signing.
Security signals we found
Resource limit reduction (batch count cap lowered)
Memory safety margin adjustment for shared device memory
Atomic batch signing behavior preserved
Evidence from the diff
The change reduces the ZCASH_BATCH_MAX_PCZTS constant from 40 to 35 in the cypherpunk firmware build and updates the matching documentation and unit test. The test is adjusted so it still exercises the limit check by declaring one more PCZT than allowed (now 36 instead of 41). The 512 KiB total batch size cap and atomic-all-or-nothing behavior remain unchanged. The commit message gives no security rationale and no external references are provided.
Changed components
rust/rust_c/src/zcash/mod.rsdocs/protocols/ur_registrys/zcash.mdInspect captured patch +3 / −3
diff --git a/docs/protocols/ur_registrys/zcash.md b/docs/protocols/ur_registrys/zcash.md
index eb2e821..0812fea 100644
--- a/docs/protocols/ur_registrys/zcash.md
+++ b/docs/protocols/ur_registrys/zcash.md
@@ -63,7 +63,7 @@ carries the PCZT-owned response in its own opaque `data` field. It also reports
the signing firmware version once for the entire response.
Batch version 1 is supported by cypherpunk firmware and currently accepts up to
-40 PCZTs. The encoded batch data and request id together, and the canonical PCZT
+35 PCZTs. The encoded batch data and request id together, and the canonical PCZT
payloads after decoding, must each fit within 512 KiB. The operation is atomic.
If any PCZT is invalid or cannot be signed, Keystone returns an error instead of
a partial result. PCZT entries with identical canonical encodings are rejected.
diff --git a/rust/rust_c/src/zcash/mod.rs b/rust/rust_c/src/zcash/mod.rs
index a1948b5..0e8ccc2 100644
--- a/rust/rust_c/src/zcash/mod.rs
+++ b/rust/rust_c/src/zcash/mod.rs
@@ -40,7 +40,7 @@ use zeroize::Zeroize;
// Cap both per-PCZT overhead and variable-size payload data to leave headroom
// in shared device memory while processing a batch.
#[cfg(feature = "cypherpunk")]
-const ZCASH_BATCH_MAX_PCZTS: usize = 40;
+const ZCASH_BATCH_MAX_PCZTS: usize = 35;
#[cfg(feature = "cypherpunk")]
const ZCASH_BATCH_MAX_TOTAL_BYTES: usize = 512 * 1024;
#[cfg(feature = "cypherpunk")]
@@ -1061,7 +1061,7 @@ mod tests {
overlong_small_count.push(0);
validate_zcash_batch_request_count(&overlong_small_count).unwrap();
- // The body declares 41 PCZTs but omits them. Reaching the count error
+ // The body declares 36 PCZTs but omits them. Reaching the count error
// proves the limit is enforced before the full request is parsed.
request[ZCASH_BATCH_REQUEST_HEADER_LEN] += 1;
let registry = ZcashSignBatch::new(vec![0xaa], request);
Why this scored 27/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.