lundi 20 décembre 2021

Chapitre 94 : Blockchain suite : gestion des clés publique et privée avec la librairie openssl

 

Dans le chapitre précédent, nous avons vu la création des clés publique et privée avec openssl dans le source portefeuille.s. Mais si nous voulons avoir des portefeuilles indépendants, il est nécessaire de pouvoir sauvegarder les clés sur des fichiers.

Dans les fonctions de openssl, il existe bien des fonctions pour sauvegarder les clés mais elles font appel à des fichiers adaptés au langage C et pas aux fichiers gérés directement par les appels système de Linux.

Heureusement, en cherchant dans le fouillis des fonctions proposées par openssl, j’ai trouvé des fonctions qui recopient les clés dans des zones mémoire que nous pouvons exploitées pour les sauvegarder sur des fichiers.

Dans le répertoire suivant sur github :

https://github.com/vincentARM/ARMassembly64/tree/master/projet64_014

vous trouverez plusieurs programmes pour gérer les clés, signer, vérifier, chiffrer et déchiffrer un fichier.

Dans le premier programme genkey64.s nous retrouvons la fonction de génération des clés que nous avons utilisée pour la blockchain. Cette fonction appelle les fonctions d’openssl qui créent les clés dans des structures internes.

Puis nous trouvons 2 fonctions qui vont écrire les clés sur les fichiers. Dans la fonction ecrireClePublique, nous créons d’abord une entité BIO et grâce à la fonction openssl PEM_write_bio_PUBKEY nous transférons la clé publique dans cette entité puis avec la fonction BIO_read nous transférons la clé dans un buffer sous le format standard de clé publique. Il ne nous reste plus qu’à écrire le buffer sur le fichier avec les appels système Linux 64 bits.

La fonction ecrireClePrivée effectue les mêmes opérations mais en utilisant la fonction PEM_write_bio_PrivateKey qui nécessite en plus le passage dans les paramètres d’une phrase de mot de passe (pass phrase)qui va permettre de chiffre la clé privée avant son écriture sur le fichier.

Cette phrase sera redemandée à chaque utilisation de la clé privée, ce qui assure sa confidentialité.

Dans le programme traiket64.s nous trouvons les fonctions pour relire les clés des fichiers et alimenter les structures BIO puis les structures internes d’openssl.

Mais la question qui se pose maintenant est celle de savoir si ces opérations sont correctes et si les clés sont utilisables.

Pour cela dans les programmes signerFichier64.s et verifierSign64.s, nous allons utiliser les fonctions de signature et de vérification utilisée pour la blockchain.

Dans le programme signerFichier64, nous allons utiliser le fichier de clé privée pour extraire la clé, signer un petit fichier texte, et générer la signature.

Puis dans le programme verifierSign64.s, nous allons utiliser le fichier de clé publique pour extraire la clé et l’utiliser pour vérifier la signature.

Tout fonctionne parfaitement !!!

Les 2 derniers programmes chiffrerFichier64.s et dechiffrerFichier64.s montre l’utilisation des clés pour chiffrer et déchiffrer un fichier texte. Je me suis servi des exemples en langage C d’openssl pour écrire ces programmes en assembleur.

Il y a donc une bizarrerie car le chiffrage exige l’utilisation d’une clé secondaire et d’une entité appelée IV qui doivent être passées au programme de déchiffrement. Normalement dans le cas d’un chiffrement asymétrique seules les clés publiques et privées devraient être utilisées. Ce point reste à éclaircir !!

Les programmes fonctionnent correctement.



mardi 7 décembre 2021

Chapitre 93 : création d"une blockchain en assembleur ARM 64 bits

 

En parcourant les divers forums sur internet, je trouve une proposition de développer un exemple de blockchain dans divers langages .

Bon dans mon inconscience je décide de voir ce que cela peut donner en assembleur. Après quelques recherches je découvre le site suivant qui propose un exemple en Java :

https://medium.com/programmers-blockchain/create-simple-blockchain-java-tutorial-from-scratch-6eeed3cb03fa

