v0.2.5-pre.008

This commit is contained in:
2026-08-19 18:47:06 +02:00
parent 518cc9257f
commit 1125ade4c1
17 changed files with 1104 additions and 36 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: docs/formats/KSPWALLET_V1.md -->
<!-- version: 5 -->
<!-- version: 6 -->
# `.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
```
`0.2.5-pre.004` ajoute les primitives KDF/AEAD normatives et un premier vecteur cryptographique public. `0.2.5-pre.005` fixe les payloads plaintext V1, l'autorité Ed25519 OWNER, les procédures de création et d'ouverture VIEW/OWNER, le profil de création KSP issu du benchmark opérateur et un vecteur `.kspwallet` complet généré indépendamment du code Rust. `0.2.5-pre.006` matérialise la persistence filesystem bornée et la création no-clobber. `0.2.5-pre.007` matérialise la signature Solana OWNER, l'administration des metadata, les rotations OWNER/VIEW, la révocation forte VIEW et leur remplacement filesystem capability-bound. Les adapters import/export restent dans les tranches suivantes. 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` ajoute les primitives KDF/AEAD normatives et un premier vecteur cryptographique public. `0.2.5-pre.005` fixe les payloads plaintext V1, l'autorité Ed25519 OWNER, les procédures de création et d'ouverture VIEW/OWNER, le profil de création KSP issu du benchmark opérateur et un vecteur `.kspwallet` complet généré indépendamment du code Rust. `0.2.5-pre.006` matérialise la persistence filesystem bornée et la création no-clobber. `0.2.5-pre.007` matérialise la signature Solana OWNER, l'administration des metadata, les rotations OWNER/VIEW, la révocation forte VIEW et leur remplacement filesystem capability-bound. `0.2.5-pre.008` matérialise les adapters Solana CLI JSON et Base58 complet, leur inspection sûre, l'import no-clobber vers un nouveau `.kspwallet` et l'export secret OWNER explicite. 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`.
@@ -665,13 +665,13 @@ Le premier vecteur cryptographique public KDF+wrapping est ajouté par `pre.004`
## 19. Invariants encore à compléter sans modifier le wire figé
Après `pre.005`, les tranches restantes portent sur les opérations autour du format déjà défini :
Les opérations autour du wire V1 sont désormais matérialisées jusqu'aux adapters de transfert :
```text
pre.006 : persistence async/atomique/no-clobber
pre.007 : signature Solana, metadata admin, rotations OWNER/VIEW et révocation forte VIEW
pre.008 : import/export
pre.009+ : audit adversarial, compliance et documentation de clôture
pre.006 : persistence async/atomique/no-clobber acquis
pre.007 : signature Solana, metadata admin, rotations et révocation acquis
pre.008 : import/export Solana CLI JSON + Base58 complet acquis
pre.009+ : audit adversarial, compliance et documentation de clôture restant
```
Toute découverte imposant de modifier la grammaire, les payloads plaintext, 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.
@@ -930,3 +930,61 @@ caller path explicite
La couche filesystem est async-first, mais les appels OS bloquants sont regroupés derrière `tokio::task::spawn_blocking`. KSP ne lit ni Config ni environnement pour choisir le chemin et ne journalise pas les chemins par défaut. Les mutations `pre.007` réutilisent la même stratégie temp/sync pour un remplacement **capability-bound** avec contrôle d'état attendu décrit en section 21.9 ; ce remplacement n'est jamais exposé comme primitive publique générique et ne modifie pas la règle create/import = no-clobber.
La durabilité est décrite sans surpromesse : `persist_noclobber` ne garantit pas une atomicité universelle sur tous les filesystems et un crash brutal peut laisser un artefact ou hard-link temporaire complet. KSP garantit le no-clobber et l'absence de publication partielle dans le flux normal et dans les fault tests avant publication ; il ne garantit pas la suppression des temporaires après kill/power-loss ni une durabilité identique de l'entrée de répertoire sur tous les OS. Ces limites concernent la persistence et ne changent pas les garanties cryptographiques du format.
## 24. Adapters de transfert matérialisés par `pre.008`
Les formats de transfert ne modifient pas le wire `.kspwallet` V1. Ils servent uniquement à importer/exporter la keypair Solana immuable de 64 octets. Deux formats sont retenus immédiatement :
```text
solana_cli_json JSON array de exactement 64 entiers u8
solana_keypair_base58 Base58 canonique de la keypair complète 64 octets
```
### 24.1 Solana CLI JSON
Le format correspond au codec `solana-keypair` actuel : un tableau JSON contenant exactement les 64 octets de la keypair. KSP accepte les espaces JSON usuels mais exige exactement 64 valeurs `0..255`, puis reconstruit la keypair avec validation de cohérence secret/public. La taille du source est bornée à **1024 octets** avant parsing.
### 24.2 Base58 de keypair complète
Le format Base58 encode les **64 octets complets** de la keypair, et non seulement le secret seed de 32 octets. KSP utilise le codec maintenu par `solana-keypair`, refuse le whitespace périphérique et impose `decode -> re-encode == input` afin de n'accepter que la représentation canonique. La taille du source est bornée à **128 octets** avant décodage. Aucun `bs58` direct n'est ajouté à Wallet.
### 24.3 Inspection sûre
`inspect_wallet_transfer` et `inspect_wallet_transfer_file` exigent que le caller choisisse explicitement le format. KSP ne fait pas d'auto-détection heuristique. Après validation complète de la keypair, l'inspection expose seulement :
```text
Pubkey Solana via ksp_core_lib::Pubkey
WalletTransferFormat
```
Aucun secret, seed, keypair brute, alias ou note n'est projeté.
### 24.4 Import vers `.kspwallet`
Un import valide :
```text
source transfer validée
-> même keypair Solana 64 octets
-> nouvelles clés OWNER/admin/content KSP
-> nouveaux slots OWNER/VIEW selon passwords fournis
-> nouvelles metadata KSP fournies par le caller
-> nouveau document .kspwallet V1
-> publication no-clobber
```
La source n'est jamais modifiée. Une destination `.kspwallet` existante retourne `wallet.destination_exists`. L'import n'est donc jamais une mutation ou un remplacement de keypair d'un wallet V1 existant.
### 24.5 Export OWNER
Seul `WalletOwner` expose l'export. `WalletView` ne possède aucune API correspondante. Deux formes existent :
```text
export_transfer(format)
export_transfer_file(destination, format)
```
La première retourne au caller des octets contenant volontairement le secret et exige donc que le caller en limite la durée de vie et les zeroize lorsque pertinent. La seconde publie un nouveau fichier en no-clobber ; sur Unix, KSP tente `0600` comme hygiène filesystem, sans transformer cette permission en garantie cryptographique du format. Aucun chemin n'est découvert via Config ou environnement.
Les exports Base58 et Solana CLI JSON doivent reconstruire exactement la même keypair et la même Pubkey que le wallet OWNER source.