Rewrite vault in Rust (format-compatible with 0.5) #1

Merged
andydixon merged 19 commits from rust-port into master 2026-10-08 18:38:32 +02:00
19 Commits
Author SHA1 Message Date
Andy DixonandClaude 06cf7355dc Optimised dev builds; idle-agent test measures only the agent
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 14:31:58 +01:00
Andy DixonandClaude 31dbdc7009 Benchmark results: Go 0.5 against Rust 0.6
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 14:15:30 +01:00
Andy DixonandClaude 0877cc7447 Parallel Argon2id lanes (unlock 180 ms -> 129 ms, Go 122 ms); AEAD throughput probe
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 13:13:25 +01:00
Andy DixonandClaude 438180b6fb Update fuzz lockfile
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 13:03:31 +01:00
Andy DixonandClaude 25496ddb97 Release matrix: Linux, Windows, macOS and FreeBSD
Drop android (same binary as linux/arm64), big-endian ppc64 (cannot be
verified: even hello-world crashes under qemu-ppc64 with the cross
toolchain), NetBSD (cross 0.2.5's sysroot lacks libexecinfo), illumos,
Solaris and WASI, as agreed. docs/PLATFORMS.md records each decision.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 12:40:30 +01:00
Andy DixonandClaude 7506c1dbef Clippy fixes
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 12:24:37 +01:00
Andy DixonandClaude 91d49aeecf Fix review findings: PAX sizes, agent stdin, PEM parity, sticky writer
- absorb uses the PAX-corrected entry size (large Go/bsdtar archives were
  stored truncated) and refuses GNU sparse entries
- the agent reads the key from fd 0 straight into locked memory, and never
  unlinks a live agent's socket
- the key file PEM parser is a port of Go's pem.Decode
- the STREAM writer fails permanently after a write error; plaintext is
  cleared on reader error paths; AEAD, HMAC and hash states are zeroized
- add/migrate refuse paths inside the vault; publish reports filesystems
  without an atomic no-replace primitive clearly and treats a leftover
  temporary name as a warning; Windows rejects NTFS-special names
- the leak test runs in its own process

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 12:23:27 +01:00
Andy DixonandClaude 25f50ed73b Network review fixes: confine mirror paths, bound rewrites, charge partial downloads
Mirror refuses local paths with ., .. or empty segments (decoded %2e%2e
could climb out of the mirror folder) and checks names stay under it;
dedupes found links and skips a page whose rewritten links would pass
four times the rewrite limit; charges bytes received before a failure to
the budget. add URL falls back to the host name for . and .. names.
Staged downloads are unlinked at creation on Unix and stored from the
open handle. Rewritten links are percent-escaped (./ before a colon), a
<base href> always points at the page itself, userinfo and proxy values
stay out of messages, ureq I/O errors are lower-cased, CGI detection
needs a non-empty REQUEST_METHOD and ::ffff:127.0.0.1 is loopback.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 12:16:50 +01:00
Andy DixonandClaude 53626a7de7 Crash and leak tests; platform matrix; ppc64 via cross; CI runs builds under qemu
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 11:56:41 +01:00
Andy DixonandClaude afdfbc5ebd Oracle README: exact provenance check and the full list of added test files
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 11:51:14 +01:00
Andy DixonandClaude 53968f8822 Docs for the Rust version; benchmarks; build.sh fixes
README, CLAUDE.md, man pages, the user guide and its screenshot script
now describe the Rust build and the intentional behaviour changes, which
docs/MIGRATION.md lists. Go and Rust micro-benchmarks for the same
operations, and scripts/bench.sh for end-to-end comparison. build.sh
exports its tree root to the per-target jobs and keeps logs out of the
output directory; riscv64 musl builds use getrandom's raw syscall
backend, since zig's musl getrandom never reaches the kernel there.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 11:50:55 +01:00
Andy DixonandClaude cddde5ca52 Cross builds, packaging split, CI, fuzzing, supply-chain policy
build.sh builds the Rust targets with the Go-era names, refuses an OUT
that is /, $HOME or the tree, checks static linking and names the Go
targets Rust cannot build. packaging/package.sh builds and inspects
packages without signing or publishing; repo.sh reuses it. Seven fuzz
targets (one found a URL-parser panic, fixed here with a regression
test), cargo-deny policy, CI for lint, tests on Linux/macOS/Windows,
cross builds with qemu runs, supply chain and fuzzing. Compatibility
specification and security notes.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 11:44:23 +01:00
Andy DixonandClaude a98931779a CLI, agent and absorb; stop tracking target/
Every Go command with the same flags, prompts and messages; the agent is
wire-compatible with Go's; tests drive the real Rust and Go binaries.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 10:36:20 +01:00
Andy DixonandClaude aedc605a82 Network import: bounded add URL and mirror
An explicit ureq client with platform TLS verification, connect/header/
request deadlines, manual bounded redirects, decoded-byte budgets and
Go-style proxy selection. A Go-compatible URL module checked against
oracle vectors, and a byte-preserving HTML tokenizer for link rewriting
(href/src/action/poster, <style> and style= url(), <base href>). Mirror
keeps to one host across redirects, bounds pages and bytes, refuses
local-name collisions and reports partial results.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 10:34:28 +01:00
Andy DixonandClaude 24ebede9bb Placeholder net module
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 10:24:34 +01:00
Andy DixonandClaude b97c690ef7 Fix ciphertext buffer preallocation precedence; clippy fixes
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 10:22:06 +01:00
Andy DixonandClaude a6610449f2 Store, validated types, bounded pipeline, no-clobber extraction
The store reads and writes the Go on-disk format (it opens the oracle's
fixture vault). Object I/O runs on one bounded worker pool with eight
reusable cleared buffers; sequential and parallel runs produce identical
bytes under seeded test randomness. Extraction publishes with
RENAME_NOREPLACE/link and only after full authentication; failed or
after-publish writes keep crash-safe ordering.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 10:21:44 +01:00
Andy DixonandClaude c324f6a306 Rust crypto core: FrodoKEM port, hybrid suite, Fury, STREAM, key files
FrodoKEM-640-SHAKE is ported from CIRCL v1.6.4 (the RustCrypto crate
implements the incompatible ISO variant) and reproduces the reference
NIST KAT digest. ML-KEM-768 comes from RustCrypto ml-kem. Derivation,
encapsulation, implicit rejection, KEK, header MAC, header parsing,
STREAM and Argon2id key files all match vectors from the Go oracle, Go's
files decrypt in Rust, and Go decrypts Rust's.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 10:12:53 +01:00
Andy DixonandClaude 69f4b90777 Freeze the Go implementation as a test-only oracle, with vectors
oracle/go is the Go code at 4c1507c, moved unchanged, plus test-only
generators that record what it computes. tests/vectors holds the
deterministic crypto/store vectors and synthetic fixtures they produce.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 09:55:17 +01:00