Ring signatures pour anonymiser les noeuds sur le réseau

Oui, mais si un membre peut avoir 50 noeuds qui apparaissent comme membre sans pouvoir identifier à quel membre il appartient, ses noeuds pèseront 50 fois plus lourd dans les requêtes décentralisées.

1 « J'aime »

Oui donc il faut trouver un moyen de reconnaitre que deux nœuds appartiennent au même membre sans savoir de quel membre il s’agit, je suis presque sûr qu’il existe un outils de crypto qui nous permettrais de faire ça :slight_smile:

2 « J'aime »

@Inso si c’est juste pour que les clients puissent déterminer quel est le consensus réseau ils peuvent s’appuyer sur des head qui seraient toujours signés de manière classique donc on saurait toujours a quel membre appartient chaque head et chaque membre n’aurais donc toujours qu’une seule voie, qu’en pense tu ?

Ce n’est pas juste une question de consensus réseau. Il faut aussi que l’on puisse vérifier que quand on demande “Est-ce que tel identité est membre ?” au réseau, cette requête ne puisse pas être victime d’une attaque sybille (ou des dizaines de noeuds malintentionnés répondent une fausse réponse…)

Pour ça, aujourd’hui, je requête par exemple 6 noeuds membre, et je ne considère la réponse correcte que si elle a reçu 6 accords. Sinon, je requête de nouveaux noeuds membres.

1 « J'aime »

@Inso @nanocryk

Je pense que la solution se situe coté réseau : il faudrait une api client fait de telle sorte que la réponse passe par l’ensemble du réseau, un peu comme ce que fait bma avec la commande sync mais en beaucoup plus sophistiqué, je m’explique :

Les clients pourraient requeter n’importe-quel noeud (membre ou pas) et lui dire : “je veut la réponse de X membres a la requête Y”. Le noeud en question relayerai alors immédiatement (via ws2p par exemple) le message a l’ensemble des nœuds auquel il est connecté puis par rebond ça se diffuserai puis il récupèrerai les réponses (le noeud d’origine aurait donc amender son ws2id+pubkey a la requete qu’il partage) et enfin il enverrai toutes les réponses au client demandeur, chaque réponse de membre étant signée de façon classique avec sa clé publique de membre dans la réponse.

Cela demanderai de bien interfacer GVA et WS2P dans le cœur, mais je ne vois pas de barrière technique en tout cas :slight_smile:

Une autre solution qui viendra avec le nouveau protocole :

Dans le nouveau protocole, tous les documents seront indexés dans un Merkle Tree.

Un client se synchronise en ne recuperant que les headers et la preuve de travail, qui contiennent les Merkle Root, tous les documents étant segregués plus loin dans le bloc (et ne faisant de la preuve que via le Merkle Root). C’est quelque chose qui pèsera très peu par bloc, surtout s’il ne stocke pas tous les informations annexes. Il peux le faire au près de plusieurs noeuds, pour être sur de partager la même chaine.

Note : en se synchronisant on peut finalement stocker uniquement les Merkle Root, soit 32 o/bloc, soit moins de 3Mo pour toute la blockchain G1, et on pourrait même imaginer de combiner les Merkle Root au fur et à mesure, pour n’en stocker un complet de toute la blockchain. Le client n’aurait alors que 32o à stocker, et log2(nombre de documents) hashs à recevoir des noeuds.

Ensuite, s’il veut vérifier que telle identité est membre, il génère le document d’identité correspondant (sans le signer), et il peux calculer son hash (l’UID du document). Il peut ensuite demander à un premier noeud “Donne moi la branche de Merkle qui contient ce document”. Si on lui donne, il est sur que ce document est bien dans la bloc chain (il peut recalculer l’arbre de Merkle et tomber sur la même Merkle Root). Si on ne lui donne pas, il va demander à un autre noeud.

Avec ce système on ne peux pas prouver que le document n’existe pas, et on peut assumer qu’après un certain nombre d’essais le document n’existe bel et bien pas. Mais dès que la preuve est obtenue (1er, 2ème requete par exemple), il n’est plus nécéssaire de demander à d’autres noeuds.

