Loïc Morel
Qu'est-ce que PayNym et BIP47 ?
Les plus attentifs d'entre vous auront peut-être aperçu ces robots étranges en photos de profil de certains bitcoiners sur les réseaux sociaux. Non, ce ne sont pas du tout des NFTs mais bien des PayNym Bots, une fonctionnalité de l'implémentation PayNym de BIP47.
Dans cet article, nous allons voir qu'est-ce que PayNym ? Comment l'utiliser concrètement ? Et comment fonctionne BIP47 ?
Mise à jour Septembre 2022 : Le présent post est déjà daté et il comporte quelques imprecisions. Je viens de publier une réécriture complète de cet article, actualisée et plus précise, que vous pouvez retrouver en cliquant ici : BIP47, le vilain petit canard.
Sommaire :

Qu'est ce qu'un BIP ?
Un BIP, pour Bitcoin Improvement Proposal, est un standard de proposition de changement ou d'amélioration sur le protocole Bitcoin.
Lorsqu'un développeur souhaite proposer une amélioration, une mise à jour ou un changement sur le protocole Bitcoin, il va formaliser sa proposition au sein d'un BIP. Tout le monde est libre de proposer une amélioration du protocole, il faut néanmoins disposer d'une certaine réputation pour que cette proposition soit prise en compte et étudiée par un plus grand nombre d'utilisateurs.
Un fois un BIP formalisé, il est testé et débattu au sein de la communauté. Chaque utilisateur est ensuite libre de mettre en place le BIP à partir de son nœud ou de le refuser. Certaines modifications du protocole sont rétro-compatibles et ne nécessitent pas de scission de la chaîne de preuve de travail (softfork), d'autres comportent des changements trop importants pour être rétro compatibles et nécessitent donc une scission de la chaîne (hardfork). D'autre BIP comme BIP47 ne sont pas ajoutées au protocole mais peuvent être implémentés sur des logiciels qui interagissent avec Bitcoin.
Qu'est-ce que PayNym ?
PayNym c'est l'implémentation du BIP47 par le logiciel Samouraï Wallet qui permet de générer un code de paiement réutilisable.
Ce BIP vise à résoudre le problème de perte de confidentialité en cas de réutilisation d'une adresse de réception Bitcoin. Comme nous l'expliquons en détail dans cet article, si un utilisateur réutilise plusieurs fois une même adresse de réception Bitcoin, tous les émetteurs qui enverront des fonds vers cette adresse pourront connaître le montant des fonds stockés sur celle-ci. Pour préserver sa confidentialité, il faut donc générer une nouvelle adresse unique pour toute transaction entrante, ce qui peut être contraignant dans de nombreux cas.
BIP47 vient résoudre ce problème en proposant une façon de générer un code de paiement (CP) réutilisable. Ainsi, plusieurs émetteurs pourront envoyer plusieurs paiements vers un seul et unique code de paiement réutilisable d'un autre utilisateur sans que le destinataire n'ait besoin de communiquer une nouvelle adresse vierge pour chaque nouvelle transaction.
Ce système peut évidemment être très pratique dans de nombreux cas :
Plateforme de DCA en bitcoins afin d'envoyer les fonds achetés vers le client.
Campagne de dons caritatifs afin de préserver la confidentialité des donneurs.
Commerçant afin de préserver sa confidentialité financière auprès de ses clients.
...
Un utilisateur peut alors communiquer librement son CP (réseau sociaux, site web...) sans risque de perte de confidentialité, contrairement à une adresse de réception classique ou une clé publique.
Pour réaliser un échange, les deux utilisateurs devront disposer d'un portefeuille Bitcoin classique disposant d'une implémentation de BIP47 (comme par exemple PayNym). L'association des codes de paiements des deux utilisateurs va permettre de mettre en place un canal chiffré entre eux. Pour mettre en place proprement ce canal, l'émetteur va devoir réaliser une transaction sur la chaîne Bitcoin : la transaction de notification (nous y revenons plus tard).
Cette association permet de générer des secrets partagés permettant eux même de générer un grand nombre d'adresses de réception Bitcoin uniques (2^32 exactement).
Quant aux PayNym Bots, ces robots que l'on aperçoit sur Twitter, ce sont simplement des représentations visuelles de votre code de paiement, réalisées par Samouraï Wallet. Ils sont créés en utilisant un algorithme de hachage, ce qui les rend uniques.
Ces Bots n'ont aucune réelle utilité technique, ils permettent d'une part de faire parler de cette implémentation sur les réseaux sociaux et d'autre part, d'ajouter un aspect visuel enfantin sur un concept assez complexe.
Comment utiliser BIP47 ?
Pour utiliser BIP47, il suffit de disposer d'un portefeuille qui l'a implémenté. L'implémentation la plus connue est PayNym et elle est disponible sur Samouraï Wallet sur mobile et sur Sparrow Wallet sur PC.
Sur Samouraï, il suffit de cliquer sur le "+" en bas à droite de l'écran, puis sur "PayNyms" pour y accéder. Vous pourrez ensuite vous connecter à un autre utilisateur en cliquant de nouveau sur le "+", puis en collant simplement son code de paiement ou en scannant son QR code. Cette connexion coûte quelques frais pour l'implémentation et quelques frais de minage pour la transaction de notification.
Sur Sparrow, il suffit de cliquer sur "Tools" dans la barre de menu en haut de l'écran, puis sur "Show PayNym". Vous accéderez ensuite à l'interface d'utilisation ou vous pourrez établir des connexions avec d'autres utilisateurs de la même façon que pour Samouraï.
Comment fonctionne BIP47 ?
C'est super tout cela, mais comment fonctionne techniquement BIP47 ?
La connexion entre les deux utilisateurs se fait grâce au protocole ECDH (Elliptic Curve Diffie-Hellman). C'est un protocole d'échange de clés basé sur la cryptographie sur les courbes elliptiques dérivé du protocole Diffie-Hellman.
Diffie-Hellman est un vieux protocole de chiffrement (1976) encore beaucoup utilisé aujourd'hui. Il intervient notamment au cœur du protocole de TLS (Transport Layer Security) et de son prédécesseur SSL (Secure Socket Layer), couches de chiffrement utilisées dans le protocole HTTPS (Hypertext Transfer Protocol). Et oui, le petit cadenas que vous voyez dans votre navigateur lorsque vous allez sur un site web est ici en partie grâce à Diffie-Hellman.
Ce protocole est également souvent utilisé pour le chiffrement des communications via VPN (Virtual Private Network).
Au final, Diffie-Hellman permet simplement d'établir un secret partagé entre deux utilisateurs à travers un canal de communication public non sécurisé. Secret commun qui est ensuite utilisé pour chiffrer une communication. Dans le cas de TLS, le canal de communication public est Internet. Dans le cas de BIP47, le canal de communication public est Bitcoin.
Pour comprendre le fonctionnement technique d'ECDH, voici un schéma que nous allons expliquer :

