Cette série d’articles a pour but de rendre compréhensibles les nombreuses améliorations développées par les experts du réseau Bitcoin, à travers le compte-rendu exhaustif de la conférence organisée en novembre à l’Université de Standford – Scaling Bitcoin.
Dans cette troisième partie, focus sur des protocoles informatiques qui ont fait couler beaucoup d’encre : les smart contracts.
Bitcoin reste pour l’instant assez limité lorsqu’il s’agit de programmer des transactions conditionnelles. De nombreux chercheurs fournissent des outils mathématiques pour ouvrir la voie à de nouvelles possibilités, et les développeurs implémentent peu à peu ces procédés cryptographiques complexes au sein du code source de Bitcoin.
Atomically Trading with Roger: Gambling on the success of a hardfork
Par Ethan Heilman (University College London)
Cette étude est partie du pari entre Loaded et Roger Ver au sujet du potentiel hard fork Bitcoin Unlimited : Loaded avait proposé de miser 60 000 coins. Roger devait envoyer ses 60 000 coins sur l’une des chaînes et recevoir 60 000 BTC sur l’autre. Comment rendre cela possible ?
L’idée derrière le travail de Patrick McCorry, Andrew Miller et Ethan Heilman est de décrire un protocole d’atomic trade[1] lors d’un hard fork sur le réseau Bitcoin :
- Il faut pouvoir configurer l’échange avant le hard fork ;
- Les deux parties sont alors engagées dans l’échange et lorsque le hard fork survient, elles sont obligées d’échanger leurs coins ;
- À la fin de l’échange, l’une des parties a tous ses coins sur une des chaînes et l’autre partie a tous ses coins sur l’autre.
C’est très complexe à réaliser sans avoir réglé le problème de la malléabilité des transactions[2], mais beaucoup plus facile à effectuer lorsque c’est le cas (grâce à SegWit).
L’une des possibilités est de configurer un portefeuille multi-signatures 2 sur 3 afin que les deux parties y envoient leur transaction, puis de passer par un tiers de confiance pour envoyer une transaction sur l’une des chaînes et une transaction sur l’autre chaîne. Mais sans avoir recours à un tiers de confiance et en passant par un atomic swap, c’est une autre paire de manches :
- Alice et Bob ont tous deux des coins sur la blockchain pré-fork ;
- Ils déposent leurs coins dans une transaction sur la blockchain ;
- Quelques blocs plus tard, un hard fork survient ;
- Alice doit alors se retrouver avec tous ses coins ainsi que ceux de Bob sur le fork 2, et Bob doit se retrouver avec tous ses coins sur le fork 1 (càd : les coins d’Alice sur le fork 1 se retrouvent contrôlés par Bob).
C’est là où la malléabilité des transactions devient importante :
- Tant que le hash d’une transaction n’est pas accepté par la blockchain, il est malléable (car la signature cryptographique ne couvre pas toute la transaction, donc une tierce partie, voire les signataires, peut modifier les identifiants de la transaction).
- Signer une chaîne de transactions non confirmées n’est donc pas fiable ;
- Ainsi, sans résoudre le problème de la malléabilité, le dépôt doit être stocké dans la blockchain.
Sans malléabilité des transactions, c’est beaucoup plus simple : il est possible de signer la transaction de dépôt puis de signer d’autres transactions qui la dépensent sans attendre confirmation sur la blockchain. C’est une énorme différence : en pratique, cela rend beaucoup plus facile de programmer des smart contrats sur le réseau Bitcoin.
Les différentes étapes :
Dépôt des fonds : Alice et Bob signent chacun une transaction de dépôt avant le hard fork. Alice signe également une transaction d’annulation qui permettra à Bob d’annuler l’échange durant un nombre de blocs définis. Bob a alors un certain temps pour diffuser sa transaction.
Mise en place de l’échange : Alice et Bob vont devoir échanger et signer les transactions de transfert. Alice va devoir choisir une valeur r dont le hash sera présent dans la transaction de dépôt. Elle ne peut récupérer ses coins qu’en révélant r, et Bob peut faire de même car il aura également accès à cette valeur. Étant donné que c’est Alice qui initie l’échange, il faut pouvoir l’obliger à l’exécuter jusqu’au bout. Et il faut aussi, au bout d’un moment, empêcher Bob d’annuler sa transaction. Lorsque le verrouillage est effectué, l’échange a lieu.
Il y a donc une transaction avec trois sorties : le dépôt d’Alice, le dépôt de Bob, et la sortie correspondant à l’annulation de Bob.
- La transaction de dépôt doit être confirmée dans le bloc 1 (sans fixer la malléabilité).
- La transaction d’annulation rembourse les deux parties. Bob va demander à Alice de la signer : si elle ne le fait pas, les deux parties seront remboursées au bout d’un nombre défini de blocs. Lorsqu’ Alice a signé, Bob peut annuler l’échange en diffusant cette transaction sur la blockchain.
- La transaction de transfert déplace les coins d’Alice vers le dépôt de Bob. Pour les récupérer, il faut qu’Alice révèle le secret r, le hash de r étant encodé dans la transaction de dépôt. Une transaction similaire envoie les coins de Bob sur le dépôt d’Alice. Il faut bien évidemment implémenter une replay protection[3] pour que cela fonctionne correctement. Si Alice ne signe pas la transaction de transfert, alors elle perd tous ses coins. Une fois qu’elle a signé, cela supprime la possibilité d’annuler la transaction du côté de Bob et l’échange est alors verrouillé.
Exemple : un hard fork aura lieu dans 5 blocs. Alice veut ses coins sur le fork 2 et Bob sur le fork 1.
Avant le fork, si Alice ne signe pas la transaction d’annulation, les coins sont recrédités aux deux parties grâce au timeout. Si Alice signe la transaction d’annulation mais ne signe pas les transactions suivantes, Bob peut diffuser la transaction d’annulation et les deux parties sont recréditées.
Ce protocole requiert 4 transactions off-chain pour fonctionner. Avec SegWit et donc en l’absence de malléabilité des transactions, c’est plus simple :
- Il faut créer une transaction dépensant les coins en dépôt qui ne sera valide que sur le fork 2 ;
- Il faut créer une transaction dépensant les coins en dépôt qui ne sera valide que sur le fork 1 ;
- Ces transactions sont signées par les deux parties ;
- Le fait de diffuser la transaction de dépôt permet de créer ces deux transactions.
Ce système permet donc de parier sur un hard fork à venir et de programmer un échange entre les deux branches antérieurement, avec ou sans malléabilité des transactions. C’est assez similaire à l’ouverture d’un canal de paiement. Les références au pari osé de Roger Ver ont beaucoup amusé l’audience, mais l’utilité d’un tel protocole n’a pas été unanimement reconnue !
Les slides de la présentation.
Discreet Log Contracts
Par Thaddeus Dryja (MIT Digital Currency Initiative)
Le chercheur, très engagé dans le développement du Lightning Network, a présenté ses smart contracts “discrets” pour Bitcoin, c’est-à-dire des smart contracts qui ne sont pas visibles pour un observateur extérieur.
Rappel : qu’est-ce qu’un smart contract ?
Il s’agit d’un paiement conditionnel : deux parties déposent de l’argent, et lorsque certaines conditions sont remplies (basées sur des données externes), l’argent bouge. Par exemple, Alice et bob désirent parier sur le temps qu’il fera demain : s’il pleut, Alice gagne un coin et si c’est l’inverse, c’est Bob qui gagne un coin.
Afin de connaître la météo, ou toute autre donnée externe à la blockchain, il faut un oracle[4] Une façon de mettre cela en place est d’utiliser un multisig 2 sur 3 : en cas de désaccord entre Alice et Bob, Olivia confirmera qu’il a bien plu et signera la transaction. Le problème est qu’Alice peut s’entendre avec Olivia (corruption de l’oracle) : ce protocole est interactif et l’oracle connaît les détails de chaque contrat, et décide de leur exécution. Il faudrait donc trouver un système où l’oracle ne peut pas tricher, et où il ne connaît pas du tout les détails du contrat.
Ce n’est pas possible avec les signatures ECDSA utilisées actuellement; le chercheur a alors présenté les signatures de Schnorr – le protocole de Schnorr est une de ces fameuses preuves à divulgation nulle de connaissance[5] évoquées régulièrement.
Dans notre cas, il s’agit d’utiliser comme clef privée du contrat, en plus de la clef secrète d’Alice, la signature de Schnorr de l’oracle Olivia. Ainsi, quand Olivia signe le message “il pleut”, la signature de ce message est utilisée comme clef privée partielle. Alice et Bob peuvent compléter cette clef privée partielle avec la leur. Cela permet de générer trois transactions en même temps : seule une d’entre elles sera valide, mais il n’est pas possible de savoir laquelle, car cela dépend du résultat du pari.
Certes, l’oracle peut toujours signer “il pleut” alors qu’il fait soleil, mais cette donnée est publique : tout le monde pourra voir sa signature mensongère. Il ne peut pas non plus signer à la fois “il pleut” et “il fait soleil” : sa clef privée serait alors révélée. De plus, l’oracle ne sait pas sur quoi ont parié les deux parties.
Ces discreet log contracts entre Alice et Bob ressemblent beaucoup à un canal de paiement sur le Lightning Network :
- Il y a une transaction de dépôt où les parties envoient leurs coins.
- Ensuite, une série de doubles dépenses est générée.
Il y a cependant une différence notable : dans le cas Lightning, les règles du protocole s’assurent que seule la dernière transaction générée est valide et diffusable. Dans le cas des discreet log contrats, trois transactions sont générées sans que nous sachions laquelle sera valide : cela dépend de l’oracle qui révélera sa signature dans le futur. Selon l’issue des événements, Alice ou Bob pourront dépenser les coins en ajoutant leur clef privée à la signature d’Olivia pour générer la transaction.
Ces contrats sont avantageux en termes de scalabilité car il est possible de les créer à l’intérieur d’un canal de paiement. Si les parties coopèrent, il est possible de générer des milliers de contrats, le tout pour 3 transactions diffusées sur la blockchain.
Ils sont également confidentiels : seules les contreparties ont connaissance de leur contenu. Lors de la diffusion des transactions sur la blockchain, il reste très difficile de voir qu’il s’agit de contrats, même si c’est possible en utilisant des méthodes comparatives statistiques.
La publication des chercheurs.
Bitcoin script 2.0 and strengthened payment channels
Johnson Lau (Bitcoin protocole developer) et Olaoluwa Osuntokun (Co-founder Lightning Labs)
J. Lau et O. Osuntokun ont présenté de nouvelles fonctions de script pour le protocole Bitcoin et démontré comment elles pouvaient servir à renforcer les canaux de paiements.
Les deux développeurs ont commencé par rappeler l’historique du système de script du réseau Bitcoin :
- 2009-2010 : correctif d’urgence (problèmes avec les signatures, attaques potentielles de déni de service, fork accidentel)
- 2012 : taille des adresses fixée pour implémenter des scripts complexes (Pay-to-script-hash, BIP16)
- 2015 : format des signatures plus strict (DER – BIP66)
- 2015 – 2016 : introduction du verrouillage temporel avec OP_CHECKLOCKTIMEVERIFY (BIP65) et OP_CHECKSEQUENCEVERIFY (BIP112)
- 2016 : Segregated Witness (BIP141), réglage du problème de malléabilité des transactions.
Il reste cependant de nombreux défauts au système de script actuel, notamment le manque de mécanisme de mise à niveau.
- Il n’est pas possible de redéfinir des opérations existantes ;
- Il manque également de nombreuses opérations portant sur les chaînes de caractères permettant de les combiner ou d’en examiner une partie. Ces fonctions ont été rétablies de façon sécurisée dans le projet Elements (sidechains pour Bitcoin) ;
- Le nombre d’opérations numériques reste très limité – Satoshi en avait désactivé plusieurs. Certains formats portent à confusion (ex. : les entrées sont des entiers signés de 32 bits, contre 64 bits pour les sorties) ;
- Il n’est pas possible d’ajouter des scripts supplémentaires sans dépenser puis recréer une transaction. Proposition : permettre de signer des scripts additionnels via OP_CHECKSIG ;
- L’accès aux composantes d’une transaction est limité – Proposition : nouvelle version de SIGHASH qui couvre plus d’éléments.
Olaoluwa Osuntokun a présenté quelques nouvelles fonctions bien utiles, comme les MAST (Merkalized Abstract Syntax Trees) qui permettent de créer des scripts très longs comportant de nombreuses branches, ou encore l’agrégation de clefs publiques (transformer un multisig n-n en singlesig). Il a aussi évoqué les fonctions ajoutées dans le projet Elements comme OP_CHECKSIGFROMSTACK.
Johnson Lau a alors fait plusieurs suggestions pour améliorer les canaux de paiements, dont l’ajout de nouvelles extensions du système de script. Il a décrit diverses méthodes pour révoquer les engagements des parties dans un canal de paiement (delegated trapdoor channel outsourcing), ainsi que plusieurs modifications améliorant la confidentialité des paiements ainsi que la sécurité des canaux.
Les slides de la présentation.
State of cryptography for blockchains beyond ECDSA and SHA256
Signatures and zero-knowledge proofs, par Benedikt Bunz, Stanford University
Le chercheur a dressé l’état des lieux de la cryptographie consacrée à la sécurisation des blockchains.
Les signatures : elles permettent de diffuser une transaction sur le réseau, en signant un message. Il est facile pour le réseau de vérifier qu’une transaction a bien été signée par le propriétaire de la clef privée associée à une adresse en utilisant sa clef publique et ce sans compromettre la sécurité du système (impossible de forger une signature). Dans le cas du réseau Bitcoin et de nombreuses crypto-monnaies, c’est l’algorithme ECDSA, faisant appel à la cryptographie sur les courbes elliptiques, qui est utilisé. Problème : il est malléable (on peut modifier la signature d’un message déjà signé).
Benedikt Bunz a présenté des algorithmes de signatures alternatifs :
- Les signatures BLS (Boneh–Lynn–Shacham) qui peuvent être agrégées facilement ;
- Les signatures à seuil (permettent à plusieurs parties de coopérer durant le déchiffrage d’un message) ;
- Les signatures de cercle (utilisées notamment par Monero, elles permettent de signer un message au nom d’un ensemble de clefs publiques) ;
- les signatures aveugles (signatures effectuées sur un document qui a été masqué avant d’être signé, afin que le signataire ne puisse prendre connaissance de son contenu – décrites par David Chaum en 1982).
Les preuves à divulgation nulle de connaissance :
Elles ont de nombreuses applications :
- Transactions confidentielles ;
- Mimblewimble (registre distribué basé sur une blockchain différente de celle de Bitcoin au niveau de la confidentialité des transactions et du scripting) ;
- Zerocash (paiements anonymes et décentralisés pour Bitcoin) ;
- Preuves de solvabilité pour les plateformes de change ;
- Canaux de paiements confidentiels ;
- Compression de la blockchain.
Benedikt Bunz a exposé différents types de zero-knowledge proofs :
- Protocoles Sigma (toutes les zero-knowledge proofs interactives mettant en jeu trois échanges[6] entre un prouveur et un vérifieur ) ;
- Zero-knowledge Sudoku (Alice a trouvé la solution à un Sudoku mais pas Bob : comment Alice peut-elle prouver qu’elle a la solution sans la donner ?) ;
- Preuves non interactives à divulgation nulle de connaissance (variantes de preuves ne reposant pas sur l’interaction prouveur – vérifieur) ;
- Signatures de Schnorr ;
- Preuves succintes.
Le chercheur a décrit différentes méthodes pour générer ces preuves (trusted setup[7], multiple parties) et a discuté du temps de génération ainsi que de leur taille. Les preuves idéales permettront d’ouvrir la voie notamment aux smart contracts confidentiels; la recherche est très active à ce sujet mais pour l’instant aucune implémentation n’a vu le jour. Il y a d’autres types de preuves comme les bulletproofs qui sont très prometteuses : leur taille est réduite et elles ne nécessitent pas de trusted setup. Elles sont idéales pour créer des transactions confidentielles (protocole CoinJoin par exemple), des preuves de solvabilité, des services de mixage…
Les slides de la présentation.
En conclusion
Ces présentations exposent différentes techniques qui permettront d’améliorer le système de script et de décupler ses possibilités : les contrats autonomes qui font la fierté des développeurs d’Ethereum verront également le jour sur Bitcoin. Cela nécessite de mettre en place de nombreuses solutions de contournement, et de modifier certains paramètres directement dans le protocole lui-même via des soft forks ou des hard forks : les tests et les implémentations se font peu à peu, en prenant un maximum de précautions afin de ne pas faire diminuer le niveau de sécurité global du réseau. À suivre…
Commentaires