v0.5.2-pre.003
This commit is contained in:
211
docs/NATIVE_FORMAT.md
Normal file
211
docs/NATIVE_FORMAT.md
Normal file
@@ -0,0 +1,211 @@
|
||||
<!-- file: docs/NATIVE_FORMAT.md -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# Format natif `.kswallet` — version 1
|
||||
|
||||
## Statut
|
||||
|
||||
Ce document fixe le codec binaire de la version `1` introduit par `0.5.2-pre.003`.
|
||||
|
||||
`pre.003` fixe le layout et implémente le décodage/validation strict ainsi que la lecture bornée nécessaires au scan, mais **ne chiffre encore aucune vraie keypair avec un mot de passe**. L'encodage de création, la publication atomique, le raccordement password/KDF/AEAD et l'ouverture signante appartiennent à `pre.004`.
|
||||
|
||||
Un fichier natif porte le nom :
|
||||
|
||||
```text
|
||||
<alias>.kswallet
|
||||
```
|
||||
|
||||
Tous les entiers multi-octets sont encodés en **little-endian**.
|
||||
|
||||
## Objectifs du format v1
|
||||
|
||||
Le conteneur doit :
|
||||
|
||||
- être identifiable sans heuristique ;
|
||||
- distinguer clairement sa version et ses algorithmes ;
|
||||
- exposer uniquement l'identité publique nécessaire avant unlock ;
|
||||
- borner toutes les longueurs et paramètres avant allocation ou KDF ;
|
||||
- authentifier avec l'AEAD toutes les métadonnées influençant identité et déchiffrement ;
|
||||
- permettre une publication atomique sans écrasement silencieux ;
|
||||
- rester incompatible par construction avec le JSON keypair Solana legacy.
|
||||
|
||||
Le caractère binaire du format ne constitue pas une protection cryptographique. La confidentialité du secret sera fournie par l'AEAD après dérivation d'une clé depuis le mot de passe en `pre.004`.
|
||||
|
||||
## Layout binaire v1
|
||||
|
||||
Le header fixe occupe **72 octets**.
|
||||
|
||||
| Offset | Taille | Champ | Contrat v1 |
|
||||
|--------------:|-----------:|----------------------|-------------------------------------------------|
|
||||
| `0` | `8` | magic | ASCII `KSWALLET` |
|
||||
| `8` | `2` | format version | `1` |
|
||||
| `10` | `2` | header length | `72 + alias_length` |
|
||||
| `12` | `2` | flags | `0` |
|
||||
| `14` | `1` | KDF id | `1` = Argon2id |
|
||||
| `15` | `1` | KDF version | `0x13` = Argon2 v19 |
|
||||
| `16` | `1` | AEAD id | `1` = XChaCha20-Poly1305 |
|
||||
| `17` | `1` | salt length | `16` |
|
||||
| `18` | `1` | nonce length | `24` |
|
||||
| `19` | `1` | alias length | `1..64` |
|
||||
| `20` | `4` | reserved | quatre octets `0` |
|
||||
| `24` | `4` | Argon2 memory KiB | borné, voir ci-dessous |
|
||||
| `28` | `4` | Argon2 passes | borné, voir ci-dessous |
|
||||
| `32` | `4` | Argon2 parallelism | borné, voir ci-dessous |
|
||||
| `36` | `4` | ciphertext length | `80` |
|
||||
| `40` | `32` | Solana pubkey | 32 octets bruts |
|
||||
| `72` | variable | alias | ASCII validé par `WalletAlias` |
|
||||
| après alias | `16` | salt | sel Argon2id |
|
||||
| après salt | `24` | nonce | nonce XChaCha20-Poly1305 |
|
||||
| après nonce | `80` | ciphertext | keypair 64 octets protégé + tag AEAD 16 octets |
|
||||
|
||||
Aucun octet supplémentaire n'est accepté après le ciphertext déclaré.
|
||||
|
||||
## Identité publique et payload secret
|
||||
|
||||
L'alias et la pubkey sont disponibles avant unlock afin de permettre :
|
||||
|
||||
- le scan et le lookup ;
|
||||
- l'affichage d'une identité non sensible ;
|
||||
- la détection des collisions ;
|
||||
- le choix du wallet par un consommateur.
|
||||
|
||||
Le secret Ed25519 n'est jamais placé dans ce header. Le plaintext protégé de la version `1` est exactement le keypair Solana brut de **64 octets** déjà caractérisé par le format CLI legacy. XChaCha20-Poly1305 ajoute un tag de 16 octets : le ciphertext v1 est donc exactement de **80 octets**. Toute évolution de la structure secrète nécessite une nouvelle version du format.
|
||||
|
||||
Le nom `<alias>.kswallet` et l'alias encodé doivent correspondre exactement. Une divergence est une erreur et ne déclenche aucun fallback vers le legacy.
|
||||
|
||||
Avant déverrouillage, cette identité est **déclarative** : le codec peut vérifier sa structure, mais pas encore le tag AEAD. `pre.004` doit authentifier le conteneur puis vérifier que la pubkey dérivée du keypair déchiffré correspond exactement à cette pubkey déclarée avant de créer une capacité de signature.
|
||||
|
||||
## KDF v1
|
||||
|
||||
Le KDF sélectionné est **Argon2id version 19**.
|
||||
|
||||
Le profil d'écriture par défaut retenu est :
|
||||
|
||||
```text
|
||||
memory = 65536 KiB (64 MiB)
|
||||
passes = 3
|
||||
parallelism = 4 lanes
|
||||
salt = 16 bytes
|
||||
output key = 32 bytes
|
||||
```
|
||||
|
||||
Ce profil correspond au second profil recommandé par RFC 9106 pour les environnements à mémoire contrainte et produit la clé de 256 bits requise par l'AEAD choisi.
|
||||
|
||||
Le codec accepte uniquement des paramètres dans les bornes suivantes :
|
||||
|
||||
```text
|
||||
memory = 65536..262144 KiB
|
||||
passes = 3..10
|
||||
parallelism = 1..8
|
||||
```
|
||||
|
||||
La mémoire déclarée doit en plus respecter la relation Argon2 `m >= 8 * p` et être un multiple de `4 * p` afin que la valeur encodée corresponde sans ambiguïté au nombre de blocs réellement retenu.
|
||||
|
||||
Ces bornes servent deux objectifs distincts :
|
||||
|
||||
- refuser un conteneur v1 plus faible que le plancher retenu pour `ks-wallet` ;
|
||||
- empêcher qu'un fichier hostile impose des coûts KDF arbitrairement élevés lors de `pre.004`.
|
||||
|
||||
## AEAD v1
|
||||
|
||||
L'AEAD sélectionné est **XChaCha20-Poly1305** :
|
||||
|
||||
```text
|
||||
key = 32 bytes
|
||||
nonce = 24 bytes
|
||||
tag = 16 bytes
|
||||
```
|
||||
|
||||
`pre.004` devra générer un nonce neuf pour chaque nouvelle protection du payload. Une modification de mot de passe devra donc produire au minimum un nouveau sel et un nouveau nonce.
|
||||
|
||||
Ce choix appartient au format natif `ks-wallet`, pas à un format Solana externe. La documentation RustCrypto signale qu'il n'existe pas de spécification XChaCha20-Poly1305 autoritative unique, tout en documentant des implémentations interopérables et l'audit de la crate. Le layout v1 fixe donc explicitement l'algorithme et ses tailles au lieu de dépendre d'une convention implicite.
|
||||
|
||||
## Données authentifiées
|
||||
|
||||
Le contrat v1 réserve comme **AEAD associated data** l'intégralité des octets précédant le ciphertext :
|
||||
|
||||
```text
|
||||
fixed header
|
||||
+ alias
|
||||
+ salt
|
||||
+ nonce
|
||||
```
|
||||
|
||||
Le champ `ciphertext_length` appartient donc lui aussi aux données authentifiées.
|
||||
|
||||
Ainsi, une altération de la version, des IDs crypto, des paramètres KDF, de la pubkey, de l'alias, du sel, du nonce ou de la longueur du ciphertext devra faire échouer l'ouverture authentifiée en `pre.004`.
|
||||
|
||||
## Bornes du codec
|
||||
|
||||
Le codec v1 impose :
|
||||
|
||||
```text
|
||||
alias <= 64 bytes
|
||||
plaintext keypair = 64 bytes
|
||||
ciphertext + tag = 80 bytes
|
||||
native file total = 193..256 bytes
|
||||
```
|
||||
|
||||
La taille du fichier est vérifiée à partir des métadonnées du fichier ouvert **avant** l'allocation du buffer de lecture. Après lecture des octets attendus, le lecteur vérifie également qu'aucun octet supplémentaire n'est apparu pendant l'opération. La somme exacte des longueurs déclarées doit être égale à la taille réelle ; truncation, croissance concurrente et trailing bytes sont refusés.
|
||||
|
||||
Les flags inconnus, IDs KDF/AEAD inconnus, version Argon2 inconnue et octets reserved non nuls sont refusés.
|
||||
|
||||
## Permissions et publication
|
||||
|
||||
Sous Unix :
|
||||
|
||||
```text
|
||||
wallet directory : 0700
|
||||
.kswallet file : 0600
|
||||
```
|
||||
|
||||
La publication que `pre.004` devra implémenter pour produire un conteneur v1 suit cette séquence :
|
||||
|
||||
1. encoder entièrement le conteneur ;
|
||||
2. créer dans le même répertoire un fichier temporaire privé avec `create_new` ;
|
||||
3. écrire le contenu complet ;
|
||||
4. `sync_all` du fichier temporaire ;
|
||||
5. publier sans remplacement par hard-link vers `<alias>.kswallet` ;
|
||||
6. synchroniser le répertoire parent sous Unix ;
|
||||
7. supprimer le nom temporaire ;
|
||||
8. synchroniser à nouveau le répertoire parent sous Unix.
|
||||
|
||||
L'utilisation d'un hard-link de même répertoire garantit que la destination existante n'est jamais remplacée silencieusement. Si le filesystem ne permet pas cette publication, l'opération échoue au lieu de revenir à une écriture destructive.
|
||||
|
||||
## Non-divulgation
|
||||
|
||||
Les structures internes contenant sel, nonce ou ciphertext :
|
||||
|
||||
- ne sont pas une API crate-root publique ;
|
||||
- n'implémentent pas `Debug` automatiquement ;
|
||||
- ne sont pas sérialisées vers Tauri ;
|
||||
- ne doivent pas apparaître dans les erreurs ou logs.
|
||||
|
||||
`WalletFileHandle` ne projette que :
|
||||
|
||||
- alias ;
|
||||
- pubkey déclarée ;
|
||||
- version du format ;
|
||||
- identité persistante non sensible.
|
||||
|
||||
Le chemin local reste conservé en interne pour permettre l'ouverture ultérieure du fichier sélectionné.
|
||||
|
||||
## Suite en `pre.004`
|
||||
|
||||
`pre.004` devra compléter ce codec sans modifier silencieusement son layout pour :
|
||||
|
||||
- encoder le conteneur de création et publier le fichier atomiquement/no-clobber selon la séquence ci-dessus ;
|
||||
- dériver une clé avec Argon2id ;
|
||||
- chiffrer/déchiffrer les 64 octets du keypair avec XChaCha20-Poly1305 ;
|
||||
- vérifier que la pubkey dérivée du keypair déchiffré est exactement celle du header ;
|
||||
- créer une capacité de signature seulement après authentification réussie ;
|
||||
- changer le mot de passe en conservant la même keypair/pubkey ;
|
||||
- zéroïser les buffers plaintext et clés dérivées possédés par `ks-wallet`.
|
||||
|
||||
Toute modification incompatible du layout défini ici doit utiliser une nouvelle version de format plutôt qu'une heuristique de décodage.
|
||||
|
||||
## Références de conception v1
|
||||
|
||||
- RFC 9106 — Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications, notamment le second profil recommandé Argon2id `t=3`, `p=4`, `m=64 MiB`, sel 128 bits et sortie 256 bits.
|
||||
- Documentation RustCrypto `argon2` 0.5 — dérivation de clé Argon2id et paramètres explicites.
|
||||
- Documentation RustCrypto `chacha20poly1305` 0.11 — contrat `XChaCha20Poly1305`, clé 32 octets, nonce 24 octets et tag 16 octets, ainsi que la note de statut de spécification XChaCha.
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/README.md -->
|
||||
<!-- version: 33 -->
|
||||
<!-- version: 34 -->
|
||||
|
||||
# Documentation active de Khadhroony Bot3
|
||||
|
||||
@@ -52,6 +52,7 @@ Les audits et rapports de travail `0.4.8-pre.*` sont archivés sous `../olddocs/
|
||||
- [`IDL_TO_KB_LIB_NOMENCLATURE.md`](IDL_TO_KB_LIB_NOMENCLATURE.md) ;
|
||||
- [`MISSING_PROGRAM_IDLS.md`](MISSING_PROGRAM_IDLS.md) ;
|
||||
- [`OPERATION_NAMING_CONVENTION.md`](OPERATION_NAMING_CONVENTION.md) ;
|
||||
- [`NATIVE_FORMAT.md`](NATIVE_FORMAT.md) : format binaire natif versionné de `ks-wallet` ;
|
||||
- [`IDEA_REMINDERS.md`](IDEA_REMINDERS.md).
|
||||
|
||||
Les idées ne rejoignent un `TODO.md` qu’après confirmation, attribution et reformulation en tâche vérifiable.
|
||||
@@ -105,7 +106,7 @@ Les preuves détaillées de `0.4.8-pre.*` restent accessibles sous `../olddocs/a
|
||||
|
||||
Les plans temporaires `0.5.0` et `0.5.1` sont clôturés et archivés sous `../olddocs/archivekbot3/docs/plans/`.
|
||||
|
||||
Le plan détaillé de `0.5.2` sera créé dans sa première prerelease conformément au cycle de développement ; aucun plan temporaire `0.5.2` n’est préécrit avant cet inventaire.
|
||||
Le plan temporaire détaillé de `0.5.2` est actif sous [`plans/V0_5_2_KS_WALLET_RESTRUCTURING_PLAN.md`](plans/V0_5_2_KS_WALLET_RESTRUCTURING_PLAN.md) et sera archivé lors de la dernière prerelease de `0.5.2`.
|
||||
|
||||
## 11. Prompt de reprise
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/plans/V0_5_2_KS_WALLET_RESTRUCTURING_PLAN.md -->
|
||||
<!-- version: 4 -->
|
||||
<!-- version: 6 -->
|
||||
|
||||
# Plan `0.5.2` — restructuration de `ks-wallet`
|
||||
|
||||
@@ -132,9 +132,19 @@ Le format binaire devra au minimum permettre d'identifier sans ambiguïté :
|
||||
- le payload protégé ;
|
||||
- les informations d'intégrité/authentification nécessaires.
|
||||
|
||||
La disposition exacte des champs, l'algorithme AEAD, le KDF, les tailles de nonce/sel et leurs paramètres ne sont **pas** décidés dans `pre.001`. Ils doivent être choisis après vérification des versions réellement résolues des dépendances et des exigences de sécurité.
|
||||
`pre.003` ferme cette décision technique pour le format v1 après vérification des dépendances et des références cryptographiques :
|
||||
|
||||
`argon2`, `chacha20poly1305` et `zeroize` existent déjà dans les dépendances du workspace, mais leur présence ne suffit pas à fixer le contrat.
|
||||
- KDF : Argon2id version 19 ;
|
||||
- profil d'écriture par défaut : 64 MiB, 3 passes, 4 lanes, sel 16 octets, sortie 32 octets ;
|
||||
- AEAD : XChaCha20-Poly1305, clé 32 octets, nonce 24 octets, tag 16 octets ;
|
||||
- header fixe : 72 octets little-endian avant l'alias ;
|
||||
- plaintext v1 : exactement les 64 octets du keypair Solana ;
|
||||
- ciphertext v1 : exactement 80 octets avec le tag AEAD ;
|
||||
- taille totale v1 : 193 à 256 octets selon la longueur de l'alias ;
|
||||
- paramètres KDF acceptés : mémoire 64 à 256 MiB, 3 à 10 passes, 1 à 8 lanes, avec les relations Argon2 de mémoire validées ;
|
||||
- données authentifiées réservées pour `pre.004` : header complet + alias + sel + nonce.
|
||||
|
||||
Le layout normatif exact est documenté dans `docs/NATIVE_FORMAT.md`. `pre.003` décode et valide strictement ces champs pour le scan mais n'encode encore aucun vrai wallet persistant et n'effectue aucune dérivation de clé ni aucun chiffrement réel avec un mot de passe ; la création/écriture reste strictement dans `pre.004`.
|
||||
|
||||
## 4. Caractérisation du legacy actuel
|
||||
|
||||
@@ -480,15 +490,21 @@ Le découpage reste borné mais peut être ajusté si une tranche devient trop l
|
||||
|
||||
Le préambule d'identification introduit ici ne définit pas encore le payload protégé : le codec complet, les bornes du conteneur, KDF et AEAD restent dans `pre.003`.
|
||||
|
||||
### `0.5.2-pre.003` — codec et stockage `.kswallet`
|
||||
### `0.5.2-pre.003` — format et décodage `.kswallet`
|
||||
|
||||
- spécification binaire versionnée ;
|
||||
- sélection et justification KDF/AEAD ;
|
||||
- encode/decode stricts ;
|
||||
- bornes de taille ;
|
||||
- permissions ;
|
||||
- écriture atomique ;
|
||||
- tests corruption/version/atomicité.
|
||||
- [x] spécification binaire v1 documentée dans `docs/NATIVE_FORMAT.md` ;
|
||||
- [x] Argon2id v19 + XChaCha20-Poly1305 retenus et identifiés explicitement dans le header ;
|
||||
- [x] profil KDF par défaut 64 MiB / 3 passes / 4 lanes et bornes anti-DoS ;
|
||||
- [x] décodage/validation stricts avec rejet des versions, flags, algorithmes, réserves et longueurs inconnus ;
|
||||
- [x] plaintext keypair v1 fixé à 64 octets, ciphertext/tag à 80 octets et fichier total à 193..256 octets ;
|
||||
- [x] lecture bornée avant allocation et détection d'une croissance concurrente ;
|
||||
- [x] alias du header vérifié contre le nom `<alias>.kswallet` ;
|
||||
- [x] `WalletFileHandle` enrichi de la pubkey déclarée et de la version sans exposer le chemin ;
|
||||
- [x] validation des permissions privées à la lecture ;
|
||||
- [ ] encodage de création et publication atomique/no-clobber — `pre.004` ;
|
||||
- [x] tests du wire v1, truncation, trailing bytes, KDF hors bornes, alias mismatch et réouverture bornée.
|
||||
|
||||
Aucune vraie keypair n'est encore chiffrée par cette tranche : le password, la dérivation Argon2id, l'appel AEAD et la capacité de signature ouverte restent `pre.004`.
|
||||
|
||||
### `0.5.2-pre.004` — password et cycle de vie persistant
|
||||
|
||||
@@ -587,7 +603,7 @@ Le plan est désormais centré sur les décisions suivantes :
|
||||
14. le format keypair JSON des binaires Solana est obligatoire en import et en export dans `0.5.2` ;
|
||||
15. une matrice officielle des formats Phantom/Solflare/Backpack/Trust/Coinbase-Base et autres cibles pertinentes sera finalisée avant les adaptateurs ;
|
||||
16. un seul adaptateur wallet tiers est implémenté dans `0.5.2` comme exemple, les autres formats faisables étant reportés au TODO sans version déterminée ;
|
||||
17. les détails KDF/AEAD et le modèle runtime d'un wallet ouvert seront décidés dans leurs tranches techniques, après tests et vérification des dépendances ;
|
||||
17. le format v1 utilise Argon2id v19 et XChaCha20-Poly1305 selon `docs/NATIVE_FORMAT.md`, tandis que le modèle runtime d’un wallet ouvert reste à fermer en `pre.004` ;
|
||||
18. le scan automatique reste limité au répertoire configuré, tandis qu'un consommateur peut fournir explicitement un autre chemin `.kswallet` à `ks-wallet` sans modifier le store ni enregistrer ce fichier automatiquement.
|
||||
|
||||
Ces décisions ont permis d'ouvrir `0.5.2-pre.002`.
|
||||
|
||||
Reference in New Issue
Block a user