Skip to content

docs: fix README to reflect salted (forgery-resistant) key derivation#1

Draft
kryp2 wants to merge 1 commit into
mainfrom
agent/readme-salt-correctness
Draft

docs: fix README to reflect salted (forgery-resistant) key derivation#1
kryp2 wants to merge 1 commit into
mainfrom
agent/readme-salt-correctness

Conversation

@kryp2

@kryp2 kryp2 commented May 30, 2026

Copy link
Copy Markdown
Contributor

What

The top-level README.md described an older, saltless key-derivation model that the spec bodies have since moved away from. This PR brings the README in line with the normative specs (BEVISET v0.7.0, HELTENIG v0.5.0).

Three fixes

  1. Saltless -> salted derivation. The "Shared foundation" and "Quick reference" sections omitted the per-user 256-bit salt (the presentation key) and claimed "no server, no database, no trust required". Both specs derive keys from IKM = identity_input || salt and explicitly state identity alone is not sufficient (BEVISET §4.1, §4.4, §4.5; HELTENIG §5.1). The old saltless derive_key(identity_input, domain) snippet is reproducible by anyone who knows the low-entropy identity inputs (BankID PIDs ~5M combinations) — i.e. forgeable. The salt is precisely what the specs added in v0.6.0 to fix this.

  2. Wrong domain separators. The README's diagram listed beviset-v1-keygen, heltenig-v1-keygen, yourapp-v1-keygen, none of which appear in the specs. The canonical values are wab-keygen-beviset-v1, beviset-v1-keygen-emailphone, wab-keygen-heltenig-v1, heltenig-v1-keygen-emailphone (BEVISET §4.3, HELTENIG §5.2).

  3. Quick-reference snippet updated to take salt and build ikm = identity_input + salt, matching the normative algorithm, with a caveat that it is illustrative.

Scope

README-only. The normative spec bodies (BEVISET.md, HELTENIG.md) were already correct — this only fixes the landing-page summary that drifted behind them.

🤖 Generated with Claude Code

The README's "Shared foundation" and "Quick reference" described the
pre-v0.6.0, SALTLESS derivation model and stated "no server, no database,
no trust required" without the per-user salt. Both specs have since moved
to salted HKDF-SHA256 (BEVISET v0.7.0 §4, HELTENIG v0.5.0 §5): the IKM is
identity_input || salt, and identity alone is explicitly NOT sufficient to
derive a key. The old saltless snippet is reproducible by anyone who knows
the low-entropy identity inputs (BankID PIDs have ~5M combinations) — i.e.
forgeable, which is exactly what the salt fixes.

Also corrects the domain-separator chart: the README listed invented
separators ("beviset-v1-keygen", "heltenig-v1-keygen", "yourapp-v1-keygen")
that do not match the canonical values in BEVISET §4.3 / HELTENIG §5.2
("wab-keygen-beviset-v1", "beviset-v1-keygen-emailphone", etc.).

Changes are README-only; the normative spec bodies were already correct.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

2 participants