Note 2 : Cette technique fonctionne avec n’importe quel document, et permet aussi de prouver que des certifications/transactions/revocations existent, ce qui pourrait être très pratique pour les clients.

Du coup chaque request est broadcast à tous les membres du réseau ? Ca risque pas d’être assez énorme comme charge ?

Correction : log2 et pas ln.
Correction 2 : log2(nombre de documents) et pas log2(nombre de blocs).

Non seulement aux nœuds auquel le noeud est connecté via ws2p, ensuite on peut limiter les rebond a 1 ou 2 step en fonction du nombre X de membres différents souhaités. C’est d’ailleurs ce que je pense déjà vous proposer pour les head afin d’éviter une surcharge du réseau le jours ou il sera très grand :wink:

Le mécanisme basé sur les merkleRoot ne permet malheuresement pas de faire des requêtes avancées telles qu’on l’envisage avec GVA (Telle identité est elle membre, est-elle dans la WoT ou trop loin des sentries,e tc).

Mais c’est un mécanisme intéressant pour toutes les requêtes de type “validation d’écriture de document dans la chaine”. Ca spam moins le réseau que de faire une requête comparative.


Sinon le mécanisme d’elois pourrait fonctionner. Ca risque par contre de surcharger les sockets inter-noeuds au lieu des sockets externes (clients <-> noeuds) ce qui est un risque il me semble. Et les délais de réponse peuvent être allongés (on rajoute N rebonds entre le client et les noeuds, au lieu d’avoir un lien direct client <-> noeud).

1 « J'aime »

Alors en fait le plus souvent il ne s’y échange rien, sauf l’hors de l’arrive d’un nouveau bloc, mais entre deux blocs les sockets inter-nœuds sont largement sous-exploités :slight_smile:

Oui il faudrait bien réfléchir a comment optimiser ça. Après dans la pratique un noeud étant connecté en moyenne a plus de 10 autres, et les membres étant prioritaires, 1 seul rebond suffirait pour voir une réponse de 6 membres différents :wink:

Avec le recul, ça pose quand même un problème : ce n’est pas le client qui décide qui lui répond dans ce cas. Comme les 6 noeuds ne sont pas décidés par lui, on peut imaginer qu’un noeud malveillant enverrait spécifiquement une demande de confirmation à 5 autres noeuds malveillant. Ca affaiblit quand même fortement le modèle de sécurité de ces requêtes.

@Inso A un moment il faut faire un choix entre sécurité ou vitesse, ça pourrait être au client de choisir :

Soit le client choisi X membres parmi ceux dans la fenetre courante et dit qu’il veut la réponse de ses 6 membres la, il y aura plus de rebond et un temps de réponse un peu plus long mais ce sera safe.
Soit le client dit “je veut la réponse de X membre le plus vite possible” et la c’est les plus proches sur le réseau qui répondent.

A voir si déja il est vraiment nécessaire d’anonymiser les noeuds sur le réseau :slight_smile:

Savoir quelle clé membre correspond à quelle machine/IP me semble plutôt risqué.

1 « J'aime »

La couche Tor ne suffirait-elle pas ?

1 « J'aime »

Elle permet effectivement de masquer son ip, mais il est toujours possible de lancer une attaque DDOS sur le endpoint public en .onion. Et c’est dommage de ne faire que du ws2p privé je trouve :confused:

De plus beaucoup d’"informations restent publiques :

  • On sait quand un membre a des nœuds sur le réseau ou pas et combien il en a.
  • on sait qui tente de se connecter a soi et donc on peut refuser selon des critères personnels, c’est le même problème qu’avec les unités monétaires non-anonymes an final.

Enfin TOR est quand même lent et n’est pas user-friendly, donc seul ceux qui ont un très bon niveau technique pourront s’anonymiser, ce que je ne trouve pas très juste. Si on se contente de TOR, dans les faits la majorité des nœuds membres seront vulnérables, l’anonymisation sur le réseau me semble indispensable a long terme !

2 « J'aime »