Je vais donc m’en inspirer pour créer ma propre blockchain locale. En effet pour cette première approche il n’est pas question d’écrire toute la partie distribuée du fonctionnement d’une blockchain. L’exemple propose la création des blocs, des portefeuilles, et des transactions ainsi que la vérification complète de la blockchain créée.

Le projet complet se trouve dans github à cette adresse :

https://github.com/vincentARM/ARMassembly64/tree/master/projet64_013

Le programme source blockchain1.s contient le programme maître, les routines de création de bloc, d’ajout d’un bloc dans la blockchain, d’ajout d’une transaction et la vérification complète de la blockchain.

Le programme effectue les initialisations, la création des portefeuilles, la création de la première transaction qui effectue un virement de 100 totos puis la création des blocs et des transactions des virements entre les portefeuilles.

La blockchain est une double liste chaînée, ce qui permet l’insertion d’un bloc à la fin de la chaîne sans avoir à balayer toute la liste.

Un bloc contient le hash du bloc précédent, son propre hash, un timestamp fourni par un appel système linux et diverses informations.

Le calcul et l’affichage des hash sont effectués par des routines du programme sha256_64.s écrites en assembleur. J’avais écrit ce programme pour une autre utilisation.

Les blocs sont crées sur le tas et ne peuvent pas être sauvegardés dans cet exemple. Le minage d’un bloc consiste à calculer un hash avec des zéros en tête. Plus on veut de zéros et plus c’est long à miner. Ici la routine se limite à vérifier la présence des 8 premiers zéros mais déjà le minage à 5 zéros dure un certain temps !! (constante DIFFICULTE à adapter dans le fichier constantesARM64.inc).

Le programme portefeuille.s contient les routines pour créer les portefeuilles, créer les clés publiques et privées, calculer le solde et envoyer des fonds à un autre portefeuille. Remarque : les clés publiques et privées ne sont pas sauvegardées sur un fichier externe !!

Les montants des soldes et virements sont exprimés par des floats de 64 bits (doubles). Leur affichage est effectué par une routine (dans utilFloat.s) différente de grisu et beaucoup plus simple. Merci au site  https://blog.benoitblanchon.fr/lightweight-float-to-string/ pour la présentation de cette solution. Bien sûr l'affichage peut être amélioré pour enlever le E0 derrière les montants !!!

La monnaie s'appelle dans cet exemple : toto !!!!

La génération des clés, la signature d’une transaction, et sa vérification nécessitent l’utilisation de la librairie openssl qu’il faudra donc télécharger et installer sur le raspberry pi. (voir les options du linker dans le makefile ).

Dans le programme transaction.s nous trouvons les routines de création et de gestion des transactions. La routine traiterTransaction est un peu complexe à comprendre mais vous pouvez vous reporter à l’exemple en Java du site cité plus haut.

Voici un exemple d’exécution de ce programme :

 

Début programme.

Init librairie SSL

Init sorties UTXO

création blockchain

création portefeuille 1

création portefeuille 2

création portefeuille depart

création transaction départ

Calcul signature TX départ

Création tx sortie départ

Ajout TX dans liste et hashmap

Création bloc 0

Ajout TX origine au bloc 0

Ajout bloc 0 à la blockchain

creation bloc 1

Solde A

Solde du portefeuille = +100E0 totos

Virement 1

Le solde est OK

Ajout transaction de virement 1

Virement 2

Le solde est OK

Ajout transaction de virement 2

Solde A

Solde du portefeuille = +70,5E0 totos

Solde B

Solde du portefeuille = +29,5E0 totos

Ajout bloc 1 à la blockchain

creation bloc 2

Virement 3

Le solde est OK

Ajout transaction de virement 2

Ajout bloc 2

SOLDE A

Solde du portefeuille = +65,25E0 totos

SOLDE B

Solde du portefeuille = +34,75E0 totos

Verification de la blockchain

La blockchain est valide.

Fin normale du programme.