Ceci est une ancienne révision du document !
Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172
Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172
Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172
Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172
Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Table des matières
Block Chain
Vous pourrez utiliser le module rsa.py qui contient ce qu'il faut pour chiffrer et déchiffrer des messages de taille arbitraire en rsa.
Une blockchain, est une technologie de stockage et de transmission d'informations sans organe de contrôle. Comme pour le réseau internet devant fonctionner de façon décentralisée, la blockchain distribue ses données en divers point tout en garantissant leur authenticité.
Contrairement à la base de données classique, sur un serveur, sous le contrôle d'un propriétaire, dans le cas d'une blockchain, tous les participants possèdent une copie de la chaîne et l'algorithme permet d'obtenir un consensus pour toute modification.
Preuve de travail
Une blockchain met en œuvre le problème des généraux byzantins : des généraux de l'armée byzantine campent autour d'une cité ennemie. Ils ne peuvent communiquer qu'à l'aide de messagers et doivent établir un plan de bataille commun, faute de quoi la défaite sera inévitable. Cependant certains de ces généraux peuvent être des traîtres, qui essayeront donc de semer la confusion parmi les autres. Le problème est donc de trouver un algorithme pour s'assurer que les généraux loyaux arrivent tout de même à se mettre d'accord sur un plan de bataille.
L'ensemble des participants à la blockchain doivent maintenir la fiabilité même en cas de défaillance ou de piratage sur part minoritaire des participants. La solution à ce problème est la preuve de travail. Il s'agit d'un problème mathématique dont la solution permet de vérifier que le mineur a bien réalisé un travail. La résolution de la preuve nécessite une puissance de calcul élevée. Les mineurs fournissent cette puissance et doivent prouver leur travail.
Les calculs nécessaires pour le minage ont un coût énergétique important et devient un désastre environnemental. Dans le cas des bitcoins, seul le mineur ayant obtenu le premier un résultat reçoit un paiement. Les mineurs sont en concurrences mais doivent être solidaires car le problème devient plus ardu quand il y a beaucoup de mineurs. L'idée est d'empêcher qu'un groupe minoritaire prenne des décisions. D'autres approches existent. Le Burstcoin utilise une preuve de stockage qui a une faible consommation énergétique.
L'aspect décentralisé d'une blockchain est très important, et donc la façon d'obtenir un consensus l'est également. Nous n'étudierons pourtant pas cet aspect. Nous envisagerons ici une chaîne sur une machine unique et nous allons voir comment on peut garantir son authenticité.
Transaction et bloc
Une transaction est une opération consistant à modifier l'état de la chaîne, c'est à dire à ajouter des données.
Les transactions enregistrées sont regroupées en blocs. Quand un bloc est créé, les mineurs analyse l'historique complet de la chaîne. Si le bloc est valide, il est horodaté et ajouté à la chaîne.
Un bloc contient :
- des transactions
- une somme de contrôle – empreinte, hachage
- la somme de contrôle du bloc précédent
- une mesure de la quantité de travail qui a été nécessaire pour produire le bloc
Implémentation
Nous allons faire l'implémentation d'une chaîne représentant l'évolution des comptes d'un certain nombre d'utilisateurs. Pour faire plus simple, les utilisateurs seront connus dès le début.
Chaque utilisateur aura :
- un nom,
- un compte en unité de la monnaie de la blockchain,
- une paire de clés Kpu, Kpr.
La blockchain ne connaît que le clé publique Kpu de chaque utilisateur. Les utilisateurs doivent conserver secrètement leur clé privée Kpr.
Les seules transactions envisagées sont des transaction ou un utilisateur A donne à un utilisateur B une quantité de monnaie.
Blocs
Pour implémenter un bloc, vous pouvez par exemple utiliser une classe Block.
Un objet Block devra, pour être créé, recevoir :
- empreinte, hachage du bloc précédent,
- un tableau contenant les informations nécessaires.
On doit distinguer deux situations :
- le bloc initial contenant les informations sur les utilisateurs et servant d'amorce à la chaîne,
- les blocs suivants contenant les échanges.
Bloc initial
Comme ce bloc n'a pas de bloc avant lui, et donc pas d'empreinte de bloc précédent, on peut le créer en lui fournissant "0" à la place de l'empreinte du bloc précédent.
Les informations qu'on lui donne on la forme (nom, compte, Kpu). La clé, suivant le protocole RSA, est en deux morceaux. Par exemple :
[
("Paul", 45, 11758971846281690449, 65537), # Kpr = (11758971846281690449, 3602673231362159633)
("Judith", 92, 16218573123863373407, 65537), # Kpr = (16218573123863373407, 6385025328607971353)
("Michel", 52, 15421843742480106653, 65537), # Kpr = (15421843742480106653, 1380358199906286977)
("Laure", 39, 11452260091047556889, 65537), # Kpr = (11452260091047556889, 32502561540434945)
]
Bloc d'échanges
Les blocs ordinaires recevront l'empreinte (hachage) du bloc précédent et les informations de transaction.
Pour simplifier, on supposera qu'il n'y a qu'une transaction dans un tel bloc. Une transaction prend la forme suivante :
("Paul", "Judith", 5),
Information supplémentaire
Le bloc s'achève avec l'empreinte (hachage) de l'ensemble des informations qu'il contient :
- empreinte du bloc précédent,
- données (initialisation pour le bloc 0 et transaction pour les autres)
Pour le hachage, on pourra utiliser le module hashlib
import hashlib # module de fonctions de hachage
# exemple de hachage d'une donnée de type bytes
b = "tralala".encode('utf8')
h = hashlib.sha256(b)
# on peut produire une écriture hexadécimale de h
h_hex = h.hexdigest()
# on produire un écriture en bytes
h_bytes = h.digest()
On peut indiquer l'empreinte de chaque bloc dans sa version hexdigest, c'est du texte et c'est plus simple.
Sauvegarde
Il peut être intéressant de sauvegarder un bloc sous forme d'un fichier. On pourra par exemple sauvegarder un bloc sous cette forme :
empreinte du bloc précédent en format hexdigest chaque ligne de donnée avec séparateur ; empreinte du bloc en format hexdigest
Il faudrait donc aussi prévoir de créer un bloc à partir d'un tel fichier.
Chaîne
Créons une classe BlockChain.
Un objet Blockchain est initialisé avec les données des utilisateurs qui permettent de créer un bloc initial. Dès la création de la chaîne on crée donc ce premier bloc.
La classe BlockChain devra également prévoir des méthodes pour :
- ajouter un bloc : on donne une transaction,
BlockChainutilise l'empreinte de son dernier bloc pour créer un nouveau bloc. - lire l'ensemble de la chaîne pour calculer les comptes de chaque utilisateur.
Par exemple, Paul commence à 45 et Judith à 92. Après l'échange où Paul donne 5 à Judith, Paul aura 40 et Judith 97.
Signature
Dans la transaction ("Paul", "Judith", 5) comment être certain que c'est bien Paul qui a émis cette demande ? Pour cela nous allons utiliser le concept de signature.
Quand l'utilisateur crée une demande D = (source, cible, montant), il doit :
- calculer
z = h(D)ouhest une fonction de hachage, - chiffrer
zen utilisant sa clé Kpr, soitSle résultat, - fournir
S, la signature, à la suite deD.
Exemple : Pour l'échange ("Paul", "Judith", 5),
- on fabrique le texte
t = "Paul;Judith;5" - on fait l'encodage de ce texte
b = t.encode('utf8') - on calcule l'empreinte
z = hashlib.sha256(b) - on obtient la version bytes de
zavecd = z.digest()
On obtiendra ici pour S :
b"\x12\xd1\xcc\x8b'\x16O\xdcD\x0b\xde\x81\x904\x7f\xe0HD\x89\xbf\x9e\x04\xe7\x1f,\xd6\xed\xf1\x82\x91\r\xd4\x93\xc0,h\xbf\x01\xfau*)\x7f\xa3L5\x8djE\x1d\xef\xfcw\xdf9\xb3"
et on place ce S comme 4e élément de la transaction : ("Paul", "Judith", 5, S).
Pour vérifier la signature, on doit :
- calculer
z = h(D), - déchiffrer
Sen utilisant la clé Kpu associée à la source indiquée dansD, - vérifier que
zest bien égal au résultat du déchiffrement.
La signature permet de s'assurer que l'émetteur de la demande est bien le propriétaire de la clé privée liée à Kpu. Puisque la chaîne connaît les Kpu de tous les utilisateurs, on est sûr du propriétaire.
On aimerait ajouter une méthode dans BlockChain qui se chargerait de faire tout ce travail. Mais l'utilisateur doit calculer S de son côté car il ne doit jamais donner Kpr au gestionnaire de la blockchain. On peut si on veut créer une fonction indépendante qui se charge de produire S en fonction des données de la transaction et de Kpr.
Vérification d'un bloc
Lors de l'ajout d'un bloc, il va falloir prévoir une étape de vérification. Pour chaque transaction :
- vérifier que la signature,
- vérifier que la demande est valide compte-tenu des comptes en l'état actuel de la chaîne
Ne pas autoriser Paul à donner 5 s'il ne possède que 3.
Sauvegarde
Il serait intéressant de prévoir la sauvegarde de la chaîne. Chaque bloc serait sauvegardé dans un fichier séparé et nommé avec un nom comme 1.bc pour le bloc de rang 1.
Il faudrait alors prévoir de recréer la chaîne à partir de cette sauvegarde.