Et puis surtout si tous les nœuds font du privé ça ne marche plus ! C’est bien le WS2P public qui permet le privé.

Après je n’ai pas de solution immédiate à proposer pour protéger son nœud, mais j’ai tout un tas de pistes en tête. Je suis confiant sur ce sujet. Il nous faut continuer à creuser, et notamment identifier notre besoin : est-ce que l’on veut se cacher ? se protéger ? Car la réponse n’est pas forcément la même.

Par contre concernant le besoin d’ @Inso, à savoir requêter directement les nœuds membres, je pense qu’à terme c’est une chose qui va sauter. Interroger les nœuds de membre en direct me semble être un luxe, leur rôle devrait se limiter à dialoguer entre eux pour garantir l’écriture de la blockchain.

Car au final, l’authenticité, c’est dans la blockchain qu’on la constate. Même un nœud miroir devrait pouvoir répondre à nos questions sans qu’on ait le moindre doute quant à la véracité de l’information donnée qui doit pouvoir être recoupée.

4 « J'aime »

Il y a peut être une forme de délégation de clé pour les réponses aux API à mettre en place.

Par contre je suis beaucoup moins confiant que toi sur la possibilité de demander aux clients de vérifier ce qui est dans la chaîne. La distance, la destruction de monnaie, etc, rendent tout ça bien plus difficile. De plus, on a de la chance dans Duniter de pouvoir identifier les noeuds et se protéger facilement et de manière certain des attaques sybilles. Ce serait vraiment dommage de garder les même faiblesses que bitcoin/ethereum là dessus. (Ils souffrent du même risque, si le client télécharge les headers de la chaine sur un réseau majoritairement corrompu, il télécharge une chaine corrompue…)

Mais du coup, je pense à quequechose : les noeuds miroirs peuvent être utilisés pour le obtenir les données, les noeuds membres pour valider. Et c’est une nuance importante ! C’est peut être ça la clé qui peut nous aider à résoudre notre problème. cc @vit

Par exemple, on peut imaginer 2 couches :

  • Une couche “obtenir les données” où une requête = une liste de données complètes. On ne peut pas filtrer les données autant que ce qu’on voulait avec GraphQL, on les obtient nécessairement en bloc pré-définis, mais au moins on peut les obtenir en une seule requête “Qui sont les certifieurs de X, quel est leur statut d’adhésion ?”
  • Une couche “validation des données” où les requêtes sont clairement définies “Quel est le statut d’adhésion de X” “Qui sont les certifieurs de X”.

Cette couche de validation peut être requêtée sur un noeud membre ou non-membre. Sur un noeud non-membre, il requête des noeuds membres directement connectés pour obtenir une liste de hash de réponses signées.

Le client, pour obtenir et valider des données, va donc :

  • Requêter un noeud aléatoire, de préférence non-membre, pour obtenir des données
  • Requêter 3 à 4 noeuds, membres ou non-membres, pour valider des données. Les données ne sont validées que pour par exemple 12 validations authentifiées. On peut s’appuyer sur WS2P pour transférer des demandes de validation, comme l’a suggéré elois (développement d’un module “ws2p-validation” ?) Pour chaque “bloc” de données obtenu, il calcul l’arbre merkle et vérifie qu’il peut trouver 12 signatures authentifiées qui garantissent de la validité des données parmis toutes les validations reçues.

Un réseau qui serait victime d’attaque sybille serait fortement paralysé (difficulté pour les clients léger de faire valider des données si il n’y a pas de noeud membre qui répond), mais ne serait pas compromis.

Tout ce que ça implique, c’est de télécharger dans un premier temps la liste de toutes les clés publiques membres, et de les mettre à jour régulièrement, afin de pouvoir vérifier les validations authentifiées.

Pour se défendre contre les attaques sybilles qui parallyserait le réseau, il faudrait implémenter un système de “délégation de clé pour les API”. Ainsi les noeuds membres qui calculent des blocs peuvent le faire de manière distincte des noeuds membres qui répondent aux requêtes des clients.

2 « J'aime »

