Fonctionnement du prototype de transactions anonymes sur la blockchain Waves

image


Nous avons mis en place un prototype de transactions anonymes basé sur zkSNARK pour assurer des transactions confidentielles sur la blockchain Waves. Dans notre implémentation, nous utilisons le système de preuve Groth16 sur la courbe BN254 et le circuit DSL.
Nous expliquons comment cela fonctionne.


zkSNARKs


zkSNARK est une primitive cryptographique qui confirme la connaissance d'un ensemble de données spécial (preuves) correspondant à l'ensemble des équations suivantes (système de contraintes):


⟨ai,w⟩⟨bi,w⟩+⟨ci,w⟩=0 

une partie de la preuve est privée. Cette construction permet de prouver, par exemple, la connaissance de l'image inverse de hachage sans divulguer l'image inverse. Il peut également être utilisé dans le mécanisme de transaction privée pour le modèle UTXO ( sortie de transaction non dépensée (TX)), où seuls les hachages UTXO sont publiés, et la validité de la transaction est prouvée dans zkSNARK (preuve de propriété, preuve d'économie du montant).
zkSNARK est une technologie non interactive de divulgation zéro, c'est-à-dire qu'elle n'implique pas un protocole d'interaction entre les participants qui est mis en œuvre pour prouver la connaissance. Dans la technologie zkSNARK, le prouveur construit la preuve et l'envoie au prouveur - aucune interaction supplémentaire n'est requise. L'examinateur peut vérifier l'exactitude et l'exactitude de l'utilisation des données probantes sans recourir à des informations supplémentaires. Initialement, les zkSNARK ont été créés comme un protocole de «calcul confidentiel»: lors du calcul du résultat, les données impliquées dans les calculs ne sont pas divulguées.
En utilisant la technologie zkSNARK, un schéma de validation de divulgation peut être implémenté: le prouveur calcule le hachage, le donne au prouveur et fait une preuve spéciale qu'il connaît l'image inverse du hachage x. En substituant les valeurs de x et de hachage dans la formule, et en passant cette formule et la preuve à l'examinateur, l'examinateur peut s'assurer que le prouveur connaît x. C'est la base des transactions anonymes: nous connaissons la clé privée et certaines entrées spécifiques (UTXO non dépensées) avec un montant spécifique que l'utilisateur a créé sur le contrat intelligent. Sans divulguer ces données, l'utilisateur peut confirmer avec un contrat intelligent qu'il s'agit de sa contribution, qu'il peut en disposer et la donner à quelqu'un pour utilisation.
Maintenant, la technologie n'est pas utilisée partout, car la preuve est générée pendant plusieurs minutes, ce qui n'est pas très pratique pour l'utilisateur.
En savoir plus sur la programmation zkSNARK dans l'article de Vitalik Buterin «Programmes arithmétiques quadratiques: de zéro à héros» et dans l'article d'Iden3 sur la conception de circuits circulaires.


Modèle de compte


Pour les transactions dans Waves, ils utilisent généralement des clés et des adresses basées sur curve25519 . Cette courbe n'est pas compatible avec zkSNARK, donc pour les transactions anonymes, nous utilisons le sous-groupe Edwards de courbes torsadées de BabyJubJub . De plus, nous utilisons des clés publiques comme adresses, car lors de l'envoi, vous devez crypter les données pour le destinataire.


Modèle UTXO


Dans notre modèle, UTXO est représenté par un ensemble de 3 paramètres: équilibre, clé publique du propriétaire et secret unique. La blockchain ne contient que des hachages sans chiffrement supplémentaire. Le propriétaire est représenté par une clé publique et, comme indiqué précédemment, nous utilisons des clés publiques non pas sur la courbe curve25519 , mais sur la courbe BabyJubJub compatible avec BabyJubJub . L'ID UTXO doit être généré de manière aléatoire, car si l'utilisateur spécifie deux identifiants identiques, il ne peut récupérer (dépenser) UTXO que sur l'un d'eux. Dans ce cas, seul UTXO avec l'ID correspondant pour l'utilisateur actuel sera bloqué, mais pas pour le reste. Il est dans l'intérêt de l'utilisateur de choisir id en utilisant un générateur de nombres aléatoires (253 bits sont alloués sur id, il est donc difficile d'obtenir une collision).
Pour dépenser UTXO, vous devez publier un nullifier, une fonction déterministe d'UTXO, définie comme hachage (secret, owner_privkey). Cette valeur est déterministe et unique à chaque UTXO; seul le propriétaire la connaît. Hormis le propriétaire, personne ne peut associer UTXO à son nullificateur correspondant.
Les UTXO sont stockés dans la carte de hachage dApp, c'est-à-dire dans le style de contrat. Sur la blockchain, les UTXO sont cryptés. Afin de prendre son argent, l'utilisateur doit scanner la blockchain et essayer de décrypter chaque UTXO.


État dapp


Le style dApp contient des cartes de hachage représentant deux ensembles:


  • hachages utxo
  • annuleurs

Ainsi, dApp peut vérifier l'existence d'un ensemble anonyme UTXO et l'unicité des annulateurs. Cela suffit pour traiter les transferts anonymes avec une protection contre la falsification de nouveaux actifs et le double des dépenses.
DApp dispose de 3 méthodes qui correspondent aux types de transactions de base:


  • Caution
  • Transfert
  • Conclusion

Pour transférer et retirer des fonds, nous utilisons nos propres vérificateurs qui assurent l'interaction de dApp avec des comptes anonymes spéciaux basés sur la courbe BabyJubJub. Les dépôts sont traités à partir des comptes Waves réguliers.


Les commissions


Pour le réapprovisionnement du compte, des frais sont prélevés sur le compte de la curve25519 . Pour les virements et les retraits, la commission est débitée du compte anonyme. Au niveau dApp, cela ressemble à ceci:
dApp paie la transaction elle-même, c'est-à-dire que le jeton natif dépensé pour payer la commission est débité de son solde
Entre les entrées et les sorties, une partie de la commission est brûlée pour annuler les actifs correspondant aux actifs réels du smart contract
Au niveau UTXO, nous brûlons un certain montant en tant que commission lors du traitement d'une transaction.


Les transactions


Un dépôt est une opération simple, chaque dépôt ajoute un nouvel élément à UTXO.


image


Les transferts sont basés sur la primitive de traduction 2 en 2.


image


Certaines entrées et sorties peuvent être nulles. À titre d'exemple partiel d'une telle construction, tout type de traduction simple peut être représenté (jointure, division et autres transferts, à l'exception des échanges atomiques).


Les conclusions fonctionnent comme les autres transactions, mais au lieu de créer un deuxième UTXO, elles permettent à l'utilisateur de retirer son UTXO de dApp. Il peut également y avoir deux UTXO à l'entrée, UTXO à la sortie avec le reste des fonds et retirer, qui sont publiés sur la blockchain.


image


Lors du retrait ou du transfert, dApp vérifie que les annulateurs correspondants n'ont pas encore été trouvés dans sa pile.
En utilisant zkSNARK, nous pouvons calculer que la somme des entrées de transaction est égale à la somme des sorties. Lors de l'exécution d'une transaction, nous la dépensons en UTXO et en un autre zéro UTXO, qui n'est pas dans l'arborescence merkle. Pour dépenser UTXO, vous devez prouver la connaissance de la clé privée de son propriétaire. Vérifiez que la clé privée, lorsqu'elle est multipliée par le générateur de groupe, se traduit par une clé publique. Par conséquent, sans connaître la clé privée, une transaction ne peut pas être effectuée.


Ensemble anonyme


Nous utilisons un ensemble anonyme de 8 éléments. L'élément cible est sélectionné en privé dans l'ensemble représenté dans l'entrée publique zkSNARK. Cette méthode vous permet d'obscurcir le graphe de transaction (s'il est possible de restaurer le graphe d'interaction UTXO, alors il y a la possibilité de désanonymiser les transactions).
De plus, un simple collecteur de 8 éléments peut être remplacé par un collecteur d'arbres Merkle. L'approche masque le graphique des transactions.
Pour créer une transaction valide, nous prouvons que nous dépensons des UTXO à partir de l'ensemble des UTXO. Nous mettons les preuves de merkle zkSNARK et les données UTXO dans les entrées privées et le hachage racine dans l'entrée publique. Ainsi, en utilisant SNARK, nous prouvons que nous connaissons UTXO.


image


Double protection contre les dépenses


Pour se protéger contre les dépenses doubles, nous utilisons des annulateurs - des fonctions déterministes qui ne dépendent pas directement du hachage UTXO. Pour calculer l'annulateur, nous prenons la fonction de la clé privée, il est prouvé qu'elle correspond à la clé publique, id et hachage UTXO. Pour chaque UTXO, il n'y a qu'un seul nullificateur.


Pour chaque transaction, l'annuleur des sorties UTXO dépensées doit être présenté comme une entrée publique pour zkSNARK. À l'intérieur du circuit zkSNARK, il doit également être confirmé qu'il appartient à l'UTXO épuisé.


Si le contrat dApp reçoit une valeur d'annulation non unique, la transaction est rejetée. Ainsi, il est garanti que chaque UTXO est dépensé une fois.


Après avoir dépensé UTXO, l'annulateur est publié dans la liste des annulateurs dépensés dans l'article dApp. C'est-à-dire que dans la table de hachage, en face de cet nullificateur, "true" est défini. Avant de publier le nullificateur dans l'article, nous vérifions que ce nullificateur n'a pas encore été utilisé, ce qui signifie que les UTXO avec cet identifiant peuvent être dépensés.

Source: https://habr.com/ru/post/fr479622/


All Articles