Alice et Bob connaissent un point P sur une courbe elliptique (donnée publique, en jaune). Chacun dispose d'un secret privé k (orange et vert) qui servira à calculer une valeur publique Q (orange clair et bleu) tel que :
P * k = Q
Alice et Bob vont ensuite s'échanger leurs valeurs publique Q respectives sur un canal public non sécurisé.
Une fois que chacun dispose du Q de l'autre, Alice et Bob vont calculer un secret partagé à partir de leurs k respectifs (valeur privée) et du Q de l'autre (valeur publique).
Ces deux calculs, du côté de Bob et du côté d'Alice mènent au même résultat car :
k Alice * Q Bob
= k Alice * (k Bob * P)
= k Alice * k Bob * P
= k Bob * (k Alice * P)
= k Bob * Q Alice
Donc : k Alice * Q Bob = k Bob * Q Alice
Ce secret partagé ne peut pas être déterminé par une autre personne observant le réseau de communication non sécurisé car les seules valeurs Q ne permettent pas de déterminer le secret partagé. Pour ce faire, il faut obligatoirement disposer d'une valeur privée dont seuls Alice et Bob disposent.
Ici nous utilisons la multiplication dans notre exemple, mais c'est une image. En réalité, ces opérations sont des additions de points sur une courbe elliptique, une succession de tangentes à la courbe et de symétries. Cela permet de réaliser facilement le calcul d'une clé publique à partir de sa clé privée, mais le calcul inverse est très difficile. Le moyen le plus efficace de résoudre ce problème, et donc de casser le chiffrement, serait de résoudre le problème du logarithme discret. Un calcul impossible à réaliser avec les ordinateurs actuels.
Alice et Bob pourront donc utiliser ce secret partagé comme clé de chiffrement commune afin de pouvoir échanger des informations chiffrées sur ce même réseau de communication non sécurisé.
Voici donc comment fonctionne ECDH schématiquement. Voyons maintenant comment ECDH est utilisé au sein du BIP47 :
Dans BIP47, le canal de communication public utilisé dans le protocole ECDH, c'est Bitcoin. En effet, le protocole Bitcoin peut être détourné de sa fonction première pour transmettre ou ancrer une petite quantité de données. Pour ce faire, nous allons utiliser un Opcode : l'OP_RETURN.
L'OP_RETURN est un script qui permet de marquer un output d'une transaction Bitcoin comme invalide. Il est utilisé pour diffuser ou ancrer de l'information. On peut alors y stocker jusqu'à 80 octets de data qui sera inscrite sur la chaîne Bitcoin au sein d'une transaction visible par tous les utilisateurs.

