C·HIAVE

How it works — honestly

Chiave is the reference flow for Sign-In With Postern Wallet: the platform login is your own post-quantum wallet, not an email account. This page is one static file. It makes zero network requests — no CDN, no fonts, no APIs, no telemetry. Everything below happens inside this tab.

Your seed phrase — shown once, kept nowhere

Generated locally, displayed once for you to write down, then erased from the page. It is the only recovery: no email reset, no support recovery, ever. A forgotten passphrase is recoverable from the seed; a lost seed is permanent loss.

Your wallet at rest — ciphertext only

Sealed with AES-256-GCM under a key derived from your passphrase (PBKDF2-SHA-256, 310,000 it. — stand-in for Argon2id). localStorage holds only the ciphertext, the KDF salt, and your login public key — the same shape as the bloch-crypto encrypted keyfile. A wrong passphrase fails the GCM tag: all-or-nothing, no partial unlock.

Signing in — a local ceremony, run with RP discipline

Passphrase → KDF → decrypt → derive the m/login identity key (domain-separated from m/spend, so logging in never touches the funds key) → the verifier issues a challenge — a single-use random nonce with a 2-minute expiry, bound to this page's origin — the wallet signs its canonical bytes, and the session is granted only after the signature verifies against the enrolled public key. A captured challenge/signature pair can never be replayed, and a challenge minted for another origin never verifies here. No server is consulted because none exists; this page plays the RP role itself, and that verifier is the reference for the real login manager.

Biometrics — a gate, not a key

Optional WebAuthn platform authenticator (Touch ID / Windows Hello) with the PRF extension: the assertion releases key material that decrypts a second sealed copy of the wallet. The passphrase always remains; biometrics can never recover a lost seed. Panic Lock disables the biometric path — a coerced finger then opens nothing.

Stand-ins, labeled (the flow is the real thing; the primitives differ in a browser):

In this demoIn the product
Ed25519 (or ECDSA P-256) via WebCryptoHybrid Falcon-1024 ‖ ML-DSA-65 in the device TEE, non-exportable
PBKDF2-SHA-256, 310,000 iterationsArgon2id (256 MiB, t=4) — memory-hard, as in bloch-crypto
SHA-256 domain tags (postern:login:v1, postern:vault:v1)SHA3-256 domain tags — the bloch-crypto diversifier pattern
256-word demo wordlist, 24 words + checksum (184-bit entropy)BIP39 English, 2048 words, 24 words (256-bit) — SeedPhrase
WebAuthn platform authenticator + PRFStrongBox / Secure Enclave biometric-gated key release, enrollment-change invalidation
Stand-in keypair generated at setup, sealed alongside the seedML-DSA login anchor derived deterministically from the seed (stable fingerprint across restores); Falcon half re-enrolled and cross-signed

What we won't claim: a browser cannot guarantee memory zeroization or hardware key protection — that is exactly why the real product keeps the wallet key in the TEE and does this in Rust (zeroize). What this page does do: the signed-in session keeps only non-extractable WebCrypto handles, dropping the seed and private-key material as soon as those handles are derived, and re-asks for your passphrase if biometric enrollment later needs the secret again. And coercion of a passphrase is not solved by any login design: that is Panic Lock's job (postern-panic) — instant re-lock to ciphertext, nothing destroyed. Design of record: docs/specs/POSTERN-IDENTITY.md.

Confirm your passphrase

Enrolling biometrics needs the sealed wallet secret, which this session deliberately does not hold — it kept only the derived signing and vault handles. Your passphrase re-opens the seal once; the secret is used for enrollment and dropped again.