**Motivations:** - Export Signet and mining wallet backups to git with only 2 versions kept - Document and add backup/restore scripts for signet and mining wallet **Correctifs:** - Backup-to-git uses SSH URL for passwordless cron; copy timestamped files only; prune to 2 versions; remove *-latest from backup repo **Evolutions:** - data/backup-to-git-cron.sh: daily export to git.4nkweb.com/4nk/backup - save-signet-datadir-backup.sh, restore-signet-from-backup.sh, export-mining-wallet.sh, import-mining-wallet.sh - features/backup-to-git-daily-cron.md, docs/MAINTENANCE.md backup section - .gitignore: data/backup-to-git.log **Pages affectées:** - .gitignore, data/backup-to-git-cron.sh, docs/MAINTENANCE.md, features/backup-to-git-daily-cron.md - save-signet-datadir-backup.sh, restore-signet-from-backup.sh, export-mining-wallet.sh, import-mining-wallet.sh - Plus autres fichiers modifiés ou non suivis déjà présents dans le working tree
3.9 KiB
UserWallet — Dérivation de clés et clés multiples par pair
Author: Équipe 4NK
Date: 2026-02-02
Version: 1.0
Objectif
Permettre à un pair (identité locale ou appareil distant) d’avoir plusieurs clés publiques et de dériver de nouvelles paires de clés de façon déterministe à partir d’une clé privée. Vérifier rapidement si une clé publique donnée « appartient » à une clé privée (clé principale ou l’une des clés dérivées).
Modèle de données
PairConfig
publicKey?: string— Clé publique principale (hex 66 caractères). Utilisée pour ECDH, pairing, etc.publicKeys?: string[]— Liste optionnelle de clés publiques supplémentaires. Un pair « possède » toute clé dans{ publicKey } ∪ publicKeys.
Un pair peut donc avoir un nombre important de clés publiques différentes (principale + dérivées ou ajoutées).
Dérivation déterministe (crypto)
Une seule clé privée permet d’obtenir plusieurs paires (clé privée enfant, clé publique enfant) sans stocker plusieurs secrets. La dérivation est déterministe : même index ⇒ même paire.
Algorithme
- Entrée : clé privée parente (64 hex), index ≥ 0.
- Procédé : HMAC-SHA256(clé_privée_parente,
"userwallet-derive-v1-"+ index) → 32 octets ; réduction modulo (ordre de la courbe secp256k1 − 1) + 1 pour obtenir un scalaire valide ; clé publique = multiplication du point de base par ce scalaire (format compressé). - Sortie : paire (clé privée enfant, clé publique enfant).
Courbe : secp256k1 (même que Bitcoin). La clé principale (index « aucun ») est la clé publique dérivée directement de la clé privée de l’identité.
API (userwallet)
| Fonction | Rôle |
|---|---|
deriveChildKeyPair(parentPrivateKeyHex, index) |
Retourne la paire (privée, publique) pour l’index donné. |
getDerivedPublicKeys(parentPrivateKeyHex, count) |
Retourne [clé principale, dérivée(0), …, dérivée(count−1)]. Longueur = 1 + count. |
publicKeyBelongsToIdentity(identityPrivateKeyHex, publicKeyHex, maxDerived?) |
Vrai si la clé publique est la clé principale ou l’une des dérivées d’indice 0..maxDerived−1. Par défaut maxDerived = 0 (seule la clé principale est testée). |
Performance : la vérification « cette clé appartient-elle à mon identité ? » est en O(1) pour la clé principale (une dérivation + comparaison). Pour les dérivées, au plus maxDerived dérivations + comparaisons ; en pratique on borne maxDerived pour rester rapide.
Pairing (pairs et multi-clés)
| Fonction | Rôle |
|---|---|
getPairPublicKeys(pair, identityPrivateKeyHex?, derivedCount?) |
Liste toutes les clés publiques du pair. Pour le pair local + clé privée fournie : clé principale + dérivées 0..derivedCount−1. Pour un pair distant : publicKey + publicKeys. |
pairContainsPublicKey(pair, publicKeyHex, identityPrivateKeyHex?, maxDerived?) |
Vrai si le pair possède cette clé (locale : dérivation bornée ; distant : test d’appartenance à publicKey / publicKeys). |
addPairPublicKey(pairUuid, publicKeyHex) |
Ajoute une clé à publicKeys du pair (sans doublon avec publicKey). |
Fichiers concernés
userwallet/src/utils/crypto.ts:deriveChildKeyPair,getDerivedPublicKeys,publicKeyBelongsToIdentityuserwallet/src/utils/pairing.ts:getPairPublicKeys,pairContainsPublicKey,addPairPublicKeyuserwallet/src/types/identity.ts:PairConfig.publicKeys
Usage typique
- Obtenir N clés dérivées :
getDerivedPublicKeys(identity.privateKey, N). - Vérifier qu’une clé appartient à l’identité (avec au plus 100 dérivées) :
publicKeyBelongsToIdentity(identity.privateKey, somePubKey, 100). - Vérifier qu’un pair possède une clé :
pairContainsPublicKey(pair, somePubKey, identity?.privateKey, 100).