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.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md -->
<!-- version: 48 -->
<!-- version: 49 -->
# Séquence des releases fonctionnelles KSP
@@ -412,6 +412,8 @@ La release doit fournir `docs/formats/KSPWALLET_V1.md` comme spécification sép
`0.2.5-pre.003` ouvre le format sans effectuer encore de cryptographie : `KspWalletEnvelopeV1` parse/serialize le JSON strict borné à 1 MiB, impose Base64url sans padding canonique, exactement un slot OWNER et un slot VIEW optionnel lié par `view_descriptor`, puis produit les octets déterministes du transcript OWNER et des AAD par TLV domain-separated. `docs/formats/KSPWALLET_V1.md` devient l'autorité indépendante du code pour ce wire figé. Les paramètres Argon2 de création, KDF/AEAD effectifs, payloads et vérification Ed25519 restent `pre.004+`.
`0.2.5-pre.004` matérialise les primitives cryptographiques in-memory sans encore créer/ouvrir un wallet complet : Argon2id version 19 dérive une KEK de 32 octets depuis le password et les paramètres sérialisés, XChaCha20-Poly1305 wrappe/déwrappe les content keys avec les AAD figés, `getrandom` fournit le CSPRNG OS et les buffers secrets possédés sont zeroized. Un vecteur public test-only fixe l'interop KDF+AEAD. Le profil Argon2 de création n'est pas inventé : trois candidats sont benchmarkables par un test `#[ignore]` et le gate `pre.005` attend le résultat opérateur avant de figer le default.
## `0.2.6` — Wallet Desk
Mission : valider Config composite + `.kspwallet` + transport HTTP dans une application Tauri mince.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md -->
<!-- version: 6 -->
<!-- version: 7 -->
# Plan `0.2.5` — Wallet foundation
@@ -392,9 +392,9 @@ Audit source notable : `solana-keypair 3.1.2` contient un bloc `unsafe` interne
| scrypt | `0.12.0` | alternative maintenue, non ajoutée |
| PBKDF2 | `0.13.0` | compatibilité/legacy seulement, non ajouté |
Les paramètres Argon2 de création seront benchmarkés sur les machines cibles. Ils ne sont pas copiés de bot3, d'un RFC ou d'un default de crate. Le fichier sérialise tous les paramètres nécessaires afin qu'un ancien wallet conserve son profil historique.
Les paramètres Argon2 de création sont benchmarkés sur les machines cibles. `pre.004` livre trois candidats explicites (64 MiB / 128 MiB / 256 MiB, trois passes, une lane) et un test opérateur ignoré par défaut ; **aucun candidat n'est déclaré default avant retour du benchmark opérateur**. Ils ne sont pas copiés de bot3, d'un RFC ou d'un default de crate. Le fichier sérialise tous les paramètres nécessaires afin qu'un ancien wallet conserve son profil historique.
Le parseur impose des **bornes maximales** avant de lancer le KDF, afin qu'un fichier hostile ne puisse demander arbitrairement mémoire/CPU. Les valeurs exactes de création et de rejet sont gelées en `pre.004` après benchmark.
Le parseur impose des **bornes maximales** avant de lancer le KDF, afin qu'un fichier hostile ne puisse demander arbitrairement mémoire/CPU. `pre.004` ajoute également l'invariant Argon2 `memory_kib >= 8 * parallelism` avant tout calcul coûteux. Les bornes structurelles restent indépendantes du default de création ; celui-ci est figé seulement après le benchmark opérateur de `pre.004`.
### 8.3 AEAD
@@ -1197,4 +1197,4 @@ Une future `format_version >= 2` pourra réétudier des facteurs/ancrages extern
## 26. Suite immédiate
`0.2.5-pre.003` fige désormais le codec JSON strict, les limites structurelles, `slot_id` 16 octets, le descripteur VIEW, les DTOs denveloppe/key slots, les TLV transcript/AAD et la première spécification `docs/formats/KSPWALLET_V1.md`. La fixture `kspwallet_v1_wire_only.json` est volontairement structurelle et non cryptographiquement valide. La suite immédiate devient `pre.004` : benchmark des defaults Argon2 puis KDF/AEAD/wrapping/CSPRNG effectifs et premiers vecteurs cryptographiques publics.
`0.2.5-pre.003` fige le codec JSON strict, les limites structurelles, `slot_id` 16 octets, le descripteur VIEW, les DTOs denveloppe/key slots, les TLV transcript/AAD et la première spécification `docs/formats/KSPWALLET_V1.md`. `0.2.5-pre.004` ajoute les primitives effectives Argon2id v19, XChaCha20-Poly1305, CSPRNG OS, wrapping de content keys, zeroization des clés possédées et un vecteur crypto public déterministe. La seule partie de `pre.004` qui reste volontairement à confirmer par lopérateur est le choix du **default de création Argon2**, via le benchmark candidat livré et ignoré par défaut. `pre.005` ne doit pas figer ce default sans ce résultat.