v0.2.6-pre.016

This commit is contained in:
2026-08-22 08:18:38 +02:00
parent 946d88322b
commit 92a2c4fff3
43 changed files with 2813 additions and 280 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: docs/formats/000-README.md -->
<!-- version: 6 -->
<!-- version: 7 -->
# Formats KSP
@@ -10,4 +10,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 l'enveloppe/wire et les transcripts/AAD, `pre.004` ajoute Argon2id/XChaCha20-Poly1305/CSPRNG OS, `pre.005` fixe les payloads plaintext, le profil de création KSP calibré, l'autorité Ed25519 OWNER et le vecteur complet, `pre.006``pre.008` matérialisent persistence/administration/transfert, `pre.009` ferme l'audit adversarial/interoperabilité/compliance et `pre.010` synchronise la documentation finale sans modifier le wire V1.
- [`KSPWALLET_V2.md`](KSPWALLET_V2.md) — wire binaire natif V2 introduit par `0.2.6-pre.015` : framing canonique KSP, IDs numériques, longueurs big-endian, aucun Base64/compression, domains/transcripts V2 distincts et politique `default != latest`.
- [`KSPWALLET_V2.md`](KSPWALLET_V2.md) — wire binaire natif V2 introduit par `0.2.6-pre.015` puis runtime multi-version matérialisé en `pre.016` : framing canonique KSP, IDs numériques, longueurs big-endian, aucun Base64/compression, domains/transcripts V2 distincts et politique `default != latest`.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/formats/KSPWALLET_V1.md -->
<!-- version: 12 -->
<!-- version: 13 -->
# `.kspwallet` V1 — spécification du format natif Wallet KSP
@@ -1043,7 +1043,6 @@ Limites explicitement conservées en V1 :
- la zeroization réduit les copies possédées mais ne constitue pas une preuve d'effacement physique de toute copie potentielle produite par le compilateur, l'OS ou le matériel ;
- aucune revendication de résistance side-channel supplémentaire au-delà des primitives et bibliothèques retenues.
## 26. Statut de clôture V1
À la publication stable `0.2.5`, cette spécification constitue la version normative V1 du format `.kspwallet`. Les guides d'utilisation KSP sont [`../../crates/ksp-wallet-lib/README.md`](../../crates/ksp-wallet-lib/README.md) et [`../../crates/ksp-wallet-lib/USAGE.md`](../../crates/ksp-wallet-lib/USAGE.md) ; ils ne remplacent pas le présent document comme autorité normative du wire.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/formats/KSPWALLET_V2.md -->
<!-- version: 1 -->
<!-- version: 2 -->
# `.kspwallet` V2 — spécification du wire binaire natif KSP
@@ -19,7 +19,7 @@ préserver les frontières cryptographiques Wallet
Le caractère binaire **n'ajoute aucune propriété cryptographique**. La confidentialité et l'authenticité continuent de dépendre d'Argon2id, XChaCha20-Poly1305 et Ed25519, jamais de l'absence de JSON.
`0.2.6-pre.015` fige la grammaire binaire, les identifiants numériques, les bornes structurelles et les transcripts/AAD V2. La création/ouverture/persistence V2, l'auto-détection V1/V2 et le basculement de l'API générique vers V2 sont matérialisés dans les tranches suivantes de `0.2.6`.
`0.2.6-pre.015` fige la grammaire binaire, les identifiants numériques, les bornes structurelles et les transcripts/AAD V2. `0.2.6-pre.016` matérialise la création/ouverture/persistence V2, l'auto-détection V1/V2, les APIs génériques/versionnées et le basculement de Wallet Desk vers la façade non versionnée.
V1 reste un format stable supporté. V2 ne réinterprète jamais un document V1 avec sa propre grammaire.
@@ -57,6 +57,30 @@ open_wallet_*_file_v3(...) -> exige V3 si V3 existe un jour
Le même principe s'applique aux opérations dont la version de fichier est pertinente, notamment inspection et import natif.
### 2.1 Surface matérialisée en `pre.016`
La politique ci-dessus est désormais du code, pas uniquement une cible documentaire :
```text
create_wallet(...) -> V2 default
create_wallet_v1(...) -> V1 forcé
create_wallet_v2(...) -> V2 forcé
create_wallet_file(...) -> V2 default
create_wallet_file_v1(...) -> V1 forcé
create_wallet_file_v2(...) -> V2 forcé
open_wallet_view/owner(...) -> détecte V1/V2
open_wallet_*_v1/_v2(...) -> exige exactement V1/V2
inspect_locked_wallet(...) -> détecte V1/V2
inspect_locked_wallet_v1/_v2 -> exige exactement V1/V2
import_wallet_transfer(...) -> crée le default V2
import_wallet_transfer_v1/_v2 -> force le format natif produit
```
`WalletOwner` et `WalletView` mémorisent le format natif authentifié. Les opérations d'administration et de rotation persistent dans ce même format ; aucune mutation ordinaire ne réalise de conversion V1/V2. `to_native_bytes()` sérialise le format courant, tandis que `to_json_bytes()` reste une compatibilité V1 et rejette V2.
## 3. Encodage général
Un document V2 est :
@@ -80,14 +104,14 @@ Une implémentation conforme doit vérifier les bornes **avant** toute allocatio
Le début de fichier est strictement :
| Ordre | Champ | Taille | Valeur / règle |
|------:|---------------------------|-----------------:|------------------------------------------------|
| 1 | `magic` | 9 | ASCII exact `KSPWALLET` |
| 2 | `format_version` | 2 | `0x0002` |
| 3 | `document_length` | 4 | longueur totale exacte du fichier |
| 4 | `flags` | 2 | bit 0 = VIEW activé ; tous les autres bits = 0 |
| 5 | `owner_auth_public_key` | 32 | clé publique Ed25519 OWNER |
| 6 | `view_descriptor.slot_id` | 16 conditionnels | présent uniquement si `flags & 0x0001 != 0` |
| Ordre | Champ | Taille | Valeur / règle |
|---:|---|---:|---|
| 1 | `magic` | 9 | ASCII exact `KSPWALLET` |
| 2 | `format_version` | 2 | `0x0002` |
| 3 | `document_length` | 4 | longueur totale exacte du fichier |
| 4 | `flags` | 2 | bit 0 = VIEW activé ; tous les autres bits = 0 |
| 5 | `owner_auth_public_key` | 32 | clé publique Ed25519 OWNER |
| 6 | `view_descriptor.slot_id` | 16 conditionnels | présent uniquement si `flags & 0x0001 != 0` |
Offsets fixes avant le descripteur conditionnel :
@@ -130,21 +154,21 @@ Aucun compteur de slots ou de compartiments n'est nécessaire : leur cardinalit
Chaque key slot est encodé ainsi :
| Champ | Taille | Valeur / règle |
|--------------------------|---------:|-----------------------------------------|
| `role` | 1 | `0x01` OWNER, `0x02` VIEW |
| `slot_id` | 16 | identifiant binaire exact |
| `kdf_algorithm` | 1 | `0x01` Argon2id |
| `kdf_version` | 4 | `19` |
| `memory_kib` | 4 | `1..1 048 576`, et `>= parallelism * 8` |
| `iterations` | 4 | `1..64` |
| `parallelism` | 4 | `1..64` |
| `salt_length` | 1 | `16..64` |
| `salt` | variable | exactement `salt_length` octets |
| `wrap_algorithm` | 1 | `0x01` XChaCha20-Poly1305 |
| `wrap_nonce` | 24 | nonce exact |
| `wrap_ciphertext_length` | 2 | `16..4096` |
| `wrap_ciphertext` | variable | exactement la longueur déclarée |
| Champ | Taille | Valeur / règle |
|---|---:|---|
| `role` | 1 | `0x01` OWNER, `0x02` VIEW |
| `slot_id` | 16 | identifiant binaire exact |
| `kdf_algorithm` | 1 | `0x01` Argon2id |
| `kdf_version` | 4 | `19` |
| `memory_kib` | 4 | `1..1 048 576`, et `>= parallelism * 8` |
| `iterations` | 4 | `1..64` |
| `parallelism` | 4 | `1..64` |
| `salt_length` | 1 | `16..64` |
| `salt` | variable | exactement `salt_length` octets |
| `wrap_algorithm` | 1 | `0x01` XChaCha20-Poly1305 |
| `wrap_nonce` | 24 | nonce exact |
| `wrap_ciphertext_length` | 2 | `16..4096` |
| `wrap_ciphertext` | variable | exactement la longueur déclarée |
Ordre obligatoire :
@@ -165,14 +189,14 @@ Toute divergence est invalide avant KDF/déchiffrement.
Chaque compartiment est encodé :
| Champ | Taille | Valeur / règle |
|---------------------|---------:|------------------------------------------------------|
| `kind` | 1 | `0x01` OWNER-CONTROL, `0x02` METADATA, `0x03` SECRET |
| `payload_version` | 4 | `1` pour le profil initial V2 |
| `algorithm` | 1 | `0x01` XChaCha20-Poly1305 |
| `nonce` | 24 | nonce exact |
| `ciphertext_length` | 4 | longueur exacte |
| `ciphertext` | variable | ciphertext + tag Poly1305 |
| Champ | Taille | Valeur / règle |
|---|---:|---|
| `kind` | 1 | `0x01` OWNER-CONTROL, `0x02` METADATA, `0x03` SECRET |
| `payload_version` | 4 | `1` pour le profil initial V2 |
| `algorithm` | 1 | `0x01` XChaCha20-Poly1305 |
| `nonce` | 24 | nonce exact |
| `ciphertext_length` | 4 | longueur exacte |
| `ciphertext` | variable | ciphertext + tag Poly1305 |
Bornes initiales :
@@ -190,10 +214,10 @@ Les payloads plaintext V2 conservent le modèle fonctionnel établi en V1 pour c
La fin du document est :
| Champ | Taille | Valeur / règle |
|-----------------------------|-------:|---------------------------|
| `state_signature.algorithm` | 1 | `0x01` Ed25519 |
| `state_signature.signature` | 64 | signature detached exacte |
| Champ | Taille | Valeur / règle |
|---|---:|---|
| `state_signature.algorithm` | 1 | `0x01` Ed25519 |
| `state_signature.signature` | 64 | signature detached exacte |
Aucun octet ne peut suivre ces 65 octets.
@@ -353,17 +377,17 @@ Le nonce/ciphertext n'est pas inclus dans son propre AAD.
V1 et V2 sont deux formats explicites :
| Propriété | V1 | V2 |
|--------------------------|------------------------------------|---------------|
| enveloppe | JSON UTF-8 | binaire KSP |
| champs binaires | Base64url no-pad | bytes directs |
| version | `1` | `2` |
| canonicalité | sémantique JSON + Base64 canonique | byte-exact |
| taille fixture wire-only | 2037 octets | 628 octets |
| Argon2id | oui | oui |
| XChaCha20-Poly1305 | oui | oui |
| Ed25519 OWNER state | oui | oui |
| VIEW/OWNER | oui | oui |
| Propriété | V1 | V2 |
|---|---|---|
| enveloppe | JSON UTF-8 | binaire KSP |
| champs binaires | Base64url no-pad | bytes directs |
| version | `1` | `2` |
| canonicalité | sémantique JSON + Base64 canonique | byte-exact |
| taille fixture wire-only | 2037 octets | 628 octets |
| Argon2id | oui | oui |
| XChaCha20-Poly1305 | oui | oui |
| Ed25519 OWNER state | oui | oui |
| VIEW/OWNER | oui | oui |
La réduction mesurée sur le fixture structurel de référence est :
@@ -402,7 +426,7 @@ Lecture :
0001 = VIEW_ENABLED
```
La fixture `wire_only` vérifie framing/canonicalité ; elle n'est pas présentée comme une signature cryptographique V2 valide tant que la création/open V2 n'est pas intégrée par la tranche suivante.
La fixture `wire_only` vérifie uniquement framing/canonicalité et reste volontairement distincte des wallets V2 runtime produits depuis `pre.016`; elle n'est pas présentée comme une signature cryptographique valide.
## 14. Compatibilité et migration