anchorage_layer_simple/docs/USERWALLET_KEY_DERIVATION.md
ncantu 937646cc45 Daily backup to git cron, backup/restore scripts, docs
**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
2026-02-04 03:07:57 +01:00

61 lines
3.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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) davoir **plusieurs clés publiques** et de **dériver** de nouvelles paires de clés de façon déterministe à partir dune clé privée. Vérifier rapidement si une clé publique donnée « appartient » à une clé privée (clé principale ou lune 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 dobtenir 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 lidentité.
### API (userwallet)
| Fonction | Rôle |
|----------|------|
| `deriveChildKeyPair(parentPrivateKeyHex, index)` | Retourne la paire (privée, publique) pour lindex donné. |
| `getDerivedPublicKeys(parentPrivateKeyHex, count)` | Retourne [clé principale, dérivée(0), …, dérivée(count1)]. Longueur = 1 + count. |
| `publicKeyBelongsToIdentity(identityPrivateKeyHex, publicKeyHex, maxDerived?)` | Vrai si la clé publique est la clé principale ou lune des dérivées dindice 0..maxDerived1. 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..derivedCount1. 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 dappartenance à `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`, `publicKeyBelongsToIdentity`
- `userwallet/src/utils/pairing.ts` : `getPairPublicKeys`, `pairContainsPublicKey`, `addPairPublicKey`
- `userwallet/src/types/identity.ts` : `PairConfig.publicKeys`
## Usage typique
- **Obtenir N clés dérivées** : `getDerivedPublicKeys(identity.privateKey, N)`.
- **Vérifier quune clé appartient à lidentité** (avec au plus 100 dérivées) : `publicKeyBelongsToIdentity(identity.privateKey, somePubKey, 100)`.
- **Vérifier quun pair possède une clé** : `pairContainsPublicKey(pair, somePubKey, identity?.privateKey, 100)`.