Avant de parler de minage et de gouvernance, il est nécessaire de s'attarder sur les concepts très imagés que sont les clés privées, les clés publiques, les adresses et les signatures numériques. Ces éléments interviennent dans la sécurité de Bitcoin et il est essentiel de les comprendre si l'on veut avoir confiance dans le système.
Sur la chaîne de blocs, les bitcoins sont échangés entre des adresses publiques, usuellement représentées sous forme de chaînes de caractères alphanumériques, comme par exemple 1QKN7V8uuMAF3eqNZPG9up745bjrbN5G2w. Une adresse est une sorte de « compte » appartenant à un utilisateur dont il peut se servir pour envoyer et recevoir des fonds.
Sauf cas exceptionnel, chaque adresse est liée à ce qu'on appelle une clé privée. Cette clé privée est un nombre secret choisi au hasard dans un intervalle compris entre 1 et 2256. Elle permet à celui qui la possède de dépenser les bitcoins présents à l'adresse correspondante : en effet, elle seule est capable de produire la signature numérique nécessaire à l'envoi d'une transaction provenant de cette adresse. La clé privée joue un peu le rôle de « mot de passe » que l'utilisateur doit fournir pour dépenser les fonds présents à son adresse. Ainsi, on peut dire quelqu'un possède des bitcoins dans la mesure où il contrôle les clés privées liées aux adresses contenant ces bitcoins.
En règle générale, les clés privées sont conservées dans des programmes qu'on appelle des portefeuilles (wallets). Ceux-ci peuvent fonctionner selon leur utilité sur un téléphone portable, sur une tablette, sur un ordinateur ou sur des objets spécialisés appelés portefeuilles matériels (hardware wallets). Outre le fait de conserver les clés privées, ces portefeuilles permettent d'envoyer et de recevoir des transactions.
La plupart du temps, les clé privées sont générées de manière déterministe à partir d'une phrase secrète de 12 ou 24 mots. Si vous utilisez un portefeuille, conservez cette phrase précieusement : si votre appareil tombe en panne, elle vous permettra de retrouver vos fonds sur un autre portefeuille.
Dans cet exposé, je vous propose d'examiner en détail le fonctionnement des clés et des adresses.
Bases de numération
Avant de rentrer dans le vif du sujet, intéressons-nous aux bases de numération. Pour représenter les nombres dans notre vie de tous les jours, nous utilisons ce qu'on appelle la base 10 ou le système décimal. Cela nous paraît tout à fait naturel mais il s'agit d'une convention, qui est liée au fait que nous avons longtemps compté avec nos 10 doigts. Les ordinateurs, eux, utilisent la base 2, ou système binaire, plus conforme à leur fonctionnement électronique. À l'instar du système décimal qui utilise 10 chiffres, le système binaire n'en utilise que 2 : le 0 et le 1 (qui peuvent correspondre à deux états électriques distincts, comme la présence ou l'absence de courant par exemple). Ces chiffres binaires sont appelés bits (contraction de binary digit en anglais).
Dans Bitcoin, deux bases sont principalement utilisées : la base 16 et la base 58. Le système hexadécimal (base 16) est un système largement utilisée dans le développement informatique, car il permet de représenter de manière plus compacte les nombres binaires. En tant que chiffres, il utilise les 16 caractères suivants :
0123456789abcdef
le « a » valant 10, le « b » 11, etc. Lorsqu'il y a ambiguïté, le préfixe 0x
est souvent placé avant le nombre pour indiquer qu’on utilise cette base. Tout comme dans le système décimal, la position des chiffres détermine leur importance : à ceci près qu'à la place des puissances de 10 (unité, dizaine, centaine, millier, etc.), ce sont les puissances de 16 qui sont utilisées. Par exemple, on peut décomposer le nombre 0xa09e
comme suit :
a09e = « a » × 163 + « 0 » × 162 + « 9 » × 16 + « e » = 10 × 4096 + 0 × 256 + 9 × 16 + 14 = 41 118
Notons aussi que le système hexadécimal est très adapté pour représenter les octets (appelés bytes en anglais) : en effet, un octet, qui est un ensemble de 8 bits, peut être symbolisé par 2 caractères hexadécimaux.
Dans Bitcoin, pour être conservées et exportées par les portefeuilles, les clés privées et les adresses sont représentées en base 58. Dans ce système, les nombres sont écrits en utilisant tous les caractères alphanumériques (chiffres, lettres minuscules, lettres majuscules) sauf les caractères 0 (zéro), O (o majuscule), l (L minuscule) et I (i majuscule), qui peuvent être confondus entre eux et constituer une source d’erreurs. En d'autres termes, l'alphabet de cette base est :
123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz
où le caractère « 1 » représente le 0, « 2 » représente le 1, « A » le 9, « a » le 33, « z » le 57, etc.
Clé privée, clé publique, signature
Les concepts de clé privée, de clé publique et de signature numériques sont issus de la cryptographie asymétrique. Dans Bitcoin, ils servent à définir la propriété des jetons présents sur la chaîne de blocs, en faisant en sorte que ces jetons ne puissent pas être dépensés par n'importe qui. Pour ce faire, le protocole utilise un algorithme de signature à clé publique appelé ECDSA (Elliptic Curve Digital Signature Algorithm).
Bien qu'il soit basé sur des notions mathématiques complexes, l'algorithme ECDSA est assez simple à comprendre en surface. Le principe est le suivant :
- Un utilisateur possède une paire de clés.
- L'une, connue de lui seul, lui permet de signer numériquement des messages sans être dévoilée : c'est la clé privée.
- L'autre est connue par tous les autres utilisateurs et leur permet de vérifier que c'est lui qui a écrit ces messages signés : c'est la clé publique.
Dans le cas de Bitcoin, il est nécessaire de produire une signature numérique pour envoyer une transaction. Par exemple, supposons qu'Alice veuille donner 12 mili-bitcoins à Bob. Afin d'y arriver, elle devra envoyer le message « Moi, Alice, envoie 12 bitcoins à Bob. » au réseau en le signant avec sa clé privée. Les autres membres du réseau vérifieront ensuite à l'aide de sa clé publique que le message de transaction émane bien d'elle. Si c'est le cas, la transaction sera exécutée et Bob recevra bien les bitcoins.
Loin d'être des objets informatiques complexes, les deux clés (clé privée et clé publique) sont des nombres. Comme on l'a dit, la clé privée est un nombre choisi aléatoirement dans un ensemble très grand de possibilités. Plus précisément, elle doit se trouver entre 1 et n - 1 où
n = fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
Cette limite supérieure est considérablement élevée (approchant 2256 = 1.1579 × 1077) si bien qu'il est statistiquement impossible, si on a choisi au hasard une clé privée, de tomber deux fois dessus.
La clé privée est une information de 256 bits, soit 32 octets, et on peut donc la représenter par 64 caractères hexadécimaux. Ici on prendra l'exemple de la clé privée suivante :
k = 6ef6b8ddb7d09b14a3f5239b1d76ed943bc697765ffd242baf08e532cdbe6197
La clé publique, quant à elle, est calculée à partir de la clé privée grâce à l'algorithme ECDSA. Voyons un peu comment cela est réalisé.
L'algorithme ECDSA est basé sur la courbe elliptique secp256k1 d'équation y2 = x3 + 7
, c'est-à-dire que tout les points de coordonnées (x, y)
présents sur la courbe vérifient cette équation. On peut la représenter sur un graphique comme ci-dessous.
Cependant, cette courbe elliptique n'est pas définie pour tous les nombres mais se limite aux nombres entiers (0, 1, -1, 2, -2, etc.) Pour être plus précis, elle est définie sur le corps fini des nombres entiers modulo p où p est un nombre premier spécifiquea. Tout ceci fait appel à des notions évoluées d'algèbre, mais il est possible de définir une addition sur l'ensemble des points de la courbe qui se comporte comme l'addition classique : si P1 et P2 sont des points de la courbe, alors on peut trouver un point de la courbe P3 tel que P1 + P2 = P3. Grâce à cette addition, il est possible de « multiplier » un point P par un nombre entier : il suffit de l'additionner avec lui-même le bon nombre de fois (2 × P = P + P, 3 × P = P + P + P, etc.)
La clé publique est calculée par l'intermédiaire de cette multiplication : on la définit comme étant le point de la courbe qui est le produit de la multiplication d'un point fixe par la clé privée. Ce point fixe est appelé point générateur et est noté Gb. La clé publique est notée K et est donc donnée par la formule :
K = k × G
Dans notre cas :
K = ( d307d94c5d7cbf8ce1a6b62b3286eafddf13065ad4b101f7b7a222f673f9508c, e9581deecf3bf37220f5c48d427913c522f80b74576d2bd5108055c0d54b88d9 )
La multiplication ainsi utilisée est à sens unique : il n'existe pas de division permettant de retrouver la clé privée à partir de la clé publique. C'est pourquoi l'algorithme est sécurisé.
Dans Bitcoin, la clé publique est représentée de manière sérialisée, c'est-à-dire que les deux coordonnées sont écrites à la suite auxquelles on ajoute le préfixe 0x04
. Ici, la clé publique sérialisée est :
04 d307d94c5d7cbf8ce1a6b62b3286eafddf13065ad4b101f7b7a222f673f9508c e9581deecf3bf37220f5c48d427913c522f80b74576d2bd5108055c0d54b88d9
Il existe également une représentation compressée de la clé publique. Cela rendu possible par le fait que la courbe elliptique est symétrique par rapport à l'axe des abcisses (l'axe horizontal) : si le point (x, y) est sur la courbe, alors le point (x, - y) l'est aussi. Dans le corps fini, prendre l'opposé de y inverse sa polaritéc. Ainsi, pour compresser l'information, il suffit donc de donner l'abcisse x, qu'on préfixe par 0x02
si y est pair ou par 0x03
si y est impair. On pourra ensuite retrouver y grâce à l'équation. Ici, puisque y est impair (il finit par 9), la clé publique sérialisée compressée est :
03 d307d94c5d7cbf8ce1a6b62b3286eafddf13065ad4b101f7b7a222f673f9508c
Ce format permet de réduire la taille des transactions (et donc les frais) : c'est pour cela qu'il est utilisé dans la plupart des portefeuilles récents. Le format non compressé tend à disparaître, même s'il reste toujours valide.
Pour connaître plus en profondeur l'algorithme qui permet de signer numériquement le message de transaction avec la clé privée et de vérifier l'authenticité de cette signature avec la clé publique, vous pouvez vous référer à la page Wikipédia d'ECDSA.
Adresses
Les adresses sont calculées à partir des clés publiques grâce à ce qu'on appelle des fonctions de hachage. Ces dernières sont très utilisées en cryptographie à cause de leur propriétés particulières. Dans Bitcoin, les fonctions de hachage employées sont SHA256, SHA512 et RIPEMD160. SHA256, par exemple, intervient à divers reprises dans le protocole, notamment dans le processus de minage.
Ces fonctions de hachage sont des fonctions à sens unique qui sont exécutées rapidement. Elles transforment un message de taille variable en un hachage de taille fixe (aussi appelé empreinte) : pour SHA256, le hachage sera de 256 bits (soit 32 octets) ; pour RIPEMD160, il sera de 160 bits (soit 20 octets). La particularité de ces fonctions est qu'une petite modification du message d'origine engendre un grand changement dans le hachage produit. Par exemple, si on considère le message « Le chat joue dans la cuisine », le fait de lui rajouter un point ou de faire une faute de frappe changera complètement son hachage par la fonction SHA256 :
SHA256( "Le chat joue dans la cuisine" ) = c95938c5bcfa85d715f71de6446a67660fd1364aac18006a78db8a9872331a75 SHA256( "Le chat joue dans la cuisine." ) = 4fd4ee90e50efa75bdef7211313137885f1a76baccbe236617613c4eb01a8dc7 SHA256( "Le chot joue dans la cuisine" ) = 53aacaed1f2d0a833a2ae76264575479c3e7b2e038dd97f413c4c59a3600ae17
L'adresse est calculée à partir de la clé publique (sous forme sérialisée) par les hachages successifs des fonctions SHA256 et RIPEMD160. Dans Bitcoin, la composée de ces deux fonctions est communément appelée HASH160. Ainsi l'adresse est donnée par la formule :
A = HASH160( K ) = RIPEMD160( SHA256( K ) )
Ces fonctions étant à sens unique, il est impossible de retrouver la clé publique à partir de l'adresse. Cela constitue une sécurité supplémentaire au cas où ECDSA serait compromis. Puisque RIPEMD160 produit des hachages de 160 bits, il ne peut exister que 2160 adresses : il y a donc moins d'adresses que de clés privées. Cependant, ceci n'est pas vraiment un problème : le risque de tomber par hasard deux fois sur la même adresse, appelé risque de collision, est statistiquement nul.
À partir d'une seule clé privée, il est possible de calculer deux adresses : la première issue de la clé publique non compressée, la seconde issue de la clé publique compressée. Rien ne différencie ces adresses d'un point de vue extérieur : pour savoir à quelle adresse se rapporte la clé privée, il faut donc rajouter une information.
Pour notre exemple, on peut déjà donner nos deux adresses sous forme hexadécimale. L'adresse issue de la clé publique non compressée est :
ffc400eb6f76f47ee29151b5b08ec0e49b2f9a37
tandis que l'adresse issue de la clé publique compressée est :
19a584b281fdd294c251f0be19228fea3ac1288c
Encodage en base 58
Bitcoin utilise la base 58 pour encoder les clés privées et les adresses de manière compacte. Afin de détecter les erreurs de copie, l'encodage utilisé est muni d'un système de somme de contrôle (checksum) ; cet encodage est appelé Base58Check. Dans Bitcoin, la somme de contrôle est réalisée par le biais du double SHA256 (deux hachages successifs par la fonction SHA256) : l'information est hachée deux fois et les quatre premiers octets du résultat sont conservés. Les fonctions de hachages sont en effet particulièrement bien adaptées pour produire une somme de contrôle : comme on l'a vu, n'importe quelle modification de l'information d'origine change complètement son hachage.
Pour savoir comment est effectué l'encodage de manière détaillée, j'ai décrit le protocole dans un article précédent.
Le format lié à l'encodage en Base58Check des clés privées est appelé Wallet Import Format (WIF). Deux sous-formats existent pour indiquer à quelle clé publique (non compressée ou compressée), et par conséquent à quelle adresse, correspond une clé privée. L'un, commençant toujours par un 5, indique que la clé privée est liée à la clé publique non compressée ; l'autre, commençant toujours par un K ou un L, indique que la clé privée est liée à la clé publique compressée.
Ici notre clé privée est :
6ef6b8ddb7d09b14a3f5239b1d76ed943bc697765ffd242baf08e532cdbe6197
Dans le cas « non compressé », cette dernière devient :
5JfA14GGdTGCYWtfRmmv2dMNtwiHB2LHfzqcwMVi3BfzAx3GqhW
Dans le cas « compressé », elle devient :
KzwQjFQPytv5x6w2cLdF4BSweGVCPEt8b8HbcuTi8e75LRQfw94L
Les adresses, quant à elles, sont encodées de façon à toujours commencer par un 1. Dans notre cas, l'adresse issue de la clé publique non compressée, après encodage, est :
1QKN7V8uuMAF3eqNZPG9up745bjrbN5G2w
tandis que l'adresse issue de la clé publique compressée, après encodage, devient :
13LcBDK1szyXRiParmZP3Y4QEwRKcYoJSq
Ci-dessous vous pouvez trouver un schéma qui récapitule comment sont liées les clés privées, les clés publiques et les adresses.
Ainsi, la clé privée est un nombre choisi au hasard, permettant à un utilisateur de produire des signatures numériques. La clé publique, calculée à partir de la clé privée, permet aux autres utilisateur de vérifier qu'un message signé émane bien d'une clé privée sans la dévoiler. L'adresse, calculée à partir de la clé publique, est l'endroit où se trouvent les bitcoins de l'utilisateur : ce dernier doit signer un message de transaction avec sa clé privée pour les dépenser. Il existe deux formats de clés publiques : l'un non compressé, l'autre compressé ; et par conséquent, deux formats de clés privées et deux adresses différentes.
Les adresses présentées ici sont des adresses simples, dites P2PKH pour Pay to Public Key Hash. Notez qu'il existe aussi des adresses P2SH (Pay-to-Script-Hash) qui sont notamment utilisées en tant qu'adresses multisignatures, où plusieurs personnes peuvent avoir le contrôle sur les mêmes fonds.
Dans le cadre de la mise à jour SegWit sur le réseau Bitcoin, d'autres types d'adresses sont apparus (P2WPKH et P2WSH), ce qui rajoute en complexité. Pour représenter ces adresses, SegWit suggère d'utiliser un nouveau format appelé bech32, qui encode les adresses en base 32. Un exemple de ce format d'adresses est : bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq
.
Bitcoin Cash a aussi introduit un nouveau format d'adresses appelé CashAddr, qui s'inspire fortement du format bech32. Dans ce format, les adresses ressemblent à bitcoincash:qrlugq8tdam0glhzj9gmtvywcrjfktu6xuxlug2f2f
et ne sont qu'une représentation différente des adresses traditionnelles.
Merci d'avoir lu cet article.
Notes
a. Le corps fini des entiers modulo p est usuellement noté Fp. Ici le nombre premier choisi est :
p = 2256 - 232 - 29 - 28 - 27 - 26 - 24 - 1 = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
b. Le point générateur est :
G = ( 79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798, 483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 )
c. Soit y compris entre 1 et p-1. p est premier donc impair. Dans Fp, il s'ensuit que : si y est pair, -y = -y + p est impair ; si y est impair, -y = -y + p est pair.
Crédit illustration : Coindesk.
Tu es un fou furieux ! :D
Ah je sais. Je ferai plus léger au prochain article 😁
Merci !
Merci pour cet article très complet. Tu as dû mettre un temps fou à l’écrire
J'ai déjà écrit des articles similaires mais même en recopiant ça m'a pris pas mal de temps oui 😁 J'espère que la prochaine partie (sur la blockchain et le minage) me prendra moins de temps.
Merci pour ton commentaire !
Cet article a été nominé pour figurer dans la sélection des @francosteemvotes ! Félicitations !
Merci beaucoup @francosteemvotes ça fait chaud au cœur.