Nous poursuivons notre série sur la blockchain Monero, et l'article d'aujourd'hui se concentrera sur le protocole RingCT (Ring Confidential Transactions), qui introduit des transactions confidentielles et de nouvelles signatures en anneau. Malheureusement, il existe peu d'informations sur Internet sur son fonctionnement et nous avons essayé de combler cette lacune.
Nous expliquerons comment le réseau cache les montants des transferts à l'aide de ce protocole, pourquoi ils ont abandonné les signatures en anneau cryptonotes classiques et comment cette technologie va se développer davantage.
Ce protocole étant l'une des technologies les plus complexes de Monero, le lecteur aura besoin d'une connaissance de base de la conception de cette blockchain et d'une connaissance approfondie de la cryptographie à courbe elliptique (pour parfaire ces connaissances, vous pouvez lire les premiers chapitres de notre article précédent sur
Protocole RingCT
L’une des attaques possibles contre les monnaies cryptonotes est l’analyse de la blockchain basée sur la connaissance du montant et de l’heure de la transaction envoyée. Ceci permet
Il est à noter que l’idée de cacher des montants n’est pas nouvelle. Greg Maxwell, développeur de Bitcoin Core, a été l'un des premiers à le décrire dans son
Entre autres choses, le protocole aide à éliminer les problèmes liés au mélange des sorties de poussière - des sorties d'une petite quantité (généralement reçues sous forme de monnaie provenant de transactions), qui ont créé plus de problèmes qu'elles n'en valaient la peine.
En janvier 2017, un hard fork du réseau Monero a eu lieu, permettant l'utilisation facultative de transactions confidentielles. Et déjà en septembre de la même année, avec le hard fork de la version 6, ces transactions sont devenues les seules autorisées sur le réseau.
RingCT utilise plusieurs mécanismes à la fois : des signatures de groupe anonymes spontanées liées multicouches (Multilayered Linkable Spontaneous Anonymous Group Signature, ci-après dénommé MLSAG), un système d'engagement (Pedersen Commitments) et des preuves de portée (ce terme n'a pas de traduction établie en russe) .
Le protocole RingCT introduit deux types de transactions anonymes : simples et complètes. Le portefeuille génère le premier lorsqu'une transaction utilise plus d'une entrée, le second - dans la situation inverse. Ils diffèrent par la validation des montants des transactions et les données signées avec une signature MLSAG (nous en reparlerons plus en détail ci-dessous). De plus, les transactions de type full peuvent être générées avec n'importe quel nombre d'entrées, il n'y a pas de différence fondamentale. Dans le livre
Signature MLSAG
Rappelons ce que sont les entrées de transaction signées. Chaque transaction dépense et génère des fonds. La génération de fonds se produit en créant des sorties de transaction (une analogie directe est les factures), et la sortie que la transaction dépense (après tout, dans la vraie vie, nous dépensons des billets de banque) devient l'entrée (attention, il est très facile de se tromper ici).
Une entrée fait référence à plusieurs sorties, mais n’en dépense qu’une, créant ainsi un « écran de fumée » rendant difficile l’analyse de l’historique de traduction. Si une transaction a plus d’une entrée, alors une telle structure peut être représentée comme une matrice, où les lignes sont les entrées et les colonnes sont les sorties mixtes. Pour prouver au réseau que la transaction dépense exactement ses sorties (connaît leurs clés secrètes), les entrées sont signées avec une signature en anneau. Une telle signature garantit que le signataire connaissait les clés secrètes de tous les éléments de l'une des colonnes.
Les transactions confidentielles n'utilisent plus les transactions classiques
Ils sont appelés multicouches car ils signent plusieurs entrées à la fois, chacune étant mélangée à plusieurs autres, c'est-à-dire qu'une matrice est signée, et non une ligne. Comme nous le verrons plus tard, cela permet d'économiser sur la taille de la signature.
Regardons comment une signature en anneau est formée, en utilisant l'exemple d'une transaction qui dépense 2 sorties réelles et utilise m - 1 sorties aléatoires de la blockchain pour le mélange. Notons les clés publiques des produits que nous dépensons comme
, et leurs images clés en conséquence : On obtient donc une matrice de taille 2xm. Tout d’abord, nous devons calculer les soi-disant défis pour chaque paire de résultats :
Nous commençons les calculs avec les sorties, que nous dépensons en utilisant leurs clés publiques :et des nombres aléatoiresEn conséquence, nous obtenons les valeurs suivantes :
, que nous utilisons pour calculer le défi
la paire de sorties suivante (pour faciliter la compréhension de ce que nous remplaçons par où, nous avons mis en évidence ces valeurs dans différentes couleurs). Toutes les valeurs suivantes sont calculées dans un cercle à l'aide des formules données dans la première illustration. La dernière chose à calculer est le défi pour une paire de résultats réels.
Comme nous pouvons le voir, toutes les colonnes sauf celle contenant les sorties réelles utilisent des nombres générés aléatoirement.. Pour π- colonne nous en aurons également besoin. Transformons-nousen s :
La signature elle-même est un tuple de toutes ces valeurs :
Ces données sont ensuite écrites dans une transaction.
Comme on peut le voir, MLSAG ne contient qu’un seul défi c0, ce qui permet de gagner sur la taille de la signature (qui demande déjà beaucoup d'espace). De plus, tout inspecteur, utilisant les données, restitue les valeurs c1,…, cm et vérifie que. Ainsi, notre bague est fermée et la signature a été vérifiée.
Pour les transactions RingCT de type complet, une ligne supplémentaire est ajoutée à la matrice avec des sorties mixtes, mais nous en parlerons ci-dessous.
Engagements de Pedersen
Les engagements Monero sont utilisés pour masquer les montants des transferts et utiliser l'option la plus courante - les engagements Pedersen. À propos, un fait intéressant - au début, les développeurs ont proposé de masquer les montants par mélange ordinaire, c'est-à-dire en ajoutant des résultats pour des montants arbitraires afin d'introduire de l'incertitude, mais ils sont ensuite passés aux engagements (ce n'est pas un fait qu'ils ont économisé sur la taille de la transaction, comme nous le verrons ci-dessous).
En général, l'engagement ressemble à ceci :
Où C — le sens même de l'engagement, a - montant caché, H est un point fixe sur la courbe elliptique (générateur supplémentaire), et x — une sorte de masque arbitraire, un facteur de masquage généré aléatoirement. Le masque est ici nécessaire pour qu'un tiers ne puisse pas simplement deviner la valeur de l'engagement.
Lorsqu'un nouveau résultat est généré, le portefeuille calcule l'engagement correspondant et, lorsqu'il est dépensé, il prend soit la valeur calculée lors de la génération, soit la recalcule, en fonction du type de transaction.
RingCT simple
Dans le cas de transactions RingCT simples, afin de garantir que la transaction a créé des extrants d'un montant égal à la quantité d'intrants (n'a pas produit d'argent à partir de rien), il est nécessaire que la somme des engagements du premier et du deuxième les deux soient les mêmes, c'est-à-dire :
Les commissions d’engagement l’envisagent un peu différemment – sans masque :
Où a — le montant de la commission, il est accessible au public.
Cette approche nous permet de prouver à la partie utilisatrice que nous utilisons les mêmes montants sans les divulguer.
Pour rendre les choses plus claires, regardons un exemple. Disons qu'une transaction dépense deux sorties (ce qui signifie qu'elles deviennent des entrées) de 10 et 5 XMR et génère trois sorties d'une valeur de 12 XMR : 3, 4 et 5 XMR. En parallèle, il paie une commission de 3 XMR. Ainsi, le montant d’argent dépensé plus le montant généré et la commission est égal à 15 XMR. Essayons de calculer les engagements et regardons la différence de leurs montants (rappelez-vous les calculs) :
Nous voyons ici que pour que l’équation converge, nous avons besoin que les sommes des masques d’entrée et de sortie soient les mêmes. Pour ce faire, le portefeuille génère aléatoirement x1, y1, y2 et y3, et le reste x2 se calcule ainsi :
Grâce à ces masques, nous pouvons prouver à n’importe quel vérificateur que nous ne générons pas plus de fonds que nous n’en dépensons, sans en divulguer le montant. Originale, non ?
RingCT plein
Dans les transactions RingCT complètes, la vérification des montants des transferts est un peu plus complexe. Dans ces transactions, le portefeuille ne recalcule pas les engagements pour les intrants, mais utilise ceux calculés lors de leur génération. Dans ce cas, nous devons supposer que nous n’obtiendrons plus la différence des sommes égale à zéro, mais plutôt :
il est z — différence entre les masques d'entrée et de sortie. Si l'on considère zG en tant que clé publique (ce qui est le cas de facto), alors z est la clé privée. Ainsi, nous connaissons les clés publiques et privées correspondantes. Avec ces données en main, nous pouvons les utiliser dans la signature en anneau MLSAG avec les clés publiques des sorties mixées :
Ainsi, une signature en anneau valide garantira que nous connaissons toutes les clés privées de l'une des colonnes, et nous ne pourrons connaître la clé privée de la dernière ligne que si la transaction ne génère pas plus de fonds qu'elle n'en dépense. D'ailleurs, voici la réponse à la question « pourquoi la différence dans les montants des engagements ne conduit-elle pas à zéro » - si zG = 0, nous élargirons ensuite la colonne avec des sorties réelles.
Comment le destinataire des fonds sait-il combien d’argent lui a été envoyé ? Tout est simple ici : l'expéditeur de la transaction et le destinataire échangent des clés à l'aide du protocole Diffie-Hellman, en utilisant la clé de transaction et la clé de vue du destinataire et calculent le secret partagé. L'expéditeur écrit des données sur les montants émis, cryptées avec cette clé partagée, dans des champs spéciaux de la transaction.
Preuves de gamme
Que se passe-t-il si vous utilisez un nombre négatif comme montant des engagements ? Cela peut conduire à la génération de pièces supplémentaires ! Ce résultat est inacceptable, nous devons donc garantir que les montants que nous utilisons ne sont pas négatifs (sans divulguer ces montants, bien sûr, sinon il y a tellement de travail et tout cela en vain). En d’autres termes, il faut prouver que la somme est dans l’intervalle [0, 2n - 1].
Pour ce faire, la somme de chaque sortie est divisée en chiffres binaires et l'engagement est calculé pour chaque chiffre séparément. Il vaut mieux voir comment cela se produit avec un exemple.
Supposons que nos montants soient petits et tiennent dans 4 bits (en pratique, il s'agit de 64 bits), et nous créons une sortie valant 5 XMR. Nous calculons les engagements pour chaque catégorie et l'engagement total pour l'intégralité du montant :
Ensuite, chaque engagement est mélangé à un substitut (Ci-2iH) et est signé par paire avec la bague signature Borromeo (une autre signature de bague), proposée par Greg Maxwell en 2015 (vous pouvez en savoir plus à ce sujet
Dans l'ensemble, cela s'appelle la preuve de fourchette et vous permet de garantir que les engagements utilisent des montants compris dans la fourchette. [0, 2n - 1].
Quelle est la prochaine?
Dans l'implémentation actuelle, les preuves de plage occupent beaucoup d'espace - 6176 XNUMX octets par sortie. Cela conduit à des transactions plus importantes et donc à des frais plus élevés. Pour réduire la taille d'une transaction Monero, les développeurs introduisent des pare-balles au lieu des signatures Borromeo - un mécanisme de preuve de portée sans engagement au niveau du bit.
Posez vos questions, suggérez des sujets de nouveaux articles sur les technologies dans le domaine de la crypto-monnaie, et abonnez-vous également à notre groupe en
Source: habr.com