La génération du code de paiement en lui-même se fait à partir du portefeuille de l'utilisateur : à partir de la clé privée maîtresse et du code de chaîne maître.
Imaginons qu'Alice souhaite utiliser le code de paiement de Bob afin de lui envoyer un paiement (ou plusieurs). Pour avertir Bob qu'elle va mettre en place un canal chiffré entre leur 2 codes de paiements, elle va construire une transaction de notification et calculer les informations à y inclure comme dans ce schémas :

Alice est en connaissance de la clé publique associée à l'adresse de notification de Bob puisque cette donnée est accessible à quiconque en observant simplement le code de paiement de Bob.
Alice va alors calculer un point secret sur les courbes elliptiques à partir de sa clé privée (bleu) et de la clé publique de Bob (jaune). Ce point secret est représenté par la couleur verte.
Ce point secret va lui permettre de Xorer son code de paiement personnel. Elle va donc xorer son point secret (vert) avec son code de paiement (marron), ce qui lui donnera son code de paiement chiffré ou xoré (noir).
XOR (eXclusive OR, en français "OU exclusif") est une fonction mathématique utilisée dans de nombreux domaines de l'électronique. En cryptographie, elle est utilisée pour réaliser un chiffrement symétrique. Elle est notée ⊕. Plus d'infos sur la fonction XOR dans cet article.
Alice va ensuite inclure son code de paiement xoré dans les 80 octets de l'OP_RETURN de la transaction de notification. Cette transaction aura en output l'adresse de notification de Bob.

A ce moment-là, n'importe quel utilisateur de Bitcoin sera en capacité de voir la transaction d'Alice et de lire son OP_RETURN. Les autres utilisateurs ont donc accès au code paiement d'Alice mais ils ne pourront pas le déchiffrer. Le seul utilisateur capable de déchiffrer ce code de paiement xoré, mis à part Alice, sera Bob grâce à sa clé privée.
Bob va donc calculer le point secret (rose) permettant de déchiffrer le code de paiement chiffré d'Alice (noir). Pour ce faire, il va utiliser sa clé privée personnelle associée à son adresse de notification (rouge) et la clé publique d'Alice (blanc) qu'il aura trouvé dans la transaction de notification en Input.
Un fois le point secret calculé (rose) il va le xorer avec le code de paiement chiffré d'Alice (noir) qu'il aura trouvé dans l'OP_RETURN de la transaction de notification qu'il vient de recevoir.
Etant donné que la fonction XOR permet de réaliser un chiffrement symétrique, la clé de chiffrement et de déchiffrement est la même. En xorant le code de paiement chiffré d'Alice avec le point secret, Bob obtiendra le code de paiement d'Alice en clair (marron).
Bob est maintenant en connaissance du code de paiement d'Alice et pourra tracer et retrouver ses futurs paiements.
Alice est donc maintenant en capacité de réaliser des paiements vers Bob en générant une nouvelle adresse vierge pour chaque transaction. Pour ce faire, elle va dériver une clé privée enfant de sa clé privée maîtresse selon le standard BIP32. Elle va ensuite sélectionner la prochaine clé publique enfant vierge associée au code de paiement de Bob. A partir de cette clé privée et de cette clé publique, elle va déterminer un secret partagé sur le modèle ECDH vu précédemment. A partir de ce secret et de la clé publique enfant de Bob, elle va déterminer une clé publique de paiement éphémère, par addition des points sur les courbes elliptiques (modèle vu au dessus).
A partir de cette clé publique éphémère, associée à la clé privée maîtresse dont seul Bob dispose, Alice pourra déterminer une adresse Bitcoin vierge en hachant la clé publique et en appliquant le format approprié.
Alice pourra envoyer des fonds vers cette adresse vierge sans que Bob n'ait eu à intervenir pour lui fournir une nouvelle adresse vierge. L'envoi des bitcoins se fera alors de manière tout à fait classique, en utilisant une autre clé privée du wallet d'Alice ou même en utilisant un autre portefeuille.

