Sweeping rename across crates, CLI binary, WASM bindings, extension, docs,
and vault metadata paths. Git remote updated to relicario.git.
- crates/idfoto-{core,cli,wasm} -> crates/relicario-{core,cli,wasm}
- IdfotoError -> RelicarioError
- IDFOTO_IMAGE env var -> RELICARIO_IMAGE
- ~/.config/idfoto -> ~/.config/relicario
- .idfoto/ vault metadata dir -> .relicario/ (breaking; pre-release)
- Binary name idfoto -> relicario
- Extension wasm module idfoto_wasm -> relicario_wasm
- Storage key idfotoSettings -> relicarioSettings
- All doc filenames and content references updated
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3.1 KiB
3.1 KiB
CLAUDE.md — relicario
What is this
relicario is a git-backed, self-hostable password manager with a Rust core. Two-factor vault decryption: passphrase + a reference JPEG carrying a 256-bit secret embedded via DCT steganography. The server only ever sees opaque ciphertext.
Build and test
cargo build # build everything
cargo test # run all tests (unit + integration)
cargo test -p relicario-core # core library tests only
cargo run -- --help # CLI help
cargo run -- generate -l 32 # quick smoke test
Project structure
crates/
├── relicario-core/ # Platform-agnostic library (no filesystem, no git, no network)
│ ├── src/
│ │ ├── lib.rs # Re-exports public API
│ │ ├── error.rs # RelicarioError enum (thiserror)
│ │ ├── crypto.rs # Argon2id KDF + XChaCha20-Poly1305 encrypt/decrypt
│ │ ├── entry.rs # Entry, ManifestEntry, Manifest structs (serde)
│ │ ├── vault.rs # encrypt_entry, decrypt_entry, encrypt_manifest, decrypt_manifest
│ │ └── imgsecret.rs # DCT-based 256-bit secret embedding in JPEGs
│ └── tests/
│ └── integration.rs # Full-workflow and two-factor independence tests
└── relicario-cli/ # CLI binary
└── src/
└── main.rs # clap CLI: init, add, get, list, edit, rm, sync, generate, device
Key design decisions
- relicario-core is bytes-in/bytes-out. No filesystem, no network, no git operations. Makes it portable to WASM, Android, iOS.
- XChaCha20-Poly1305 over AES-GCM — 192-bit nonce eliminates collision risk, fast in WASM/ARM without AES-NI.
- Single master_key (no per-entry subkeys) — simpler, sufficient for family vault sizes.
- imgsecret uses central-embed DCT — embeds only in the middle 70% of the image (15% crumple zone for crop tolerance), with majority voting across 5-50 redundant copies.
- QUANT_STEP = 50.0 — higher than typical (25) to survive JPEG recompression down to Q85.
- Device ed25519 keys are separate from the KDF. Revoking a device doesn't require rotating the passphrase or reference image.
Crypto pipeline
passphrase (UTF-8 bytes) || image_secret (32 bytes from reference JPEG)
→ Argon2id(salt=vault_salt, m=64MiB, t=3, p=4)
→ master_key (32 bytes)
→ XChaCha20-Poly1305(nonce=random 24 bytes)
→ encrypted entry/manifest
Conventions
- Tests use fast Argon2id params (m=256, t=1, p=1) so they don't take forever.
- Test JPEGs are generated synthetically via
make_test_jpeg()— no binary test fixtures. - Entry IDs are random 8-char hex strings.
- Git history is preserved as an audit log — no squashing.
- The CLI shells out to
gitfor sync — no libgit2/gitoxide dependency.
Remote
Source code: ssh://git@git.adlee.work:2222/alee/relicario.git
Design spec
Full threat model, entropy analysis, and architecture: docs/superpowers/specs/2026-04-11-relicario-design.md
Roadmap
Next: WASM build + Chrome MV3 browser extension (Plan 2). Then mobile (Rust core compiles to ARM).