ncantu cad73cb265 UTXO-list: dates/blockTime historiques, récupération frais depuis ancrages, diagnostic Bloc Rewards
**Motivations:**
- Ajouter dates manquantes dans hash_list.txt et compléter historique
- Compléter blockTime manquants dans utxo_list.txt et compléter historique
- Récupérer frais depuis transactions d'ancrage (OP_RETURN) et les stocker
- Bouton UI pour déclencher récupération frais
- Diagnostic Bloc Rewards (pourquoi ~4700 BTC au lieu de 50 BTC)

**Root causes:**
- hash_list.txt sans date (format ancien)
- utxo_list.txt blockTime souvent vide
- Frais absents du fichier (métadonnées OP_RETURN non stockées)
- Pas de moyen de récupérer/compléter frais depuis UI

**Correctifs:**
- hash_list.txt : format étendu avec date (rétrocompatible)
- utxo_list.txt : blockTime complété automatiquement lors écritures
- fees_list.txt : nouveau fichier pour stocker frais
- updateFeesFromAnchors() : récupère frais depuis OP_RETURN ancrages
- Endpoint /api/utxo/fees/update pour déclencher récupération
- Bouton "Récupérer les frais depuis les ancrages" dans section Frais (spinner)
- Scripts batch : complete-hash-list-dates.js, complete-utxo-list-blocktime.js
- Script diagnostic : diagnose-bloc-rewards.js (subsidy, coinbase, listunspent)

**Evolutions:**
- Frais chargés depuis fees_list.txt dans getUtxoList
- Complétion automatique dates/blockTime lors écritures futures

**Pages affectées:**
- signet-dashboard/src/bitcoin-rpc.js
- signet-dashboard/src/server.js
- signet-dashboard/public/utxo-list.html
- scripts/complete-hash-list-dates.js
- scripts/complete-utxo-list-blocktime.js
- scripts/diagnose-bloc-rewards.js
- features/utxo-list-fees-update-and-historical-completion.md
2026-01-26 01:59:46 +01:00

2047 lines
63 KiB
Markdown
Raw 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.

