Skip to content

Reuse validated cryptographic facts during message and sigchain processing - #39

Draft
holmesworcester wants to merge 7 commits into
mainfrom
fix/ios-incremental-validation
Draft

holmesworcester wants to merge 7 commits into
mainfrom
fix/ios-incremental-validation

Conversation

@holmesworcester

@holmesworcester holmesworcester commented Sep 15, 2026

Copy link
Copy Markdown

Quiet revalidated the same lockbox key material for every message and repeated old graph cryptography when receiving a new sigchain edition. This change retains checked keys within each Team and reuses successful graph cryptographic facts for complete unchanged inputs. Ordinary message signatures and current action authorization are still checked.

Implementation

  • Each Team owns a private checked-key store. Imports copy, validate, and freeze complete keysets once; retained keys cannot be changed through caller-owned inputs. Explicit caller-owned key arguments are checked on each call.
  • Successful lockbox openings are bound to the complete encrypted delivery and checked recipient. Reconstructed copies can reuse those facts across graph replay and garbage collection. A known contents commitment alone cannot authenticate a new delivery.
  • Key selection follows the current state's lockboxes. Retaining key material does not grant access in a different branch or after access is removed. Only one selection view is retained. This replaces the global keyset, lockbox-opening, and key-map caches.
  • Reducer-owned lockboxes are snapshotted, and established commitments are indexed with an immutable radix trie.
  • Graph facts are bound to current ciphertext, signatures, resolved public keys, signed proof context, and decryption secrets. Cached plaintext is copied before returning it. Invitation and role decisions use current replay state. Facts stay attached to retained graph inputs, with bounded weak indexes and a fallback when WeakRef is unavailable.

Checked-key records last for the owning Team's lifetime; they are not serialized. A failed merge discards the store so valid prefixes of rejected graphs cannot accumulate retained keys; successful merges keep their records. Existing Team APIs and wire formats are unchanged. Standalone lockbox opening returns caller-owned key material. See the checked-key design notes.

Validation

  • 767 tests passed across auth, CRDX, crypto, and shared, with 87 existing skips. Production builds and lint of the changed TypeScript files passed.
  • The new message test decrypts 1,000 real role-encrypted messages after warm-up with zero lockbox openings, keypair revalidation, or key hashing, while verifying all 1,000 message signatures and rejecting tampering.
  • Tests cover complete delivery binding, mutable inputs, store and branch isolation, reconstructed collections without WeakRef, cycles, failed deliveries, serialized graph updates, and the retained role-removal transform (removal dispatch remains gated by protocol 4).
  • A separately generated sender plus forced-GC receiver check at 10 and 100 users verifies one new graph signature per received edition. The first edition opens four boxes, including initial local key import; the second opens one box with no keypair reconstruction. These are Linux Node 24 controls, not device benchmarks.
  • Daybreak Blue independently identified speculative key retention after rejected merges. The fix discards the store on rejection; regression tests cover repeated semantic and ciphertext failures, unchanged graph/state, and subsequent successful acceptance and reuse. Daybreak Blue reviewed the fix, reran 53 focused tests, and reported no remaining actionable findings.
  • One initial full run hit a removal-gate state-comparison failure during load; both its isolated rerun and the complete rerun passed.
  • The test-inclusive auth typecheck still has 37 pre-existing diagnostics, down from 39 at the preceding head, with no new diagnostics.

Graph traversal, hashing, filtering, and contextual replay remain proportional to history. Earlier integrated iPhone timings included a separate crypto adapter and are not performance measurements of this PR alone.

Integration

This PR changes auth only. Quiet needs a submodule pointer update to consume the latest commit; its channel index is separate. No native crypto implementation is included or required. The OpenSSL alternative is isolated in TryQuiet/quiet#3541, while native libsodium is being developed separately.

Part of TryQuiet/quiet#3536 and TryQuiet/quiet#3537; intended for TryQuiet/quiet#3539. Targets release/10.0.0.

Import immutable keysets into a private Team-owned store and retain successful delivery bindings across replay. Select keys only through the current state, keeping cryptographic material separate from authorization. Replace the global keyset, lockbox-opening, and key-map caches while preserving standalone validation and caller-owned open results.

Validate with 765 passing auth, CRDX, crypto, and shared tests (87 existing skips), production builds, scoped lint, and separate-sender forced-GC edition checks at 10 and 100 users. The test-inclusive auth typecheck has 37 existing diagnostics versus 39 at the baseline, with no new diagnostics.

Assisted-by: Codex
Discard the Team-owned checked-key store when decryption or merge validation fails, preventing rejected graph prefixes from retaining speculative keys for the Team lifetime. Preserve reuse after successful merges.

Add realistic repeated-rejection regressions for semantic and ciphertext failures, followed by acceptance and reuse of the valid prefix. Both regressions failed before the fix and pass afterward. Validation: 767 tests passed with 87 existing skips, auth production build and scoped lint passed, and the broad test-inclusive typecheck has the same 37 pre-existing diagnostics.

Assisted-by: Codex
@holmesworcester
holmesworcester changed the base branch from release/10.0.0 to main September 17, 2026 15:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant