Files
2026-08-20 09:24:10 +02:00

8.0 KiB

Delta 0.2.5-pre.009 — security / interoperability / compliance Wallet

Base

0.2.5-pre.8

Le checkpoint opérateur de la base a validé sans warning :

cargo fmt --all
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test -p ksp-wallet-lib
cargo test --workspace

Wallet : 54 passed / 1 ignored en unit tests, 2/2 dependency boundary, 9/9 public API et 2/2 doctests.

Le tree opérateur confirme aussi :

solana-keypair 3.1.2 -> parent KSP direct unique = ksp-wallet-lib
ed25519-dalek 2.2.0 -> génération unique
solana-address 2.7.0 -> génération unique partagée solana-pubkey / solana-keypair

Version workspace cible :

0.2.5-pre.9

Objectif

Cette tranche ne change ni le wire .kspwallet V1 ni les primitives crypto. Elle ferme le gate technique avant pre.010 :

adversarial tests
security contract
independent interoperability verification
dependency/cargo-tree compliance
normative Wallet rules
known limitations made explicit

Canaris adversariaux

Nouveau fichier :

crates/ksp-wallet-lib/unit_tests/security.rs

Il couvre :

OWNER KDF salt tampering         -> wallet.authentication_failed
OWNER wrap tampering             -> wallet.authentication_failed
owner-control tampering          -> wallet.authentication_failed
metadata tampering               -> wallet.authentication_failed
secret tampering                 -> wallet.authentication_failed
state_signature tampering        -> wallet.authentication_failed

state invalid + empty password   -> authentication_failed before Argon2

VIEW wrap tampering only         -> OWNER state signature stays valid
                                 -> OWNER remains unlockable
                                 -> VIEW fails with view_unlock_failed

wrong OWNER/VIEW password        -> generic capability-specific errors
                                 -> no password echo in Display/Debug

Le test de priorité state_signature invalide + password vide matérialise le contrat anti-oracle : la signature OWNER est vérifiée avant tout KDF password.

Frontière publique renforcée

Le canari dependency_boundary vérifie désormais aussi :

pas de dépendance directe solana-signer
pas de dépendance directe solana-signature
pas de re-export public solana-keypair / solana-signer / solana-signature
WalletView ne possède ni sign_message ni export_transfer
WalletTransferFormat reste #[non_exhaustive]

ksp-core-lib::Pubkey reste le seul type Solana public transversal du domaine Wallet ; la keypair secrète reste encapsulée dans Wallet.

Règles normatives Wallet

docs/rules/RULES_KSP.md formalise maintenant :

KSP-WALLET-002  format V1 autonome, sans facteur/ancre externe obligatoire
KSP-WALLET-003  indépendance VIEW / OWNER et capacité VIEW bornée
KSP-WALLET-004  keypair immuable/encapsulée, Pubkey via Core
KSP-WALLET-005  create/import no-clobber
KSP-WALLET-006  chemins fournis par caller, aucun Config/env Wallet
KSP-WALLET-007  état OWNER-signed + limites replacement/rollback total

Interopérabilité externe

Une sonde indépendante hors Rust/KSP a été exécutée pendant la préparation du delta. Elle reproduit les fixtures publiques test-only avec une implémentation distincte :

Argon2id OWNER derived key       exact
Argon2id VIEW derived key        exact
XChaCha20-Poly1305 pre.004       wrapped key exact + unwrap exact
Ed25519 state_signature          vérifiée sur le state_transcript exact
Base58 keypair 64 octets         reproduite indépendamment
Base58 Pubkey 32 octets          reproduite indépendamment

La sonde n'est pas ajoutée au dépôt et ne devient aucune dépendance runtime. Elle utilise les primitives disponibles dans l'environnement Python de préparation et une construction HChaCha20 + ChaCha20-Poly1305 IETF pour le contrôle XChaCha.

Réaudit crypto primaire

Le gate réaudit les références primaires :

RFC 9106   Argon2id
RFC 8032   Ed25519
RustCrypto chacha20poly1305
solana-keypair 3.1.2
tempfile 3.27

RFC 9106 décrit Argon2id, t=3, 64 MiB comme seconde recommandation pour les environnements contraints, cohérente avec le profil de création KSP calibré en pre.005 :

64 MiB / 3 / 1

Les paramètres restent sérialisés par slot ; ce default peut donc évoluer ultérieurement sans casser les wallets existants.

Audit Cargo / doublons

Le tree opérateur pre.008 montre les doublons transitifs suivants :

block-buffer   0.10 / 0.12
cpufeatures    0.2 / 0.3
crypto-common  0.1 / 0.2
digest         0.10 / 0.11
getrandom      0.3 / 0.4
rand           0.9 / 0.10
rand_core      0.6 / 0.9 / 0.10
sha2           0.10 / 0.11
syn            2 / 3

Verdict : acceptés comme transitifs des générations RustCrypto, Solana et Logging actuellement consommées. Wallet ne déclare pas plusieurs versions directes pour contourner les upstream. Les convergences critiques restent obtenues pour Dalek et solana-address.

solana-keypair 3.1.2 conserve un unsafe upstream dans son codec Base58 interne. KSP n'ajoute pas bs58 uniquement pour dupliquer ce codec ; #![forbid(unsafe_code)] continue de s'appliquer au code KSP lui-même.

Extensibilité transfer clarifiée

WalletTransferFormat reste #[non_exhaustive] : les formats built-in sont additifs et les consumers ne peuvent pas considérer la liste comme définitivement fermée.

pre.009 ne crée pas de trait/plugin public arbitraire de codec : un adapter externe d'import/export devrait recevoir/retourner les 64 octets secrets de la keypair, ce qui créerait une nouvelle surface publique de secret. Un vrai besoin futur d'adapters tiers recevra un contrat dédié et audité plutôt qu'une abstraction V1 prématurée.

Limites explicitement conservées

Le verdict security est positif dans le threat model V1, sans revendiquer :

anti-rollback externe
reconnaissance d'un remplacement intégral par un autre wallet valide
CAS filesystem portable linéarisable
atomicité/crash durability identique sur tous les OS/filesystems
garantie cryptographique fondée sur 0600/ACL
effacement physique absolu de toute copie mémoire
protection hardware / OTP / keychain / remote signer

Ces limites doivent rester visibles dans pre.010 et la release stable.

Documentation durable

Ajout :

docs/validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md

Mise à jour :

ROADMAP.md
docs/000-README.md
docs/formats/000-README.md
docs/formats/KSPWALLET_V1.md
docs/plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md
docs/rules/RULES_KSP.md
docs/validation/000-README.md

La prochaine tranche devient pre.010 : documentation finale, README/USAGE de ksp-wallet-lib, synchronisation de clôture et prompt 0.2.6.

Nettoyage test

Le double attribut #[test] accidentel devant owner_and_view_slots_use_independent_kdf_material est réduit à un seul attribut. Aucun comportement de production n'est modifié.

Dépendances

Aucune nouvelle dépendance tierce.

Validation statique de préparation

Le sandbox de préparation ne possède pas Cargo/Rust. Les contrôles statiques ont vérifié :

  • aucune dépendance nouvelle ;
  • aucun accès Config/Transport/Tauri/env/tracing direct/solana-pubkey direct ;
  • aucun unsafe dans les sources Wallet KSP ;
  • aucun changement du wire ni des fixtures ;
  • versions de fichiers modifiés incrémentées ;
  • archive delta limitée aux fichiers ajoutés/modifiés ;
  • reconstruction exacte du delta sur la base pre.008 avant livraison.

Une sonde crypto externe indépendante a en revanche réellement été exécutée comme indiqué plus haut.

Validation opérateur requise

cargo fmt --all
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test -p ksp-wallet-lib
cargo test --workspace

cargo tree -p ksp-wallet-lib
cargo tree -p ksp-wallet-lib -d
cargo tree -i ed25519-dalek@2.2.0
cargo tree -i solana-keypair@3.1.2
cargo tree -i solana-address@2.7.0

Commit attendu

v0.2.5-pre.009