Oui mais contrairement à Bitcoin/Ethereum, nos blocs sont signés et donc authentifiables. Nous pouvons donc aisément détecter si l’on se trouve sur le chaîne principale ou pas, par simple constat d’inertie : si je regarde les 100, 500 ou 1500 derniers headers (en-tête de bloc, en supposant que les transactions n’en font plus partie pour un téléchargement rapide et une vérification immédiate du chaînage), je peux voir si en effet les données sont cohérentes avec la tête d’une chaine principale ou non : nombre d’émetteurs différents correct, temps évoluant dans une forme similaire à d’habitude, taille de fenêtre qui varie peu, contenance d’un bloc préalablement connu et validé de longue date, etc.

Ce constat d’inertie me semble être une solution très simple et redoutablement efficace pour avoir des infos valables sans interroger de noeud membre.

Mais en plus il y a aussi la propagation du document réseau HEAD, qui permet de connaître formellement l’état courant de tout noeud du réseau, notamment ceux membres. Et ceci sans les interroger.

Oui c’est la bonne façon de faire je pense, mais pas besoin de réaliser cela sur la couche réseau. Les données suffisent : tu les obtiens par noeuds miroirs, et ensuite tu peux authentifier le contenu car tout est signé. Tout client peut vérifier la cohérence des données entre elles et détecter un éventuel floutage.

J’insiste vraiment sur le fait qu’il faut laisser les noeuds membres tranquilles car plus la monnaie va être utilisée, plus ils auront autre chose à faire que répondre à des questions. Ils passeront plutôt leur temps à recevoir des ordres et à écrire dans la blockchain, ce qui est véritablement le coeur du logiciel. Qui plus est en s’attelant à répondre à des requêtes, on expose les noeuds à des attaques réseau (seconde raison principale qui m’a fait développer WS2P : il n’y a qu’une porte d’entrée, le refus y est rapide et peu coûteux).

On peut imaginer que certains noeuds offrent plus comme avec l’ajout de l’API GVA par exemple, mais c’est du bonus. Ceux-là s’exposeront à des risques acceptés par leur mainteneur, et surtout par défaut leur noeud sera protégé car dépourvu d’API publique.

Je comprends bien votre problématique de mainteneurs de logiciel client, mais de mon côté je dois défendre le coeur du réseau car c’est vraiment la partie sensible. Avec le nombre d’utilisateurs qui grimpe, la pression monte et je vais devenir de plus en plus exigeant (qui a dit paranoïaque ?).

3 « J'aime »

6 messages ont été déplacés vers un nouveau sujet : Machine à état infalsifiable et requêtes de clients ?

Alors selon moi on n’a besoin des deux :

Se cacher permet d’empêcher toute attaque ciblée sur un membre particulier, mais les attaques non-ciblés qui vise juste “l’ensemble des nœuds membres ayant un endpoint ws2p public” restent possibles.

Il faut donc aussi des mesures de protection, mais même les protections les plus parfaites possibles ne suffiront pas face a une attaque ciblée sur un seul noeud en particulier, il est donc essentiel a long terme de permettre aux nœuds membre de ne pas dévoiler leur identité sur le réseau et ceux de façon user-friendly (un trousseau de clé alternatif a saisir point), donc TOR ne peut pas répondre a se besoin.

TOR reste cependant un atout fort appréciable pour sécuriser la monnaie car il permet d’avoir tout un réseau de nœuds membres dont on ne connais pas les IP, ce qui limite la surface d’attaque aux seuls endpoints publics en .onion.
Alors qu’un noeud dont un connais l’ip, on peut attaquer la machine correspondante sous d’autres angles, scan de port, ddos sur d’autres services derrière la même ip, exploitations de failles de sécurité, etc…

Exactement, et c’est pour cela que j’insiste, la feature d’anonymisation sur le réseau me semble obligatoire a long terme, ça ne nous sera sans doute pas utile avant des années, mais si un jours nous sommes des millions de membres et qu’on empiète sérieusement sur l’économie dominante les membres calculants seront bien content de pouvoir se cacher (car au final c’est d’abord la la faute des membres calculants tout ça, c’est eux qu’il faut anéantir).

1 « J'aime »