Skip to content

3.0 phase 1a: account cryptography (no app change) - #13

Merged
usermaneGermane merged 1 commit into
mainfrom
v3-crypto-core
Nov 8, 2026
Merged

usermaneGermane merged 1 commit into
mainfrom
v3-crypto-core

Conversation

@usermaneGermane

Copy link
Copy Markdown
Owner

3.0 phase 1a: account cryptography

The first piece of PassMan 3.0 (design: E:\CLAUDE\PassMan\DESIGN-3.0.md; owner answers 2026-11-08). It adds a pure module; nothing in the 2.x app calls it, so behaviour is unchanged and there's no version bump. Phase 1b (the local account screens, PMV3 files, importing a 2.x vault) builds on it.

account_crypto.py:

  • Argon2id (64 MiB, 3 passes, 1 lane; measured 0.12 s per unlock on the dev PC). The cost is stored in the file and capped against hostile headers. Uses cryptography ≥ 44, or argon2-cffi, which is Ubuntu's python3-argon2.
  • Secret Key: 128 bits shown as A3-XXXXX-XXXXX-XXXXX-XXXXXX-XXXXXX with a check character, so a typo reads as a typo rather than a wrong password.
  • Master password + Secret Key → HKDF → an Account Unlock Key and a separate Login Key for the server (the server learns nothing about the AUK). Passwords are NFKC-normalised, so the same password typed on Windows and Linux is one password.
  • Keyset sealed with AES-GCM; its header (KDF, cost, salt) is authenticated, so lowering the cost in a file breaks it.
  • Vault keys wrapped to members (X25519 sealed box), bound to vault id + member name. Fingerprints are 6 groups of 4 digits.
  • PMV3 vault container with an authenticated vault-id / key-generation header.
  • 12-word recovery phrase (BIP39; the official word list is embedded as bip39_words.py and its SHA-256 is checked). Unknown words are named with their position; swapped words are caught by the checksum.
  • Account lifecycle: create / unlock / recover / reseal with a new password, keeping every wrapped vault key valid.

Dependencies: cryptography>=44 (Windows), argon2-cffi in requirements-dev (so CI checks the two Argon2id libraries agree). Linux: python3-argon2 added to the .deb Depends and to requirements.txt; README updated.

Tests (tests/test_account_crypto.py, 51)

  • The RFC 9106 Argon2id vector, and 5 BIP39 reference vectors.
  • The two Argon2id libraries give identical keys (run locally with argon2-cffi; CI runs it from requirements-dev).
  • Typo handling, Unicode forms, tampered headers, absurd costs, wrong files, wrong member/vault, a 2.x vault not mistaken for PMV3, and end-to-end create → unlock → recover → new password.
  • Mutation-checked, 8/8 caught: an unauthenticated header, no cost limits, wraps ignoring the member, no vault-id check, no phrase checksum, no NFKC, Login Key = AUK, Secret Key unused.
  • Full suite: Windows 414 passed (+1 skip when argon2-cffi is absent); Linux 408 passed, 4 skipped.

🤖 Generated with Claude Code

https://claude.ai/code/session_011ojnyVg7ccsR3pZ64s7aRH

account_crypto.py holds the PassMan 3.0 key design (E:\CLAUDE\PassMan\
DESIGN-3.0.md): Argon2id (cryptography>=44, or argon2-cffi = Ubuntu's
python3-argon2) + a 128-bit Secret Key -> HKDF -> Account Unlock Key and a
separate Login Key; a keyset sealed with AES-GCM under an authenticated
header; X25519 sealed-box wrapping of vault keys bound to vault id + member;
fingerprints; the PMV3 vault container; the 12-word BIP39 recovery phrase
(official word list, hash-checked); create / unlock / recover / reseal.

Pure functions, no files, nothing in the 2.x app calls them, so 2.x
behaviour is unchanged and there is no version bump. Tests pin the RFC 9106
Argon2id vector and the BIP39 reference vectors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011ojnyVg7ccsR3pZ64s7aRH
@usermaneGermane
usermaneGermane merged commit 82e818e into main Nov 8, 2026
6 checks passed
@usermaneGermane
usermaneGermane deleted the v3-crypto-core branch November 8, 2026 21:53
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