ncantu 5689693507 UserWallet: Multiple feature implementations and updates
**Motivations:**
- Implement BIP39 mnemonic import for identity creation
- Add password-based key protection for enhanced security
- Improve pairing workflow with QR code and URL display
- Migrate hash cache from LocalStorage to IndexedDB for better scalability
- Update signet-dashboard and mempool components

**Root causes:**
- N/A (feature implementations)

**Correctifs:**
- N/A (no bug fixes in this commit)

**Evolutions:**
- BIP39 mnemonic import: Support for 12/24 word English mnemonics with BIP32 derivation path m/44'/0'/0'/0/0
- Key protection: Password-based encryption of private keys at rest with unlock/lock functionality
- Pairing workflow: QR code and URL display for device pairing, form-based word exchange between devices
- IndexedDB migration: Hash cache moved from LocalStorage to IndexedDB to avoid size limitations
- Global action bar: URL parameter support for navigation
- Pairing connection: Enhanced pairing status management

**Pages affectées:**
- userwallet/src/utils/identity.ts
- userwallet/src/utils/keyProtection.ts
- userwallet/src/utils/sessionUnlockedKey.ts
- userwallet/src/utils/indexedDbStorage.ts
- userwallet/src/utils/cache.ts
- userwallet/src/utils/pairing.ts
- userwallet/src/components/UnlockScreen.tsx
- userwallet/src/components/PairingDisplayScreen.tsx
- userwallet/src/components/PairingSetupBlock.tsx
- userwallet/src/components/GlobalActionBar.tsx
- userwallet/src/components/HomeScreen.tsx
- userwallet/src/components/ImportIdentityScreen.tsx
- userwallet/src/components/DataExportImportScreen.tsx
- userwallet/src/hooks/useIdentity.ts
- userwallet/src/hooks/usePairingConnected.ts
- userwallet/src/services/syncService.ts
- userwallet/src/services/pairingConfirm.ts
- userwallet/src/App.tsx
- userwallet/package.json
- userwallet/docs/specs.md
- userwallet/docs/storage.md
- userwallet/docs/synthese.md
- signet-dashboard/public/*.html
- signet-dashboard/public/app.js
- signet-dashboard/public/styles.css
- mempool (submodule updates)
- hash_list.txt, hash_list_cache.txt, utxo_list.txt, utxo_list_cache.txt, fees_list.txt
- features/*.md (documentation files)
2026-01-26 10:23:34 +01:00

64 KiB
Raw Blame History

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

  • Auteurs de l'action
  • contrats parents uuid, au moins 1

Objets créés lors de la création :

Lors de la création d'un Pair :

  • Création automatique d'un Pair (MessageBase avec types_names_chiffres incluant "pair")
  • Le Pair doit être associé à au moins un Membre (membres_parents_uuid, au moins 1)

Lors de la création d'un Membre :

  • Création automatique d'un Membre (MessageAValider avec types_names_chiffres incluant "membre")
  • Le Membre doit être associé à au moins une Action (actions_parents_uuid, au moins 1)

Lors de la création d'un contrat de login d'un Service :

  • Création automatique d'un Contrat (MessageAValider avec types_names_chiffres incluant "contrat")
  • Création automatique d'une ActionLogin (Action avec types_names_chiffres incluant "login")
  • Création automatique d'un Membre (MessageAValider avec types_names_chiffres incluant "membre")
  • L'ActionLogin est associée au Contrat (contrats_parents_uuid incluant l'UUID du Contrat)
  • Le Membre est associé à l'ActionLogin (actions_parents_uuid incluant l'UUID de l'ActionLogin)
  • Le nom du contrat de login est passé en paramètre initial à l'iframe ou au site, par défaut "default"

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_ABSENTS_IDENTITY_REQUIRED
  • E_IDENTITY_PRESENTS_HOME

S_IDENTITY_REQUIRED (identité manquante)

UI associée

  • écran accueil avec options “Créer” / “Importer”

Transitions

  • E_CREATE_IDENTITYS_IDENTITY_CREATE
  • E_IMPORT_IDENTITYS_IDENTITY_IMPORT

S_IDENTITY_CREATE (création identité locale)

Actions

  • A_GEN_SECP256K1_KEYPAIR
  • A_SET_T0_ANNIVERSAIRE
  • A_INIT_CACHE

Sorties

  • E_IDENTITY_CREATEDS_HOME

Erreurs

  • X_RNG_UNAVAILABLES_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_IMPORTEDS_HOME

Erreurs

  • X_IMPORT_INVALIDS_ERROR_RECOVERABLE

S_HOME (accueil)

Événements

  • E_OPEN_RELAY_SETTINGSS_RELAY_SETTINGS
  • E_SYNC_NOWS_SYNC_GLOBAL
  • E_MANAGE_PAIRSS_PAIR_MANAGEMENT
  • E_LOGIN_STARTS_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_SAVEDS_HOME
  • E_CANCELS_HOME

Erreurs

  • X_RELAYS_INVALIDS_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_DONES_HOME
  • E_SYNC_DONE_WITH_DISCOVERYS_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_BACKS_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_DONES_SERVICE_LIST
  • E_BACKS_SERVICE_LIST

S_PAIR_MANAGEMENT (gestion pairs)

Transitions

  • E_PAIR_ADDS_PAIR_ADD
  • E_PAIR_ASSOCIATE_TO_MEMBERS_PAIR_ASSOCIATE
  • E_BACKS_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_READYS_PAIR_ASSOCIATE

Erreurs

  • X_WORDS_INVALIDS_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_QUEUEDS_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_OKS_HOME
  • E_PUBLISH_PARTIALS_ERROR_RECOVERABLE

Erreurs

  • X_RELAY_DOWNS_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_BACKS_HOME

S_LOGIN_PAIRING_REQUIRED (pairing obligatoire)

Transitions

  • E_GO_PAIRINGS_PAIR_MANAGEMENT
  • E_BACKS_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_BACKS_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_OKS_LOGIN_CHECK_PAIRS
  • E_PATH_INCOMPLETES_ERROR_RECOVERABLE
  • E_PATH_INVALIDS_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_OKS_LOGIN_BUILD_CHALLENGE

S_LOGIN_NEED_MORE_PAIRS (pairs manquants)

Transitions

  • E_ADD_PAIRS_PAIR_MANAGEMENT
  • E_RESYNCS_SYNC_SERVICE
  • E_BACKS_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_READYS_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_COMPLETES_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_OKS_LOGIN_VERIFY_LOCAL
  • E_PUBLISH_LOGIN_PARTIALS_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_ACCEPTS_LOGIN_SUCCESS
  • E_LOCAL_VERDICT_REJECTS_LOGIN_FAILURE

S_LOGIN_SUCCESS (connexion OK)

Sorties

  • E_DONES_HOME

S_LOGIN_FAILURE (connexion KO)

Actions

  • Afficher diagnostics : signatures manquantes, objets manquants, anti-rejeu, etc.

Sorties

  • E_RETRYS_LOGIN_BUILD_PATH (ou S_LOGIN_COLLECT_SIGNATURES selon cause)
  • E_RESYNCS_SYNC_SERVICE
  • E_BACKS_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_NOWS_SYNC_GLOBAL
  • E_OPEN_DIAGNOSTICS_DIAGNOSTIC
  • E_BACKS_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_BACKS_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
  1. Publication MsgSignature
  • une ou plusieurs signatures (selon validateurs)
  • attachées au hash
  1. 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.