v0.2.5-pre.005
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/plans/000-README.md -->
|
||||
<!-- version: 42 -->
|
||||
<!-- version: 43 -->
|
||||
|
||||
# Plans KSP
|
||||
|
||||
@@ -20,7 +20,7 @@ Un plan décrit le périmètre, les décisions déjà acquises, les questions ou
|
||||
- [`009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md`](009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md) — plan clôturé de la release stable `0.2.2`, établi par `pre.001`, corrigé après réaudit Agave v4.2.1 puis exécuté jusqu'à `pre.007-fix.002`; il couvre les 22 wrappers Accounts/Tokens/Cluster, le smoke Transport opt-in et la préparation de `0.2.3`.
|
||||
- [`010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md`](010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md) — plan historique clôturé de la release stable `0.2.3 — HTTP Transactions`, ouvert par `pre.001`, exécuté jusqu'à `pre.009` puis publié par `rel.001`; il couvre les 11 méthodes, la classification `8 Read / 2 WriteSubmission / 1 Simulation`, `KSP-TRANSPORT-007`, le no-resend et la préparation de `0.2.4`.
|
||||
- [`011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md`](011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md) — plan historique clôturé de la release stable `0.2.4`, ouvert par `pre.001`, exécuté jusqu’à `pre.009`, complété par le fix documentaire Wallet `pre.009-fix.001` puis publié par `rel.001`; il couvre les 10 Blocks + 5 Economics et la compliance finale `52/52 + 14/14` sous `KSP-TRANSPORT-007`.
|
||||
- [`012-V0_2_5_WALLET_FOUNDATION_PLAN.md`](012-V0_2_5_WALLET_FOUNDATION_PLAN.md) — plan actif de `0.2.5 — Wallet foundation`, ouvert par `pre.001`; `pre.002` matérialise la crate et `pre.003` fige le wire JSON V1, ses key slots, limites, transcript/AAD et la première spécification interopérable `docs/formats/KSPWALLET_V1.md`, avant la cryptographie effective de `pre.004+`.
|
||||
- [`012-V0_2_5_WALLET_FOUNDATION_PLAN.md`](012-V0_2_5_WALLET_FOUNDATION_PLAN.md) — plan actif de `0.2.5 — Wallet foundation`, ouvert par `pre.001`; `pre.002` matérialise la crate, `pre.003` fige le wire JSON V1/transcript/AAD, `pre.004` ajoute Argon2id/XChaCha20-Poly1305/CSPRNG et `pre.005` fixe les payloads, le profil de création benchmarké, l’autorité Ed25519 séparée et les flux in-memory create/open VIEW/OWNER avec vecteur complet interopérable. `pre.006` porte la persistence atomique/no-clobber.
|
||||
|
||||
Le `pre.001` de chaque release fonctionnelle peut introduire son propre plan détaillé lorsque la release s'ouvre.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md -->
|
||||
<!-- version: 49 -->
|
||||
<!-- version: 50 -->
|
||||
|
||||
# Séquence des releases fonctionnelles KSP
|
||||
|
||||
@@ -414,6 +414,8 @@ La release doit fournir `docs/formats/KSPWALLET_V1.md` comme spécification sép
|
||||
|
||||
`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.5-pre.005` consomme ce benchmark (`64 MiB / 3 / 1 ≈ 1742 ms`, `128 MiB ≈ 3459 ms`, `256 MiB ≈ 6925 ms` sur la machine opérateur) et retient pour les créations KSP V1 `65 536 KiB / 3 / 1` avec salt 32 octets, tout en conservant les paramètres sérialisés comme autorité de lecture de chaque wallet. La tranche fixe les payloads `owner_control` (seed Ed25519 d’administration + `K_metadata` + `K_secret`), metadata strictes et secret Solana 64 octets, ajoute une autorité Ed25519 séparée de la keypair Solana et vérifie sa signature d’état avant tout KDF. Les API in-memory `create_wallet_v1`, `open_wallet_view_v1`, `open_wallet_owner_v1` et `inspect_locked_wallet_v1` matérialisent l’indépendance VIEW/OWNER : VIEW ne déchiffre jamais `owner_control`/secret, OWNER ne dépend pas de VIEW et la Pubkey reste un `ksp_core_lib::Pubkey`. Un vecteur `.kspwallet` complet test-only, revérifiable hors Rust, ferme l’interop de cette tranche. La persistence filesystem reste explicitement `pre.006`; signature Solana publique et mutations/rotations restent `pre.007+`.
|
||||
|
||||
## `0.2.6` — Wallet Desk
|
||||
|
||||
Mission : valider Config composite + `.kspwallet` + transport HTTP dans une application Tauri mince.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md -->
|
||||
<!-- version: 7 -->
|
||||
<!-- version: 8 -->
|
||||
|
||||
# Plan `0.2.5` — Wallet foundation
|
||||
|
||||
@@ -363,7 +363,7 @@ Il faut distinguer :
|
||||
|
||||
**keypair Solana** : immuable dans V1 après création/import. Aucun `replace_keypair` n'est exposé. Toute tentative de modifier `secret` ou la Pubkey metadata sans une réécriture OWNER valide échoue sur la `state_signature`; même avec OWNER, l'import d'une autre keypair crée un nouveau `.kspwallet` au lieu de muter l'identité cryptographique existante.
|
||||
|
||||
## 8. Primitives et dépendances réauditées le 2026-08-18
|
||||
## 8. Primitives et dépendances réauditées jusqu’au 2026-08-19
|
||||
|
||||
Aucune dépendance ci-dessous n'est ajoutée dans `pre.001`. Ce sont les candidates pour les tranches qui les consommeront réellement.
|
||||
|
||||
@@ -378,9 +378,9 @@ Aucune dépendance ci-dessous n'est ajoutée dans `pre.001`. Ce sont les candida
|
||||
|
||||
`solana-keypair` fournit le keypair Ed25519, la conversion stricte depuis 64 octets, la signature, le format JSON de 64 entiers et une représentation Base58 complète. Aucun client RPC Solana n'est nécessaire.
|
||||
|
||||
La génération SDK récente définit `Pubkey` comme alias du type `Address`, mais l'écosystème a déjà connu des incompatibilités lorsque plusieurs générations de `solana-address` coexistent. `pre.002` verrouille donc la surface publique Wallet sur **`ksp_core_lib::Pubkey` exclusivement** et n'ajoute aucune dépendance directe `solana-pubkey`. Lorsque `solana-keypair` sera réellement introduit, la tranche concernée devra prouver par compilation/cargo-tree que son `Address/Pubkey` est compatible avec la génération possédée par Core avant toute conversion interne. Aucun second type d'adresse KSP n'est introduit pour contourner un mismatch.
|
||||
La génération SDK récente définit `Pubkey` comme alias du type `Address`, mais l'écosystème a déjà connu des incompatibilités lorsque plusieurs générations de `solana-address` coexistent. `pre.002` verrouille donc la surface publique Wallet sur **`ksp_core_lib::Pubkey` exclusivement** et n'ajoute aucune dépendance directe `solana-pubkey`. `pre.005` introduit réellement `solana-keypair 3.1.2` uniquement pour posséder/valider la keypair Ed25519 ; la Pubkey Wallet reste construite via `ksp_core_lib::Pubkey` depuis les 32 octets publics du keypair, sans exposer un second type d'adresse KSP.
|
||||
|
||||
Un `cargo tree` est obligatoire lors de l'introduction réelle afin de contrôler les versions `ed25519-dalek`, `solana-signature`, `rand/getrandom` et éviter des duplications évitables.
|
||||
Un `cargo tree` est obligatoire avec `pre.005` afin de confirmer l'unification de `solana-address`, `ed25519-dalek`, `rand/getrandom` et d'éviter des duplications crypto injustifiées.
|
||||
|
||||
Audit source notable : `solana-keypair 3.1.2` contient un bloc `unsafe` interne dans sa conversion Base58 vers `String`. Cela ne modifie pas la règle `#![forbid(unsafe_code)]` du code KSP, mais doit rester visible dans l'audit des transitifs ; `pre.008` réévaluera le chemin Base58 réellement appelé et les alternatives avant de figer l'adapter.
|
||||
|
||||
@@ -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 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.
|
||||
Les paramètres Argon2 de création ont été mesurés avec le benchmark opérateur de `pre.004` : `64 MiB / 3 / 1 = 1742 ms`, `128 MiB / 3 / 1 = 3459 ms`, `256 MiB / 3 / 1 = 6925 ms` sur la machine/profil testés le 2026-08-19. `pre.005` retient donc **64 MiB / 3 passes / 1 lane** comme profil initial de création KSP, avec un salt CSPRNG indépendant de 32 octets par slot. Ce choix n'est copié ni de bot3, ni d'un RFC, ni d'un default de crate. Le fichier sérialise tous les paramètres nécessaires afin qu'un ancien wallet conserve son profil historique même lorsque les defaults KSP seront durcis.
|
||||
|
||||
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`.
|
||||
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 profil de création KSP.
|
||||
|
||||
### 8.3 AEAD
|
||||
|
||||
@@ -409,13 +409,13 @@ AES-GCM-SIV apporte une meilleure tolérance à la réutilisation accidentelle d
|
||||
|
||||
### 8.4 CSPRNG
|
||||
|
||||
`getrandom 0.4.3` est retenu comme candidate low-level pour les octets aléatoires propres au format. Les API de génération de keypair Solana restent libres d'utiliser leur CSPRNG interne maintenu.
|
||||
`getrandom 0.4.3` est retenu depuis `pre.004` comme primitive low-level pour les octets aléatoires propres au format. `pre.005` l'utilise également pour les seeds/slot IDs/salts/nonces de création. Les API de génération de keypair Solana ne deviennent pas pour autant propriétaires du CSPRNG du format.
|
||||
|
||||
### 8.5 Secret memory
|
||||
|
||||
`zeroize 1.9.0` est retenu et devient la seule nouvelle dépendance tierce de `pre.002`, car les wrappers `ViewPassword` / `OwnerPassword` l’utilisent immédiatement pour leur nettoyage au `Drop`. `secrecy` n'est pas ajouté tant qu'un besoin ergonomique concret n'est pas démontré ; des types KSP simples imposent eux-mêmes redaction/non-Clone et utilisent `zeroize`.
|
||||
|
||||
Pour la clé admin Ed25519 distincte, `ed25519-dalek 3.0.0` est une candidate standard, mais son ajout direct est **conditionné au cargo-tree** de la tranche qui implémente l'authentification afin d'éviter une génération concurrente inutile avec celle déjà tirée par `solana-keypair`.
|
||||
`pre.005` introduit directement **`ed25519-dalek ^2.2`** avec `default-features = false` et les features `signature` + `zeroize`. La génération `3.0.0`, bien que plus récente, n'est volontairement pas ajoutée : `solana-keypair 3.1.2` dépend de `ed25519-dalek ^2.1.1`, donc la branche directe `2.2` permet à Cargo d'unifier une seule génération Dalek et d'activer `zeroize` sur la `SigningKey` utilisée à la fois par l'autorité de format KSP et par le wrapper Solana. Une duplication `2.x + 3.x` n'apporterait aucune capacité nécessaire à V1.
|
||||
|
||||
### 8.6 État des audits de sécurité publics
|
||||
|
||||
@@ -432,14 +432,14 @@ L'absence d'une ligne « audited » dans ce document ne signifie donc pas « sû
|
||||
|
||||
### 8.7 Encodage et persistence
|
||||
|
||||
Candidates :
|
||||
État au terme de `pre.005` :
|
||||
|
||||
```text
|
||||
base64 0.23.1 pour Base64url sans padding des champs binaires JSON
|
||||
tempfile 3.27.0 pour temp files same-directory + persist/persist_noclobber
|
||||
base64 0.23.1 acquis depuis pre.003 pour Base64url sans padding des champs binaires JSON
|
||||
tempfile 3.27.0 candidate pre.006 pour temp files same-directory + persist/persist_noclobber
|
||||
```
|
||||
|
||||
Elles ne sont ajoutées que lorsqu'elles sont réellement consommées.
|
||||
`tempfile` ne sera ajouté que si `pre.006` confirme sa sémantique portable et son besoin réel pour l'atomicité/no-clobber.
|
||||
|
||||
## 9. Format natif `.kspwallet` V1
|
||||
|
||||
@@ -516,7 +516,7 @@ Structure V1 figée par le codec `pre.003` (les longueurs/encodages exacts sont
|
||||
}
|
||||
```
|
||||
|
||||
Les `0` ci-dessus signifient « valeur déterminée par le benchmark futur », pas des paramètres valides.
|
||||
Les paramètres de création KSP V1 sont désormais `memory_kib = 65536`, `iterations = 3`, `parallelism = 1`, avec un salt CSPRNG indépendant de 32 octets par slot. Le wire continue toutefois d'accepter tout profil V1 valide dans les bornes documentées, car les paramètres sont sérialisés par wallet.
|
||||
|
||||
### 9.3 Informations visibles wallet verrouillé
|
||||
|
||||
@@ -1031,6 +1031,26 @@ L'injection de random déterministe reste privée aux tests/codec fixtures ; l'A
|
||||
- aucun `unsafe` KSP ;
|
||||
- cargo-tree sans duplication crypto injustifiée.
|
||||
|
||||
### 19.7 État acquis après `pre.005`
|
||||
|
||||
`pre.005` matérialise désormais les invariants crypto centraux sans filesystem :
|
||||
|
||||
```text
|
||||
K_owner_root, K_metadata, K_secret indépendants
|
||||
OWNER slot -> K_owner_root
|
||||
VIEW slot -> K_metadata
|
||||
owner_control = admin Ed25519 secret || K_metadata || K_secret (96 octets)
|
||||
metadata = JSON protégé Pubkey/alias/notes avec note IDs 16 octets uniques
|
||||
secret = keypair Solana 64 octets secret||public
|
||||
state_signature Ed25519 vérifiée avant tout KDF
|
||||
open VIEW ne matérialise jamais owner-control/secret
|
||||
open OWNER vérifie autorité admin + cohérence keypair + Pubkey metadata
|
||||
create/open KDF via spawn_blocking
|
||||
vecteur complet test-only généré et revérifié indépendamment du Rust
|
||||
```
|
||||
|
||||
La persistence, la signature Solana publique, les mutations metadata et les rotations restent volontairement absentes de cette tranche.
|
||||
|
||||
## 20. Sizing
|
||||
|
||||
| Domaine | Taille | Risque principal |
|
||||
@@ -1070,31 +1090,32 @@ rel.001 publication strictement publicationnelle
|
||||
|
||||
Une `fix` ou tranche supplémentaire est préférable à la suppression d'une garantie sécurité si un des gates révèle une incompatibilité.
|
||||
|
||||
## 22. Dépendances candidates par tranche
|
||||
## 22. Dépendances par tranche
|
||||
|
||||
`pre.001` n’ajoutait aucune dépendance. `pre.002` ajoute uniquement :
|
||||
État réellement acquis au terme de `pre.005` :
|
||||
|
||||
```text
|
||||
zeroize ^1.9
|
||||
pre.002 zeroize ^1.9
|
||||
pre.003 base64 ^0.23
|
||||
pre.004 argon2 ^0.5
|
||||
chacha20poly1305 ^0.11
|
||||
getrandom ^0.4
|
||||
pre.005 ed25519-dalek ^2.2
|
||||
solana-keypair ^3.1
|
||||
tokio déjà workspace, feature locale rt pour spawn_blocking
|
||||
```
|
||||
|
||||
La dépendance est centralisée sous `[workspace.dependencies]` puis consommée avec `zeroize.workspace = true`. Elle est utilisée immédiatement par les wrappers de password ; aucune crate crypto/KDF/Solana supplémentaire n’est ajoutée par anticipation. La génération courante `zeroize 1.9.0` a été réauditée avant insertion.
|
||||
Toutes les dépendances tierces communes restent centralisées sous `[workspace.dependencies]`; le membre Wallet active uniquement les features nécessaires. `ed25519-dalek ^2.2` est volontairement aligné avec la contrainte `^2.1.1` de `solana-keypair 3.1.2` afin de permettre une seule génération Dalek et d'activer `zeroize` sur la `SigningKey` partagée par résolution Cargo.
|
||||
|
||||
Liste de travail restante, à réauditer juste avant insertion sous `[workspace.dependencies]` :
|
||||
Candidates restantes, à réauditer juste avant insertion :
|
||||
|
||||
```text
|
||||
argon2 ^0.5
|
||||
base64 ^0.23
|
||||
chacha20poly1305 ^0.11
|
||||
ed25519-dalek ^3.0 # seulement si cargo-tree justifie le direct
|
||||
getrandom ^0.4
|
||||
solana-keypair ^3.1
|
||||
solana-signer ^3.0 # si réellement nécessaire directement
|
||||
tempfile ^3.27 # pre.006 si la sémantique atomic/no-clobber est confirmée
|
||||
solana-signer ^3.0 # seulement si un contrat public/impl l'exige réellement
|
||||
solana-signature ^3.5 # seulement si le type public l'exige
|
||||
tempfile ^3.27
|
||||
```
|
||||
|
||||
Déjà présents et réutilisables :
|
||||
Déjà présents et réutilisés :
|
||||
|
||||
```text
|
||||
serde
|
||||
@@ -1122,7 +1143,7 @@ Le fait que `bs58` ne soit pas requis sera révalidé lorsque les adapters sont
|
||||
|
||||
## 23. Sources externes réauditées
|
||||
|
||||
Sources primaires consultées le 2026-08-18 :
|
||||
Sources primaires consultées initialement le 2026-08-18 puis réauditées le 2026-08-19 pour les dépendances effectivement introduites par `pre.005` :
|
||||
|
||||
```text
|
||||
https://docs.rs/solana-keypair/3.1.2/
|
||||
@@ -1136,12 +1157,12 @@ https://docs.rs/chacha20poly1305/0.11.0/
|
||||
https://docs.rs/aes-gcm-siv/0.12.0/
|
||||
https://docs.rs/getrandom/0.4.3/
|
||||
https://docs.rs/zeroize/1.9.0/
|
||||
https://docs.rs/ed25519-dalek/3.0.0/
|
||||
https://docs.rs/ed25519-dalek/2.2.0/
|
||||
https://docs.rs/base64/0.23.1/
|
||||
https://docs.rs/tempfile/3.27.0/
|
||||
```
|
||||
|
||||
Les versions sont des constats d'audit du gate, pas des dépendances ajoutées par ce delta. Chaque tranche réaudite sa candidate au moment où elle devient réellement consommée.
|
||||
Les versions sont des constats d'audit successifs : elles ne signifient pas que toutes les crates listées ont été ajoutées dans une même tranche. Chaque dépendance sensible est réauditée au moment où elle devient réellement consommée.
|
||||
|
||||
## 24. Critères de sortie `0.2.5`
|
||||
|
||||
@@ -1197,4 +1218,4 @@ Une future `format_version >= 2` pourra réétudier des facteurs/ancrages extern
|
||||
|
||||
## 26. Suite immédiate
|
||||
|
||||
`0.2.5-pre.003` fige le codec JSON strict, les limites structurelles, `slot_id` 16 octets, le descripteur VIEW, les DTOs d’enveloppe/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 l’opé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.
|
||||
`0.2.5-pre.003` fige le codec JSON strict, les limites structurelles, `slot_id` 16 octets, le descripteur VIEW, les DTOs d’enveloppe/key slots, les TLV transcript/AAD et la première spécification `docs/formats/KSPWALLET_V1.md`. `pre.004` ajoute Argon2id/XChaCha20-Poly1305/CSPRNG OS et le wrapping de content keys. Le benchmark opérateur a ensuite permis à `pre.005` de retenir le profil initial `64 MiB / 3 / 1`, de figer les payloads `owner_control`/metadata/secret, d'introduire l'autorité Ed25519 OWNER distincte de la keypair Solana, de créer/ouvrir réellement VIEW et OWNER en mémoire et de publier un vecteur `.kspwallet` complet interopérable. **La suite immédiate est `pre.006` : persistence async/atomique/no-clobber**, sans déplacer de logique filesystem dans Config.
|
||||
|
||||
Reference in New Issue
Block a user