Commit Graph

4 Commits

Author SHA1 Message Date
11d1bb97a6 feat(crypto): hybrid X25519 + ML-KEM-768 KEM primitives (Phase 3)
The two halves of the harvest-now-decrypt-later defence (design.md §5.2),
each a standalone primitive; pqxdh combines them into a root key next.

- X25519 (x25519-dalek): secret/public keys, encode round-trip, diffie_hellman.
  Secrets seeded from getrandom directly (no rng-trait plumbing, wasm-clean).
- ML-KEM-768 (ml-kem 0.3.2, FIPS 203): keygen, encapsulate/decapsulate, key
  encode/parse via kem's KeyExport; system-RNG methods route through getrandom
  0.4 (wasm_js in browser).

Tests: X25519 DH agreement + encoding round-trip; ML-KEM encapsulate↔decapsulate
agreement, public-key round-trip, and the implicit-rejection property (a wrong
decapsulation key yields a different, non-erroring secret — so transcript
binding, not a decap error, is what authenticates). Compiles to wasm32.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UMbqdSzDP4F7Y9AdK5LXaV
2026-06-30 13:05:42 +03:00
2d1c5a06a6 feat(web): Vite/WASM boundary proof + browser-run crypto KATs (Phase 0 tail)
Closes the Phase-0 scaffold: buh-crypto now compiles to WebAssembly and the web
client exercises the whole crypto stack in the browser before any session code
depends on it.

buh-crypto:
- `wasm` feature gates a small wasm-bindgen FFI (src/ffi.rs): echo plus
  wire/aead/identity self-tests. `#![forbid(unsafe_code)]` is kept for the
  native core and relaxed only under `wasm` (bindgen's glue is the only unsafe).
- getrandom standardised on 0.4 (the version crypto-common under ml-dsa pulls)
  with the `wasm_js` backend selected via .cargo/config.toml for
  wasm32-unknown-unknown; chacha20poly1305 default features off to drop the old
  getrandom-0.2 path.
- tests/wasm.rs runs the wire / XChaCha20-Poly1305 / ML-DSA-65 KATs under
  wasm-bindgen-test — the deterministic-signature digest matches native
  byte-for-byte, so every primitive is now gated native AND wasm.

web/: Vite + React + SWC + TS app wired with vite-plugin-wasm +
vite-plugin-top-level-await over a `--target bundler` wasm-pack build. On load
it round-trips a Uint8Array through echo and runs the three KATs in-browser;
verified in Firefox — all four checks green, zero console errors. All crypto is
imported through src/lib/crypto/, never from the generated pkg/ directly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UMbqdSzDP4F7Y9AdK5LXaV
2026-06-30 12:59:28 +03:00
d175634001 feat(crypto): ML-DSA-65 identity + XChaCha20-Poly1305 AEAD (Phase 2)
The user IS their key (design.md §4): identity is an ML-DSA-65 (FIPS 204)
keypair, hedged/randomized signing by default with a deterministic variant for
reproducible vectors. Fixed-size encode/parse for the public key (1952B) and
signature (3309B), verify-on-failure that leaks only that it failed.

AEAD: nonce-explicit XChaCha20-Poly1305 sealing primitive — the caller owns the
nonce (the ratchet will), so seal() is pure and KAT-pinnable; random_nonce() for
the one-off media-key cases. AAD is the place to bind the wire prelude+flags.

Tests gate the primitives:
- AEAD: the published draft-arciszewski-xchacha-03 A.1 vector (ciphertext+tag
  byte-exact), plus tamper/ciphertext/tag/AAD-downgrade/wrong-key rejection.
- Identity: sign/verify round-trip, seed determinism, encode round-trip + length
  checks, and a regression KAT pinning the seed=0 public key and deterministic
  signature by SHA-256 digest (catches encoding / wasm divergence; upstream
  ml-dsa carries the NIST ACVP vectors).

Adds ml-dsa (getrandom feature → hedged signing), chacha20poly1305, getrandom
0.3, sha2, hkdf to the workspace; only buh-crypto links them — the node never
does. CryptoError unifies wire/aead/signature/parse failures.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UMbqdSzDP4F7Y9AdK5LXaV
2026-06-30 12:50:45 +03:00
5a19fc1ab2 feat: scaffold buh cargo workspace and pure layers
Establish the AGPL-3.0 cargo workspace per the org conventions, with the
crate layout for the anti-hub messenger: buh-entities (domain types/DTOs),
buh-crypto (client crypto core; compiles to WASM, never linked by the node),
and buh-core (business logic + MailboxRepo/BlobStore/SettlementBackend ports).

The settlement value types are deliberately chain- and money-free (design
§8.5); buh-core stays honestly thin, as a blind relay has little logic.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 12:29:02 +03:00