v0.2.5-pre.004

This commit is contained in:
2026-08-19 11:29:05 +02:00
parent d5536b0778
commit 6c1172efc3
17 changed files with 859 additions and 27 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: docs/formats/000-README.md -->
<!-- version: 1 -->
<!-- version: 2 -->
# Formats KSP
@@ -9,4 +9,4 @@ Une spécification de format décrit le wire exact, les encodages, les limites,
## Formats actifs
- [`KSPWALLET_V1.md`](KSPWALLET_V1.md) — spécification du format natif autonome `.kspwallet` V1. `0.2.5-pre.003` fige son enveloppe JSON stricte, ses limites structurelles, ses key slots, son transcript OWNER et ses AAD ; les paramètres de création KDF/crypto effectifs et les vecteurs cryptographiques complets sont consolidés par les prereleases Wallet suivantes.
- [`KSPWALLET_V1.md`](KSPWALLET_V1.md) — spécification du format natif autonome `.kspwallet` V1. `0.2.5-pre.003` fige son enveloppe JSON stricte, ses limites structurelles, ses key slots, son transcript OWNER et ses AAD ; `0.2.5-pre.004` ajoute Argon2id/XChaCha20-Poly1305/CSPRNG OS, le wrapping de content keys et le premier vecteur crypto déterministe. Le default Argon2 de création reste volontairement en attente du benchmark opérateur livré par cette tranche.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/formats/KSPWALLET_V1.md -->
<!-- version: 1 -->
<!-- version: 2 -->
# `.kspwallet` V1 — spécification du format natif Wallet KSP
@@ -20,7 +20,7 @@ AAD des compartiments owner-control / metadata / secret
règles unknown-field / unknown-version
```
Les prereleases suivantes complètent les paramètres de création Argon2id benchmarkés, les opérations cryptographiques, les payloads plaintext exacts et les vecteurs cryptographiques complets. Toute évolution qui modifie un élément déjà déclaré **figé** par cette spécification exige une évolution explicitement tracée avant la release stable ; après publication de V1, une incompatibilité de wire exige un nouveau `format_version`.
`0.2.5-pre.004` complète maintenant les primitives KDF/AEAD normatives et un premier vecteur cryptographique public. Le **default de création Argon2id** reste volontairement non normatif tant que le benchmark opérateur de `pre.004` n'a pas été exécuté. Les prereleases suivantes complètent les payloads plaintext exacts, l'autorité Ed25519, les opérations create/open et les vecteurs de wallet complets. Toute évolution qui modifie un élément déjà déclaré **figé** par cette spécification exige une évolution explicitement tracée avant la release stable ; après publication de V1, une incompatibilité de wire exige un nouveau `format_version`.
Le but final est qu'une implémentation indépendante en Rust, Python, Go, C/C++, Java ou autre puisse créer, parser, vérifier et ouvrir un `.kspwallet` sans lire le code source de `ksp-wallet-lib`.
@@ -219,6 +219,7 @@ Bornes structurelles de parsing :
memory_kib : 1 .. 1 048 576
iterations : 1 .. 64
parallelism : 1 .. 64
memory_kib >= 8 * parallelism
salt : 16 .. 64 octets
```
@@ -602,16 +603,85 @@ AAD exacts
round-trip du codec
```
Les vecteurs cryptographiques publics complets avec passwords et secret test-only connus sont ajoutés après implémentation KDF/AEAD/wrapping/signature.
Le premier vecteur cryptographique public KDF+wrapping est ajouté par `pre.004`. Les vecteurs de wallet complets incluant payloads et state signature sont ajoutés après implémentation des compartiments et de l'autorité OWNER.
## 19. Invariants encore à compléter sans modifier le wire figé
Les tranches suivantes doivent compléter :
```text
pre.004 : defaults Argon2 benchmarkés + implémentation KDF/AEAD/wrapping + vecteurs crypto
pre.004 : sélection finale du default Argon2 après benchmark opérateur (KDF/AEAD/wrapping/vecteur déjà implémentés)
pre.005 : payloads owner-control/metadata/secret + create/open VIEW/OWNER + state signature effective
pre.006+ : persistence/administration/signature/import-export selon le plan Wallet
```
Toute découverte imposant de modifier la grammaire, les tags, l'ordre transcript ou les domain separators définis dans ce document doit être traitée explicitement avant la publication stable, jamais masquée par une tolérance du parseur.
## 20. Primitives cryptographiques effectives depuis `pre.004`
### 20.1 Argon2id
La dérivation d'une key-encryption key (KEK) V1 utilise exactement :
```text
algorithm = Argon2id
version = 19 / 0x13
output = 32 octets
password = octets UTF-8 exacts fournis par le caller
salt = octets sérialisés dans le key slot
m_cost = memory_kib sérialisé
t_cost = iterations sérialisé
p_cost = parallelism sérialisé
pepper = aucun
secret Argon2 externe = aucun
```
Un password vide est rejeté. V1 limite l'entrée password à 1024 octets UTF-8. Le KDF est une opération CPU/mémoire coûteuse ; les futures API async create/open l'exécuteront hors du thread executor conformément au plan Wallet.
Le default de création n'est **pas** déterminé par les defaults de la crate RustCrypto. Le benchmark opérateur compare explicitement :
```text
64 MiB / 3 passes / 1 lane
128 MiB / 3 passes / 1 lane
256 MiB / 3 passes / 1 lane
```
Le profil retenu sera enregistré après mesure sur machine cible. Un wallet conserve toujours ses propres paramètres sérialisés, indépendamment des defaults futurs.
### 20.2 XChaCha20-Poly1305
V1 utilise une clé de **32 octets** et un nonce de **24 octets**. Le résultat `ciphertext` stocké est la sortie AEAD avec tag Poly1305 postfixé de 16 octets. Chaque chiffrement/wrapping de production reçoit un nonce neuf fourni par le CSPRNG OS. Les AAD sont les TLV domain-separated définis dans cette spécification ; ils ne sont ni secrets ni chiffrés.
Une erreur de déchiffrement/tag est exposée comme une erreur générique d'authentification Wallet et ne distingue pas ciphertext, key, nonce ou AAD incorrect.
### 20.3 CSPRNG
KSP utilise la source cryptographique du système d'exploitation via `getrandom`. V1 ne définit aucun PRNG, seed ou état aléatoire propriétaire KSP. La génération de content keys, salts et nonces de production doit échouer si le CSPRNG OS échoue.
### 20.4 Content keys et wrapping
Les content keys V1 manipulées par les primitives de `pre.004` sont des clés symétriques de 32 octets :
```text
OWNER password -> Argon2id -> KEK_OWNER -> XChaCha wrap -> K_owner_root
VIEW password -> Argon2id -> KEK_VIEW -> XChaCha wrap -> K_metadata
```
Les clés possédées en mémoire sont non-`Copy`, non-`Clone` par défaut, redacted en `Debug` et zeroized au `Drop`. Lors d'un unwrap, le plaintext intermédiaire est zeroized après copie dans le type secret possédé.
### 20.5 Vecteur interopérable `pre.004`
Le fichier public :
```text
crates/ksp-wallet-lib/tests/fixtures/kspwallet_v1_crypto_vectors.json
```
contient un password, un salt, une content key et un nonce **test-only publics**. Il fixe :
```text
Argon2id -> derived_key attendu
XChaCha20-Poly1305(derived_key, nonce, AAD, content_key) -> wrapped_key attendu
```
Le vecteur a été recalculé indépendamment de l'implémentation Rust avec Argon2id puis la construction XChaCha20-Poly1305 `HChaCha20 + ChaCha20-Poly1305 IETF`. Ces valeurs ne constituent jamais des secrets de production.