# Shade 4.0 — External Crypto Review Bundle This document is the entrypoint for an external cryptographic review of Shade 4.0. It collects, in one place, every artifact a reviewer needs to audit the protocol implementation **without** rooting around the codebase first. ## Tag under review - **Version:** `4.0.0` - **Tag:** `v4.0.0` - **Date:** 2026-05-03 - **Repo:** `https://gt.zyon.no/Stian/Shade` (mirror at the consumer-app repos that vendor this code) - **Out-of-scope:** Voice / Video / Broadcast — moved to V5.0 and reviewed separately. ## What's in scope Reviewers focus on the protocol-cryptographic core. Each scope cell maps to one or more packages plus the spec / threat-model section that describes its design. ### A — Protocol core (highest priority) | Surface | Spec | Code | |---------|------|------| | X3DH initial key agreement | [`docs/archive/V3.1.md`](../archive/V3.1.md), [`THREAT-MODEL.md` §1, §2](../../THREAT-MODEL.md) | [`packages/shade-core/src/x3dh.ts`](../../packages/shade-core/src/x3dh.ts) | | Double Ratchet | [`docs/archive/V3.1.md`](../archive/V3.1.md), [`THREAT-MODEL.md` §3](../../THREAT-MODEL.md) | [`packages/shade-core/src/ratchet.ts`](../../packages/shade-core/src/ratchet.ts) | | Sender keys (group ratchet) | [`docs/archive/V3.10.md` § Group send](../archive/V3.10.md) | [`packages/shade-core/src/sender-keys.ts`](../../packages/shade-core/src/sender-keys.ts) | | Wire envelopes `0x01`, `0x02`, `0x11` | [`packages/shade-proto/README.md`](../../packages/shade-proto/README.md) | [`packages/shade-proto/src/`](../../packages/shade-proto/src/) | | At-rest storage encryption | [`docs/storage-encryption.md`](../storage-encryption.md), [`THREAT-MODEL.md` §4](../../THREAT-MODEL.md) | [`packages/shade-storage-encrypted/src/`](../../packages/shade-storage-encrypted/src/) | | Social recovery (Shamir + AEAD-gated reconstruction) | [`docs/recovery.md`](../recovery.md), [`THREAT-MODEL.md` §8](../../THREAT-MODEL.md) | [`packages/shade-recovery/src/`](../../packages/shade-recovery/src/) | ### B — Trust + transport | Surface | Spec | Code | |---------|------|------| | WebRTC P2P transport binding | [`docs/webrtc.md`](../webrtc.md), [`THREAT-MODEL.md` §11](../../THREAT-MODEL.md) | [`packages/shade-transport-webrtc/src/`](../../packages/shade-transport-webrtc/src/) | | Key Transparency log + verifier | [`docs/key-transparency.md`](../key-transparency.md), [`docs/archive/V3.12-DESIGN.md`](../archive/V3.12-DESIGN.md), [`THREAT-MODEL.md` §2 (mitigated-by-V3.12)](../../THREAT-MODEL.md) | [`packages/shade-key-transparency/src/`](../../packages/shade-key-transparency/src/) | | Fingerprint gates | [`docs/trust-ux.md`](../trust-ux.md), [`THREAT-MODEL.md` §10](../../THREAT-MODEL.md) | [`packages/shade-sdk/src/fingerprint-gates.ts`](../../packages/shade-sdk/src/fingerprint-gates.ts) | ### C — Lower-priority surfaces | Surface | Spec | Code | |---------|------|------| | Inbox store-and-forward | [`docs/inbox.md`](../inbox.md), [`THREAT-MODEL.md` §6](../../THREAT-MODEL.md) | [`packages/shade-inbox-server/src/`](../../packages/shade-inbox-server/src/), [`packages/shade-inbox/src/`](../../packages/shade-inbox/src/) | | Bridge transports (SSE / long-poll / WS) | [`docs/transport.md`](../transport.md) | [`packages/shade-transport-bridge/src/`](../../packages/shade-transport-bridge/src/) | | Web Workers crypto | [`docs/web-workers.md`](../web-workers.md), [`THREAT-MODEL.md` §12](../../THREAT-MODEL.md) | [`packages/shade-crypto-web/src/worker*`](../../packages/shade-crypto-web/src/) | | Files RPC | [`docs/files.md`](../files.md) | [`packages/shade-files/src/`](../../packages/shade-files/src/) | | Streams (chunked AEAD over ratchet) | [`docs/streams.md`](../streams.md) | [`packages/shade-streams/src/`](../../packages/shade-streams/src/), [`packages/shade-transfer/src/`](../../packages/shade-transfer/src/) | | Observability | [`docs/observability.md`](../observability.md) | [`packages/shade-observability/src/`](../../packages/shade-observability/src/) | ## Threat model The full threat model is at [`THREAT-MODEL.md`](../../THREAT-MODEL.md). Every numbered "Mitigations" entry ends with a `[tests:]` footnote linking to the file(s) that holds the mitigation in place. Reviewers can re-run any individual test in isolation: ```bash bun test packages/shade-core/tests/ratchet.test.ts bun test packages/shade-streams/tests/aead.test.ts bun test packages/shade-key-transparency/tests/manager.test.ts ``` ## Cross-platform parity The wire format and KDF-label corpus are byte-identical between TS (bun) and Kotlin (gradle). The CI gate that enforces this lives at [`.gitea/workflows/cross-vectors.yml`](../../.gitea/workflows/cross-vectors.yml). Vectors are generated by [`scripts/generate-vectors.ts`](../../scripts/generate-vectors.ts); hand-edits to [`test-vectors/`](../../test-vectors/) are rejected by CI. ```bash # Re-run the cross-platform vector suite locally: bun run test:vectors cd android && ./gradlew :shade-android:test ``` ## Build instructions (reproducible) ```bash git clone https://gt.zyon.no/Stian/Shade cd Shade git checkout v4.0.0 bun install --frozen-lockfile # TS suite bun test # Kotlin / vector suite cd android && ./gradlew :shade-android:test ``` Container image (prekey + transfer + bridge + KT): ```bash docker pull gt.zyon.no/stian/shade-prekey:4.0.0 docker run --rm -p 3900:3900 \ -e SHADE_PREKEY_PG_URL=postgres://… \ gt.zyon.no/stian/shade-prekey:4.0.0 ``` The `Dockerfile` is at [`packages/shade-server/Dockerfile`](../../packages/shade-server/Dockerfile). Multi-stage; the runtime stage uses a non-root user. ## Assumptions and known limitations 1. The runtime is honest. A malicious Bun / browser engine can defeat any JS library; we ride the platform's `SubtleCrypto` / `@noble/curves` for primitives and trust them. 2. `THREAT-MODEL.md` section "Assumptions" is the canonical list; review the residual-risks table at the bottom of the same file for intentional gaps. 3. We do **not** claim resistance to power-analysis or fault-injection side channels. 4. Memory zeroization is best-effort. V8 / JSC may retain freed buffers; we zero what we can synchronously reach. ## How to report findings - **Severity-prioritized** (CVSS 3.1 if you can, otherwise plain language). - **Reproducer in repo style** — a failing `bun test` is preferred over prose. - **Email** the maintainer (`Sterister@live.no`); see [`SECURITY.md`](../../SECURITY.md) for PGP / age key arrangement. ## Timeline The 4.0 audit window is open immediately after tag. We aim for a 4–8-week review cycle (see V4.0 plan). Any **critical** or **high** severity finding pauses the GA-stable announcement until the fix ships. Findings ship as `4.0.x` patch releases — wire-format unchanged. ## Out-of-scope (deferred to V5.0) - Voice (`@shade/voice`) — SFrame-style frame keys, key-rotation policies. - Video (`@shade/video`) — codec edges (AV1/VP9/H.264). - Broadcast (`@shade/broadcast`) — relay-helper threat model. These will get their own review window when V5.0 is ready.