## Synthèse
- **Modèle** : Messages publiés sans signatures ni clés ; signatures et clés publiées séparément ; tout adressé par hash canonique ; récupération par **GET uniquement** (pull).
- **Objets** : Service, Contrat, Champ, Action, ActionLogin, Membre, Pair, MessageBase, Hash, Signature, Validateurs, MsgChiffre, MsgSignature, MsgCle.
- **Graphe** : Service → Contrat → Champ → Action(login) → Membre → Pair ; contraintes « au moins 1 parent ».
- **Pairing** : UUID pair ↔ mots BIP32 ; pairing **obligatoire** pour login.
- **Écrans** : accueil, création/import identité, relais, pairing, sync, services, chemin login, challenge, signatures mFA, publication, résultat.
- **Machine à états** : S_INIT → S_HOME, S_SYNC_GLOBAL, S_PAIR_*, S_LOGIN_*, etc., avec erreurs récupérables / fatales.
---
Lister les étapes et ecran d'un login basé sur ce principe :
* Génération de cles secp256k1 pour signer et vérifier les signatures
* login sans serveur central par verification de conformité contrat / signature
* pairing obligatoire pour se connecter (mFA)
Contrat d'identié avec types name: au moins
Service:
Contrat
Type names chiffrés dont service
Contrat :
Message à valider
types name chiffrés dont contrat
Champ :
Message à valider
types name chiffrés dont champ
+ contrats parents uuid, au mois 1
ActionLogin:
Action
Types names chiffrés dont login
Action:
Message à valider
types name chiffrés dont action
+ Validateurs de l'action
+ contrats parents uuid, au moins 1
Membre :
Message à valider
types name chiffrés dont membre
Actions parents uuid, au moins 1
Pair :
MessageBase
Types names chiffrés dont pair
Membres parents uuid, au moins 1
Message Base:
Hash du JSON sans le hash, sans la signature
uuid
Version
Types names chiffrés dont pair
Clés de chiffrement avec tous les paramètres et l'algo
Datajson dont les attributs :
- Obligatoires : services uuid, types uuid
- optionnels :label, description longue, description courte, photo, image, bannière, URL, paragraphes (couples de textes + images), tarif
Timestpamp
Liste de relais (IP)
Hash du JSON signé du pair avec dans la signature le hash, la clé publique et la signature
Version logicielle
Hash :
* Hash du JSON (sans le hash, sans les signatures, sans clés de chiffrement)
* Algo
Signature :
* hash
* clé publique
* signature cryptographique
* Nonce et autre matériel éventuel
Message à valider :
* MessageBase +
* Validateurs du message
Validateurs:
Listes des membres du role, au moins 1
* Pour chacun des membres : la liste des signatures obligatoires des autres membres et/ou de lui même
Message individuel de déchiffrement :
* hash du message
* clé de chiffrement du message chiffré: + clé de chiffrement chiffrée avec tous le paramètres et algo
* df : + diffie-hellman à scanner contenant une clé de déchiffrement de la clé de déchiffrement dans le secret partagé
Message de signature :
* Signature
Les messages sont postés sans les signatures et sans les clés de chiffrement, les signatures et les cles sont postées spécifiquement après. Les messages sont tous envoyés chiffrés de type:
* hash
* Message chiffré
* datajson public
LEs signatures et les clés de chiffrement ne sont pas récupérées au get elles sont récupérées spécifiquement apres et ajoutés aux messages stockés
Tous les envois passent par des relais qui stockent et relaient entre relais (sauvegarde des hash pour ne pas relayer ceux déjà reçus)
Périodiquement et par services les client font des cet pour récupérer les informations
Chacun publie pour tous sans destinataire indiqué mais chiffré. Mais un diffie hellman est possible avec tous les pairs concernés pour d'échanger par la suite des clés de déchiffrement entre clé publiques, ce matériel exploitable que par les parties concernées est envoyé lors des échanges de clés
Pour ajouter un uuid d'un pair à un un membre celui ci est converti via bip32 en une liste de mots puis reconstitué (device 2 affiche les mots, device les saisis), ainsi l'uuid est une clé qui ne sert que d'identifiant
Pour se logguer il faut founir des signatures des pairs attendues dans l'action de type login de ce membre ayant dans ses services parents uuid l'uuid du service sur lequel il veut se connecter
Pour savoir si il y a un message à récupérer et déchiffrer il faut récupérer et scanner tous (depuis la date anniversaire de création des clés)les messages de clés depuis (proposer un bloom filtrer et/ou des arbres de merkle pur gérer l'historique des hash et ne pas tout rescanner) aucun message n'est reçu ils sont tous récupérés (get) en fonction des deffie hellman
Introduction
Ce qui suit décrit, de manière opérationnelle, les étapes et les écrans dun login fondé sur des clés secp256k1, une validation “sans serveur central” (conformité des contrats et signatures), et un pairing obligatoire jouant le rôle de second facteur. La description suppose un réseau de relais stockant et relayant des objets immuables adressés par hash, avec séparation stricte entre messages, signatures et clés de chiffrement, récupérées par appels dédiés.
Principes structurants à respecter à chaque étape
Séparation des flux et des objets
* Un message “métier” est publié sans signatures et sans clés de chiffrement.
* Les signatures sont publiées ensuite, séparément, via des objets “Message de signature”.
* Les clés (ou matériels) de déchiffrement sont publiées ensuite, séparément, via des objets “Message individuel de déchiffrement”.
* Les requêtes de récupération ne renvoient pas automatiquement signatures et clés ; elles sont récupérées explicitement et rattachées localement au message stocké.
Adressage et immutabilité
* Tout objet est adressé par hash (hash du JSON canonique “sans hash, sans signatures, sans clés de chiffrement” selon la règle donnée).
* Un relais conserve lhistorique des hash reçus pour ne pas relayer deux fois.
Confidentialité “publish to all”
* Tout est publié sans destinataire explicite.
* Le contenu utile est chiffré ; seuls les pairs capables dobtenir (ou de dériver) la clé de déchiffrement peuvent lire.
* Les échanges de matériels de déchiffrement peuvent sappuyer sur Diffie-Hellman (ECDH secp256k1) entre clés publiques concernées ; le “matériel DH” est publiable car inexploitable par les tiers.
Conformité “contrat / signature”
* La “vérité” dun login provient de la vérification locale dun graphe de contrats (service → contrat → champ → action → membre → pair) et de la satisfaction des validateurs (signatures requises, rôles, multi-signatures).
Pairing obligatoire (mFA)
* Sans association préalable dau moins un “pair” (device/instance), aucune session nest autorisée.
* Lajout de lUUID dun pair à un membre se fait par conversion BIP32 en mots affichés/saisis pour limiter les erreurs et éviter léchange brut didentifiants.
Objets et contraintes à refléter dans lUX (rappel synthétique)
Les écrans doivent permettre de construire, vérifier et exploiter ces objets et liens (UUID “parents” au moins 1 partout où requis).
Service
* Contrat
* Types names chiffrés dont “service”
Contrat
* Message à valider
* Types names chiffrés dont “contrat”
Champ
* Message à valider
* Types names chiffrés dont “champ”
* Contrats parents UUID, au moins 1
ActionLogin
* Action
* Types names chiffrés dont “login”
Action
* Message à valider
* Types names chiffrés dont “action”
* Validateurs de laction
* Contrats parents UUID, au moins 1
Membre
* Message à valider
* Types names chiffrés dont “membre”
* Actions parents UUID, au moins 1
Pair
* MessageBase
* Types names chiffrés dont “pair”
* Membres parents UUID, au moins 1
MessageBase
* Hash du JSON sans le hash, sans la signature
* UUID
* Version
* Types names chiffrés dont “pair” (et plus généralement le type de lobjet)
* Clés de chiffrement avec paramètres et algo
* Datajson
* obligatoires : services UUID, types UUID
* optionnels : label, descriptions, médias, URL, paragraphes, tarif
* Timestamp
* Liste de relais (IP)
* Hash du JSON signé du pair, avec dans la signature : hash + clé publique + signature
* Version logicielle
Hash
* Hash du JSON (sans hash, sans signatures, sans clés de chiffrement)
* Algo
Signature
* Hash
* Clé publique
* Signature cryptographique
* Nonce et matériel éventuel
Message à valider
* MessageBase
* Validateurs du message
Validateurs
* Liste des membres du rôle, au moins 1
* Pour chacun : liste des signatures obligatoires (lui-même et/ou autres membres)
Message individuel de déchiffrement
* Hash du message
* Clé de chiffrement du message chiffré, incluant une clé de chiffrement chiffrée avec paramètres et algo
* Matériel DH à scanner contenant une clé de déchiffrement (dans le secret partagé)
Message de signature
* Signature
Écrans et parcours, de bout en bout
Écran daccueil
Objectif
* Démarrer une session locale, présenter létat du wallet didentité (clés, pairs, cache), proposer connexion ou onboarding.
Éléments affichés
* Statut “identité locale présente / absente”
* Empreinte courte de la clé publique principale (secp256k1), si existante
* Statut “pairing requis : non satisfait / satisfait”
* Statut réseau relais : atteignables, latence, dernier sync, file dobjets en attente
* Boutons : Créer identité, Importer identité, Se connecter, Gérer pairs, Paramètres relais, Synchroniser maintenant
Écran de création didentité locale
Objectif
* Générer la paire de clés secp256k1 (signature) et initialiser les paramètres de chiffrement.
Actions
* Génération clé privée secp256k1
* Dérivation clé publique secp256k1
* Éventuelle dérivation de sous-clés (BIP32) si vous utilisez un arbre pour identités/pairs/services
Champs et options
* Nom local de lidentité (purement local)
* Option de protection locale (PIN, biométrie, mot de passe) pour chiffrer la clé privée au repos
* Paramètres crypto par défaut (algorithmes symétriques, KDF, formats) pour “Clés de chiffrement avec tous les paramètres”
Sorties
* Identité locale créée
* Date “anniversaire de création des clés” enregistrée (sert de point de départ de scan)
* Cache local initialisé (index des hash vus, index services/types, index ECDH)
Écran dimport didentité
Objectif
* Restaurer la clé privée (ou seed BIP32) et les métadonnées locales nécessaires.
Actions
* Import seed / clé privée
* Recalcul clé publique
* Réindex local minimal
Contrôles
* Vérifier cohérence clé publique dérivée
* Vérifier format/versions
Écran de gestion des relais
Objectif
* Déclarer la liste de relais, tester, prioriser, et configurer la stratégie de synchronisation.
Champs
* Liste de relais (IP ou endpoints)
* Stratégie : périodicité, par services, par fenêtres temporelles
* Paramètres anti-resscan : Bloom filter, Merkle trees (optionnel), taille de cache de hash
Actions
* Test connectivité
* Mise à jour de la liste et sauvegarde locale
Écran de pairing (obligatoire avant login)
Objectif
* Associer au moins un pair à un membre, via procédure robuste “mots BIP32”, pour fournir le second facteur.
Pré-requis conceptuel
* Un pair est un objet rattaché à un ou plusieurs membres (Membres parents UUID ≥ 1).
* Lassociation se matérialise par la publication dobjets (selon votre modèle) où lUUID du pair est présent dans le graphe du membre, et validé par les signatures attendues.
Sous-écran “ajouter un pair”
Deux modes pratiques
* Mode “ce device devient un pair”
* Générer/attribuer un UUID pair local
* Afficher la séquence de mots BIP32 dérivée de cet UUID
* Mode “associer un pair existant”
* Saisir les mots BIP32 affichés par lautre device
* Reconstituer lUUID pair
* Préparer la publication des messages nécessaires pour lier ce pair au membre
Contrôles
* Vérification de saisie (checksum/wordlist)
* Vérification que le pair nest pas déjà associé
* Vérification que le membre cible est connu (ou possibilité de le découvrir via sync)
Sorties
* UUID pair reconnu et enregistré localement
* Publication (ou préparation) des messages “pair” / “membre” nécessaires à lassociation
* Mise en file des signatures et clés de chiffrement à publier séparément
Écran de synchronisation initiale (découverte)
Objectif
* Récupérer et indexer lensemble des messages utiles pour construire le graphe et détecter ce qui est déchiffrable.
Contraintes imposées par votre modèle “publish to all”
* Aucun message nest “reçu” : tout est “récupéré (get)” puis filtré localement.
* Pour détecter un message déchiffrable, il faut scanner les messages de clés depuis la date anniversaire de création des clés (ou depuis le dernier checkpoint).
Éléments affichés
* Fenêtre temporelle de scan (début = date anniversaire / dernier checkpoint, fin = maintenant)
* Compteurs : messages récupérés, hash nouveaux, hash déjà vus, signatures en attente de fetch, clés en attente de fetch
* Indicateur Bloom/Merkle : actif/inactif, taux de faux positifs (si Bloom), profondeur/segments (si Merkle)
* Liste des services découverts (via datajson.services UUID) et types UUID
Actions
* Synchroniser maintenant
* Affiner par service
* Construire/mettre à jour lindex Merkle ou Bloom côté client
* Exporter un checkpoint local (hash racine Merkle, ou bitset Bloom) si utile
Étapes techniques de sync côté client
* GET messages chiffrés “hash + message chiffré + datajson public” depuis relais, filtrés par période et/ou service
* Déduplication par hash (cache local + cache relais)
* Pour chaque message potentiel : tenter didentifier la nécessité dune clé (via type UUID, service UUID, et index ECDH)
* Fetch dédié des “Message individuel de déchiffrement” pertinents (par hash) et construction du matériel ECDH
* Déchiffrement, parsing JSON, calcul hash canonique, vérification cohérence “Hash du JSON sans hash…”
* Fetch dédié des “Message de signature” (par hash) et attachement local
* Vérification des signatures secp256k1 conformément aux validateurs du message
Écran de sélection du service
Objectif
* Choisir le service (service UUID) sur lequel lutilisateur veut sauthentifier.
Affichage
* Liste des services disponibles (découverts localement)
* Pour chaque service : statut de confiance
* “Contrat complet et valide”
* “Contrat incomplet (éléments manquants)”
* “Contrat invalide (hash/signature/validateurs non satisfaits)”
* Option de rafraîchissement sync “par service”
Action
* Choisir un service → déclenche construction du chemin de validation login
Écran “construction du chemin login”
Objectif
* Construire et afficher la chaîne dobjets nécessaires, puis calculer la liste exacte des signatures attendues.
Chaîne minimale attendue
* Service (service UUID)
* Contrat(s) rattachés
* Champs (au moins 1 champ avec contrats parents UUID)
* ActionLogin → Action de type login
* Membre (ayant actions parents UUID incluant laction login)
* Pair(s) (ayant membres parents UUID incluant ce membre)
Travail du client
* Résoudre les liens par UUID parents, vérifier “au moins 1” partout où requis
* Vérifier les “types names chiffrés” : existence, déchiffrement si nécessaire, cohérence avec type UUID
* Pour chaque objet : recalcul hash canonique et comparer au hash déclaré
* Construire lensemble “validateurs” applicables à laction login et au message de login
* Produire la matrice “signatures obligatoires” : qui doit signer quoi, et sous quelles clés publiques
Affichage conseillé
* Graphe ou liste hiérarchique (service → … → pair), avec statut vert/rouge par nœud
* Détail des signatures requises : membre(s) valideur(s), nombre minimal, dépendances “autres membres et/ou lui-même”
Écran “vérification du pairing requis”
Objectif
* Sassurer que les pairs exigés par laction login sont présents et activables localement.
Vérifications
* Les UUID de pairs attendus sont connus localement (ou récupérables)
* Chaque pair attendu peut produire une signature (donc la clé privée correspondante est accessible localement ou via device associé)
* Le mapping pair ↔ membre ↔ action login est valide et signé selon validateurs
Cas usuels
* Pair local unique : ce device signe
* Multi-pair : exiger au moins N signatures de pairs distincts (mFA renforcé)
* Pair distant : déclencher un flux “signer sur lautre device” via procédure de partage (QR, mots, lien) sans serveur central, uniquement par publication de signatures
Écran “challenge / message à valider”
Objectif
* Générer le “Message à valider” de la session de login, puis organiser sa signature et sa vérification.
Contenu minimal à préparer
* MessageBase complet (uuid, version, timestamp, types UUID, services UUID, relais, version logicielle, datajson public minimal)
* Hash canonique calculé selon règle
* Nonce de session et/ou matériel anti-rejeu dans “Signature” (nonce et autre matériel éventuel)
* Références explicites au service UUID cible
* Références explicites à laction login UUID et au membre UUID (selon votre modèle), pour lier la preuve à lintention
Affichage
* Résumé des attributs publics (service UUID, type UUID, timestamp, relais)
* Statut “détecté comme conforme au contrat : oui/non”
* Bouton “Signer” (désactivé si pairing non satisfait)
Écran “signature(s) mFA”
Objectif
* Collecter les signatures requises, potentiellement depuis plusieurs pairs/devices.
Flux de signature
* Pour le pair local
* Signer hash canonique secp256k1
* Produire objet “Message de signature” : hash + clé publique + signature + nonce/matériel
* Pour les pairs distants
* Afficher un “paquet de demande de signature” (hash, contexte, paramètres)
* Sur lautre device : vérifier contexte, signer, publier la signature
* Sur ce device : récupérer la signature via fetch dédié et lattacher localement
Affichage
* Liste des signatures attendues avec état
* “manquante”
* “reçue”
* “valide”
* “invalide” (mauvais hash, mauvaise clé publique, signature invalide)
* Règles de validateurs satisfaites / non satisfaites, en temps réel
Écran “publication du login”
Objectif
* Publier la preuve de login dans le réseau de relais, conformément à la règle “message dabord, signatures ensuite, clés ensuite”.
Étapes démission côté client
* Publier le message chiffré (objet contenant : hash + message chiffré + datajson public)
* Sans signatures
* Sans clés de chiffrement
* Publier ensuite, séparément, les “Message de signature” nécessaires
* Publier ensuite, séparément, les “Message individuel de déchiffrement” nécessaires (si dautres parties doivent déchiffrer, par exemple le service ou un ensemble de validateurs)
* Relais : propagation inter-relais, déduplication par hash
Affichage
* Liste des relais cibles, état de publication par relais
* Hash final de la preuve
* Statut “propagation suffisante” (par exemple M relais sur N ont confirmé stockage)
Écran “vérification côté service sans serveur central”
Objectif
* Décrire ce que fait le “service” (ou lapplication de service) pour accepter la session, en ne reposant que sur contrats + signatures.
Mécanique de vérification (côté service)
* Récupérer le message publié (par hash ou par scan périodique “par service”)
* Récupérer explicitement signatures associées
* Récupérer explicitement matériels de déchiffrement si nécessaire
* Déchiffrer, recalculer hash canonique, comparer
* Vérifier signatures secp256k1, clés publiques, nonces
* Rejouer la construction du graphe (service → … → action login → membre → pairs) depuis les UUID et messages disponibles
* Vérifier validateurs : liste des membres du rôle, signatures obligatoires, seuils
* Vérifier anti-rejeu : timestamp, nonce, fenêtre temporelle, unicité du hash/nonce
* Si OK : émettre un “jeton local” (non central) ou ouvrir une session locale ; sinon refuser
Écran “résultat de connexion”
Objectif
* Donner un état explicite, traçable, et diagnostiquable.
États possibles
* Connecté : preuve acceptée
* Refusé : contrat incomplet
* Refusé : signatures insuffisantes
* Refusé : signature invalide
* Refusé : anti-rejeu déclenché (nonce déjà vu / timestamp hors fenêtre)
* Refusé : pairing requis non satisfait
* Refusé : impossibilité de récupérer signatures/clés après délai
Affichage recommandé
* Hash de la preuve
* Service UUID
* Liste des validateurs satisfaits / non satisfaits
* Journal succinct : quels objets manquaient (hash), quelles signatures manquaient (clé publique), quels matériels DH manquaient
Écran “récupération et déchiffrement en continu”
Objectif
* Assurer le fonctionnement périodique “par services” : scan, fetch des clés, fetch des signatures, mise à jour du graphe et des droits.
Fonctions
* Planification périodique : pour chaque service connu, GET des nouveaux messages depuis dernier checkpoint
* Dédup hash
* Tentative de correspondance via index ECDH pour identifier les messages potentiellement déchiffrables
* Fetch des messages de clés (déchiffrement), puis fetch des signatures, puis validation
Optimisations à exposer (au moins comme options avancées)
* Bloom filter
* Objectif : éviter de rescanner tout lhistorique des hash
* Données : bitset local, éventuellement partagé entre devices
* Limite : faux positifs possibles → nécessite vérification finale par hash
* Arbres de Merkle
* Objectif : prouver rapidement la présence/absence dun hash dans un ensemble et synchroniser des segments
* Données : racines par période/service, preuve dinclusion
* Limite : complexité de maintenance côté relais et côté client
Détails critiques de validation à intégrer (pour éviter des ambiguïtés en production)
Canonisation JSON
* Définir une canonisation stricte : ordre des clés, encodage, normalisation des nombres/chaînes, gestion des tableaux.
* Sans cela, “Hash du JSON” devient instable entre implémentations.
Gestion des versions
* “Version” et “Version logicielle” doivent être prises en compte dans la validation (compatibilité ascendante, migrations).
* Le client doit afficher clairement la version dun contrat et refuser ou isoler les versions non supportées.
Anti-rejeu
* Timestamp seul est insuffisant ; exiger un nonce unique par tentative, et un cache de nonces vus (par service) sur une fenêtre glissante.
* Le service doit rejeter un hash/nonce déjà accepté.
Clés publiques et identité
* La clé publique incluse dans la signature doit être reliée, par le graphe et les validateurs, au pair attendu.
* Interdire lacceptation dune signature “valide cryptographiquement” mais non autorisée “contractuellement”.
Séparation signatures / clés
* Prévoir un état “message reçu mais indéchiffrable (clé manquante)” et “message déchiffré mais non validé (signature manquante)”.
* LUX doit rendre ces états visibles, sinon les utilisateurs concluent à des pertes de données.
Conclusion
Un login conforme à ce modèle nest pas un simple écran “identifiant/mot de passe”, mais un enchaînement de construction et de vérification dun graphe contractuel, suivi dune collecte de signatures multi-pairs, puis dune publication en trois temps (message, signatures, clés), le tout synchronisé via des relais. La robustesse globale vient de la cohérence entre canonisation des hash, règles de validateurs, anti-rejeu, et de la capacité du client à scanner efficacement lhistorique (Bloom/Merkle) sans jamais supposer quun message “arrive” par push.
Si une suite est souhaitée, la prochaine étape naturelle consiste à produire une spécification décrans sous forme de maquettes textuelles (composants, états, erreurs, journaux), puis une machine à états formelle du protocole de login (états, transitions, timeouts, reprise sur erreur), strictement alignée sur les objets et contraintes listés ci-dessus.
# Écrans à produire pour login sans serveur central (secp256k1 + contrats + pairing mFA)
## Principes UX et contraintes non négociables
Les règles suivantes doivent être visibles dans la conception des écrans (au minimum en “états avancés”, logs, diagnostics) :
- Tous les messages sont récupérés par GET (aucun push).
- Les messages “métier” sont publiés sans signatures et sans clés de chiffrement.
- Les signatures sont publiées après, séparément.
- Les clés/matériels de déchiffrement sont publiés après, séparément.
- Un GET de message ne renvoie pas signatures et clés : elles sont fetch spécifiquement ensuite.
- Tous les objets sont adressés par hash du JSON canonique (sans hash, sans signatures, sans clés de chiffrement).
- Le login est une preuve validée localement par graphe (service → contrat → champ → action/login → membre → pair) + validateurs.
- Le pairing est obligatoire pour autoriser une connexion : au moins un pair associé et attendu par laction de login.
- Publication “pour tous” : aucun destinataire explicite. Le message est chiffré et nest lisible que par les parties capables dobtenir les clés.
## Glossaire des objets manipulés dans lUI
- Service : objet décrivant un service et son contrat associé.
- Contrat : objet “contrat didentité”.
- Champ : objet rattaché à au moins un contrat parent.
- Action : objet rattaché à au moins un contrat parent, contient des validateurs.
- ActionLogin : action de type “login”.
- Membre : objet rattaché à au moins une action parent.
- Pair : objet rattaché à au moins un membre parent (device/instance).
- MessageBase : trame commune incluant uuid/version/types/services/timestamp/relais/hash/signature/pubkey.
- Message à valider : MessageBase + validateurs.
- Hash : hash du JSON canonique (sans hash, sans signatures, sans clés de chiffrement) + algo.
- Signature : hash + clé publique + signature + nonce/matériel.
- Message de signature : objet portant une Signature.
- Message individuel de déchiffrement : objet portant matériel de déchiffrement + ECDH.
## Écran “accueil”
### Objectif
Point dentrée de lapplication : état de lidentité locale, état du pairing, accès au login et à la synchronisation.
### Pré-requis
Aucun.
### Composants UI
- Statut identité locale : présente / absente
- Empreinte de la clé publique principale (format court)
- Statut pairing : requis / satisfait / incomplet
- Statut réseau relais : OK / dégradé / indisponible
- Dernière synchronisation : date/heure
- Boutons :
- Créer une identité locale
- Importer une identité
- Se connecter
- Gérer les pairs
- Réglages relais
- Synchroniser maintenant
### États / erreurs
- Identité absente → bouton “Se connecter” désactivé
- Pairing non satisfait → “Se connecter” possible mais renverra vers pairing obligatoire
- Relais indisponibles → mode offline (lecture cache uniquement)
## Écran “création didentité locale”
### Objectif
Générer les clés secp256k1 et initialiser les paramètres crypto locaux.
### Pré-requis
Aucun.
### Composants UI
- Nom local de lidentité (optionnel)
- Protection locale :
- PIN / mot de passe / biométrie (selon plateforme)
- Paramètres crypto avancés (optionnel) :
- Algos de chiffrement symétrique
- KDF
- Format canonique JSON
- Hash (algo)
### Actions utilisateur
- Générer lidentité
### Traitements locaux
- Génération clé privée secp256k1
- Calcul clé publique secp256k1
- Enregistrement “date anniversaire de création des clés”
- Création du cache local :
- index hash vus
- index services/types
- index ECDH (si applicable)
### États / erreurs
- Erreur entropie / RNG indisponible
- Protection locale non conforme (PIN trop court, etc.)
## Écran “import didentité”
### Objectif
Restaurer une identité existante (clé privée ou seed/hiérarchie).
### Pré-requis
Disposer dun secret dimport.
### Composants UI
- Mode import :
- Seed / phrase / clé privée
- Fichier chiffré (optionnel)
- Champ dentrée + validation checksum
- Protection locale au repos (comme création)
### Traitements locaux
- Recalcul clé publique
- Vérification cohérence
- Initialisation cache
### États / erreurs
- Seed invalide
- Clé privée hors format
- Incompatibilité de version
## Écran “réglages relais”
### Objectif
Configurer la liste de relais et les stratégies de synchronisation.
### Composants UI
- Liste des relais (IP / endpoint)
- Priorité / ordre (drag & drop)
- Options :
- Sync périodique par service
- Fenêtre de scan par défaut
- Déduplication locale (taille cache hash)
- Accélérateurs : Bloom filter / Merkle (avancé)
- Boutons :
- Tester relais
- Ajouter / supprimer relais
- Sauvegarder
### États / erreurs
- Relais non joignable
- Timeout réseau
- Configuration invalide (liste vide)
## Écran “synchronisation globale”
### Objectif
Récupérer des messages publiés sur relais, sans destinataire, et mettre à jour le cache local.
### Pré-requis
Identité locale présente.
### Composants UI
- Fenêtre de scan :
- Début : anniversaire clés / dernier checkpoint
- Fin : maintenant
- Sélecteurs :
- Tous services
- Service spécifique (si déjà connu)
- Compteurs :
- messages récupérés
- hash nouveaux
- hash déjà vus
- messages déchiffrables détectés
- signatures à récupérer
- clés à récupérer
- Boutons :
- Synchroniser maintenant
- Pause / reprendre
- Forcer “fetch signatures”
- Forcer “fetch clés”
- Diagnostiquer un hash
### Traitements locaux
- GET messages chiffrés : (hash + message chiffré + datajson public)
- Déduplication par hash
- Indexation par service UUID / type UUID
- Tentatives didentification :
- ce message est-il potentiellement déchiffrable ?
- Fetch dédié des messages “clés” pertinents
- Déchiffrement, parsing JSON, recalcul hash canonique
- Fetch dédié des “messages de signature”
- Vérification signatures secp256k1
- Mise à jour du graphe (service/contrat/action/membre/pair)
### États / erreurs
- Message présent mais clé manquante → “indéchiffrable”
- Message déchiffré mais signatures manquantes → “non validé”
- Hash incohérent (JSON canonique différent) → “objet corrompu / non conforme”
- Signatures invalides → “preuve invalide”
## Écran “gestion des services”
### Objectif
Lister les services connus localement et leur état de validité contractuelle.
### Pré-requis
Au moins une synchronisation effectuée.
### Composants UI
- Liste des services (service UUID)
- Pour chaque service :
- label (si disponible et déchiffré)
- statut contrat :
- complet et valide
- incomplet (objets manquants)
- invalide (signatures/validateurs)
- dernier sync service
- Actions :
- Ouvrir
- Resync par service
- Voir graphe
### États / erreurs
- Service détecté mais contrat non résolu → “incomplet”
- Types names chiffrés non déchiffrables → “affichage minimal”
## Écran “détail service / graphe contractuel”
### Objectif
Afficher la chaîne complète : service → contrat → champ → action → membre → pair(s), avec états.
### Composants UI
- Vue hiérarchique ou graphe
- Nœuds avec :
- UUID
- type UUID
- statut (valide/incomplet/invalide)
- hash
- Liste “objets manquants” (hash attendus)
- Bouton “diagnostic”
### Traitements locaux
- Résolution des parents UUID
- Validation “au moins 1 parent” sur objets concernés
- Vérification hash canonique
- Vérification signatures et validateurs
### États / erreurs
- Cycle détecté dans les UUID parents (si possible) → bloquer
- Parent absent → incomplet
## Écran “gestion des pairs”
### Objectif
Lister les pairs connus et gérer lassociation à des membres.
### Composants UI
- Liste des pairs (UUID pair)
- Pour chaque pair :
- membres parents UUID
- statut : associé / en attente / invalide
- capacité signature : OK / indisponible
- Actions :
- Ajouter un pair
- Associer à un membre
- Retirer (local uniquement, selon politique)
- Diagnostiquer
## Écran “ajout de pair (mFA)”
### Objectif
Réaliser le pairing obligatoire via conversion BIP32 en mots.
### Pré-requis
Identité locale présente.
### Mode A : “ce device devient un pair”
Composants UI
- Générer UUID pair
- Afficher liste de mots BIP32 dérivée de lUUID
- Bouton “continuer” (confirmation)
Traitements locaux
- Conversion UUID → chemin BIP32 → mots
- Enregistrement local du pair
### Mode B : “associer un pair existant”
Composants UI
- Saisie des mots BIP32 affichés par lautre device
- Bouton “reconstituer UUID”
Traitements locaux
- Mots → reconstitution UUID
- Vérification checksum
- Enregistrement pair
### Publication
- Préparation des messages nécessaires pour lier pair ↔ membre :
- message métier (sans signature, sans clés)
- puis message(s) de signature
- puis message(s) de déchiffrement si requis
### États / erreurs
- Mots invalides / ordre incorrect
- Pair déjà présent
- Membre cible absent du cache (sync requise)
## Écran “sélection membre”
### Objectif
Choisir le membre concerné par le login (quand plusieurs membres existent).
### Pré-requis
Graphe local résolu au moins partiellement.
### Composants UI
- Liste des membres
- label (si déchiffré)
- actions parents (dont login)
- pairs associés
- Action : sélectionner
### États / erreurs
- Aucun membre avec action login → impossible de se connecter
## Écran “sélection service pour connexion”
### Objectif
Choisir le service cible du login.
### Pré-requis
Services connus.
### Composants UI
- Liste des services + statuts
- Bouton “continuer”
### États / erreurs
- Service invalide → alerte + détails
## Écran “construction du chemin login”
### Objectif
Résoudre et afficher le chemin de validation du login, et calculer les signatures attendues.
### Composants UI
- Résumé du chemin :
- service UUID
- contrat(s) UUID
- action login UUID
- membre UUID
- pairs attendus UUID
- Tableau “signatures requises” :
- validateurs
- règles (qui doit signer)
- statut (manquante/reçue/valide/invalide)
- Boutons :
- Synchroniser (si incomplet)
- Démarrer login
### Traitements locaux
- Résolution parents
- Validation validateurs de laction login
- Détermination du set minimal de signatures pour satisfaire la règle
### États / erreurs
- Contrat incomplet
- Validateurs impossibles à satisfaire (ex : pair manquant)
## Écran “message de login à valider”
### Objectif
Construire le Message à valider de login.
### Composants UI
- Résumé public :
- service UUID
- type UUID
- timestamp
- relais cibles
- Paramètres anti-rejeu :
- nonce généré (affichage possible en mode avancé)
- Bouton “signer”
### Traitements locaux
- Construction MessageBase
- Insertion datajson public minimal (services UUID, types UUID)
- Calcul hash canonique
- Préparation du message chiffré
- Préparation publication “message dabord”
### États / erreurs
- Format JSON non canonique détecté
- Relais indisponibles
## Écran “collecte des signatures (mFA)”
### Objectif
Obtenir toutes les signatures obligatoires attendues pour laction login.
### Composants UI
- Liste des signatures requises :
- clé publique attendue
- pair/membre associé
- état
- Boutons :
- Signer avec ce device
- Demander signature sur autre pair
- Rafraîchir (fetch signatures)
- Voir détail signature
### Flux “signature locale”
- Calcul signature secp256k1
- Création Message de signature
### Flux “signature distante”
- Afficher un paquet de demande (hash + contexte)
- Autre device signe et publie
- Ce device fetch la signature et rattache
### États / erreurs
- Signature invalide
- Nonce déjà utilisé (anti-rejeu)
- Délai dattente dépassé
## Écran “publication du login”
### Objectif
Publier la preuve en respectant la séparation :
message chiffré → signatures → clés de déchiffrement.
### Composants UI
- Liste des relais + état :
- envoyé / confirmé / échec
- Hash final de la preuve
- Boutons :
- Publier
- Republier sur relais manquants
- Afficher diagnostics
### Traitements réseau (ordre strict)
- POST message chiffré (sans signatures, sans clés)
- POST message(s) de signature
- POST message(s) individuels de déchiffrement (si requis)
### États / erreurs
- Message publié mais signatures non publiées → preuve incomplète
- Signatures publiées mais clés manquantes → preuve inutilisable par tiers
## Écran “résultat de connexion”
### Objectif
Afficher un verdict explicite et traçable.
### États possibles
- Connexion acceptée
- Connexion refusée : contrat incomplet
- Connexion refusée : signatures insuffisantes
- Connexion refusée : signatures invalides
- Connexion refusée : pairing non satisfait
- Connexion refusée : anti-rejeu (nonce déjà vu / timestamp hors fenêtre)
- Connexion refusée : objets manquants
### Composants UI
- Statut final
- Hash de la preuve
- Service UUID
- Détails :
- signatures requises vs obtenues
- objets manquants
- logs (mode avancé)
- Actions :
- Recommencer
- Resync
- Diagnostic
## Écran “diagnostic avancé (hash / objet)”
### Objectif
Aider à comprendre un échec (objet manquant, clé absente, signature invalide).
### Composants UI
- Entrée hash (ou sélection depuis liste)
- Détails objet :
- type UUID
- service UUID
- timestamp
- statut déchiffrement : OK/non
- statut signature : OK/non
- Boutons :
- Fetch signatures
- Fetch clés
- Vérifier canonisation JSON
- Vérifier validateurs
### Erreurs typiques affichées
- Hash recalculé ≠ hash déclaré
- Signature secp256k1 invalide
- Clé publique non autorisée par validateurs
- Matériel DH absent / non exploitable
- Parents UUID absents
## Écran “synchronisation continue par service”
### Objectif
Maintenir le cache à jour périodiquement, par service.
### Composants UI
- Liste services + toggle sync automatique
- Fréquence (min/heure/jour)
- Fenêtre de scan
- Accélérateurs :
- Bloom filter : taille, faux positifs estimés
- Merkle : segments/périodes
- Bouton “lancer maintenant”
### Traitements locaux
- GET messages depuis dernier checkpoint
- Dédup hash
- Fetch signatures et clés si nécessaire
- Validation graphe et droits
### États / erreurs
- Volume trop important → recommander Bloom/Merkle
- Relais instables → backoff
## Écran “paramètres crypto (avancé)”
### Objectif
Afficher et régler les politiques crypto et compatibilité.
### Composants UI
- Algorithme hash (ex : sha256)
- Canonisation JSON (mode strict)
- Paramètres ECDH (secp256k1)
- Paramètres KDF/symétrique (si exposés)
- Politique anti-rejeu :
- TTL nonce
- fenêtre timestamp
### États / erreurs
- Incompatibilité avec services existants
- Paramètres non supportés par version logicielle
# Machine à états du login sans serveur central (secp256k1 + contrats + pairing mFA)
## Objectif
Décrire une machine à états déterministe et implémentable pour :
- créer/importer une identité,
- synchroniser des messages via relais (pull-only),
- résoudre le graphe contractuel,
- imposer le pairing (mFA),
- construire un message de login à valider,
- collecter et vérifier les signatures attendues,
- publier la preuve (message → signatures → clés),
- obtenir un verdict local côté client et côté service (sans autorité centrale).
## Définitions globales
### Notation
- État : `S_*`
- Événement : `E_*`
- Garde (condition) : `G_*`
- Action (effet) : `A_*`
- Erreur : `X_*`
### Règles dadressage et de contenu
- Tout objet est adressé par `Hash(JSON_canonique(objet))`
- `JSON_canonique(objet)` = JSON sans :
- `hash`
- `signatures`
- `clefs_de_chiffrement`
- Les signatures et les clés sont récupérées séparément après `GET message`.
- Tout est publié pour tous (sans destinataire explicite), chiffré.
### Objets de preuve
- `MsgChiffre` : `{ hash, message_chiffre, datajson_public }`
- `MsgSignature` : `{ signature: {hash, pubkey, sig, nonce, materiel} }`
- `MsgCle` : `{ hash_message, cle_chiffrement, df_ecdh_scannable }`
### Fenêtres de synchronisation
- `T0 = date_anniversaire_creation_cles`
- `T_last = dernier_checkpoint_local`
- Scan par défaut : `[T_last ou T0 ; maintenant]`
### Cache local minimal
- `cache_hash_vus`
- `index_par_service_uuid`
- `index_par_type_uuid`
- `index_par_hash -> (msg, signatures?, cles?, statut_dechiffrement, statut_validation)`
- `index_pairs_locaux`
- `index_membres_connus`
- `index_ecdh` (si ECDH structuré par pubkeys)
## Variables de session (runtime)
- `service_cible_uuid`
- `membre_cible_uuid`
- `action_login_uuid`
- `pairs_attendus[]`
- `signatures_requises[]`
- `nonce_login`
- `hash_login`
- `msg_login_chiffre`
- `relays[]`
- `timer_deadlines` (réseau, collecte signatures, fetch clés)
## États et transitions
## S_INIT (démarrage application)
### Entrée
- Charger cache local
- Charger identité locale si présente
- Charger configuration relais
### Événements sortants
- `E_IDENTITY_ABSENT``S_IDENTITY_REQUIRED`
- `E_IDENTITY_PRESENT``S_HOME`
---
## S_IDENTITY_REQUIRED (identité manquante)
### UI associée
- écran accueil avec options “Créer” / “Importer”
### Transitions
- `E_CREATE_IDENTITY``S_IDENTITY_CREATE`
- `E_IMPORT_IDENTITY``S_IDENTITY_IMPORT`
---
## S_IDENTITY_CREATE (création identité locale)
### Actions
- `A_GEN_SECP256K1_KEYPAIR`
- `A_SET_T0_ANNIVERSAIRE`
- `A_INIT_CACHE`
### Sorties
- `E_IDENTITY_CREATED``S_HOME`
### Erreurs
- `X_RNG_UNAVAILABLE``S_ERROR_FATAL`
---
## S_IDENTITY_IMPORT (import identité)
### Actions
- `A_PARSE_SEED_OR_PRIVKEY`
- `A_DERIVE_PUBKEY`
- `A_SET_OR_CONFIRM_T0`
- `A_INIT_CACHE`
### Sorties
- `E_IDENTITY_IMPORTED``S_HOME`
### Erreurs
- `X_IMPORT_INVALID``S_ERROR_RECOVERABLE`
---
## S_HOME (accueil)
### Événements
- `E_OPEN_RELAY_SETTINGS``S_RELAY_SETTINGS`
- `E_SYNC_NOW``S_SYNC_GLOBAL`
- `E_MANAGE_PAIRS``S_PAIR_MANAGEMENT`
- `E_LOGIN_START``S_LOGIN_SELECT_SERVICE`
### Gardes
- `G_IDENTITY_PRESENT` sinon retour `S_IDENTITY_REQUIRED`
---
## S_RELAY_SETTINGS (configuration relais)
### Actions
- `A_SAVE_RELAYS_CONFIG`
- `A_TEST_RELAYS` (optionnel)
### Sorties
- `E_RELAYS_SAVED``S_HOME`
- `E_CANCEL``S_HOME`
### Erreurs
- `X_RELAYS_INVALID``S_ERROR_RECOVERABLE`
---
## S_SYNC_GLOBAL (synchronisation globale)
### Objectif
Récupérer `MsgChiffre`, dédupliquer par hash, puis fetch clés et signatures sur demande.
### Entrée
- Déterminer fenêtre `[T_scan_start; T_scan_end]`
- Initialiser compteurs
### Actions boucle (pull)
- `A_GET_MSGS_CHIFFRES(relays, window)` → liste `{hash, message_chiffre, datajson_public}`
- `A_DEDUP_HASH(cache_hash_vus)`
- `A_INDEX_PUBLIC_METADATA(service_uuid, type_uuid, timestamp)`
- `A_DETECT_POTENTIEL_DECHIFFRABLE(index_ecdh, datajson_public)` (heuristique)
- `A_FETCH_KEYS_BY_HASH(hash)` (si candidat)
- `A_TRY_DECRYPT(hash)` (si clé présente)
- `A_RECALC_CANONICAL_HASH`
- `A_FETCH_SIGNATURES_BY_HASH(hash)` (si déchiffré)
- `A_VERIFY_SIGNATURES`
- `A_UPDATE_GRAPH_CACHE`
### Sorties
- `E_SYNC_DONE``S_HOME`
- `E_SYNC_DONE_WITH_DISCOVERY``S_SERVICE_LIST`
### Erreurs récupérables
- `X_RELAY_TIMEOUT` → rester `S_SYNC_GLOBAL` avec backoff
- `X_DECRYPT_KEY_MISSING` → marquer état local “indéchiffrable”
- `X_SIG_MISSING` → marquer “non validé”
- `X_HASH_MISMATCH` → marquer “corrompu / non conforme”
---
## S_SERVICE_LIST (liste services)
### Entrée
- Charger services connus depuis `index_par_service_uuid`
### Transitions
- `E_SELECT_SERVICE(service_uuid)``S_LOGIN_SELECT_MEMBER` (ou direct si membre unique)
- `E_RESYNC_SERVICE(service_uuid)``S_SYNC_SERVICE`
- `E_BACK``S_HOME`
---
## S_SYNC_SERVICE (sync ciblée service)
### Actions
- `A_GET_MSGS_CHIFFRES(filter=service_uuid)`
- mêmes actions de déchiffrement/validation que `S_SYNC_GLOBAL`
### Sorties
- `E_SYNC_SERVICE_DONE``S_SERVICE_LIST`
- `E_BACK``S_SERVICE_LIST`
---
## S_PAIR_MANAGEMENT (gestion pairs)
### Transitions
- `E_PAIR_ADD``S_PAIR_ADD`
- `E_PAIR_ASSOCIATE_TO_MEMBER``S_PAIR_ASSOCIATE`
- `E_BACK``S_HOME`
---
## S_PAIR_ADD (ajout dun pair)
### Modes
- local : “ce device devient un pair”
- distant : “associer un pair existant”
### Actions
- `A_GEN_PAIR_UUID` (mode local)
- `A_UUID_TO_BIP32_WORDS` (affichage)
- `A_WORDS_TO_UUID` (saisie)
- `A_STORE_PAIR_LOCAL`
### Sorties
- `E_PAIR_READY``S_PAIR_ASSOCIATE`
### Erreurs
- `X_WORDS_INVALID``S_ERROR_RECOVERABLE`
---
## S_PAIR_ASSOCIATE (associer pair ↔ membre)
### Gardes
- `G_MEMBRE_EXISTS_LOCALLY` sinon `S_SYNC_GLOBAL`
### Actions (préparation publication)
- `A_BUILD_PAIR_MEMBERSHIP_MESSAGE` (message métier sans signatures/clefs)
- `A_ENCRYPT_MESSAGE`
- `A_CALC_HASH`
- `A_QUEUE_PUBLISH_MESSAGE`
- `A_QUEUE_PUBLISH_SIGNATURES_REQUIRED`
- `A_QUEUE_PUBLISH_KEYS_IF_REQUIRED`
### Sorties
- `E_ASSOCIATION_QUEUED``S_PUBLISH_QUEUE`
---
## S_PUBLISH_QUEUE (file de publication)
### Objectif
Publier dans lordre strict : message → signatures → clés.
### Actions
- `A_POST_MSG_CHIFFRE`
- `A_POST_MSG_SIGNATURES`
- `A_POST_MSG_KEYS`
### Sorties
- `E_PUBLISH_OK``S_HOME`
- `E_PUBLISH_PARTIAL``S_ERROR_RECOVERABLE`
### Erreurs
- `X_RELAY_DOWN``S_ERROR_RECOVERABLE`
---
## S_LOGIN_SELECT_SERVICE (début login : choix service)
### Gardes
- `G_PAIRING_SATISFIED` sinon `S_LOGIN_PAIRING_REQUIRED`
### Transitions
- `E_SELECT_SERVICE(service_uuid)``S_LOGIN_SELECT_MEMBER`
- `E_BACK``S_HOME`
---
## S_LOGIN_PAIRING_REQUIRED (pairing obligatoire)
### Transitions
- `E_GO_PAIRING``S_PAIR_MANAGEMENT`
- `E_BACK``S_HOME`
---
## S_LOGIN_SELECT_MEMBER (choix membre)
### Gardes
- `G_MEMBRE_WITH_ACTION_LOGIN_EXISTS` sinon `S_ERROR_RECOVERABLE`
### Transitions
- `E_SELECT_MEMBER(membre_uuid)``S_LOGIN_BUILD_PATH`
- `E_BACK``S_SERVICE_LIST`
---
## S_LOGIN_BUILD_PATH (résolution graphe et validateurs)
### Actions
- `A_RESOLVE_GRAPH(service_uuid, membre_uuid)`
- service → contrat → champ → action(login) → membre → pairs
- `A_VALIDATE_PARENTS_UUID_CONSTRAINTS`
- `A_VALIDATE_TYPES_NAMES_IF_AVAILABLE`
- `A_LOAD_ACTION_VALIDATORS`
- `A_COMPUTE_REQUIRED_SIGNATURES_SET`
### Sorties
- `E_PATH_OK``S_LOGIN_CHECK_PAIRS`
- `E_PATH_INCOMPLETE``S_ERROR_RECOVERABLE`
- `E_PATH_INVALID``S_ERROR_RECOVERABLE`
### Erreurs
- `X_PARENT_MISSING`
- `X_VALIDATORS_UNSATISFIABLE`
- `X_HASH_MISMATCH`
---
## S_LOGIN_CHECK_PAIRS (vérifier pairs attendus)
### Gardes
- `G_ALL_REQUIRED_PAIRS_AVAILABLE` sinon `S_LOGIN_NEED_MORE_PAIRS`
### Sorties
- `E_PAIRS_OK``S_LOGIN_BUILD_CHALLENGE`
---
## S_LOGIN_NEED_MORE_PAIRS (pairs manquants)
### Transitions
- `E_ADD_PAIR``S_PAIR_MANAGEMENT`
- `E_RESYNC``S_SYNC_SERVICE`
- `E_BACK``S_SERVICE_LIST`
---
## S_LOGIN_BUILD_CHALLENGE (construction message à valider)
### Actions
- `A_GENERATE_NONCE`
- `A_BUILD_MESSAGEBASE_LOGIN`
- services_uuid = service_cible_uuid
- types_uuid = type_login_uuid
- timestamp = now
- relays = relays[]
- version logicielle
- `A_ENCRYPT_LOGIN_MESSAGE`
- `A_CANONICALIZE_JSON`
- `A_CALC_HASH_LOGIN`
### Sorties
- `E_CHALLENGE_READY``S_LOGIN_COLLECT_SIGNATURES`
### Erreurs
- `X_CANONICALIZATION_FAIL`
- `X_ENCRYPT_FAIL`
---
## S_LOGIN_COLLECT_SIGNATURES (collecte signatures mFA)
### Objectif
Obtenir toutes les signatures imposées par validateurs.
### Sous-états internes (recommandé)
- `S_LOGIN_SIG_LOCAL`
- `S_LOGIN_SIG_REMOTE_WAIT`
- `S_LOGIN_SIG_FETCH`
### Actions
- `A_SIGN_LOCAL(hash_login, privkey_pair_local)` → MsgSignature
- `A_REQUEST_REMOTE_SIGNATURE(hash_login, context)` (UI/QR/mots selon design)
- `A_FETCH_SIGNATURES_BY_HASH(hash_login)`
- `A_VERIFY_SIGNATURES_SECP256K1`
- `A_CHECK_VALIDATORS_SATISFIED`
### Sorties
- `E_SIGNATURES_COMPLETE``S_LOGIN_PUBLISH_PROOF`
- `E_SIGNATURES_INCOMPLETE` → rester `S_LOGIN_COLLECT_SIGNATURES`
### Erreurs
- `X_SIGNATURE_INVALID`
- `X_SIGNATURE_TIMEOUT`
- `X_NONCE_REUSED` (si cache nonce)
- `X_PUBKEY_NOT_AUTHORIZED`
---
## S_LOGIN_PUBLISH_PROOF (publication preuve login)
### Ordre strict
1) publier message chiffré sans signatures ni clés
2) publier message(s) de signature
3) publier message(s) de déchiffrement si nécessaire
### Actions
- `A_POST_MSG_CHIFFRE(hash_login, msg_login_chiffre)`
- `A_POST_SIGNATURES(hash_login, signatures[])`
- `A_POST_KEYS_IF_REQUIRED(hash_login, key_materials[])`
### Sorties
- `E_PUBLISH_LOGIN_OK``S_LOGIN_VERIFY_LOCAL`
- `E_PUBLISH_LOGIN_PARTIAL``S_ERROR_RECOVERABLE`
### Erreurs
- `X_RELAY_POST_FAIL`
---
## S_LOGIN_VERIFY_LOCAL (vérification locale finale)
### Objectif
Le client démontre que la preuve est auto-cohérente et satisfaisante avant affichage.
### Actions
- `A_RELOAD_PUBLISHED_OBJECTS_IF_NEEDED`
- `A_VERIFY_CANONICAL_HASH(hash_login)`
- `A_VERIFY_SIGNATURES`
- `A_VERIFY_GRAPH_CONFORMITY`
- `A_VERIFY_ANTI_REPLAY(nonce, timestamp_window)`
### Sorties
- `E_LOCAL_VERDICT_ACCEPT``S_LOGIN_SUCCESS`
- `E_LOCAL_VERDICT_REJECT``S_LOGIN_FAILURE`
---
## S_LOGIN_SUCCESS (connexion OK)
### Sorties
- `E_DONE``S_HOME`
---
## S_LOGIN_FAILURE (connexion KO)
### Actions
- Afficher diagnostics : signatures manquantes, objets manquants, anti-rejeu, etc.
### Sorties
- `E_RETRY``S_LOGIN_BUILD_PATH` (ou `S_LOGIN_COLLECT_SIGNATURES` selon cause)
- `E_RESYNC``S_SYNC_SERVICE`
- `E_BACK``S_HOME`
---
## États derreur
## S_ERROR_RECOVERABLE (erreur récupérable)
### Objectif
Afficher une erreur explicite et proposer des actions de reprise.
### Sorties possibles
- `E_RETRY` → état précédent
- `E_SYNC_NOW``S_SYNC_GLOBAL`
- `E_OPEN_DIAGNOSTIC``S_DIAGNOSTIC`
- `E_BACK``S_HOME`
---
## S_ERROR_FATAL (erreur bloquante)
### Objectif
Cas impossible à corriger sans intervention externe (ex : RNG indisponible).
### Sorties
- `E_EXIT` → fin
---
## S_DIAGNOSTIC (diagnostic hash / objet)
### Actions
- `A_FETCH_MSG_BY_HASH`
- `A_FETCH_SIGNATURES_BY_HASH`
- `A_FETCH_KEYS_BY_HASH`
- `A_TRY_DECRYPT`
- `A_VERIFY_HASH`
- `A_VERIFY_SIGNATURES`
- `A_VERIFY_VALIDATORS`
### Sorties
- `E_BACK``S_HOME` (ou état appelant)
## Anti-rejeu et cohérence temporelle (contrainte transversale)
### Règles
- Un login doit inclure un `nonce_login` unique.
- Le service (ou le validateur final) doit maintenir un cache `nonce_vus` par fenêtre temporelle.
- Le client doit également maintenir un cache local pour éviter de republier un nonce déjà utilisé.
### Erreurs
- `X_NONCE_REUSED` : nonce déjà vu → rejet.
- `X_TIMESTAMP_OUT_OF_WINDOW` : timestamp trop ancien/futur → rejet.
## Optimisation de scan (optionnel)
### Bloom filter
- État utilisateur : activé/désactivé
- Effet : éviter de re-fetch massivement des hash déjà vus
- Limite : faux positifs → toujours confirmer par vérification hash
### Merkle trees
- État utilisateur : activé/désactivé
- Effet : synchroniser par segments et preuves dinclusion
- Limite : complexité de maintenance côté relais
## Résumé des sorties réseau par phase
### Synchronisation
- GET `MsgChiffre` (par fenêtre temporelle, éventuellement par service)
- GET `MsgCle` par hash (ciblé)
- GET `MsgSignature` par hash (ciblé)
### Publication preuve (ordre strict)
- POST `MsgChiffre` (sans signatures ni clés)
- POST `MsgSignature`
- POST `MsgCle` (si requis)
## Table des causes déchec et état de reprise conseillé
- Contrat incomplet → `S_SYNC_SERVICE` puis `S_LOGIN_BUILD_PATH`
- Parent UUID manquant → `S_SYNC_GLOBAL` puis `S_LOGIN_BUILD_PATH`
- Message indéchiffrable (clé manquante) → `S_SYNC_GLOBAL` + fetch clés → retry
- Signature manquante → `S_LOGIN_COLLECT_SIGNATURES` + fetch signatures → retry
- Signature invalide → rester `S_LOGIN_COLLECT_SIGNATURES` (recollect)
- Pubkey non autorisée → `S_LOGIN_BUILD_PATH` (recalcul validateurs)
- Nonce rejoué → `S_LOGIN_BUILD_CHALLENGE` (nouveau nonce)
- Relais down → `S_RELAY_SETTINGS` ou `S_PUBLISH_QUEUE` avec retry/backoff
# Catalogue des objets du projet (contrats, identité, pairing, login, relais)
## Portée
Ce document recense lensemble des objets manipulés par le protocole :
- structure des contrats et des entités (service, contrat, champ, action, membre, pair),
- structure commune de message (MessageBase, hash, signature),
- objets de validation (validateurs, message à valider),
- objets cryptographiques séparés (message de signature, message individuel de déchiffrement),
- enveloppes réseau (messages chiffrés publiés sur relais),
- contraintes de publication et de récupération.
La règle principale est la séparation stricte :
- publication du message sans signatures ni clés,
- publication des signatures ensuite,
- publication des clés/matériels de déchiffrement ensuite.
## Conventions et invariants
### Types (types uuid et types names chiffrés)
Chaque objet porte un `types_uuid` et un `types_names_chiffres` incluant au minimum le type de lobjet.
Le type name est chiffré et peut inclure des sous-types (ex : "login" pour ActionLogin).
### Hash canonique
Le `hash` est calculé sur le JSON canonique de lobjet :
- sans le champ `hash`,
- sans la liste `signatures`,
- sans les champs `cles_de_chiffrement` (ou équivalents),
- sans tout bloc de signature ou matériel crypto posté séparément.
Le hash doit spécifier explicitement lalgorithme.
### Signature secp256k1
Les signatures servent à prouver :
- lintégrité (le hash),
- lautorité (clé publique autorisée par validateurs),
- lanti-rejeu (nonce / matériel additionnel éventuel).
### Publication “pour tous”
Tous les messages sont publiés :
- sans destinataire explicite,
- sous forme chiffrée,
- récupérés par GET périodiques via relais.
### Récupération séparée
Un GET de message ne doit pas renvoyer automatiquement :
- signatures,
- clés/matériels de déchiffrement.
Ils sont récupérés par requêtes dédiées ensuite.
## Structure commune : MessageBase
### Rôle
Base obligatoire dun message de lécosystème.
Supporte ladressage (hash), lindexation (uuid, version, type, service), et la synchronisation (timestamp, relais).
### Champs obligatoires
- `uuid` : identifiant unique de lobjet
- `version` : version du schéma de cet objet
- `types` :
- `types_uuid` : identifiant de type
- `types_names_chiffres` : au minimum le type (ex : "pair", "membre", "contrat")
- `cles_de_chiffrement` : paramètres + algorithmes (présents dans le message complet, mais exclus du hash canonique)
- `datajson` :
- obligatoires :
- `services_uuid[]` : au moins 1
- `types_uuid[]` : au moins 1
- optionnels :
- `label`
- `description_longue`
- `description_courte`
- `photo`
- `image`
- `banniere`
- `url`
- `paragraphes[]` : couples texte + image
- `tarif`
- `timestamp` : horodatage
- `liste_relais[]` : liste de relais (IP / endpoints)
- `version_logicielle` : version du client ayant produit le message
### Champs dérivés / attachés après coup
- `hash` : hash canonique (stockable dans le message complet, mais calculé sans certains champs)
- `signatures[]` : non inclus dans le message publié initialement (posté séparément)
## Objet : Hash
### Rôle
Décrit le hash canonique dun objet.
### Champs
- `algo` : nom de lalgorithme (ex : sha256)
- `hash_value` : valeur du hash (encodage à spécifier)
### Calcul
Le hash porte sur le JSON canonique :
- sans `hash`,
- sans signatures,
- sans clés de chiffrement.
## Objet : Signature
### Rôle
Preuve cryptographique associée à un hash.
### Champs
- `hash` : hash signé (référence)
- `cle_publique` : clé publique secp256k1
- `signature` : signature cryptographique secp256k1
- `nonce` : anti-rejeu
- `materiel` : champs optionnels (ex : contexte, challenge, metadata anti-rejeu)
### Contraintes
- La clé publique doit être autorisée selon les validateurs du message et/ou de laction.
- Le nonce doit être unique dans la fenêtre de validité considérée.
## Objet : Message à valider
### Rôle
Enveloppe logique dun message nécessitant validation contractuelle.
### Composition
- `MessageBase`
- `validateurs`
### Finalité
Permet de déterminer :
- quelles signatures sont requises,
- qui a autorité pour signer,
- quelles dépendances de signatures sont nécessaires.
## Objet : Validateurs
### Rôle
Définir les exigences de signatures, sous forme de règles par rôle/membre.
### Champs
- `membres_du_role[]` : au moins 1
Pour chaque membre de rôle :
- `signatures_obligatoires[]` :
- signatures exigées des autres membres et/ou de lui-même
- cardinalité minimale (si modèle seuil)
- dépendances éventuelles
### Contraintes
- La liste des membres du rôle doit être non vide.
- Les signatures doivent pouvoir être résolues vers des clés publiques présentes dans le graphe (membre/pair).
## Objet : Message de signature
### Rôle
Publication séparée dune ou plusieurs signatures associées à un message.
### Champs obligatoires
- `signature` : structure Signature complète
### Indexation recommandée
- `hash_cible` : hash du message ciblé (si non redondant avec signature.hash)
### Cycle de vie
1) message publié sans signatures
2) message(s) de signature publiés ensuite et attachés localement au message ciblé
## Objet : Message individuel de déchiffrement
### Rôle
Publication séparée des éléments permettant de récupérer une clé de déchiffrement (ou une clé enveloppe).
### Champs obligatoires
- `hash_message` : hash du message chiffré concerné
- `cle_de_chiffrement_message` :
- clé de chiffrement du message chiffré
- clé de chiffrement chiffrée (enveloppe)
- paramètres et algorithmes complets
- `df_ecdh_scannable` :
- matériel Diffie-Hellman à scanner
- contient une clé (ou information) permettant de déchiffrer la clé enveloppe via secret partagé
### Contraintes
- Le matériel DH est inutilisable sans possession dune clé privée correspondante.
- Ce message doit pouvoir être filtré/identifié côté client lors dun scan global.
## Objet : Enveloppe réseau “message chiffré publié”
### Rôle
Format minimal publié sur les relais pour la diffusion “pour tous”.
### Champs
- `hash` : hash canonique du message (référence)
- `message_chiffre` : payload chiffré (opaque)
- `datajson_public` :
- métadonnées non sensibles utiles au filtrage
- doit inclure au minimum :
- `services_uuid[]`
- `types_uuid[]`
- peut inclure :
- `timestamp`
- `version`
- autres marqueurs de routage/filtrage
### Contraintes
- Ne doit pas inclure signatures.
- Ne doit pas inclure clés de chiffrement.
## Objets “contrats / identité”
## Objet : Service
### Rôle
Décrit un service, son identité contractuelle, et sert de racine à une authentification.
### Champs spécifiques
- `contrat_uuid` : référence vers un Contrat
- `types_names_chiffres` inclut "service"
### Contraintes
- Doit exister dans `datajson.services_uuid[]` des objets liés au service.
- Doit être résoluble via sync par service.
## Objet : Contrat
### Rôle
Contrat didentité principal pour un service.
### Champs spécifiques
- `message_a_valider` : base + validateurs applicables
- `types_names_chiffres` inclut "contrat"
### Contraintes
- Le contrat doit être déchiffrable et validable pour autoriser des actions.
## Objet : Champ
### Rôle
Unité contractuelle rattachée à un ou plusieurs contrats.
### Champs spécifiques
- `message_a_valider`
- `types_names_chiffres` inclut "champ"
- `contrats_parents_uuid[]` : au moins 1
### Contraintes
- Au moins un parent contrat.
- Permet détendre la structure du contrat et des exigences.
## Objet : Action
### Rôle
Action exécutable dans le contexte du contrat.
Contient ses propres validateurs.
### Champs spécifiques
- `message_a_valider`
- `types_names_chiffres` inclut "action"
- `validateurs_action`
- `contrats_parents_uuid[]` : au moins 1
### Contraintes
- Au moins un parent contrat.
- Les validateurs doivent être satisfaisables.
## Objet : ActionLogin
### Rôle
Spécialisation de Action, de type “login”.
### Champs spécifiques
- `action` : référence Action
- `types_names_chiffres` inclut "login"
### Contraintes
- Doit être identifiable comme action de login dans le graphe.
- Les signatures requises pour login sont tirées des validateurs de laction.
## Objet : Membre
### Rôle
Identité dun membre (acteur) autorisé à exécuter des actions, dont login.
### Champs spécifiques
- `message_a_valider`
- `types_names_chiffres` inclut "membre"
- `actions_parents_uuid[]` : au moins 1
### Contraintes
- Doit référencer au moins une action.
- Doit pouvoir être lié à un ou plusieurs pairs (devices).
## Objet : Pair
### Rôle
Représente un device/instance participant aux signatures (mFA).
### Champs spécifiques
- `MessageBase`
- `types_names_chiffres` inclut "pair"
- `membres_parents_uuid[]` : au moins 1
### Contraintes
- Pairing obligatoire : au moins un pair attendu doit être disponible pour login.
- LUUID du pair sert didentifiant uniquement (clé didentification), pas de secret.
## Conversion UUID pair ↔ mots (BIP32)
### Rôle
Procédure robuste dassociation pair ↔ membre sans échanger lUUID brut.
### Procédé
- UUID du pair converti via dérivation BIP32 en une liste de mots.
- Device A affiche les mots.
- Device B saisit les mots.
- Reconstitution de lUUID du pair.
### Contraintes
- La liste de mots doit inclure un checksum ou mécanisme de détection derreur.
- Les mots nexposent pas de secret exploitable : lUUID nest quun identifiant.
## Objet : Relais (entité réseau)
### Rôle
Stocker et relayer des objets adressés par hash.
Assurer une diffusion inter-relais.
### Responsabilités minimales
- Stocker :
- enveloppes `MsgChiffre`
- messages `MsgSignature`
- messages `MsgCle`
- Relayer entre relais
- Déduplication :
- sauvegarder les hash reçus pour ne pas relayer deux fois
### Contraintes
- Un relais ne doit pas “fusionner” message + signatures + clés lors dun GET.
- Le client doit pouvoir GET par période et idéalement filtrer par service.
## Catalogue des flux (rappel)
## Publication dun objet (ordre strict)
1) Publication `MsgChiffre`
- contient hash + message chiffré + datajson public
- sans signatures
- sans clés
2) Publication `MsgSignature`
- une ou plusieurs signatures (selon validateurs)
- attachées au hash
3) Publication `MsgCle`
- clés / matériels DH nécessaires au déchiffrement
- attachés au hash
## Récupération côté client
1) GET `MsgChiffre` (pull périodique, par fenêtre)
2) Déduplication par hash
3) GET `MsgCle` (si candidat déchiffrable)
4) Déchiffrement, parsing, recalcul hash canonique
5) GET `MsgSignature`
6) Vérification secp256k1 + validateurs
7) Mise à jour graphe local
## Conditions de login (rappel)
Pour se logguer, il faut :
- cibler un `service_uuid`,
- trouver lActionLogin du membre,
- satisfaire les validateurs de laction login,
- fournir les signatures attendues des pairs requis,
- publier preuve (message → signatures → clés),
- permettre au service de vérifier la conformité contrat/signature sans serveur central.