v0.2.5-pre.003
This commit is contained in:
12
docs/formats/000-README.md
Normal file
12
docs/formats/000-README.md
Normal file
@@ -0,0 +1,12 @@
|
||||
<!-- file: docs/formats/000-README.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Formats KSP
|
||||
|
||||
Ce répertoire contient les spécifications de formats durables appartenant à KSP et destinées à être implémentables indépendamment du code source Rust.
|
||||
|
||||
Une spécification de format décrit le wire exact, les encodages, les limites, les règles de parsing/rejet, les données authentifiées et les procédures d'interopérabilité nécessaires. Elle ne dépend pas d'un type Rust interne comme condition de compréhension.
|
||||
|
||||
## 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.
|
||||
617
docs/formats/KSPWALLET_V1.md
Normal file
617
docs/formats/KSPWALLET_V1.md
Normal file
@@ -0,0 +1,617 @@
|
||||
<!-- file: docs/formats/KSPWALLET_V1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# `.kspwallet` V1 — spécification du format natif Wallet KSP
|
||||
|
||||
## 1. Statut et objectif
|
||||
|
||||
Ce document est l'autorité normative du **wire `.kspwallet` `format_version = 1`**.
|
||||
|
||||
`0.2.5-pre.003` fige :
|
||||
|
||||
```text
|
||||
enveloppe JSON UTF-8 stricte
|
||||
encodage Base64url sans padding
|
||||
key slots OWNER / VIEW
|
||||
limites structurelles V1
|
||||
transcript binaire OWNER
|
||||
AAD de wrapping OWNER / VIEW
|
||||
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`.
|
||||
|
||||
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`.
|
||||
|
||||
## 2. Modèle de confiance V1
|
||||
|
||||
V1 est **autonome**. Ouvrir un wallet ne requiert aucun :
|
||||
|
||||
```text
|
||||
salt externe
|
||||
pepper KSP
|
||||
OTP
|
||||
secret compilé dans KSP
|
||||
service distant
|
||||
réseau
|
||||
keychain OS
|
||||
fichier secret annexe
|
||||
ancre de confiance externe
|
||||
```
|
||||
|
||||
Tous les salts, nonces, paramètres KDF, wrapped keys, ciphertexts et éléments nécessaires à l'interprétation cryptographique sont dans le fichier.
|
||||
|
||||
Sans password OWNER, un détenteur du fichier ne doit pas obtenir la keypair Solana, signer, exporter le secret ni produire une modification OWNER-authentifiée des metadata. VIEW donne uniquement accès à Pubkey/alias/notes et à la rotation de **son propre password VIEW**.
|
||||
|
||||
Les ACL et permissions du système de fichiers sont hors du contrat cryptographique de `.kspwallet`. Remplacer entièrement un fichier par un autre wallet valide ne révèle pas l'ancien secret et revient à substituer une autre identité Wallet.
|
||||
|
||||
## 3. Encodage général
|
||||
|
||||
Le document est :
|
||||
|
||||
```text
|
||||
JSON
|
||||
UTF-8
|
||||
objet top-level unique
|
||||
maximum 1 048 576 octets
|
||||
trailing whitespace JSON autorisé
|
||||
trailing data non-whitespace interdit
|
||||
```
|
||||
|
||||
L'ordre des propriétés JSON n'est **pas sémantique**. Une implémentation peut réordonner ou réindenter le JSON sans changer le transcript cryptographique tant que l'état sémantique parsé est identique.
|
||||
|
||||
Tous les champs binaires utilisent **Base64url RFC 4648 alphabet URL-safe, sans padding** :
|
||||
|
||||
```text
|
||||
alphabet : A-Z a-z 0-9 - _
|
||||
padding = interdit
|
||||
trailing bits non canoniques = interdits
|
||||
```
|
||||
|
||||
Le parsing normatif effectue conceptuellement :
|
||||
|
||||
```text
|
||||
decode Base64url sans padding
|
||||
-> re-encode Base64url sans padding
|
||||
-> la chaîne obtenue doit être exactement égale à l'entrée
|
||||
```
|
||||
|
||||
## 4. Magic et version
|
||||
|
||||
Valeurs V1 :
|
||||
|
||||
```text
|
||||
magic = "KSPWALLET"
|
||||
format_version = 1
|
||||
```
|
||||
|
||||
Un `magic` différent est invalide.
|
||||
|
||||
Un `format_version` différent doit être signalé comme **version non supportée**, et non interprété avec la grammaire V1.
|
||||
|
||||
`format_version` ne change pas lors d'une rotation de password, d'une modification d'alias/note ou d'une réécriture atomique.
|
||||
|
||||
## 5. Enveloppe JSON exacte
|
||||
|
||||
La forme V1 est :
|
||||
|
||||
```json
|
||||
{
|
||||
"magic": "KSPWALLET",
|
||||
"format_version": 1,
|
||||
"owner_auth_public_key": "<32 octets Base64url>",
|
||||
"view_descriptor": {
|
||||
"enabled": true,
|
||||
"slot_id": "<16 octets Base64url ou null>"
|
||||
},
|
||||
"key_slots": [
|
||||
{
|
||||
"slot_id": "<16 octets Base64url>",
|
||||
"role": "owner",
|
||||
"kdf": {
|
||||
"algorithm": "argon2id",
|
||||
"version": 19,
|
||||
"memory_kib": 65536,
|
||||
"iterations": 3,
|
||||
"parallelism": 1,
|
||||
"salt": "<16..64 octets Base64url>"
|
||||
},
|
||||
"wrap": {
|
||||
"algorithm": "xchacha20-poly1305",
|
||||
"nonce": "<24 octets Base64url>",
|
||||
"ciphertext": "<Base64url>"
|
||||
}
|
||||
},
|
||||
{
|
||||
"slot_id": "<16 octets Base64url>",
|
||||
"role": "view",
|
||||
"kdf": {
|
||||
"algorithm": "argon2id",
|
||||
"version": 19,
|
||||
"memory_kib": 32768,
|
||||
"iterations": 4,
|
||||
"parallelism": 1,
|
||||
"salt": "<16..64 octets Base64url>"
|
||||
},
|
||||
"wrap": {
|
||||
"algorithm": "xchacha20-poly1305",
|
||||
"nonce": "<24 octets Base64url>",
|
||||
"ciphertext": "<Base64url>"
|
||||
}
|
||||
}
|
||||
],
|
||||
"owner_control": {
|
||||
"control_version": 1,
|
||||
"algorithm": "xchacha20-poly1305",
|
||||
"nonce": "<24 octets Base64url>",
|
||||
"ciphertext": "<Base64url>"
|
||||
},
|
||||
"metadata": {
|
||||
"metadata_version": 1,
|
||||
"algorithm": "xchacha20-poly1305",
|
||||
"nonce": "<24 octets Base64url>",
|
||||
"ciphertext": "<Base64url>"
|
||||
},
|
||||
"secret": {
|
||||
"secret_version": 1,
|
||||
"algorithm": "xchacha20-poly1305",
|
||||
"nonce": "<24 octets Base64url>",
|
||||
"ciphertext": "<Base64url>"
|
||||
},
|
||||
"state_signature": {
|
||||
"algorithm": "ed25519",
|
||||
"signature": "<64 octets Base64url>"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Les valeurs Argon2 chiffrées dans cet exemple sont **des valeurs de fixture structurelle**, pas les defaults de création V1. Les defaults ne deviennent normatifs qu'après benchmark de `pre.004`.
|
||||
|
||||
## 6. `owner_auth_public_key`
|
||||
|
||||
`owner_auth_public_key` contient exactement **32 octets** : la clé publique Ed25519 de l'autorité d'administration du format Wallet.
|
||||
|
||||
Elle est distincte de la keypair Solana. La Pubkey Solana reste dans le compartiment metadata chiffré et ne doit pas apparaître dans l'enveloppe verrouillée.
|
||||
|
||||
La clé privée correspondant à `owner_auth_public_key` appartient au matériau OWNER protégé ; elle n'est jamais un champ public du fichier.
|
||||
|
||||
## 7. Descripteur VIEW
|
||||
|
||||
`view_descriptor` est OWNER-authentifié.
|
||||
|
||||
Règles :
|
||||
|
||||
```text
|
||||
enabled = true => slot_id contient exactement 16 octets et un unique slot role="view" possède le même slot_id
|
||||
enabled = false => slot_id est null et aucun slot role="view" n'existe
|
||||
```
|
||||
|
||||
Le `slot_id` VIEW est stable pendant une rotation self-service du password VIEW.
|
||||
|
||||
VIEW peut modifier uniquement les paramètres de protection de **son slot VIEW courant** dans les limites V1 et rewrapper la même capability metadata. VIEW ne peut pas modifier le descripteur signé, désactiver/recréer VIEW ou transformer son slot en OWNER.
|
||||
|
||||
## 8. Key slots
|
||||
|
||||
V1 accepte :
|
||||
|
||||
```text
|
||||
exactement 1 slot role="owner"
|
||||
0 ou 1 slot role="view"
|
||||
maximum total = 2
|
||||
slot_id unique entre les slots
|
||||
```
|
||||
|
||||
L'ordre des entrées dans le tableau JSON `key_slots` n'est pas sémantique. Pour le transcript, OWNER est traité séparément et VIEW est représenté par son descripteur stable.
|
||||
|
||||
### 8.1 KDF
|
||||
|
||||
Identifiant V1 :
|
||||
|
||||
```text
|
||||
algorithm = "argon2id"
|
||||
version = 19
|
||||
```
|
||||
|
||||
Bornes structurelles de parsing :
|
||||
|
||||
```text
|
||||
memory_kib : 1 .. 1 048 576
|
||||
iterations : 1 .. 64
|
||||
parallelism : 1 .. 64
|
||||
salt : 16 .. 64 octets
|
||||
```
|
||||
|
||||
Ces plafonds sont des bornes de format/rejet hostile ; ils ne définissent pas les paramètres de **création par défaut**. Ceux-ci sont benchmarkés séparément.
|
||||
|
||||
Le password KDF futur est la séquence exacte des octets UTF-8 fournis, sans normalisation Unicode implicite, avec une longueur maximale de 1024 octets et un password vide refusé à la création.
|
||||
|
||||
### 8.2 Wrapping
|
||||
|
||||
Identifiant V1 :
|
||||
|
||||
```text
|
||||
algorithm = "xchacha20-poly1305"
|
||||
nonce = 24 octets
|
||||
ciphertext >= 16 octets
|
||||
ciphertext <= 4096 octets
|
||||
```
|
||||
|
||||
Le ciphertext contient le tag Poly1305 de 16 octets produit par l'AEAD.
|
||||
|
||||
Le contenu plaintext exact des wrapped capabilities est figé avec la couche crypto/payload suivante ; la grammaire envelope/key-slot et son AAD sont déjà figés ici.
|
||||
|
||||
## 9. Compartiments chiffrés
|
||||
|
||||
Trois compartiments indépendants existent :
|
||||
|
||||
```text
|
||||
owner_control
|
||||
metadata
|
||||
secret
|
||||
```
|
||||
|
||||
Leurs versions initiales sont indépendantes :
|
||||
|
||||
```text
|
||||
control_version = 1
|
||||
metadata_version = 1
|
||||
secret_version = 1
|
||||
```
|
||||
|
||||
Les trois utilisent :
|
||||
|
||||
```text
|
||||
algorithm = "xchacha20-poly1305"
|
||||
nonce = 24 octets
|
||||
```
|
||||
|
||||
Bornes ciphertext V1 :
|
||||
|
||||
```text
|
||||
owner_control : 16 .. 4096 octets
|
||||
metadata : 16 .. 65 552 octets
|
||||
secret : 16 .. 4096 octets
|
||||
```
|
||||
|
||||
La metadata plaintext V1 reste bornée à 65 536 octets. Les payloads plaintext exacts sont consolidés dans la tranche dédiée, mais les champs wire ci-dessus ne changent pas.
|
||||
|
||||
Le compartiment metadata contient à terme au minimum :
|
||||
|
||||
```text
|
||||
Pubkey Solana Base58 canonique
|
||||
alias optionnel <= 256 octets UTF-8
|
||||
maximum 64 notes
|
||||
texte note <= 8192 octets UTF-8
|
||||
id de note = 16 octets aléatoires
|
||||
```
|
||||
|
||||
Le compartiment secret contient la keypair Solana exacte nécessaire à la signature OWNER.
|
||||
|
||||
## 10. Signature d'état OWNER
|
||||
|
||||
V1 :
|
||||
|
||||
```text
|
||||
algorithm = "ed25519"
|
||||
signature = 64 octets
|
||||
```
|
||||
|
||||
La signature porte sur le **transcript sémantique OWNER-controlled**, jamais sur les octets JSON bruts.
|
||||
|
||||
`state_signature.signature` elle-même est exclue du transcript. L'identifiant `algorithm = "ed25519"` est inclus.
|
||||
|
||||
Les paramètres/salt/nonce/ciphertext du slot VIEW self-service sont exclus de la signature OWNER ; le descripteur stable VIEW est inclus.
|
||||
|
||||
## 11. Codec binaire transcript/AAD
|
||||
|
||||
### 11.1 Préfixe de domaine
|
||||
|
||||
Chaque transcript/AAD commence par :
|
||||
|
||||
```text
|
||||
ASCII(domain_separator) || 0x00
|
||||
```
|
||||
|
||||
### 11.2 Champ TLV
|
||||
|
||||
Chaque champ suivant utilise exactement :
|
||||
|
||||
```text
|
||||
tag : u16 big-endian
|
||||
length : u64 big-endian
|
||||
value : `length` octets
|
||||
```
|
||||
|
||||
Un entier `u32` est encodé dans `value` comme **4 octets big-endian**.
|
||||
|
||||
Un booléen est encodé comme un octet :
|
||||
|
||||
```text
|
||||
false = 0x00
|
||||
true = 0x01
|
||||
```
|
||||
|
||||
Les champs binaires sont les **octets décodés** du Base64url, jamais le texte Base64url.
|
||||
|
||||
### 11.3 Tags V1
|
||||
|
||||
| Tag hex | Champ |
|
||||
|--------:|----------------------------------------------------|
|
||||
| `0001` | magic |
|
||||
| `0002` | format_version |
|
||||
| `0003` | owner_auth_public_key |
|
||||
| `0010` | view enabled |
|
||||
| `0011` | rôle VIEW littéral `view` |
|
||||
| `0012` | view slot_id ; longueur zéro lorsque VIEW disabled |
|
||||
| `0100` | slot_id |
|
||||
| `0101` | slot role |
|
||||
| `0102` | KDF algorithm |
|
||||
| `0103` | KDF version |
|
||||
| `0104` | KDF memory_kib |
|
||||
| `0105` | KDF iterations |
|
||||
| `0106` | KDF parallelism |
|
||||
| `0107` | KDF salt |
|
||||
| `0108` | wrap algorithm |
|
||||
| `0109` | wrap nonce |
|
||||
| `010A` | wrap ciphertext |
|
||||
| `0200` | compartment kind |
|
||||
| `0201` | compartment payload version |
|
||||
| `0202` | compartment algorithm |
|
||||
| `0203` | compartment nonce |
|
||||
| `0204` | compartment ciphertext |
|
||||
| `0500` | state-signature algorithm |
|
||||
|
||||
Les tags ne remplacent pas l'ordre normatif ; **l'ordre ci-dessous est obligatoire**.
|
||||
|
||||
## 12. Transcript OWNER state signature
|
||||
|
||||
Domain separator :
|
||||
|
||||
```text
|
||||
KSPWALLET-V1-STATE
|
||||
```
|
||||
|
||||
Ordre exact :
|
||||
|
||||
```text
|
||||
0001 magic = ASCII "KSPWALLET"
|
||||
0002 format_version = u32 BE 1
|
||||
0003 owner_auth_public_key = 32 octets
|
||||
|
||||
0010 view enabled = 00/01
|
||||
0011 ASCII "view"
|
||||
0012 view slot_id = 16 octets si enabled, longueur 0 sinon
|
||||
|
||||
OWNER slot uniquement :
|
||||
0100 owner slot_id
|
||||
0101 ASCII "owner"
|
||||
0102 ASCII "argon2id"
|
||||
0103 Argon2 version u32 BE
|
||||
0104 memory_kib u32 BE
|
||||
0105 iterations u32 BE
|
||||
0106 parallelism u32 BE
|
||||
0107 owner salt
|
||||
0108 ASCII "xchacha20-poly1305"
|
||||
0109 owner wrap nonce
|
||||
010A owner wrap ciphertext
|
||||
|
||||
owner_control :
|
||||
0200 ASCII "owner-control"
|
||||
0201 control_version u32 BE
|
||||
0202 ASCII "xchacha20-poly1305"
|
||||
0203 nonce
|
||||
0204 ciphertext
|
||||
|
||||
metadata :
|
||||
0200 ASCII "metadata"
|
||||
0201 metadata_version u32 BE
|
||||
0202 ASCII "xchacha20-poly1305"
|
||||
0203 nonce
|
||||
0204 ciphertext
|
||||
|
||||
secret :
|
||||
0200 ASCII "secret"
|
||||
0201 secret_version u32 BE
|
||||
0202 ASCII "xchacha20-poly1305"
|
||||
0203 nonce
|
||||
0204 ciphertext
|
||||
|
||||
0500 ASCII "ed25519"
|
||||
```
|
||||
|
||||
Sont explicitement **exclus** du transcript OWNER :
|
||||
|
||||
```text
|
||||
VIEW KDF parameters
|
||||
VIEW salt
|
||||
VIEW wrap nonce
|
||||
VIEW wrap ciphertext
|
||||
state_signature.signature
|
||||
```
|
||||
|
||||
Cette exclusion autorise VIEW à changer son propre password en rewrappant sa capability sans posséder l'autorité OWNER. Elle ne lui permet pas de modifier metadata/secret/OWNER state, qui restent signés.
|
||||
|
||||
## 13. AAD des key slots
|
||||
|
||||
### 13.1 OWNER
|
||||
|
||||
Domain separator :
|
||||
|
||||
```text
|
||||
KSPWALLET-V1-AAD-OWNER-SLOT
|
||||
```
|
||||
|
||||
Ordre exact :
|
||||
|
||||
```text
|
||||
0001 magic
|
||||
0002 format_version
|
||||
0003 owner_auth_public_key
|
||||
0100 slot_id
|
||||
0101 "owner"
|
||||
0102 "argon2id"
|
||||
0103 KDF version
|
||||
0104 memory_kib
|
||||
0105 iterations
|
||||
0106 parallelism
|
||||
0107 salt
|
||||
0108 "xchacha20-poly1305"
|
||||
```
|
||||
|
||||
Le nonce est passé séparément à l'AEAD et n'est pas répété dans l'AAD. Le ciphertext/tag est le résultat AEAD et n'appartient pas à son propre AAD.
|
||||
|
||||
### 13.2 VIEW
|
||||
|
||||
Domain separator :
|
||||
|
||||
```text
|
||||
KSPWALLET-V1-AAD-VIEW-SLOT
|
||||
```
|
||||
|
||||
La suite TLV est identique à OWNER sauf :
|
||||
|
||||
```text
|
||||
0101 = ASCII "view"
|
||||
0100 = slot_id VIEW signé par view_descriptor
|
||||
```
|
||||
|
||||
Les paramètres KDF/salt sont volontairement dans l'AAD calculé pour **l'état courant** du slot VIEW. VIEW peut les remplacer lors d'une rotation de son password, puis produire un nouveau wrapping valide de la même capability metadata.
|
||||
|
||||
## 14. AAD des compartiments
|
||||
|
||||
Les trois AAD commencent par les champs communs :
|
||||
|
||||
```text
|
||||
0001 magic
|
||||
0002 format_version
|
||||
0003 owner_auth_public_key
|
||||
```
|
||||
|
||||
Puis :
|
||||
|
||||
```text
|
||||
0200 compartment kind
|
||||
0201 compartment payload version
|
||||
0202 "xchacha20-poly1305"
|
||||
```
|
||||
|
||||
Domain separators :
|
||||
|
||||
```text
|
||||
owner_control : KSPWALLET-V1-AAD-OWNER-CONTROL
|
||||
metadata : KSPWALLET-V1-AAD-METADATA
|
||||
secret : KSPWALLET-V1-AAD-SECRET
|
||||
```
|
||||
|
||||
Valeurs de `compartment kind` :
|
||||
|
||||
```text
|
||||
owner-control
|
||||
metadata
|
||||
secret
|
||||
```
|
||||
|
||||
Le nonce est fourni séparément à l'AEAD et le ciphertext/tag est le résultat de l'opération ; ni l'un ni l'autre n'est dupliqué dans cet AAD.
|
||||
|
||||
## 15. Parsing et rejet stricts
|
||||
|
||||
V1 rejette :
|
||||
|
||||
```text
|
||||
magic inconnu
|
||||
champ top-level inconnu
|
||||
champ nested inconnu
|
||||
champ requis absent
|
||||
champ dupliqué JSON
|
||||
role slot autre que owner/view
|
||||
algorithme autre que les identifiants V1
|
||||
Argon2 version autre que 19
|
||||
KDF hors bornes structurelles
|
||||
Base64url invalide, paddé ou non canonique
|
||||
owner_auth_public_key != 32 octets
|
||||
slot_id != 16 octets
|
||||
XChaCha nonce != 24 octets
|
||||
state signature != 64 octets
|
||||
OWNER slot absent ou dupliqué
|
||||
VIEW slot dupliqué
|
||||
slot_id OWNER == slot_id VIEW
|
||||
VIEW descriptor incohérent avec VIEW slot
|
||||
payload version autre que 1
|
||||
ciphertext sous 16 octets ou au-dessus de sa borne V1
|
||||
document > 1 MiB
|
||||
trailing data non-whitespace
|
||||
```
|
||||
|
||||
La vérification de taille du document précède le parsing JSON et toute opération KDF coûteuse.
|
||||
|
||||
## 16. JSON produit par KSP
|
||||
|
||||
Le serializer KSP V1 émet actuellement :
|
||||
|
||||
```text
|
||||
JSON pretty-print
|
||||
ordre stable des champs du modèle KSP
|
||||
OWNER slot avant VIEW slot
|
||||
newline final
|
||||
```
|
||||
|
||||
Cet ordre et ce pretty-print sont un **profil de sortie KSP**, pas une canonicalisation cryptographique. Une implémentation externe conforme peut produire un autre ordre/espacement JSON si le parsing V1 aboutit au même état sémantique.
|
||||
|
||||
## 17. Checksum
|
||||
|
||||
Aucun checksum supplémentaire V1.
|
||||
|
||||
La détection cryptographique repose sur :
|
||||
|
||||
```text
|
||||
AEAD des wrapped keys/compartiments
|
||||
state_signature OWNER pour l'état OWNER-controlled
|
||||
AAD domain-separated
|
||||
```
|
||||
|
||||
Un checksum non authentifié n'ajouterait pas de garantie de sécurité utile.
|
||||
|
||||
## 18. Fixture structurelle `pre.003`
|
||||
|
||||
Le dépôt contient :
|
||||
|
||||
```text
|
||||
crates/ksp-wallet-lib/tests/fixtures/kspwallet_v1_wire_only.json
|
||||
```
|
||||
|
||||
Cette fixture est **wire-only et test-only** :
|
||||
|
||||
```text
|
||||
ses ciphertexts sont des octets artificiels
|
||||
sa signature est artificielle
|
||||
elle ne constitue pas un wallet cryptographiquement valide
|
||||
elle ne fixe pas les defaults Argon2 de production
|
||||
elle ne contient aucune clé réelle
|
||||
```
|
||||
|
||||
Elle fige néanmoins :
|
||||
|
||||
```text
|
||||
JSON V1
|
||||
Base64url
|
||||
longueurs
|
||||
slots/descripteur
|
||||
transcript OWNER exact
|
||||
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.
|
||||
|
||||
## 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.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.
|
||||
Reference in New Issue
Block a user