Bob sera en capacité de retrouver les adresses créées par Alice en observant le code de paiement d'Alice. Pour ce faire, il va retrouver le code de paiement d'Alice à partir de la transaction de notification (comme vu précédemment).
Bob va ensuite calculer chaque clé publique enfant dérivée du code de paiement d'Alice selon le standard BIP32. Il calculera également les clés privées enfants dérivées de sa clé privée maîtresse associée à son code de paiement personnel. En utilisant ECDH, il sera en capacité de déterminer chaque secret partagé généré par Alice. Il pourra donc déterminer les clés privées éphémères associées aux clé publiques éphémères générées par Alice par addition des points sur les courbes elliptiques.
Une fois qu'il a accès à ces clé privées éphémères, il pourra retrouver les clés publiques associées en les dérivant sur les courbes elliptiques à partir desdites clés privées.
Bob aura alors accès aux bitcoins associés à ces clés publiques. Il sera le seul utilisateur à être capable de calculer les clés privées permettant de débloquer ces fonds. Il en est donc le seul propriétaire.

Si Bob souhaite rembourser Alice sur le même modèle, il lui suffira de réaliser le chemin inverse : transaction de notification, création d'une clé publique éphémère à partir d'un secret partagé et transaction vers l'adresse vierge associée.

Tout ce processus technique n'est évidemment pas réalisé manuellement par l'utilisateur. C'est l'implémentation qui s'occupera de le réaliser. Vous n'avez donc pas besoin de comprendre tous ces concepts techniques pour utiliser BIP47.
Les limites et critiques de BIP47.
La première publication de BIP47 date de 2017. Cinq ans après, encore très peu d'implémentations de cette proposition existent et seule une minorité de wallets le proposent à leurs utilisateurs.
La faible adoption de cette amélioration semble être due à deux phénomènes : d'une part l'implémentation est assez complexe à réaliser car elle fait intervenir des protocoles cryptographiques extérieurs à Bitcoin. Et d'autre part, une partie des utilisateurs et des développeurs Core critiquent l'utilisation de Bitcoin comme réseau de communication via l'opcode OP_RETURN, parlant même de spam pour le réseau.
Selon nous chaque individu doit être libre d'utiliser Bitcoin comme bon lui semble du moment qu'il respecte les règles qui lui permettent de rester dans le consensus. BIP47 et PayNym respectent cela, chacun doit donc être libre de pouvoir les utiliser ou non.
La principale critique sur BIP47 vient de la transaction de notification qui serait une transaction de "spam" selon certains. Mais cette transaction n'est pas forcément obligatoire dans l'utilisation des codes de paiement. En effet, il est tout à fait possible de créer un secret partagé sans notifier à l'autre utilisateur ce secret via Bitcoin. La notification devra alors se faire via un autre moyen de communication quelconque. Le principal problème mené par cette pratique est que le destinataire des bitcoins ne pourra pas entièrement reconstruire sont wallet à partir de sa seed. Le wallet devra alors recevoir toutes les notifications pour reconstruire entièrement le wallet initial et retrouver les paiements réalisés à partir du code de paiement.
Conclusion.
Personnellement, j'apprécie beaucoup BIP47 car c'est une amélioration qui vient répondre à une contrainte majeure dans l'utilisation de Bitcoin : la réutilisation d'adresses de réception et tous les effets secondaires que cela implique.
Techniquement parlant, c'est une utilisation tout à fait ingénieuse de l'opcode OP_RETURN pour venir introduire des protocoles cryptographiques inutilisés auparavant dans Bitcoin comme ECDH.
Je trouve également que cette proposions s'inscrit complètement dans l'esprit de développement initial de Bitcoin : Utiliser des outils cryptologiques existants et les détourner de leur utilisation première afin de créer des outils permettant la souveraineté et le respect de la privée de l'utilisateur.