Repository navigation
Harden sponge lifecycle, pattern encoding and secret-output storage #37
Description
Goal
Harden SAFE's lifecycle, IO-pattern encoding and secret-output storage while preserving valid encodings and native/circuit consumers. Track the implementation, compatibility evidence and resource tradeoffs together before merging or releasing it.
Assessed base: 57ff3f7f5db48a2bbbed59f5fb1020c5fc1844b9 (dusk-safe 0.3.0).
Confirmed problems
- Operation errors erase state but do not permanently invalidate progress. Direct callers can resume or successfully finalize after an error or explicit zeroization.
- Aggregated operation lengths can cross the 31-bit length field into the operation marker. Checking individual lengths or only full-u32 overflow is insufficient to preserve unique pattern encoding.
- Derived Debug includes state, buffered output and backend data.
- Growing a secret-bearing Vec can release its previous allocation without wiping it; continuing a clone must follow the same safe growth policy.
- Existing ciphertext-tampering tests also change the domain, so they do not isolate authentication rejection under the correct domain.
- Width zero can panic during construction; width one has no usable rate.
The reproductions establish library mechanics, not an authentication bypass, freed-memory extraction or deployed exploitability. Correct-domain tampering controls rejected all tested mutations.
Intended behavior and compatibility
- Any operation error or explicit zeroization permanently invalidates that instance; cloning a failed instance must preserve failure. An independent clone created before failure is not globally revoked.
- Reject unrepresentable aggregated runs with the existing
InvalidIOPattern, retaining both valid tag bytes and the original per-call pattern. - Reject widths below two before backend invocation and use metadata-only Debug.
- Grow output for actual squeeze demand: allocate replacement, copy, wipe old storage, then free it. Preserve amortized streaming growth, avoid unnecessary final-operation spare capacity, and handle continued clones without removing Clone.
- Output-growth allocation failure uses existing
InvalidIOPatternand makes failure terminal. Do not add an error variant that breaks downstream exhaustive conversions. - Guard encryption/decryption temporaries through late errors and unwinding. Returned output and backend-owned secrets retain their existing ownership/cleanup responsibilities.
- Document native constant-time requirements separately from circuit constraints; a circuit equality method can defer enforcement to proving/verification.
- No dependency, public function signature, protocol/version or valid wire-encoding change is intended. Invalid-use behavior, unsupported lengths/widths and Debug output intentionally change.
Resource and evidence limits
Do not eagerly reserve the full output declared by untrusted metadata. Callers still need memory/work budgets; only output-growth allocation failure is made recoverable. Other allocation failure, process abort, overcommit, compiler copies and backend-owned secrets are not solved by this change.
Replacement buffers temporarily coexist. Measured 4096-scalar encryption peak live heap fell about 33%; decryption was effectively unchanged (+32 bytes). Toy streaming peak remains higher than unhardened baseline. Performance must be checked with and without LTO: an initial ~47% single-element streaming slowdown was addressed, but shared-machine native timings do not establish a zero-overhead guarantee.
Acceptance
- Terminal-failure, clone, width and redacted-Debug behavior covered by durable regressions.
- Checked 31-bit aggregation and literal canonical-encoding controls, including operation transitions and boundary lengths.
- Correct-domain tampering coverage at rate boundaries; independently generated mechanics vectors clearly distinguished from production cryptographic KATs.
- Allocator-boundary wiping and injected late allocation-failure cleanup tests, including Miri.
- Debug/release, MSRV, no-default/encryption, prescribed quality/docs and bare-metal checks.
- Pinned Poseidon native/circuit, Phoenix, Merkle and Rusk-core compatibility checks using the candidate; representative baseline outputs unchanged.
- Performance/memory evidence for both release profiles, with limitations and less favorable observations retained.
- Issue-linked Unreleased notes and backend/resource documentation.
- Independent review and normal CI before merge; release/downstream rollout handled separately.
Draft implementation and local validation: #38. Acceptance remains open for review; passing local checks is not independent approval. This tracker is not a formal cryptographic audit or release authorization.
Activity
Enforce terminal sponge failure and bounded pattern encoding
Wipe secret output before growing its allocation
Enforce terminal sponge failure and bounded pattern encoding
Wipe secret output before growing its allocation
Enforce terminal sponge failure and bounded pattern encoding
Wipe secret output before growing its allocation
Enforce terminal sponge failure and bounded pattern encoding
Wipe secret output before growing its allocation
Harden sponge lifecycle, encoding and secret-output storage
Address sponge hardening review notes
HDauven commentedon Sep 11, 2026
The separate equality follow-up requested in moCello's review of #38 is tracked in #39. It covers the pre-existing
Sponge::PartialEqAPI and the compatibility decision for a breaking release; it is not part of #38 and remains open when this issue closes.