Skip to content

feat(session): add recipient and SPQR 1.6 parity - #38

Merged
intel352 merged 1 commit into
mainfrom
libsignal-v01040-protocol
Oct 3, 2026
Merged

intel352 merged 1 commit into
mainfrom
libsignal-v01040-protocol

Conversation

@intel352

@intel352 intel352 commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Add the pure-Go recipient pre-key API and upstream SPQR 1.6 behavior without changing wire schemas or existing protocol fixtures.

  • PreKeyDecryptStores / DecryptPreKey establish PQXDH sessions, resume current or archived sessions, enforce identity binding, and commit successful pre-key consumption in upstream order.
  • Authentication rejection preserves identity, pre-key, signed-pre-key, Kyber-use and session stores, including host stores that return aliased records. Write failures return no plaintext; cross-store transaction guarantees remain host-owned and are documented.
  • Fresh sessions require SPQR V1. Explicit legacy V0-negotiation states still work. Open higher-version negotiation derives epoch-zero keys; closed negotiation and below-minimum errors match upstream.
  • Genuine Rust generates/replays 36 cases covering negotiation, malformed preambles, chain seeds and low-byte minimum-version conversion. Both recipient modes prove upstream identity mismatch denial without store writes.

Locked Scope

Plan/design: GoCodeAlone/workspace/docs/plans/2026-07-10-signal-spaces-group-channels{,-design}.md; additive API: 2026-10-02-libsignal-v01040-upstream-audit.md.

PR Count: 34. Tasks: 41. Status: Locked 2026-10-03T08:47:45Z.

Group Title Task Branch
13 Port upstream protocol and SPQR parity 32 libsignal-v01040-protocol

Task 31 merged independently in #37. No tag here; Task 10 owns consolidated v0.8.0 release/provenance. Encrypted Spaces work remains deferred under ADR 0150, not completed.

Verification

  • Go 1.26.4: final full go test -race ./... -count=1, focused recipient/SPQR/oracle suites, go vet ./..., CGO_ENABLED=0 go build ./..., and golangci-lint run (0 issues).
  • Actual public recipient API is used by live Go/Rust interop, both roles and both optional-pre-key modes, repeated unacknowledged messages, out-of-order exchange and persistence. Final full interop race suite passes.
  • Recipient ciphertext fuzzing: 30 seconds, 19,356 executions, PASS. SPQR state fuzz smoke also passes.
  • Rust 1.98.1 compiler selected explicitly: release/locked/offline oracle replay, 4 tests PASS. SPQR commit 06959b4708f9b7b1e94d0f8cc835f3958c077e94; upstream libsignal 257105c55a7389ca6b1e85185e2769465e6729f1.
  • SPQR fixture SHA-256: 9d53c9cecf7f5a5c5a3dc868a8a6836a9d956a80f7173dee0a23f40a2193dc94.
  • Protocol .proto files and existing session/Sender Key/PQ fixtures are unchanged. External public API signature/store-field compile fixture passes.
  • Independent full code/security review: SHIP-IT, no Important/Critical findings; one stale package comment corrected without a new broad review cycle.

Regression proof with protections temporarily bypassed:

identity guard bypassed: current/archived identity mismatch tests FAIL (plaintext escaped)
whole-record clone bypassed: aliased archive denial test FAIL (record mutated)
old higher-version ignore behavior restored: four Rust oracle cases FAIL
V0 fresh floor restored: fresh PQXDH minimum-version test FAIL
all protections restored: focused suites and final full race suite PASS

The old fallback test now supplies an explicit legacy state; default V1 downgrade denial is tested separately. Nine malformed minimum-version cases ensure lint-safe conversion retains Rust's low-byte semantics rather than adding Go-only rejection rules.

Doc-reconciliation: clean. Current oracle/parity additions are distinguished from the inherited global proof-report baseline, which Task 10 updates.

Bind resumed pre-key sessions to their established identity and clone entire records before authentication. Require SPQR V1 for fresh sessions while retaining explicit legacy-state compatibility. Genuine Rust oracles guard negotiation and parser parity.
@intel352
intel352 merged commit b85d096 into main Oct 3, 2026
11 checks passed
@intel352
intel352 deleted the libsignal-v01040-protocol branch October 3, 2026 10:36
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