GROUPE ESEO

RAPPORT DE STAGE

présenté par

ROMAIN FERON

Etude, implémentation et évaluation de fonctions de hachage innovantes sur FPGA

EADS DS – Saphir²

September 2009

CHAPITRE 1 Le groupe EADS 2

Remerciements

Je voudrais, avant d’entrer dans le vif du sujet, adresser un certain nombre de remerciements à tous ceux qui m’ont accompagné d’une façon où d’une autre durant ce stage.

A Monsieur Roland Stoffel mon tuteur, expert FPGA et Asic au sein de la section Network R&D d'EADS Defence and Security, pour son accompagnement tout au long de mon étude.

A Monsieur Philippe Mieli, responsable du service Hardware and RF, pour son accueil au sein de son équipe.

A Monsieur Marc Mouffron, responsable cryptologie et spécialement Mademoiselle Céline Thuillet, doctorante au sein du service Secure and Special Program.

A tous les stagiaires et prestataires du service pour leur sympathie, en particulier Céline, Bouba, François, Mathieu et Pierre.

3

Tables des matières

Synthèse 6

Introduction 7

1. Le groupe EADS 8 1.1 Présentation du groupe ...... 8 1.1.1 Histoire ...... 8. 1.1.2 Organisation ...... 8 . 1.2 Defence and Security ...... 10 . 1.3 Defence and Communications Systems ...... 11 .

2. Fonction de hachage 13 2.1 Définition ...... 13 . 2.1.1 Généralités ...... 13 . 2.1.2 Description générale d'une fonction de hachage séquentielle itérative . . 17 . 2.1.3 Exemples de constructions ...... 19. . 2.2 Quelques algorithmes de référence ...... 21 . 2.2.1 Secure Hash Algorithm ...... 21 . 2.2.2 Message Digest ...... 21. 2.2.3 Whirpool ...... 22 . 2.2.4 Autres ...... 22 2.3 La compétition SHA-3 ...... 24

3. L'algorithme Shabal 25 3.1 Etude ...... 25 . 3.1.1 Conventions ...... 25 . 3.1.2 Mode Opératoire ...... 27 . 3.1.3 Spécifications ...... 31 . 3.1.4 Première approche en terme de ressources ...... 33. . 3.2 Développement VHDL ...... 34 . 3.2.1 Outils ...... 34. . 3.2.2 Description générale du système ...... 34. . 3.2.3 Entité d'interface ...... 36 . 3.2.4 Entité de séquencement ...... 37 . 4

3.2.5 Entité de calcul ...... 39. . 3.2.6 La permutation ...... 40 . 3.3 Optimisations et Résultats ...... 41. . 3.3.1 Paramètres déterminants ...... 41 . 3.3.2 Optimisations successives ...... 43 . 3.3.3 Résultats et observations ...... 46. . 3.4 SHABAL 3.0 ...... 48 . 3.4.1 Description du code VHDL ...... 48 . 3.4.2 Résultats ...... 51 . 3.4.3 L'apport EADS ...... 51. .

4. Algorithmes concurrents et comparatif 51 4.1 Etapes de la compétition ...... 51 . 4.2 Algorithmes concurrents ...... 52. . 4.2.1 CubeHash ...... 52 . 4.2.2 Grøstl ...... 53 4.2.3 Lane ...... 55 4.2.4 Spectral Hash ...... 57. . 4.3 Comparatif ...... 59. . 4.3.1 Eléments de comparaison ...... 59 . 4.3.2 Représentations et observations ...... 59

Conclusion 66

Bibliographie 67

Annexe A – Code Shabal 2.2 68 A.1 Package.vhd ...... 68. . A.2 System.vhd ...... 69. . A.3 Prebloc_32bits.vhd ...... 70. . A.4 Hash.vhd ...... 72 A.5 Sequenceur.vhd ...... 73. . A.6 Operation.vhd ...... 74. . Annexe B – Résultats Shabal 2.2 79 Annexe C – Code Shabal 3.1 80 Annexe D – Résultats Shabal 3.1 (High-Speed Implementation) 83 Annexe E – Résultats Shabal 3.1 (Low-Area Implementation) 84 5

Table des figures

1.1 Effectifs de EADS au 31 décembre 2008 ...... 9 1.2 Répartition des effectifs de EADS par secteur d'activité ...... 9 1.3 Evolution du chiffre d'affaire de EADS (en millions d'euros) ...... 10 1.4 Hiérarchie directe de Hardware & RF ...... 12

2.1 Construction générale d'une fonction de hachage itérative ...... 18 2.2 Construction de Davies -Meyer ...... 19 2.3 Construction de Matyas-Meyer-Oseas ...... 20 2.4 Construction de Miyaguchi-Preneel ...... 20

3.1 Mode opératoire de Shabal : routine de traitement ...... 27 3.2 Finalisation de Shabal : première approche ...... 27 3.3 Finalisation de Shabal : seconde approche ...... 28 3.4 Schématique de l'architecture externe de Shabal ...... 35 3.5 Schématique de l'architecture interne de Shabal ...... 35 3.6 GRAFCET de Shabal ...... 38 3.7 Schématique de la permutation de Shabal ...... 40 3.8 Première étape du double décalage dans la permutation de Shabal ...... 44 3.9 Première étape du double décalage dans la permutation de Shabal ...... 45 3.10 Evolution des performances de Shabal ...... 47

4.1 Schématique de la fonction de permutation de CubeHash ...... 53 4.2 Fonction de compression de Grøstl ...... 54 4.3 Permutations P et Q de Grøstl ...... 54 4.4 Fonction de compression de Lane ...... 56

4.5 Schématique de la permutation P i /Qj de Lane ...... 56 4.6 Schématique de la fonction de compression de Spectral Hash ...... 57 4.7 High-Speed Implementation Results...... 61 4.8 Performances des algorithmes de hachage (High-Speed Implementation) ...... 62. . 4.9 TP/slice des algorithmes de hachage (High-Speed Implementation) ...... 63 . . 4.10 Low-Area Implementation Results ...... 64 4.11 Performances des algorithmes de hachage (Low-Area Implementation) ...... 65

6

Synthèse

EADS Defence and Security Romain FERON 1, boulevard Jean Moulin Stagiaire fin d'études ZAC La Clef Saint Pierre Promotion Zeeman 78 990 Elancourt Mars-Septembre 2009

Etude, implémentation et évaluation de fonctions de hachage innovantes sur FPGA

SUJET Le NIST a lancé fin 2007 un concours pour le développement de fonctions de hachage dans l'optique d'établir d'un nouveau standard en cryptographie. La société EADS, ainsi que ses partenaires et avec l'aide de l'ANR s'est impliquée dans ce projet en participant à l'élaboration d'une fonction candidate. L'un de ses objectifs aujourd'hui est de pouvoir évaluer, tester et enfin comparer les performances de ses algorithmes sur cible FPGA, afin d'en prouver l'efficacité en terme de fonctionnement hardware.

LES RESULTATS Nous avons pu déterminer les critères de comparaison et réaliser une évaluation des performances de différents algorithmes inscrits au concours. Nous avons développé, optimisé et testé une implémentation de Shabal, l'algorithme candidat de EADS et ses partenaires. Il propose donc à ce jour de bonnes performances sur cible, ce qui lui permet de rester en lice pour le choix du standard NIST. Le développement du code VHDL s'est fait sous ModelSim 6.0. La synthèse, le placement/routage et l'implémentation se sont faites avec Xilinx ISE 10.1 et iMPACT 10.1. L'étude a nécessité l'achat d'une plateforme d'évaluation FPGA Virtex-5 ML507. 7

Introduction

Le stage qui nous est proposé s'inscrit dans la collaboration EADS DS dans le projet SAPHIR² (Sécurité et Analyse des Primitives de Hachage Innovantes et Récentes), financé par l'ANR.

On nomme fonction de hachage une fonction particulière qui, à partir d'une donnée fournie en entrée, calcule une empreinte servant à identifier rapidement, bien qu'incomplètement, la donnée initiale. Les fonctions de hachage occupent aujourd'hui une place très importante dans le monde technologique. Ainsi, elle permettent de par leurs propriétés de stocker des données (type mot de passe) sans les afficher en clair par exemple, de vérifier l'intégrité d'un fichier, ou encore de générer des nombres pseudo-aléatoires.

Cependant, avec les avancées mathématiques et technologiques, ces fonctions sont, comme tout algorithme de cryptage, appelées à être cassées. C'est pourquoi il est nécessaire de définir régulièrement de nouveaux standards. C'est dans ce but que le NIST (National Institute of Standards and Technology) a lancé fin 2007 une campagne de sélection pour un nouvel algorithme de hachage de référence.

A ce jour, il reste une quinzaine de candidats en compétition, dont celui proposé par SAPHIR² : Shabal. Afin d'en prouver la bonne capacité de fonctionnement, il est à présent nécessaire d'en produire une implémentation hardware optimale, et c'est précisément l'objectif de notre étude.

Introduction 8

Chapitre 1

Le groupe EADS

1.1 Présentation du groupe 1.1.1 Histoire

EADS (European Aeronautics Defence and Space company) est un groupe industriel dans le secteur de l'aéronautique et du spatial civil et militaire. Né en 2000 de la fusion de trois entreprises européennes – DASA (Allemagne), Matra (France) et CASA (Espagne), il est aujourd'hui leader européen pour la défense et deuxième mondial pour l'aéronautique, en concurrence directe avec Boeing. Cette fusion répond d'ailleurs à la volonté de l'Europe de disposer d'un groupe industriel de puissance mondiale dans le secteur.

1.1.2 Organisation

Principalement détenu par l'état français, le groupe Lagardère, SEPI et Daimler AG, EADS emploie environ 118 000 personnes en 2008 pour un chiffre d'affaire d'environ 43.3 milliards d'euros. L'évolution du chiffre d'affaires ainsi que la répartition géographique des effectifs d'EADS sont visibles figures 1.1 et 1.3 Le groupe conduit quatre activités principales réparties en autant de divisions : • Airbus : construction d'avions civils et militaires. • Eurocopter : construction d'hélicoptères civils et militaires • Astrium : construction de lanceurs spatiaux ainsi que de satellites de télécommunication et d'observation de la Terre. • Defence and Security : construction d'armement et d'équipement électroniques.

CHAPITRE 1 Le groupe EADS 1.1 Présentation du groupe 9

EADS regroupe le reste de ses activités avions turbopropulseurs, aviation légère, conversion des avions passagers en cargos, ainsi que ses activités aérostructures et sièges d’avion. Ainsi, les Unités opérationnelles ATR, EADS EFW, EADS Sogerma et SOCATA sont classées dans la catégorie « Autres activités », laquelle ne constitue pas une Division d’EADS à part entière. Le diagramme de répartition des employés par secteur d'activité est visible figure 1.2.

France Allemagne Espagne Royaume-Uni Monde

44 380 42 987 10 104 13 826 États -Unis (37,5 %) (36,3 %) (8,5 %) (11,7 %) 2 555 (2,2 %)

Autres pays 4 497 (3,8 %)

Total : 118 349

FIG 1.1 – Effectifs de EADS au 31 décembre 2008

Cette place unique qu'occupe EADS dans le paysage industriel militaire et aéronautique mondial lui permet d'être leader dans quelques domaines spécifiques notamment les hélicoptères civils avec Eurocopter, le lancement de satellites avec Arianespace et les missiles militaires avec MBDA.

Astrium 13674 (12%) Airbus 58816 (50%)

Eurocopter 15667 (13%)

Siège social & Defence and Security 27779 autres activités (23%) 2413 (2%)

FIG 1.2 – Répartition des effectifs de EADS par secteur d'activité

CHAPITRE 1 Le groupe EADS 1.1 Présentation du groupe 10

40 000 43 300

39 434 39 123

34 206 30 000 31 761 29 901 30 133 30 798

20 000 24 208

10 000

0

2000 2001 2002 2003 2004 2005 2006 2007 2008

FIG 1.3 – Evolution du chiffre d'affaire de EADS (en millions d'euros)

1.2 Defence and Security

La Division Defence & Security (DS) d’EADS représente l’entité chef de file du groupe pour le développement de solutions de systèmes intégrés parfaitement conformes aux besoins des clients en matière de capacités réseau-centrées. Elle interconnecte toutes les ressources utiles pour offrir des solutions en réseau combinant les aéronefs militaires, les systèmes de missiles, les systèmes de défense et de communication, l’électronique de défense et les services associés. Ce dispositif garantit l’interopérabilité interarmées et interalliés dans le cadre de campagnes multinationales.

La division Defence and Security emploie environ 28 000 personnes en 2008 et réalise un chiffre d'affaire de 5,7 milliards d'euros. Elle se décompose en cinq entités :

• Defence Electronics , dont les activités majeures sont celles de fournisseur en seconde source de senseurs et sous-systèmes et visent le marché de la surveillance et de la reconnaissance, de la gestion des missions militaires, de l’autoprotection des plates- formes, des capacités réseaux et du soutien des forces. • Military Air Systems , qui intègre toutes les capacités d'EADS dans les domaines des avions de combat à haute performance, des drones (UAV), des avions d’entraînement et des équipements associés basés au sol. Le produit phare des activités d'EADS

CHAPITRE 1 Le groupe EADS 1.2 Defence and Security 11

Military Air Systems est l'Eurofighter (EADS détenant 46 % du capital d’Eurofighter GmbH). • MBDA , détenu à 37,5% par EADS offre des capacités hors du commun dans le domaine des systèmes de missiles et couvre toute la gamme des solutions destinées à la supériorité aérienne et aux missions de contrôle du territoire et de maîtrise des mers, en fournissant également à ces trois services les solutions technologiques les plus évoluées en matière d’armes de frappe et de défense antimissile. • Eurofighter GmbH , détenu à 46% par EADS en partenariat avec BAE Systems, il a été créé en 1983 afin de concevoir un avion de combat multi-rôles européen : le Typhoon. • Defence and Communication Systems , dont nous allons développer les spécificités ci-après.

1.3 Defence and Communications Systems

Véritable "Pôle Systèmes" d'EADS, DCS a pour rôle de concevoir, développer et mettre en œuvre des systèmes capables d’interconnecter le plus large éventail possible de plates-formes et de sous-systèmes au sein d’un réseau unique (Large System Integration – LSI). L’intégration des systèmes est également de plus en plus importante pour les clients non militaires dans des domaines comme la Sécurité du Territoire. Dans ces domaines, les solutions en matière de systèmes d’information et de communication sécurisée ainsi que les systèmes permettant une surveillance efficace des frontières et des côtes constituent une autre grande priorité de DCS. Cette entité est elle-même divisée en deux pôles, Integrated Systems et Security and Communications Solutions .

Dans le cadre de notre stage de fin d'études, nous faisons partie d'un service appartenant à cette dernière entité : Network R&D – Hardware and RF . La hiérarchie directe de ce service est visible figure 1.4. Ce service a pour mission l'étude de faisabilité, la conception d'architecture, l'intégration, le test et le support produit des solutions PMR (Private Mobile Radiocommunications). Pour ce faire, il intègre des compétences et spécialisations en électronique RF, System on Chip (FPGA & ASIC…), environnements physiques (mécanique, thermique…), logicielles (boot, drivers, operating systems…), et ce à destination de produits allant du simple composant jusqu'à la plateforme réseau. Ainsi, il élabore des solutions pour des environnements multiples.

CHAPITRE 1 Le groupe EADS 1.3 Defence and Communications Systems 12

EADS

Airbus Astrium Defence & Security Eurocopter

Defence Electronics Eurofighter Defence & Military Air Systems MBDA Communications Systems

Security Integrated Systems & Communication Solutions

Product Line Security Product Line Networks Product Line Applications

Core Platform Projects Network R&D Tetrapol Networks Projects

DSP Software Hardware & RF Integration, Vérification & Maintenance

FIG 1.4 – Hiérarchie directe de Hardware & RF

CHAPITRE 1 Le groupe EADS 13

Chapitre 2

Fonction de hachage

2.1 Définition 2.1.1 Généralités

Définition

On nomme fonction de hachage une fonction particulière qui, à partir d'une donnée fournie en entrée, calcule une empreinte servant à identifier rapidement, bien qu'incomplètement, la donnée initiale. Ce type de fonction est très utilisé en cryptographie, principalement dans le but de réduire la taille des données à traiter par la fonction de cryptage. En effet, la caractéristique principale d'une fonction de hachage est de produire un haché des données, c'est-à-dire un condensé de ces données. Ce condensé est de taille fixe, dont la valeur diffère suivant la fonction utilisée : nous verrons plus loin les tailles habituelles et leur importance au niveau de la sécurité.

Destruction d'information - Conservation de propriétés

Prenons l'exemple des empreintes digitales : dans la perception que nous en avons à l'heure actuelle, une empreinte digitale est unique et représente un individu d'une façon si certaine que nous pouvons la qualifier de sure. Pourtant la connaissance de cette empreinte ne permet pas à elle-seule de remonter à l'individu, ni de reconstituer cet individu. Il faut que la correspondance ait été préalablement établie dans une base de données pour que l'identification puisse avoir lieu par comparaison.

CHAPITRE 2 Fonction de hachage 2.1 Définition 14

C'est exactement ce genre de propriétés que présente une fonction de hachage. En effet, le haché est caractéristique d'un texte ou de données uniques. Différentes données donneront toutes des condensés différents (en théorie). De plus, tout comme l'empreinte digitale, le condensé ne contient pas assez d'informations en lui-même pour permettre la reconstitution du texte original : c'est pour cela que l'on parle d'ailleurs de fonction à sens unique (l'opération de hachage est destructrice dans le sens où elle conduit à une perte d'informations). Mais il faut bien comprendre que le but d'un condensé n'est pas de véhiculer ou de transporter de l'information. Il est juste représentatif d'une donnée particulière et bien définie. D'autant que les algorithmes de hachage les plus courants sont publics et ne représentent pas en eux-mêmes un secret.

Utilisation

Le but d'un condensé est simple : représenter des données de façon certaine tout en réduisant la taille utile qui sera réellement chiffrée. Prenons l'exemple de la cryptographie asymétrique; tout le monde admet qu'elle est très sure, fiable et durable. Néanmoins, sa complexité (calcul sur des nombres premiers de plusieurs centaines de chiffres par exemple) entraine une inévitable lourdeur d'emploi (charge CPU, etc...). On évite donc de l'utiliser pour de grandes masses de données ou pour des chiffrements de flux.

Par contre imaginons que l'on souhaite envoyer un fichier par mail, mais que ce fichier est de taille importante. L'objectif est ici de rassurer le destinataire sur la provenance de ce fichier et sur son contenu. Plutôt que de chiffrer le fichier directement avec une clé privée, il suffit hacher ce fichier et de chiffrer le condensé obtenu avec la clé privée. Nous enverrons ensuite le fichier original ainsi que le condensé chiffré (la signature) au destinataire.

Celui-ci va, lors de la réception, hacher d'une part le fichier reçu et d'autre part déchiffrer le condensé reçu (au moyen de la clé publique).

S'il n'y a pas égalité entre les 2 résultats, cela signifiera :

• soit que la signature n'est plus celle d'origine, donc que quelqu'un a intercepté le fichier (pour le modifier ou le remplacer, etc...)

CHAPITRE 2 Fonction de hachage 2.1 Définition 15

• soit que le fichier n'est plus le même que l'original (mais la signature n'a pas été remplacée); dans ce cas, le hachage ne peut plus donner le même condensé ce qui conduit au rejet lors du test de comparaison.

Dans les deux cas, ni l'intégrité ni l'authentification du fichier n'ont été vérifiées. Il ne faut donc pas faire confiance au fichier.

Nous voyons comment dans ce cas simple, l'utilisation d'une fonction de hachage permet de s'assurer de l'intégrité des données et indirectement de les authentifier. Il existe bien sûr de nombreuses autres applications pour les fonctions de hachage, comme les MACs ( code), certificats, etc...

Les attaques

Un fonction de hachage doit être résistante aux collisions, c’est-à-dire que deux messages distincts doivent avoir très peu de chances de produire la même signature. De par sa nature, tout algorithme de hachage possède des collisions mais on considère le hachage comme cryptographique si les conditions suivantes sont remplies :

• Il est très difficile de trouver le contenu du message à partir de la signature (attaque sur la première préimage) • A partir d'un message donné, de sa signature et du code source de la fonction de hachage, il est très difficile de générer un autre message qui donne la même signature (attaque sur la seconde préimage) • Il est très difficile de trouver deux messages aléatoires qui donnent la même signature (résistance aux collisions)

Par très difficile, on entend « techniquement impossible en pratique », c'est-à-dire par toutes techniques algorithmiques et matérielles, en un temps raisonnable.

De l'importance de la taille de l'empreinte

On peut se demander pourquoi il existe plusieurs tailles d'empreinte ou encore pourquoi celle-ci est fixe. Il faut garder à l'esprit le but ultime d'un haché qui est d'être le plus court possible, tout en gardant ses propriétés. Or, cela nous amène tout naturellement au

CHAPITRE 2 Fonction de hachage 2.1 Définition 16 problème des collisions vues précédemment, également connu sous la dénomination de théorème ou paradoxe des anniversaires.

Prenons donc notre haché H , qui présente une longueur de n bits. Nous pouvons d'ores et déjà déduire qu'il n'existe que 2 n hachés de ce type possibles, puisque chaque bit n'a que 2 valeurs possibles, 0 ou 1. Le problème survient lorsqu'on se rend compte que de l'autre côté, il peut y avoir une infinité de textes ou données initiaux (dont la taille, elle, n'est pas fixée). Nous risquons donc, un jour ou l'autre, de produire un haché qui pourrait correspondre à un ou plusieurs autres textes originaux : c'est la perte de la propriété principale d'une empreinte, qui est l'unicité. Nous avons trouvé une collision.

Le théorème des anniversaires prouve qu'il faut 2 n/2 essais pour trouver une collision au hasard. C'est le chiffre qui sera utilisé pour évaluer la force d'une fonction de hachage. Pourtant, il ne faut pas négliger le fait que la collision citée précédemment a été obtenue au hasard, ce qui n'est pas exploitable par une personne malveillante. En effet, le but serait de trouver un message significatif et bien formé conduisant au même haché, ce qui augmente considérablement les essais et calculs nécessaires et le rend quasiment impossible. Quoiqu'il en soit, cela suffit en théorie pour briser la propriété d'unicité de notre empreinte.

D'un point de vue pratique, et dans l'état de l'art actuel, il est généralement accepté que 2 56 calculs représentent un défit réalisable. En conséquence, avec n/2=56 et n=112, le théorème des anniversaires nous indique que les hachés de 112 bits sont faibles et donc insuffisants à l'heure actuelle. De la même manière, les hachés de 128 bits (n/2=64) ne représentent plus une sécurité à moyen terme. C'est pour cela que la norme actuelle est à 160 bits (n/2=80) voire plus.

CHAPITRE 2 Fonction de hachage 2.1 Définition 17

2.1.2 Description générale d'une fonction de hachage séquentielle itérative

Construction itérative

De manière générale, la plupart des constructions itératives suivent le même modèle. Nous appellerons S l'état interne de la fonction de hachage, M le message d'entrée et H la valeur du message haché. Le processus de traitement s'établit comme il suit :

• L'initialisation : - On applique un formatage du message d'entrée afin d'obtenir une série de blocs

message de taille identique M1…Mk. Cette étape peut contenir des opération d'encodage et/ou de padding (rembourrage). = - On place une valeur initiale dans le buffer interne Si S0 .

• Routine de traitement des blocs messages : pour i allant de 1 à k, M est inséré dans = Si−1 et on calcule Si à l'aide d'une fonction de compression R : Si R(M i , Si−1 ) . Ce modèle est appelé Merkle-Damgård. • Discontinuité : on effectue une transformation finale après le dernier calcul : = Sk+1 F(Sk ) . • Obtention de la valeur hachée : pour j allant de 1 à t : = - On extrait une valeur hachée Hj du buffer interne d'état Sk+ j : H j ext (Sk+ j ) = - On met à jour le buffer interne à l'aide d'une fonction T : Sk+ j+1 T (Sk+ j )

On peut bien évidemment enlever ou modifier certaines étapes en fonction de la construction désirée. Par exemple R, F et T peuvent être la même fonction. Cependant il faut toujours garder à l'esprit les deux objectifs contradictoires lors de la conception d'une fonction : sécurité et performance. Là où la sécurité requiert un maximum d'indépendance entre les différentes fonctions, la performance privilégiera un maximum de réutilisabilité. Ce jeu de balance entre ces deux paramètres explique le grand nombre d'algorithmes développés à ce jour utilisant une unique fonction de compression pour les différentes étapes de traitement.

CHAPITRE 2 Fonction de hachage 2.1 Définition 18

FIG 2.1 – Construction générale d'une fonction de hachage itérative

La fonction de compression

Elle est généralement basée sur un chiffrement par bloc. L'idée générale est la suivante :

1. Remplacer les caractères par un code binaire (par exemple le code ASCII en base 2). On obtient ainsi une longue chaîne de 0 et de 1. 2. Découper cette chaîne en blocs de longueur donnée, par exemple 64 bits. Cette étape est effectuée lors du pré-formatage du message M. 3. Chiffrer un bloc en l'"additionnant" bit par bit à une clef. 4. Déplacer certains bits du bloc. 5. Recommencer éventuellement un certain nombre de fois l'opération 3. On appelle cela une ronde. 6. Passer au bloc suivant et retourner au point 3 jusqu'à ce que tout le message soit chiffré.

CHAPITRE 2 Fonction de hachage 2.1 Définition 19

2.1.3 Exemples de constructions

La plupart des algorithmes de hachage se basent sur quelques principaux types de constructions. Nous allons en décrire succinctement le fonctionnement afin de simplifier la description des différents algorithmes abordés par la suite dans ce document.

Construction de Merkle-Damgård

Cette construction, très largement utilisée en cryptographie, accepte un message de taille quelconque tout en produisant une sortie de taille fixe, et en satisfaisant les contraintes de sécurité. Comme nous l'avons détaillé précédemment, elle emploie une fonction de compression R avec une entrée et une sortie de taille fixe, et divise le message à hacher en blocs de taille fixe. Les blocs sont ensuite envoyés les uns après les autres dans la fonction de compression. Ce qui va déterminer la robustesse de la construction, c'est la robustesse de sa fonction de compression.

Ce qui va différencier les différentes constructions est la manière dont le résultat de la fonction de compression va être transmis au bloc suivant. Les paragraphes suivants présentent donc des variantes de construction.

Construction de Davies-Meyer

Elle consiste à effectuer un XOR entre la sortie de la fonction de compression et la sortie de la compression précédente.

M i

R

H − i 1 E H i

FIG 2.2 – Construction de Davies -Meyer

CHAPITRE 2 Fonction de hachage 2.1 Définition 20

Si elle fut très utilisée dans le passé, elle montre à ce jour une faiblesse face au attaques sur la première préimage (cf. chapitre 2.1.1) déterminée par Drew Dean en 1999. Ceci nécessite donc des améliorations dans son fonctionnement puisque les fonctions de hachage construites dessus sont moins robustes.

Construction de Matyas-Meyer-Oseas

Elle propose un fonctionnement similaire à la construction de Davies-Meyer à ceci près que H i−1 est traitée par une fonction g avant d'être introduite dans la fonction de compression et que c'est le message d'entrée que l'on XOR à la sortie de la fonction de compression.

M i

R

H − g i 1 E H i

FIG 2.3 – Construction de Matyas-Meyer-Oseas

Construction de Miyaguchi-Preneel

Elle propose un fonctionnement similaire à la construction de Matyas-Meyer-Oseas à ceci près que H i−1 est elle aussi associée au XOR à la sortie de la fonction de compression. Il s'agit en fait d'une version renforcée de la construction de Matyas-Meyer-Oseas.

M i R

H − g i 1 E H i

FIG 2.4 – Construction de Miyaguchi-Preneel

CHAPITRE 2 Fonction de hachage 2.2 Quelques algorithmes de référence 21

2.2 Quelques algorithmes de référence 2.2.1 Secure Hash Algorithm

Les fonctions de hachage SHA ont été conçues par la NSA (National Security Agency) des États-Unis, et publiées par le gouvernement des États-Unis comme un standard fédéral de traitement de l'information (Federal Information Processing Standard du National Institute of Standards and Technology (NIST)).

On distingue trois familles d'algorithmes différentes : SHA-0 (1993), SHA-1 (1995) et SHA-2 (2000 et 2004). Seule SHA-2 permet des tailles de sorties différentes.

SHA-1 est la plus utilisée et est employée dans de nombreux protocoles et applications de sécurité. En 2005, des doutes sur la résistance de SHA-1 furent émis, à propos de l'éventuelle existante d'une faille mathématique. SHA-2 étant très proche, il est lui aussi touché par cette faille.

En conséquence, SHA-3 est en cours de développement. La nouvelle fonction sera sélectionnée via la compétition ouverte que nous détaillerons plus loin.

2.2.2 Message Digest

Message Digest est une famille de fonctions de hachage cryptographiques conçues par Ronald Rivest. Elle comporte à ce jour trois principales versions : MD2, MD4 et MD5. Nous nous pencherons sur la dernière, plus récente.

En 1991, Ronald Rivest améliore l'architecture de MD4 pour contrer des attaques potentielles qui seront confirmées plus tard par les travaux de Hans Dobbertin.

Cinq ans plus tard, en 1996, une faille qualifiée de grave (possibilité de créer des collisions à la demande) est découverte et indique que MD5 devrait être mis de côté au profit de fonctions plus robustes comme SHA-1. En 2004, une équipe chinoise découvre des collisions complètes. MD5 n'est donc plus considéré comme sûr au sens cryptographique.

CHAPITRE 2 Fonction de hachage 2.2 Quelques algorithmes de référence 22

Cependant, la fonction MD5 reste encore largement utilisée comme outil de vérification lors des téléchargements et l'utilisateur peut valider l'intégrité de la version téléchargée grâce à l'empreinte. Ceci peut se faire avec un programme comme md5sum pour MD5 et sha1sum pour SHA-1. MD5 peut aussi être utilisé pour calculer l'empreinte d'un mot de passe ; c'est le système employé dans GNU/Linux avec la présence d'un salage compliquant le décryptage. Ainsi, plutôt que de stocker les mots de passe dans un fichier, ce sont leurs empreintes MD5 qui sont enregistrées, de sorte que quelqu'un qui lirait ce fichier ne pourra pas découvrir les mots de passe.

Ronald Rivest a, dans le cadre du concours SHA-3, développé un nouvel algorithme de hachage : MD6. Cependant, celui a été éliminé lors du second tour de qualification le 24 juillet 2009.

2.2.3 Whirlpool

Whirlpool est une fonction de hachage cryptographique conçue par Vincent Rijmen et Paulo Barreto pour le projet NESSIE. La fonction utilise une architecture de type Miyaguchi- Prenee, et produit des empreintes de 512 bits.

En interne, l'algorithme travaille sur 512 bits grâce à une fonction similaire à celle de l'algorithme de chiffrement symétrique AES. Des empreintes de 512 bits sont très robustes (64 caractères) du point de vue cryptographique. Une attaque par le paradoxe des anniversaires nécessiterait au moins 2 256 opérations.

Whirlpool a été accepté dans la norme ISO/IEC 10118-3 et son utilisation est complètement libre, aucun brevet ne limite son emploi. Son utilisation est encore marginale mais de plus en plus de bibliothèques incorporent des routines supportant Whirlpool.

2.2.4 Autres

RIPEMD

L'algorithme de hachage RIPEMD, pour RACE Integrity Primitives Evaluation Message Digest, est une fonction de hachage qui produit une signature de 128 bits. Elle a été développée en Europe par le RIPE Consortium. Une collision complète a été trouvée en août

CHAPITRE 2 Fonction de hachage 2.2 Quelques algorithmes de référence 23

2004, en même temps que la collision sur le MD5. Une autre attaque sur une version simplifiée avait été publiée en 1997 par Hans Dobbertin.

Tiger

Tiger a été conçue par Ross Anderson et Eli Biham en 1996. Tiger fournit une empreinte sur 192 bits mais des versions sur 128 et 160 bits existent aussi. Ces versions raccourcies prennent simplement les premiers bits de la signature de 192 bits. Elle fut ensuite améliorée, donnant naissance à Tiger 2.

Haval

Haval est une fonction de hachage qui se décline en plusieurs variantes. Des empreintes de 128, 160, 192, 224 ou 256 bits peuvent être produites. Elle a été conçue en 1994 par Zheng, Pieprzyk, Seberry. Une collision complète sur la version de 128 bits a été découverte en août 2004.

Panama

PANAMA est une primitive cryptographique qui peut faire office de fonction de hachage cryptographique ou de chiffrement de flot. Elle a été conçue par et Craig Clapp en 1998 à partir de StepRightUp. En 2001,une attaque permettant de trouver des collisions sur PANAMA est élaborée. La méthode nécessite 282 opérations pour un hachage de 256 bits. Lors de la conférence FSE 2007, est présentée une attaque pratique sur la fonction de hachage de PANAMA.

CHAPITRE 2 Fonction de hachage 2.3 La compétition SHA-3 24

2.3 La compétition SHA-3

Développée par la NSA et certifiée par le NIST la famille des fonctions de hachage SHA : SHA-0 (taille de hash à 160bits) , SHA-1 (taille de hash à 160 bits), SHA-256 et SHA- 512, sont les plus couramment utilisées et toutes basées sur les concepts des algorithmes MD4 et MD5 (la taille de hash est de 128 bits).

Au cours de ces dernières années, la cryptanalyse de ces fonctions a constaté des failles qui permettraient d'aboutir dans un laps de temps raisonnable à des collisions (c'est à dire la construction d'une donnée dont le hash a exactement la valeur recherchée, cf. chapitre 2.1.1) démontrées dans MD4, MD5 et SHA-0 et qui laissent penser que SHA-1 pourrait aussi subir une attaque. À ce jour cependant, aucune faille n'a été trouvée dans SHA-256 et SHA-512, mais le patrimoine commun et les principes de conception de l'ensemble de ces fonctions les rend suspectes. Plus précisément, si SHA-256 et SHA-512 devrait être cassées, l'univers de l'information serait laissé sans des fonctions de hachage sures.

Pour remédier à cette situation, le NIST a ouvert un concours public, similaire à celui lancé pour le standard de chiffrement avancé AES, pour développer un nouvel algorithme de hachage cryptographique. Le nouvel algorithme de hachage sera appelé "SHA-3" et développera les algorithmes de hachage actuellement spécifiés dans la norme FIPS 180-2, Secure Hash Standard. Le concours a été annoncé au Federal Register dans l'avis publié le 2 Novembre 2007 et les inscriptions pour le concours ont été clôturées le 31 octobre 2008.

Le NIST devrait choisir l'une des propositions en tant que SHA-3 au cours de l'année 2012. 64 algorithmes ont été présentés au départ, puis n'en restait que 51 après le premier tour, et enfin seuls restent à ce jour 14 candidats issus du second tour.

CHAPITRE 2 Fonction de hachage 25

Chapitre 3

L'algorithme SHABAL

Shabal est l'algorithme proposé pour la compétition par le projet SAPHIR (Sécurité et Analyse des Primitives de Hachage Innovantes et Récentes) regroupant plusieurs entreprises et laboratoires (EADS DS, Sagem Sécurité, INRIA, DCSSI…) et financé par l'ANR. C'est donc sur cet algorithme que s'est concentrée notre attention, afin d'en proposer une implémentation compétitive et par là même de favoriser la sélection de Shabal comme standard mondial de hachage.

3.1 Etude 3.1.1 Conventions

Endianess

Les données en entrée de Shabal sont une séquence de bits de longueur arbitraire. Shabal accepte n'importe quelle longueur de message en entrée. Cependant, les critères de sécurité sont garantis pour des longueurs inférieures à 2 73 bits. Cette longueur doit être une valeur entière non nécessairement multiple de 8. Pour une séquence de bits données, on numérotera les bits selon leur place, le premier étant le bit 0. Nous utiliserons les termes left et right pour décrire une séquence de bits ordonnés : leftmost bit le premier bit de la séquence, et rightmost bit pour le dernier.

Tout d'abord, le message d'entrée est paddé – on préférera cet anglicisme trivial à la traduction "rembourré" : on ajoute des bits supplémentaire afin d'obtenir une séquence en entrée qui soit multiple de 32. Puis le message est découpé en groupe de 8 bits.

CHAPITRE 3 L'algorithme SHABAL 3.2 Développement VHDL 26

Une fois la conversion en groupe d'octets effectuée, ces octets sont regroupés en groupe de 4 consécutifs : les premiers (leftmost) 4 octets deviennent alors le premier groupe, les 4 suivants le second et ainsi de suite. Chacun de ces regroupements est donc désormais un mot de 32 bits ou plus simplement un mot. Étant donné que la longueur de la séquence paddée est multiple de 32, nous obtiendrons un nombre entier de mots. La valeur de chaque mot est donnée par les 4 octets par la convention little-endian : le premier (leftmost) octet est donc de poids faible. Si on appelle les 4 octets de gauche à droite C 0, C 1, C2 et C 3 (chacun d'entre eux compris entre 0 8 16 24 et 255), la valeur du mot est donnée par : C 0 + 2 C1 + 2 C2 + 2 C3.

La séquence de sortie de Shabal est une succession de mots qui sont par la suite transformés en séquence de bits par l'opération inverse : les mots sont séparés en octets (avec la convention little-endian), et les octets en bits donc le bit de poids fort est le leftmost. On pourra noter le fait que ces conventions sont identiques à celles utilisées pour la fonction MD5, et sont parfois appelées mixed-endian : big-endian au niveau bit et little-endian au niveau octet.

Notations

Dans ce paragraphe, nous exposons les principales notations utilisées dans cette partie. Soient x et y des mots (de 32 bits par définition). Nous noterons x ⊕ y le OU exclusif bit à bit (XOR) de x et y ; x ^ y le ET logique bit à bit de x et y. Le complément de x sera noté x ⊕ 1 - le "1 gras" symbolise le mot x"FFFFFFFF". Autrement, x <<< j traduit une rotation de x de j bits vers la gauche et x << j le décalage de x de j bits vers la gauche. A noter que la rotation diffère du décalage en ce sens que les bits "disparaissant" par la gauche reviennent par la droite tandis que pour le décalage, ils sont tout simplement supprimés (donc x << j veut dire que ce sont des 0 qui entrent par la droite). Si j n'est pas un multiple de 32, alors on lui appliquera un modulo avant d'opérer la rotation.

Toutes les opérations logiques sont effectuées bit à bit à l'intérieur même des mots. Nous utilisons aussi des opérateurs mot à mot comme des additions ou des soustractions modulo 232. On notera ces additions ou +. En d'autres termes, si X et Y sont deux registres composés de mots de 32 bits, le résultat de X + Y sera un registre contenant les mots de X et Y additionnés sans propagation de retenue d'un mot à l'autre. Il en va de même pour la soustraction.

CHAPITRE 3 L'algorithme SHABAL 3.2 Développement VHDL 27

3.1.2 Mode opératoire de SHABAL

Description

La construction de Shabal est articulé autour d'une permutation chiffrée P. Pour cela, elle inclue un buffer interne divisé en 3 registres A, B et C qui sont initialisés aux valeurs A 0,

B0, C 0. On verra qu'il existe deux types d'initialisation. Un registre auxiliaire W de 64 bits est utilisé comme compteur des blocs messages entrants. Etant donné sa fonction particulière, il n'est pas considéré comme appartenant au buffer interne.

Shabal traite les blocs messages de façon itérative. La permutation P, principale structure de l'algorithme peut s'écrire comme il suit :

→ = PM ,C (: A, B) PM ,C (A, B) P(M , A, B,C)

FIG 3 .1 – Mode opératoir e de Shabal : routine de traitement

FIG 3.2 – Finalisation de Shabal : première approche

CHAPITRE 3 L'algorithme SHABAL 3.2 Développement VHDL 28

Une vue graphique de la construction de Shabal est visible figure 3.1. A noter qu'une simple optimisation dans l'étape finale consiste à économiser l'étape de soustraction et d'échange à chaque fois et de prendre directement le contenu du registre B en sortie de la dernière permutation.

FIG 3.3 – Finalisation de Shabal : seconde approche

CHAPITRE 3 L'algorithme SHABAL 3.2 Développement VHDL 29

Description du mode opératoire

← Initialisation : (A, B,C,W ) (A0 , B0 ,C0 )1,

Padding : on pad la séquence d'entrée afin d'avoir un nombre de bits multiple de 32.

Routine de traitement : Pour w allant de 1 à k ( w = 2 32 .W ]1[ +W ]0[ ) on fait :

• add : le bloc message est introduit.

← + B B M w

Il s'agit ici d'une addition mot à mot, comme expliqué précédent, sans propagation de retenue.

• counter : XOR le compteur avec A ]0[ et A ]1[ .

A ]0[ ← A ]0[ ⊕W ],0[ A ]1[ ← A ]1[ ⊕ W ]1[

• permute : on applique la permutation P .

← (A, B) PM ,C (A, B)

• sub : on soustrait le message à C.

← − C C M w

Il s'agit ici d'une soustraction mot à mot

• swap : on interchange B et C .

(B, C) ← (C, B)

Finalisation : On opère ici une série de tours : la routine de traitement est appliquée

trois fois avec le dernier message inséré M k . Pendant cette phase, le compteur w reste figé à la valeur k .

− Sortie : Les mots allant de C 16[ lh 32/ ] à C 15[ ] constituent le message de sortie –

avec lh la longueur de sortie désirée.

CHAPITRE 3 L'algorithme SHABAL 3.2 Développement VHDL 30

Vue de haut niveau

Voici une approche plus synthétique de l'algorithme Shabal.

Initialisation : (A, B,C,W ) ← (A , B ,C )1, 0 0 0

= Routine de traitement : M M1,..., M k

For w from 1 to k do

1. B ← B + M w 2. A ← A ⊕ w ← 3. (A, B) PM ,C (A, B)

4. C ← C − M w 5. (B, C) ← (C, B)

End do

Finalisation :

For i from 1 to 2 do

← + 1. B B M w ← ⊕ 2. A A w ← 3. (A, B) PM ,C (A, B) ← − 4. C C M w ← 5. (B, C) (C, B)

End do

= Sortie : H msb lh (C)

Résultats en termes de sécurité

Il a été prouvé ([4] chapitre 5) que Shabal est indifférentiable par un random oracle , résistant aux collisions, résistant aux attaques sur le première préimage et sur la seconde préimage, sachant que la permutation P se comporte comme une permutation aléatoire.

CHAPITRE 3 L'algorithme SHABAL 3.2 Développement VHDL 31

3.1.3 Spécifications de SHABAL

Dans le chapitre précédent, nous avons décrit le mode opératoire de la fonction Shabal. Dans cette partie, nous décrirons quelques détails d'implémentation propre à Shabal.

Vue d'ensemble

= Shabal traite des blocs messages de longueur lm 512 bits exclusivement. Le buffer interne, composé des registres A , B et C , est configurable à l'aide de deux paramètres de sécurité : p ≥ 2 et r ≥ 2 . Il est donc de longueur (1024 + 32 r ) bits organisés par mots de 32 bits. Pour être plus précis, B et C sont des registres de 16 mots tandis que A est un registre = de r mots. On note la longueur la 32 r . Le compteur W , non considéré comme faisant partie du buffer interne, est vu comme un registre de 2 mots.

Comme nous l'avons mentionné précédemment, il existe deux approches en termes d'initialisation. Dans le premier cas, il s'agit de calculer les états initiaux des registres. On fera tourner la routine de traitement avec des messages blocs M −2 et M −1 précalculées. Ceci implique un traitement différent pour le compteur W que l'on fera démarrer à -1. Aussi, il marquera 1 pour le premier message bloc entrant. Le second cas présente cette alternative de directement stocker en mémoire l'état du buffer interne au démarrage et d'attribuer = directement ces données : (A, B,C) IV lh avec IV lh : Initilization Vector. Le choix de l'initialisation dépendra essentiellement du type de matériel utilisé.

La permutation

Il existe plusieurs manières d'aborder la permutation interne de Shabal, nous les détaillerons par la suite. En voici une description d'ensemble ci-après.

Dans cette description, U : x → 3× x mod 232 et V : x → 5× x mod 232 sont utilisées comme fonctions non linéaires.

CHAPITRE 3 L'algorithme SHABAL 3.2 Développement VHDL 32

Permutation P interne de Shabal

Entrée : M , A, B,C

Sortie : A, B

Déroulement :

1. For i from 1 to 15 do

B[i] ← B[i] <<< 17

End do

2. For j from 1 to p −1 do

For i from 0 to 15 do

• Compute

+ ← + ⊕ − + <<< A[i 16 j mod r] U (A[i 16 j mod r )] V (A[i 1 16 j mod r] 15 ) ⊕ C 8[ − i mod 16 ])

⊕ B[i + o mod 16 ] 1 ⊕ + ∧ + (B[i o2 mod 16 ] B[i o3 mod 16 )] ⊕ M i][

= où (o1 , o2 , o3 ) 13( )6,9, sont des valeurs d'offset nécessaires à une meilleure

diffusion dans la permutation.

• B i][ ← (B i][ <<< )1 ⊕ A[i + 16 j mod r]

End do

End do

3. For j from 0 to 35 do

A[ j mod r] ← A[ j mod r] + C[ j + 3mod 16 ]

End do

Le choix des paramètres

Les paramètres de sécurité p et r sont fixés à 3 et 12 par les concepteurs de Shabal. Cependant, une étude concernant la pertinence de ce choix sera sans doute faite par la suite par l'équipe de recherche. Les valeurs d'offsets ont quand à elles été soigneusement choisies ([4] chapitre 4.3).

CHAPITRE 3 L'algorithme SHABAL 3.2 Développement VHDL 33

3.1.4 Première approche en termes de ressources

Parallèlisme [4]

Tout d'abord, une première étape consiste à paralléliser certaines fonctions. L'inconvénient de l'utilisation de ces parallélismes est l'accroissement du nombre de portes. • L'encodage d'un bloc message en 16 mots peut être effectué en // (selon la largeur et la vitesse du bus d'entrée). • L'addition (à B) et la soustraction (à C) du message peuvent être effectuées en //. • La rotation des mots de B de 17 bits vers la gauche peut être effectuée en //. • L'ajout de C dans A modifie les mots de A indépendamment les uns des autres. • L'échange de B et C peut être effectué en //. Si on se concentre sur le cas FPGA, on peut dénombrer les possibilités suivantes: • Design construit autour de la double boucle de permutation (48 itérations). L'utilisation de registre à décalage parait être facile à mettre en place puisque tous les registres (A, B, C, M) "tournent" de la même façon à chaque itération; • Les mises à jour de B peuvent être effectuées en parallèle dans la permutation grâce à l'offset. • L'ajout de C dans A, la soustraction de M à C et le début du traitement du bloc suivant peuvent être effectués simultanément. Il suffit d'utiliser un registre à décalage pour C ainsi qu'un bloc additionneur. • Les multiplications par 3 ou 5 sont exprimables en simples additions. A × 5= (A << )2 + A

Estimation des ressources nécessaires [4]

Voici une première estimation du nombre de portes, temps de propagation, cycles d'horloge, proposée par les concepteurs de Shabal. • 700 cycles d'horloge pour un message de 512 bits en entrée (pour un design permettant 3 portes traversées par cycle). • 20000 portes au total comprenant :  5600 portes pour les additionneurs (800 chacun).  6000 portes pour les registres à décalage.  Portes pour le XOR  Portes pour l'incrémentation du compteur…

CHAPITRE 3 L'algorithme SHABAL 3.2 Développement VHDL 34

3.2 Développement VHDL 3.2.1 Outils

Pour développer une routine de traitement de SHABAL en VHDL, nous avons décidé d'utiliser l'outils ModelSim SE version 6.0 de Mentor Graphics. Nous bénéficions ainsi d'un environnement complet de simulation et de débogage.

Pour ce qui est de la synthèse et du placement/routage, nous utiliserons l'outil de développement intégré au FPGA ciblé. Il s'agit d'un Virtex-5 de chez Xilinx donc cette étape se fera à l'aide de ISE 10.1.

3.2.2 Description du système

Au cours de notre étude, l'architecture de notre système a subi maints changements. Nous ne détaillerons pas les multiples versions dans ce rapport, ou tout du moins seulement les optimisations importantes et/ou intéressantes (cf. chapitre 3.3.2).

La structure de l'algorithme SHABAL se présente de telle manière qu'il nous est apparu logique de découper la routine de cryptage en plusieurs blocs entités, permettant une lecture claire et logique du design.

Un bloc-entité Hash, concernant le traitement à proprement parlé des données qui est divisé en deux blocs. Tout d'abord une entité Séquenceur ; en effet, l'algorithme présente de lui-même une construction séquentielle itérative. Cette entité permet donc de gérer les états et transitions entre les étapes de traitement des données. Puis une entité Operation, qui gère la pluparts des opérations sur les registres A, B, C, M et W ainsi que toutes les étapes de la permutation. La partie d'interface que nous avons appelé Prebloc_32bits permet de récupérer les données à traiter via un bus 32 bits, et les formate en blocs messages de 512 bits (16 x 32 bits) qu'elle envoie ensuite vers Hash pour traitement. Elle effectue aussi l'opération en sens inverse – conversion du résultat de routine vers un bus de 32 bits.

CHAPITRE 3 L'algorithme SHABAL 3.2 Développement VHDL 35

Un schématique de l'architecture de SHABAL est visible figure 3.5, nous détaillerons la fonction des différents signaux un peu plus loin.

FIG 3.4 – Schématique de l'architecture externe de Shabal

FIG 3.5 – Schématique de l'architecture interne de Shabal

CHAPITRE 3 L'algorithme SHABAL 3.2 Développement VHDL 36

3.2.3 Entité d'interface

Le fonctionnement de l'entité gérant l'interface du système est basée sur le principe d'une FIFO ; les données entrantes (bus de 32 bits) sont "stockées" dans un magasin correspondant au format d'un bloc-message (16 mots de 32 bits). Lorsque le magasin est plein, alors on le transmet en intégralité à l'entité de calcul qui le traitera alors comme il se doit. De la même manière, l'entité reçoit les données en sortie de la fonction de hachage pour les renvoyer selon le même format qu'en entrée.

Toutes ses opérations sont soumises au contrôles de différents signaux. Voici la description des principaux signaux internes et externes à Prebloc_32bits :

Externes CLK_I : Horloge du système. RST_I : Reset du système. WE_I : Write Enable Input en provenance du bus. DATA : Flot de données en provenance du bus.

in RDY : Indicateur en provenance de Hash comme quoi la routine reçoit le flot de données sortant. FINISH : Indicateur en provenance de Hash lorsqu'il a fini les calculs et envoie le résultat. DAT_O : Flot de données entrant – bloc message – en provenance de Hash.

START : Indicateur à destination de Hash comme quoi le flot de données suivant – bloc message – est prêt à être envoyé. out DAT_I : Flot de données sortant – bloc message – à destination de Hash. DATA_OUT : Flot de données à destination du bus. WE_O : Write Enable Output à destination du bus.

Internes STORE_IN : Registre de stockage des données en provenance du bus entrant. POINTER_IN : Pointeur sur STORE_IN. POINTER_IN_FULL : indicateur de registre plein (STORE_IN). VALID_WRITE_IN : indicateur permettant d'écrire ou non dans STORE_IN. POINTER_OUT : indicateur de mots en sortie (16 maximum pour SHABAL-512) POINTER_OUT_FULL : indicateur de nombre de mots maximum atteint.

CHAPITRE 3 L'algorithme SHABAL 3.2 Développement VHDL 37

3.2.4 Entité de séquencement

Notre système est basé sur un fonctionnement séquentiel, cette entité est là pour gérer les différents états et transitions liés à ce fonctionnement. Dans sa version finale, le séquenceur gère 6 états différents ainsi que les transitions associées dont le grafcet est visible figure 3.6.

Toutes ses opérations sont soumises au contrôles de différents signaux. Voici la description des signaux internes et externes au séquenceur :

Externes CLK_I : Horloge du système. RST_I : Reset du système. INIT : Indicateur permettant de passer de la phase d'initialisation à la routine

in d'Update. START : Indicateur en provenance de Prebloc_32bits comme quoi le flot de données suivant – bloc message – est prêt à être envoyé. N0_FINAL : Compteur des tours finaux TERM : Indicateur de fin de permutation en provenance de l'entité de calcul. out ETAT : Etat du séquenceur.

Internes ETAT_IN : Etat du séquenceur.

CHAPITRE 3 L'algorithme SHABAL 3.2 Développement VHDL 38

0 INITIALISATION 1

1 M <= DAT I or M <= PREFIXE

START = '1' or N0 FINAL /= 0 or INIT = '0'

2 A xor W B <= (B + M) <<<17 1

3 PERMUTATION

TERM = '1'

4 A <= A + C C <= C - M 1 N0 FINAL /= 3 5 B <> C W++

N0 FINAL = 3 6 DAT_O <= C

FIG 3.6 – GRAFCET de Shabal

CHAPITRE 3 L'algorithme SHABAL 3.2 Développement VHDL 39

3.2.5 Entité de calcul

Les principales opérations sur l'état interne de l'algorithme sont opérées au sein de l'entité de calcul. Elle est décomposée en un certain nombre de process, chacun d'entre eux gérant un ou plusieurs registres. Voici la description des signaux internes et externes de cette entité :

Externes

CLK_I : Horloge du système.

in ETAT : Etat du séquencement. DAT_I : Flot de données entrant – bloc message – en provenance de Prebloc_32bits.

FINISH : Indicateur en provenance de Hash et à destination de Prebloc_32bits comme quoi la routine est terminée et est prête à envoyer le flot de données résultat. DAT_O : Signature post-hash. out RDY : Indicateur à destination de Prebloc_32bits comme quoi la routine est prête à recevoir le flot de données – bloc message – suivant. INIT : Indicateur permettant de passer de la phase d'initialisation à la routine d'Update. N0_FINAL : Compteur de la routine Final.

Internes A_IN : Registre A. B_IN : Registre B. C_IN : Registre C. M_IN : Registre M. W_IN : Compteur de boucle. N0_FINAL_IN : Compteur interne de N0_FINAL. INIT_IN : Indicateur interne de INIT.

CHAPITRE 3 L'algorithme SHABAL 3.2 Développement VHDL 40

3.2.6 La permutation

La structure interne de la permutation est ainsi faite qu'elle permet un fonctionnement basé sur le décalage des registres. Puisque à chaque itération ne sont sollicités que quelques mots dans les registres A, B, C et M, alors on peut construire la permutation comme le montre la figure 3.7

FIG 3.7 – Schématique de la permutation de Shabal

Bien entendu, cette représentation de la permutation ne montre pas les deux étapes que sont la rotation de B précédente et l'addition de C à A à la suite des 48 itérations.

CHAPITRE 3 L'algorithme SHABAL 3.3 Optimisations et Résultats 41

3.3 Optimisations et Résultats 3.3.1 Paramètres déterminants

Afin de comparer de façon juste et objective les résultats de notre étude avec d'autres, il nous faut tout d'abord définir les paramètres représentatifs des performances d'un algorithme de hachage implémenté sur FPGA.

La surface

La surface sur cible est de fait le premier résultat auquel nous avons accès. Dans le cas d'un développement sur FPGA Xilinx, elle s'exprime en "slice". Toutefois, il est nécessaire de rester prudent quant à cette notion car la définition même d'un slice peut varier d'un FPGA à l'autre. Prenons l'exemple du Spartan-3 et du Virtex-5 puisque c'est à ces deux FPGAs que nous avons eu affaire. Un slice du premier contient deux 4-LUTs (Look-Up Table ou table de correspondance), c'est-à-dire deux LUTs à quatre entrées et une sortie, ainsi que deux registres. Par contre, dans le cas du Virtex-5, un slice contient quatre 6-LUTs, c'est-à-dire quatre LUTs à 6 entrées et 1 sortie ou 5 entrées et 2 sorties, ainsi que quatre registres. En résumé, un slice de Virtex-5 embarque donc à priori plus de 2 fois plus de logique qu'un slice de Spartan-3. Nous exprimerons nos résultats de surface en slice "type Virtex-5" puisque c'est sur ce modèle que c'est effectuée notre étude ainsi que la plupart des autres.

A noter que les résultats en termes de surface exposés par la suite concerneront uniquement la partie opératoire de Shabal, c'est-à-dire la surface occupée par la fonction de compression.

Il est bien entendu que nous cherchons à diminuer au maximum le taux d'occupation du FPGA. Il est cependant intéressant de noter que pour les personnes concernées par la compétition, trop peu de logique peut vouloir signifier une trop grande fragilité de l'algorithme.

La fréquence maximale de fonctionnement

Un autre paramètre déterminant pour l'évaluation de notre implémentation est sa fréquence de fonctionnement maximale. Là aussi, il nous faut faire très attention aux résultats

CHAPITRE 3 L'algorithme SHABAL 3.3 Optimisations et Résultats 42 que peut nous fournir l'outils de développement et à la façon de les obtenir. Lors de la synthèse, l'outils ISE nous donne une première estimation de la fréquence de fonctionnement du système. Cette donnée est à prendre avec beaucoup de précaution puisque non précise. Il faut attendre le placement/routage pour avoir une valeur correcte. A noter aussi qu'il est indispensable de contraindre progressivement notre design en fréquence (fichier .ucf) afin d'en obtenir le meilleur résultat.

Le nombre de cycles d'horloge

Le nombre de coups d'horloge pour le traitement d'un bloc-message – dans notre cas 512 bits – intervient directement dans l'évaluation de notre implémentation. Ainsi, on peut obtenir des informations concernant le débit de sortie lorsqu’il est associé à la fréquence de fonctionnement.

Le débit en sortie

Le débit en sortie out Throughput (TP) est sans aucun doute un paramètre très important puisqu'il nous renseigne directement sur la capacité qu'à un algorithme à hacher un message. Il s'exprime en Mbps (megabits par seconde) et se calcule comme il suit :

nb bits par bloc message × fréquence max TP = nb cycles d'hor log e par bloc message

Ainsi, une fonction de hachage offrant un bon TP peut prétendre à des applications de type serveur réseau par exemple.

Enfin, un autre indicateur nous permettant de d'analyser les performances de notre implémentation, spécialement dans le domaine des FPGAs est le rapport TP sur slice, qui sera exprimé en kbps/slice (kilobits par seconde par slice).

CHAPITRE 3 L'algorithme SHABAL 3.3 Optimisations et Résultats 43

3.3.2 Optimisations successives

Au cours de notre étude, notre code a subi de nombreuses modifications, ajouts, suppressions et remaniements. Si la plupart d'entre eux ne sont pas significatifs, il en est certains que nous souhaitons consigner dans ce rapport pour leur impact notoire dans les performances de Shabal.

Les entrées/sorties

Arrivant à l'étape de synthèse, il nous a fallu rapidement réfléchir sur le mode de transmission des données en entrée/sortie de notre fonction de hachage. Il est évident que rentrer directement les 16 mots de 32 bits (soit 512 bits) en une seule fois est impensable au vu des architectures de bus standard existantes. Nous avons donc opté pour une gestion de ces données en amont de l'étape de calcul, et donné naissance à l'entité Prebloc_32bits vu précédemment (cf. chapitre 3..2.3). Ainsi, la liaison avec l'extérieur du système se fait par l'intermédiaire de bus 32 bits.

Regroupement d'entités

Au départ de notre conception, nous avions décidé de "séparer naïvement" au maximum les différents organismes de calcul, afin d'en clarifier le fonctionnement. Au bout d'un certain temps, ceci apparait dégradant en terme de performance puisque nécessite des registres intermédiaires et autres signaux de contrôle finalement superflus. C'est pourquoi nous avons fusionné successivement les entités Operation et Echange (Hash v1.1), puis Operation et Permutation (Hash v2.0).

Suppression du système d'indiçage

L'une de nos améliorations majeures fût le remaniement profond de notre système de permutation. Il nous faut au préalable détailler le fonctionnement initial de cette dernière. Le déroulement de la fonction de compression de Shabal était basé sur deux compteurs : l'un de 0 à 2 et l'autre de 0 à 15, ce qui nous donne 3x16 = 48 itérations. Il s'agit des compteurs i et j

CHAPITRE 3 L'algorithme SHABAL 3.3 Optimisations et Résultats 44

(cf. chapitre 3.1.3). Finalement, nos registres étaient "statiques" et seuls les compteurs régissaient les données du calcul.

Nous nous sommes rendus compte que cette façon de procéder ralentissait considérablement le système puisqu'elle induisait l'ajout d'un étage de multiplexage. Nous avons donc décider de passer à une implémentation telle que décrite au chapitre 3.2.6.

Le double décalage

L'étape suivante dans l'optimisation de l'implémentation de Shabal découle logiquement de la précédente. Maintenant que nous opérons notre permutation au moyen d'un décalage à chaque tour, on en vient à se demander si plusieurs décalages, donc plusieurs étapes de calcul à chaque coup d'horloge, n'amélioreraient pas les performances en débit de notre implémentation. Cette logique présente le raisonnement suivant ; si l'on divise par deux le nombre de coups d'horloge, on réduira aussi la fréquence maximale de fonctionnement. Cependant, si la fréquence maximale obtenue est supérieur à la fréquence initiale divisée par deux, alors on augmente le débit de sortie (TP). Le double décalage, correspondant à deux étapes de calcul en un coup d'horloge est schématisé par les figures 3.8 et 3.9.

FIG 3.8 – Première étape du double décalage dans la permutation de Shabal

CHAPITRE 3 L'algorithme SHABAL 3.3 Optimisations et Résultats 45

La première d'entre elles présente la première "étape" : elle se présente comme la permutation simple à ceci prêt que les résultats sont placés en A(10) et B(14), le registre de 32 bits A_TEMP servant seulement d'entrée à l'étape suivante.

Cette dernière (figure 3.9) prend en argument les mots suivants* dans les registres A, B, C et M et place les résultats dans les registres A(11) et B(15).

Bien entendu, ces deux étapes sont effectuées simultanément ainsi que les deux décalages dans tous les registres, non représentés sur les figures 3.8 et 3.9.

Cette opération nous permet de diviser par deux le nombre de cycles d'horloge nécessaires à la permutation; on passe donc de 48 à 24 itérations.

FIG 3.9 – Première étape du double décalage dans la permutation de Shabal

*dans le sens de la permutation du registre CHAPITRE 3 L'algorithme SHABAL 3.3 Optimisations et Résultats 46

Inclusion de C-M à la permutation

Toujours dans l'objectif de gagner en nombre de cycles d'horloge par bloc-message et de réduire la logique de notre implémentation, nous avons étalé l'opération de soustraction de M à C au sein même de la permutation. Ceci se fait donc dans le second tiers de la permutation, soit de la huitième à la seizième itération (puisqu'elle compte désormais 48/2 = 24 itérations) et nécessite un registre auxiliaire AUX. Il est initialisé aux valeurs de C au début du cycle (ETAT = 2), et profite de la sollicitation de M(0) à chaque itération pour effectuer l'opération : AUX <= (AUX )0( − M ))0( & AUX 15( downto )1 Une fois la permutation terminée, il ne reste plus qu'à mettre AUX dans B, et B dans C. Nous gagnons donc un cycle d'horloge par bloc-message et le nombre d'additionneurs nécessaires à ce calcul passe de 16 à 2.

3.3.3 Résultats et observations

Nous ne présenterons pas ici tous les résultats obtenus au long de notre étude mais seulement quelques uns des plus représentatifs. Pour une plus grande clarté dans ces données, nous les avons consignées dans un tableau et représentées par un histogramme (figure 3.10). Les documents relatifs au code et aux résultats les plus récents sont consultables en annexe de ce rapport.

# Version Observations 1 1.2 Version stable

2 - Suppression du système d'indiçage

3 2.0 Fusion des entités Operation et Permuteur 4 - Fonction de compression remaniée 5 2.1 Mise en place du double décalage 6 2.2 Inclusion de C-M à la permutation 7 - Version finale optimisée # Version Area (slices) Freq (MHz) #Cycles TP (Mbps) TP/Area (kbps/slice) 1 1.2 2310 91,3 150 311 135 2 - 2168 137,7 65 1085 500 3 2.0 2401 147 53 1421 592 4 - 2369 149,3 53 1442 609 5 2.1 2445 98,2 28 1796 734 6 2.2 2112 114 28 2085 987 7 - 2148 134 27 2541 1183

CHAPITRE 3 L'algorithme SHABAL

FIG 3.10 – Evolution des performances de Shabal Evolution des performances de Shabal

3000

2500

2000

1500

1000

500

0 1 2 3 4 5 6 7

Slices (nb) TP (Mbps) TP/slice (kbps/slice)

3.4 SHABAL 3.0 48

3.4 SHABAL 3.0

Un autre organisme, le Laboratoire Lorrain de Recherche en Informatique et ses Applications (LORIA), a proposé une implémentation de Shabal en VHDL fin juillet présentant de très bonnes performances tant au niveau surface que fréquentielles. Nous nous sommes donc mis en relation avec les chercheurs à l'origine de ce code afin de leur proposer une mise en commun de nos optimisations pour en sortir une version optimale.

3.4.1 Description du code VHDL

Le code VHDL de Shabal est écrit de manière à ce que les tours s'enchainent de la meilleure des façons. Il s'agit d'un code "pur", c'est-à-dire sans signaux de contrôle et présente une logique quasi-combinatoire. A chaque coup d'horloge, tous les registres, compteurs et signaux d'état se voient assignés un "état suivant" qui peut varier selon l'état des dits compteurs et signaux d'état.

Ils emploient aussi d'autres astuces pour obtenir un minimum de coups d'horloge par bloc-message traité. Ainsi, les opérations C-M et B+M sont faites en série ( i.e. mot à mot ), en parallèle des 32 derniers cycles d'exécution de la permutation. L'addition de A aux mots de C se fait en parallèle (en 1 cycle d'horloge). Au final, il faut 49 cycles d'horloge pour traiter un bloc-message.

Enfin, à noter qu'ils ne pratiquent pas de tours d’initialisation, mais chargent directement les registres à leur état initial (IV). Voici de façon plus détaillée le fonctionnement de leur implémentation.

CHAPITRE 3 L'algorithme SHABAL 3.4 SHABAL 3.0 49

Permutation P interne de Shabal 3.0

Conditions initiales : <= M M k A <= A ⊕ W <= + <<< B (B M k ) 17 C <= C ; D <= C

Permutation : Cycle 0 : itération de la permutation [...] Cycle 15 : itération de la permutation À ce stade, on a fait 16 itérations de la permutation (soit j = 0)

Cycle 16 : itération de la permutation D <= D 1( to 15 ) & (D )0( − M ))0( [...] Cycle 31 : itération de la permutation D <= D 1( to 15 ) & (D )0( − M ))0( À ce stade, on a fait 32 itération de la permutation (soit j =1) et le registre D contient désormais C – Mk.

Cycle 32 : itération de la permutation <= M M 1( to 15 ) & M k+1 )0( <= − D D 1( to 15 ) & (D )0( M k +1 ))0(

Cycle 33 : itération de la permutation <= M M 1( to 15 ) & M k +1 )1( <= − D D 1( to 15 ) & (D )0( M k+1 ))1( [...] Cycle 47 : itération de la permutation <= M M 1( to 15 ) & M k+1 15( ) <= − D D 1( to 15 ) & (D )0( M k+1 15( )) W + + À ce stade, on a fait 48 itérations de la permutation (soit j = 2), le registre D contient désormais C - Mk + M(k+1), le registre M contient désormais M(k+1), et le registre W vaut désormais k + 1

Cycle 48 : • for i from 0 to 11 do A i)( <= A i)( + C(( i + )3 mod 16 ) + C(( i +11 ) mod 16 ) + C(( i +15 ) mod 16 End do • A <= A ⊕ W • B <= D ; C <= D • B <= (D <<< 17 ) À ce stade, toutes les conditions sont réunies pour lancer le tour suivant; le message est déjà chargé et les registres prêts à entamer la permutation suivante.

CHAPITRE 3 L'algorithme SHABAL 3.4 SHABAL 3.0 50

3.4.2 Résultats

Les résultats des performances de l'implémentation communiqués par le LORIA sont présentés dans le tableau ci-dessous. Ils résultent des mêmes outils, matériel et conditions de synthèse et placement/routage que ceux utilisés pour les résultats vus précédemment :

Area Fréquence #Cycles TP TP/Area (slices) (MHz) (Mbps) (kbps/slice)

990 208.3 49 2177 2199

Afin de vérifier le bon fonctionnement du code, nous avons dû rajouter un signal de contrôle pour l'acquisition des données. En effet, les résultats ci-dessus correspondent exclusivement à la partie calcul de l'algorithme.

3.4.3 L'apport EADS

La principale contribution apportée à l'implémentation détaillée précédemment est l'intégration de la technique du double décalage (cf. chapitre 3.3.2), afin de gagner en TP. En sélectionnant les options d'optimisation en vitesse, on obtient les résultats suivants :

Area Fréquence #Cycles TP TP/Area (slices) (MHz) (Mbps) (kbps/slice)

1171 126.4 25 2588 2210

Nous sommes à ce jour en possession d'une implémentation testée et optimisée (version 3.1), consultable en annexe de ce rapport, ce qui permet donc à Shabal de se placer en bonne position au sein de la compétition SHA-3 (cf. chapitre 4.3.2).

CHAPITRE 3 L'algorithme SHABAL 51

Chapitre 4

Algorithmes concurrents et comparatif

Nous allons, dans ce chapitre, exposer l'étude de quelques autres candidats à la compétition SHA-3. Nous pourrons ainsi comparer leurs performances (à ce jour) à celle de notre algorithme Shabal. Il ne s'agit donc pas ici d'en faire une étude détaillée, mais seulement d'apporter quelques éléments afin d'en faciliter la compréhension à toute personne désireuse d'aller plus loin dans cette démarche. Commençons par faire un bref résumé chronologique des différentes étapes de la compétition.

4.1 Etapes de la compétition

Dans le cadre de la compétition, ce sont en tout plus de 60 propositions qui sont arrivées sur la table du NIST avant le 31 octobre 2008, date limite de participation au concours. Après élimination des algorithmes fantaisistes ou facilement cassables, il en restait 42 pour le premier tour de la compétition.

Le 24 juillet 2009, le NIST a annoncé la liste des 14 "survivants" qui allaient pouvoir passer en demi-finale : BLAKE, Blue Midnight Wish, CubeHash, ECHO, Fugue, Grøstl, Hamsi, JH, Keccak, Luffa, Shabal , SHAvite-3, SIMD, et enfin . Les cryptologues du monde entier ont maintenant un an (jusqu'à la conférence SHA-3 d'août 2010) pour tester les candidats et déceler les failles potentielles avant que ne soit annoncés les deux ou trois participants à la finale.

CHAPITRE 4 Algorithmes concurrents et comparatif 4.2 Algorithmes concurrents 52

4.2 Algorithmes concurrents 4.2.1 CubeHash CubeHash r / b-h est un algorithme développé par Daniel J. Bernstein, qui produit une empreinte de h-bits à partir d'un message de longueur variable. Cette signature dépend de deux paramètres ajustables r et b qui permettent une gamme de possibilités faisant varier le rapport sécurité/performance de l'algorithme. CubeHash est donc défini par trois paramètres :

- b ∈{1, 2, 3,…, 128}, le nombre d'octets dans un bloc message - r ∈ {1, 2, 3,…}, le nombre d'itération de la fonction de compression pour chaque bloc message (8 recommandées). - h ∈ {8, 16, 24,…, 512}, la longueur en bits du message de sortie;

Fonctionnement Le registre d'état interne (1024 bits) est composé de 32 mots de 32 bits, chacun d'entre eux répondant à la convention little-endian : x(t) avec 0<= t <=31.

1. Initialisation . Les mots x(0), x(1) et x(2) prennent respectivement les entiers h/8, b et r. Les mots restants sont mis à 0. On applique la fonction de compression 10 r fois.

2. Mise en forme du message . Le message M est découpé en N b-byte blocs Mi, 0<= i <= N – 1.

3. Compression du message . Le bloc M i est XORé avec les b premiers octets du registre d'état, et la fonction de compression est appliqué au registre d'état r fois. Ces deux étapes sont appliqués à tous les blocs messages.

4. Finalisation et sortie . Une fois le bloc-message M N-1 traité, l'entier 1 est XORé avec le dernier mot du registre d'état et on lui applique à nouveau la fonction de compression 10 r fois. Le message de sortie est composé des h premiers bits du registre d'état.

Fonction de compression Elle est composée des étapes suivantes, la schématique est visible figure 4.1 : - 2 inputs de 512 bits A et B (deux moitiés des 1024 bits formant les mots) - 2x16 additions modulo 2^32 (wbw) - 2x16 32 bit boolean XOR (wbw) - 2x16 rotations. - 4x8 échanges.

CHAPITRE 4 Algorithmes concurrents et comparatif 4.2 Algorithmes concurrents 53

Les sorties A' et B' peuvent être directement réinjectées aux entrées A et B pour l'itération suivante de la fonction de compression si nécessaire.

FIG 4.1 – Schématique de la fonction de permutation de CubeHash Observations le TP de CubeHash est très faible, parce que chaque message block dans cette configuration ne comporte qu'un octet. Les performances de CubeHash sont visibles sur les figures 4.7 et 4.8.

4.2.2 Grøstl

Grøstl est une fonction de hachage itérative développée par Praveen Gauravaram, Lars Knudsen, Krystian Matusiewicz, Florian Mendel, Christian Rechberger, Martin Schläffer, and Søren S. Thomsen. Sa fonction de compression comprend deux grandes permutation distinctes et définies P et Q. Le registre d'état interne est de longueur l.

Elle a de particulier que la longueur du registre d'état interne l varie en fonction de la longueur du message de sortie voulue ( n bits). l=512 pour h=224/256 et l=1024 pour h=384/512.

Fonctionnement

1. Initialisation . les l-bits sont mis à une valeur initiale H -1.

2. Mise en forme du message . Le message M est découpé en N l-byte blocs M i, 0<= i <= N – 1.

3. Compression du message . Chaque bloc message M i est combiné avec le précédent

résultat H i-1 et traité par la permutation P. Dans le même temps, la permutation Q est

CHAPITRE 4 Algorithmes concurrents et comparatif 4.2 Algorithmes concurrents 54

appliquée à M i. La fonction de sortie H i est le résultat d'un XOR entre H i-1, la sortie de P et la sortie de Q comme le montre la figure 4.2.

4. Opération finale . On applique la fonction P(x) XOR x, où x est la valeur finale H N-1. Le résultat (l bits) est tronqué pour obtenir le nombre de bits n désiré au départ.

Fonction de compression Les permutations P et Q sont basées sur le chiffrement par bloc AES, ceci est illustré par la figure 4.3. Chaque entrée est présentée comme une séquence d'octets; placés dans une matrice d'état. Si l = 512, alors on aura une matrice 8 x 8 (8 x 8 x 8bits = 512) et si l = 1024, une matrice 8 x 16. P et Q sont exécutés de façon itérative r fois et comportent quatre étapes de traitement : 1. AddRoundConstant : un octet est ajouté au registre d'état. 2. SubBytes : on applique l'AES S-box à chacun des octets du registre. 3. ShiftBytes : on applique un décalage sur chaque ligne de la matrice. 4. MixBytes : chaque colonne de la matrice d'état est traité en utilisant une multiplication de matrice. Les concepteurs recommandent r = 10 pour Grøstl-224/256 et r = 14 pour Grøstl-384/512.

FIG 4.2 – Fonction de compression de Grøstl FIG 4.3 – Permutations P et Q de Grøstl

CHAPITRE 4 Algorithmes concurrents et comparatif 4.2 Algorithmes concurrents 55

P et Q sont similaires en tous points excepté la valeur de l'octet ajouté lors de la phase AddRoundConstant. Par conséquent on peut exécuter Q en parallèle de P par réplication hardware. Une autre approche consiste à partager le design entre les deux permutations : ainsi, on réutilise le hardware de P pour exécuter Q. Il en résulte logiquement une augmentation du nombre de CLK (fois 2) mais une réduction de la logique.

Autre élément d'optimisation, le stockage des S-boxes peut se faire de deux manières différentes : FPGA slice LUTs ou Block RAM. L'avantage de l'utilisation des BRAMs est la réduction du nombre de slices sans augmentation du nombre de cycles d'horloge puisqu'ils sont synchrones.

Observations On remarque que l'implémentation des S-boxes sur BRAMs améliore la fréquence tout en réduisant le nombre slices. Ceci engendre donc un meilleur rapport TP/area. Les performances de Grøstl sont visibles sur les figures 4.7 et 4.8.

4.2.3 Lane

L'algorithme Lane a été développé par le groupe de recherche COSIC de l'Université Catholique de Louvain, Belgique. Comme Grøstl, la fonction de compression de Lane comporte des éléments de chiffrement par bloc AES. La longueur du registre d'état interne l varie en fonction de la longueur du message de sortie voulue ( n bits). l=256 pour h=224/256 et l=512 pour h=384/512.

Fonctionnement 1. Initialisation . On traite un message de type string prédéterminé avec la fonction de

compression : H -1. On peut effectuer un salage à ce niveau. 2. Mise en forme du message . Le message M est découpé en N 512-bits blocs Mi. (et "zeros-padded") pour Lane 224/256 (1024-bits blocs pour Lane 384/512).

3. Compression du message . Chaque bloc message est combiné avec H i-1 et traité avec un certain nombre de tours (contrôlés par un compteur) de transformations basées sur le chiffrement AES.

CHAPITRE 4 Algorithmes concurrents et comparatif 4.2 Algorithmes concurrents 56

4. Finalisation et sortie. On repasse H N-1 dans la fonction de compression avec le message d'entrée type string composé de la longueur du message et, optionnellement, d'une valeur aléatoire (salage).

Fonction de compression Un diagramme de la fonction de compression est visible figure 4.4. Elle démarre avec une expansion du message où M i est combiné avec H i-1 et comprend des XOR et concaténations successifs. Le résultat de cette étape se compose de 6 mots de 256 bits.

FIG 4.4 – Fonction de compression de Lane

Le reste de la fonction se compose de 5 XORs et huit lignes de permutations : P i (6) et

Qj (2) exécuté séquentiellement. Chacune d'entre elles reprend un certain nombre d'éléments du chiffrement par bloc AES : SubBytes, ShiftRows, MixColumns, AddConstant, SwapColumns comme le montre la figure 4.5.

FIG 4.5 – Schématique de la permutation P i /Qj de Lane

CHAPITRE 4 Algorithmes concurrents et comparatif 4.2 Algorithmes concurrents 57

En ce qui concerne l'implémentation de la fonction de compression, on peut largement utiliser le parallélisme évident du design. Si l'on veut favoriser la vitesse d'exécution en dépit de la surface logique, on utilisera 6 circuits de permutation P i. Deux de ces circuits peuvent ensuite servir pour Q j. A l'inverse, pour diminuer l'espace logique, on implémentera un seul circuit de permutation. Les tableaux de résultats présentent 3 types d'approche en fonction du nombre de circuits de permutation implémentés en parallèle.

Observations Lane a été officiellement éliminé de la compétition SHA-3 au second tour le 24 juillet 2009. Les performances de Lane sont visibles sur les figure 4.7 et 4.8.

4.2.4 Spectral Hash

Cette fonction a été développée par Gokay Saldamlı, Cevahir Demirkıran, Megan Maguire, Carl Minden, Jacob Topper, Alex Troesch, Cody Walker, Çetin Kaya Koç. Basée sur la construction de Merkle-Damgård, elle dernière utilise la transformée de Fourrier discrète pour satisfaire les critères de diffusion.

Fonctionnement

La fonction de compression de l'algorithme prend en argument le bloc message M i, le résultat du hachage du précédent message H i-1 mais aussi un état interne de la permutation Pi dépendant de la compression précédente. Il est composé de registres, appelés prismes, et est représenté par 4 x 4 x 8 matrices de différentes tailles de mots.

1. Mise en forme du message et initialisation . Le message est découpé en t blocs de 512 bits. On crée un p-prism de mots de 7 bits, initialisé avec les valeurs de 0 à 127. Les

mots de p-prism sont ensuite échangés selon les valeurs des mots de M 1. Le résultat de l'état précédent sont mis à 0 et stocké dans h-prism.

2. Compression du message . M i est placé dans un s-prism de mots de 4 bits, et traité avec

Hi-1 et Pi.

CHAPITRE 4 Algorithmes concurrents et comparatif 4.2 Algorithmes concurrents 58

3. Finalisation et sortie . Une fois tous les blocs messages traités, on prélève le nombre de bits désirés de h-prism.

Fonction de compression Une représentation de la fonction de compression est visible figure 4.6. Deux approches ont été effectuée : l'une "classique" et l'autre en parallélisme total, ce qui a pour conséquence d'alourdir considérablement la logique.

FIG 4.6 – Schématique de la fonction de compression de Spectral Hash

Observations Spectral Hash a été officiellement éliminé de la compétition SHA-3 au second tour le 24 juillet 2009. Les performances de Spectral Hash sont visibles au chapitre 4.3.2.

CHAPITRE 4 Algorithmes concurrents et comparatif 4.3 Comparatif 59

4.3 Comparatif 4.3.1 Eléments de comparaison Comme nous l'avons vu précédemment (cf. chapitre 3.3.1), les éléments de comparaison seront la surface sur cible, le débit en sortie – donné par la fréquence maximale de fonctionnement et le nombre de cycle pour une longueur de message-bloc donnée – et le rapport des deux (TP/slice).

Nous avons eu accès ces dernières semaines à d'autres résultats d'implémentations FPGA d'autres algorithmes ayant passés le second tour de la compétition. Nous avons donc consigné les plus significatifs de ces résultats avec ceux déjà en notre possession (même type d'implémentation, même FPGA). Ainsi, notre panel comparatif s'élargit d'autant. A noter que nous ne nous intéresserons à ce stade aux seuls algorithmes retenus pour le second tour. C'est pourquoi les résultats de Lane et Spectral Hash seront donnés mais non représentés.

Nous proposons à ce jour deux types d'implémentation : une "High-Speed Implementation" et une "Low-Area Implementation". En effet, l'un des objectifs de le compétition est de démontrer la modularité de notre algorithme, c'est-à-dire sa capacité à s'adapter à un cahier des charges données : un meilleur débit pour une logique plus importante, ou bien une logique plus petite avec un débit de fait plus faible.

4.3.2 Représentations et observations. High-Speed Implementation Ici, il s'agit donc de comparer les implémentations "optimisées vitesse" de chaque algorithme. Le tableau des performances est visible figure 4.7. Afin de clarifier la lecture des résultats, nous avons décidé de procéder de la façon suivante : - Le premier graphe (figure 4.8) représente le nombre de slices utilisés ainsi que le TP de chaque algorithme. - Le second graphe (figure 4.9) ne présente que le TP/area (kbps/slice) de chaque algorithme, puisque ce paramètre nous renseigne sur l'efficacité hardware de chacun d'eux, c'est-à-dire le débit maximum qu'il peut nous offrir pour une surface donnée.

Les résultats des performances de Shabal (version HSI) données par Synthèse/Placement- routage Xilinx ISE sont consultables en annexe de ce rapport.

CHAPITRE 4 Algorithmes concurrents et comparatif 4.3 Comparatif 60

Low-Area Implementation

Le deuxième axe de comparaison est donc d'observer les performances de chaque algorithme pour une surface occupée minimale. N'ayant pas beaucoup de données à ce jour concernant les autres algorithmes qualifiés, il nous faut garder un certain recul, même si cela peut nous apporter une première idée. Ces résultats sont visibles figure 4.10 et représentées sur la figure 4.11. A noter que nous avons utilisé l'implémentation avec simple décalage pour cette partie (cf. chapitre 3.4).

Les résultats des performances de Shabal (version LAI) données par Synthèse/Placement- routage Xilinx ISE sont consultables en annexe de ce rapport.

Observations

A la lecture de ces graphes, on peut affirmer en terme purement hardware que Shabal se situe en haut du tableau des algorithmes dont nous possédons les résultats d'implémentation. Il propose un bon débit en sortie et ce pour une faible surface d'occupation sur cible. En conséquent, il se place dans les algorithmes les plus efficaces.

Il ne faut cependant pas oublier que l'autre critère principal de sélection reste la fiabilité des algorithmes et que ces résultats interviendront justement pour départager ceux qui resteront après les multiples tentatives de "craquage".

En ce qui concerne notre algorithme sur ce point, l'équipe de Jean-Philippe Aumasson (Blake) a démontré que la permutation interne de Shabal n'est pas parfaitement aléatoire. Ainsi, ils ont pu trouvé un distingueur en utilisant "Cube Attack". Toutefois, il n'en résulte aucune d'attaque pour le moment.

CHAPITRE 4 Algorithmes concurrents et comparatif 61

# Algorithme Area (slices) Max. Freq. (Mhz) # Cycles TP (Mbps) TP/Area (kbps/slice) 1 CubeHash 8/1 1 178 167 8 167 142 2 Grostl-224/256 – BRAM (1) 3 184 250 20 6 411 2 013 3 Grostl-224/256 – BRAM – Parallel (1) 4 516 143 10 7 315 1 620 4 Grostl-384/512 – BRAM 6 368 144 28 5 267 827 5 Grostl-384/512 – Slice LUTs (1) – Parallel 19 161 83 14 6 093 318 6 Shabal 1 171 126 25 2 588 2 210 7 Blake-32 1 694 67 - 3 103 1 831 8 Blake-64 4 329 35 - 2 389 552 9 Skein-256 (2) 937 68 - 1 751 1 869 10 Skein-512 (2) 1 632 69 - 3 535 2 166 11 ECHO-224/256 (2) 9 333 84 - 14 860 1 592 12 ECHO-384/512 (2) 9 097 88 - 7 810 858 13 Keccak (2) 1 412 122 - 6 900 4 887 - Lane-384/512 - 2 Parallel Pi units 4 030 116 35 3 394 842 - Lane-384/512 - 6 Parallel Pi units 14 649 70 17 4 204 287 - Spectral Hash - Low Area 9 051 125 339 189 21 - Spectral Hash - Single Cycle 26 444 49 1 25 103 949

FIG 4.7 – High-Speed Implementation Results

(1) cf. chapitre 5.2.2 – Fonction de compression (2) Fully autonomous : inclus aussi le système d'interface

62

PerformancesFIG 4.8 – Performances des algorithmes des algorithmes de de hachage hachage (High-Speed Implementation)

20 000

18 000

16 000

14 000

12 000

Slices (nb) 10 000 TP (Mbps)

8 000

6 000

4 000

2 000

0 1 2 3 4 5 6 7 8 9 10 11 12 13

63

FIG 4.9 Throughput– TP/slice des algorithmes par slice de hachage (High-Speed Implementation)

5000

4500

4000

3500

3000

2500

2000 TP/slice (kbps/slice) 1500

1000

500

0 1 2 3 4 5 6 7 8 9 10 11 12 13 Algorithme

64

# Algorithme Area (slices) Max. Freq. (Mhz) # Cycles TP (Mbps) TP/Area (kbps/slice)

6 Shabal 596 109 49 1 142 1 916

7 Blake-32 390 91 - 575 1 474

8 Blake-64 939 59 - 533 568

13 Keccak 444 265 - 70 597

FIG 4.10 – Low-Area Implementation Results

65

FIG 4.11 – Performances des algorithmes de hachage (Low-Area Implementation Results)

2 000

1 800

1 600

1 400

1 200

Slices (nb) 1 000 TP (Mbps) TP/slice (kbps/slice)

800

600

400

200

0 6 7 8 13

66

Conclusion

Au terme de ce stage, l'entreprise EADS dispose dans le cadre du projet Saphir² d'une étude hardware de l'algorithme de hachage Shabal. De plus, elle dispose à ce jour d'une implémentation compétitive présentant des résultats testés et validés, ce qui lui permet d'augmenter d'autant plus ses chances de devenir le nouveau standard mondial de hachage.

Cette expérience fut pour moi l'occasion de mettre en pratique mes capacités de raisonnement, de travail et de créativité. Le fait de travailler "à cheval" entre deux mondes distincts – la cryptologie et l'électronique hardware – m'a fait prendre conscience de la disparité des objectifs selon le point du vue des acteurs et de la nécessité pour un ingénieur aujourd'hui de diversifier au quotidien son champ de connaissances et d'action.

En outre, mes capacités d'autonomie furent mises à rude épreuve, puisque ne faisant pas partie d'une équipe, j'ai dû m'organiser en conséquence. J'ai aussi pu constater et me plier aux mécanismes complexes d'un grand groupe.

Le climat de compétition fut aussi un véritable enrichissement. En effet, Shabal peut à tout moment être éliminé de la compétition; ceci rajoute donc une contrainte supplémentaire mais procure un engouement particulier dans la démarche de recherche.

67

Ressources bibliographiques

[1] Jean-René R EINHARD : Sécurité et Analyse des Primitives de Hachage Innovantes et Récentes – Analyse des Attaques Existantes . 2006

[2] Pierre-Alain F OUQUE , Gilles P IRET : Sécurité et Analyse des Primitives de Hachage Innovantes et Récentes – Etat de l’art sur les constructions de fonctions de hachage . 2007

[3] Pierre-Alain F OUQUE : Sécurité et Analyse des Primitives de Hachage Innovantes et Récentes – Synthèse des nouvelles conceptions . 2009

[4] Anne C ANTEAUT , Benoît C HEVALLIER -MAMES , Aline G OUGET , Pascal P AILLIER , Thomas P ORNIN : Shabal, a Submission to NIST's Cryptographic Hash Algorithm Competition . 2008

[5] Gaëtan L EURENT : SIMD Is a Message Digest . 2009

[6] Brian B ALDWIN , Andrew B YRNE , Mark H AMILTON , Neil H ANLEY , Robert P. M CEVOY , Weibo P AN and William P. M ARNANE – Claude Shannon Institute for Discrete Mathematics, Coding and .Department of Electrical & Electronic Engineering,University College Cork, Cork, IRELAND : FPGA implementation of SHA3 candidates . 2009

[7] Xilinx ISE : Software Manuals . ( XST User Guide …) Documentation Viretx-4 et Virtex-5

[8] Daniel G ENET : Conception synchrone . 2005

[9] Daniel G ENET : Initiation au langage VHDL . 2006

[10] Encyclopédie en ligne : http://fr.wikipedia.org

[11] Sébastien V ARRETTE : Fonctions de Hachage et Signatures Electroniques. 2008

[12] Daniel J. B ERNSTEIN : CubeHash Specifications. 2008

[13] Sebastiaan I NDESTEEGE , Elena A NDREEVA , Christophe De C ANNIERE , Orr DUNKLEMAN , Emilia K ASPER , Svetla N IKOVA , Bart P RENEEL , and Elmar T ISCHHAUSER : The Lane Hash Function – Extended Abstract. 2008

68

Annexe A

Code VHDL Shabal 2.2

A.1 Package.vhd : Contient le package necessaire à la definition de nos registres. library ieee ; use ieee .std_logic_1164 .all; use ieee .numeric_std .all; package addition_types is type std_logic_vector_31d0_array_15d0 is array ( 15 downto 0) of std_logic_vector (31 downto 0); type std_logic_vector_31d0_array_11d0 is array ( 11 downto 0) of std_logic_vector (31 downto 0); type std_logic_vector_31d0_array_7d0 is array ( 7 downto 0) of std_logic_vector (31 downto 0); type std_logic_vector_31d0_array_1d0 is array ( 1 downto 0) of std_logic_vector (31 downto 0); type unsigned_31d0_array_15d0 is array ( 15 downto 0) of unsigned (31 downto 0); end addition_types ;

69

A.2 System.vhd : Bloc global integrant le bloc d'interface et le bloc de hash library ieee ; use ieee .std_logic_1164 .ALL; use ieee .std_logic_signed .ALL; use ieee .numeric_std .all; use work .addition_types .all; ------entity System is port( QUARTZ : in std_logic ; RST_I : in std_logic ; WE_I : in std_logic ; DATA : in std_logic_vector (31 downto 0); WE_O : out std_logic ; DATA_OUT : out std_logic_vector (31 downto 0) ); end System ;

------architecture Behavioral of System is

component PREBLOC_32BITS is port( CLK_I : in std_logic ; RST_I : in std_logic ; WE_I : in std_logic ; DATA : in std_logic_vector (31 downto 0); RDY : in std_logic ; FINISH : in std_logic ; DAT_O : in std_logic_vector_31d0_array_15d0 ; START : out std_logic ; DAT_I : out std_logic_vector_31d0_array_15d0 ; DATA_OUT : out std_logic_vector (31 downto 0); WE_O : out std_logic ); end component;

component HASH is port( CLK_I : in std_logic ; RST_I : in std_logic ; START : in std_logic ; DAT_I : in std_logic_vector_31d0_array_15d0 ; RDY : out std_logic ; FINISH : out std_logic ; DAT_O : out std_logic_vector_31d0_array_15d0 ); end component;

------signal CLK_I : std_logic; signal START : std_logic ; signal DAT_I : std_logic_vector_31d0_array_15d0 ; signal RDY : std_logic ; signal FINISH : std_logic ; signal DAT_O : std_logic_vector_31d0_array_15d0 ;

------begin

U0 : PREBLOC_32BITS port map( CLK_I ,RST_I ,WE_I ,DATA ,RDY ,FINISH ,DAT_O ,START ,DAT_I ,DATA_OUT ,WE_O ); U1 : HASH port map( CLK_I ,RST_I ,START ,DAT_I ,RDY ,FINISH ,DAT_O );

P_CLK_I : process ( QUARTZ ) begin if QUARTZ' event and QUARTZ = '1' then CLK_I <= not CLK_I; end if; end process P_CLK_I ; end Behavioral ;

70

A.3 Prebloc_32bits.vhd : Bloc de gestion des donnees provenant du bus d'entree 32 bits library ieee ; use ieee .std_logic_1164 .ALL; use ieee .numeric_std .all; use work .addition_types .all;

------entity Prebloc_32bits is generic ( WIDTH : integer := 32 ); -- détermine la largeur du magasin port( CLK_I : in std_logic ; RST_I : in std_logic ; WE_I : in std_logic ; DATA : in std_logic_vector (31 downto 0); RDY : in std_logic ; FINISH : in std_logic ; DAT_O : in std_logic_vector_31d0_array_15d0 ; START : out std_logic ; DAT_I : out std_logic_vector_31d0_array_15d0 ; DATA_OUT : out std_logic_vector (31 downto 0); WE_O : out std_logic ); end Prebloc_32bits ;

------architecture rtl of Prebloc_32bits is constant SRL_LENGTH : integer := 16 ; -- détermine la longueur du magasin constant POINTER_VEC : integer := 4; -- détermine le nb de bits pour le pointeur sur magasin type srl_array is array ( srl_length - 1 downto 0 ) of std_logic_vector ( 31 downto 0 ); signal STORE_IN : srl_array; signal POINTER_IN : integer range 0 to srl_length ; signal POINTER_IN_FULL : std_logic ; signal VALID_WRITE_IN : std_logic ; signal POINTER_OUT : integer range 0 to srl_length ;--srl_length downto 0; signal POINTER_OUT_FULL : std_logic ; begin

-- Valid write in - permet l'ecriture dans le magasin d'entree à l'etat haut

VALID_WRITE_IN <= '1' when ( WE_I = '1' and POINTER_IN_FULL = '0' ) else '0' ;

------

-- Mise en magasin d'entree et gestion du pointeur sur magasin

DATA_IN_SRL :process( CLK_I , RST_I ) begin

if RST_I = '1' then POINTER_IN <= 0; elsif rising_edge( CLK_I ) then

if VALID_WRITE_IN = '1' then STORE_IN (POINTER_IN ) <= DATA ; POINTER_IN <= POINTER_IN + 1; elsif POINTER_IN_FULL <= '0' and POINTER_IN /= 0 then STORE_IN (POINTER_IN ) <= x"00000000" ; POINTER_IN <= POINTER_IN + 1; end if;

if POINTER_IN_FULL <= '1' and WE_I = '1' and RDY = '1' then POINTER_IN <= 0; end if; end if; end process;

------

-- Mise en magasin de sortie et gestion du pointeur sur magasin

DATA_OUT_SRL :process( CLK_I , RST_I ) begin

if RST_I = '1' then POINTER_OUT <= 0; elsif rising_edge( CLK_I ) then

if FINISH = '1' and DAT_O (POINTER_OUT ) /= x"00000000" and POINTER_OUT_FULL = '0' then DATA_OUT <= DAT_O (POINTER_OUT ); POINTER_OUT <= POINTER_OUT + 1;

71

end if;

if POINTER_OUT_FULL = '1' then DATA_OUT <= DAT_O (SRL_LENGTH -1); end if; end if; end process;

------

-- Gestion des permissions de lecture/écriture et mise à disposition des donnees

WE_O <= '1' when RDY = '0' and WE_I = '1' and POINTER_IN_FULL = '0' else '0' ; START <= '1' when POINTER_IN_FULL = '1' else '0' ; POINTER_IN_FULL <= '1' when POINTER_IN = SRL_LENGTH else '0' ; POINTER_OUT_FULL <= '1' when POINTER_OUT = SRL_LENGTH -1 else '0' ; DAT_I <= std_logic_vector_31d0_array_15d0 (STORE_IN ); end rtl ;

72

A.4 Hash.vhd : Bloc generique de la routine de cryptage library ieee ; use ieee .std_logic_1164 .ALL; use ieee .std_logic_signed .ALL; use ieee .numeric_std .all; use work .addition_types .all;

------entity Hash is port( CLK_I : in std_logic ; RST_I : in std_logic ; START : in std_logic ; DAT_I : in std_logic_vector_31d0_array_15d0 ; RDY : out std_logic ; FINISH : out std_logic ; DAT_O : out std_logic_vector_31d0_array_15d0 ); end Hash ;

------architecture Behavioral of Hash is

component SEQUENCEUR is port( CLK_I : in std_logic ; RST_I : in std_logic ; INIT : in std_logic ; START : in std_logic ; N0_FINAL : in integer range 0 to 3; TERM : in std_logic ; ETAT : out integer range 0 to 5); end component;

component OPERATION is port( CLK_I : in std_logic ; ETAT : in integer range 0 to 5; DAT_I : in std_logic_vector_31d0_array_15d0 ; FINISH : out std_logic ; DAT_O : out std_logic_vector_31d0_array_15d0 ; RDY : out std_logic ; INIT : out std_logic ; TERM : out std_logic ; N0_FINAL : out integer range 0 to 3); end component;

------signal ETAT : integer range 0 to 5; signal N0_FINAL : integer range 0 to 3; signal INIT : std_logic ; signal TERM : std_logic ;

------begin

U0 : SEQUENCEUR port map( CLK_I ,RST_I ,INIT ,START ,N0_FINAL ,TERM ,ETAT ); U1 : OPERATION port map( CLK_I ,ETAT ,DAT_I ,FINISH ,DAT_O ,RDY ,INIT ,TERM ,N0_FINAL ); end Behavioral ;

73

A.5 Sequenceur.vhd : Bloc de sequencement de la routine de cryptage.

library ieee ; use ieee .std_logic_1164 .ALL; use ieee .std_logic_signed .ALL; use ieee .numeric_std .all; use work .addition_types .all;

------entity Sequenceur is port( CLK_I : in std_logic ; RST_I : in std_logic ; INIT : in std_logic ; START : in std_logic ; N0_FINAL : in integer range 0 to 3; TERM : in std_logic ; ETAT : out integer range 0 to 5 ); end Sequenceur ;

------architecture Behavioral of Sequenceur is signal ETAT_IN : integer range 0 to 5; begin

ETAT <= ETAT_IN ;

P_SEQUENCEUR :process( CLK_I ,RST_I ,START ,TERM ,N0_FINAL ,INIT ) begin if RST_I = '1' then ETAT_IN <= 0; elsif rising_edge( CLK_I ) then

case ETAT_IN is

when 0 => ETAT_IN <= 1;

-- Condition de départ d'un cycle de hash d'un message entrant when 1 => if START = '1' or (N0_FINAL /= 0) or INIT = '0' then ETAT_IN <= 2; end if;

when 2 => ETAT_IN <= 3;

-- Condition d'arrêt de la routine de permutation when 3 => if TERM = '1' then ETAT_IN <= 4; else ETAT_IN <= 3; end if;

-- Condition d'arret de la routine de finalisation when 4 => if ( N0_FINAL = 3) then ETAT_IN <= 5; elsif INIT = '0' then ETAT_IN <= 1; else ETAT_IN <= 1; end if;

when others =>

end case; end if; end process P_SEQUENCEUR ; end Behavioral ;

74

A.6 Operation.vhd : Bloc de gestion des registres principaux de l'algorithme de cryptage. library ieee ; use ieee .std_logic_1164 .ALL; use ieee .std_logic_signed .ALL; use ieee .numeric_std .all; use work .addition_types .all;

entity Operation is port ( CLK_I : in std_logic ; ETAT : in integer range 0 to 5; DAT_I : in std_logic_vector_31d0_array_15d0 ; FINISH : out std_logic ; DAT_O : out std_logic_vector_31d0_array_15d0 ; RDY : out std_logic ; INIT : out std_logic ; TERM : out std_logic ; N0_FINAL : out integer range 0 to 3 ); end Operation ; architecture Behavioral of Operation is constant SM : integer := 16 ; constant NR : integer := 12 ; constant LOH : integer := 256 ; signal A_IN : std_logic_vector_31d0_array_11d0 ; signal B_IN : std_logic_vector_31d0_array_15d0 ; signal C_IN : std_logic_vector_31d0_array_15d0 ; signal M_IN : std_logic_vector_31d0_array_15d0 ; signal W_IN : std_logic_vector_31d0_array_1d0 ; signal AUX : std_logic_vector_31d0_array_15d0 ; signal N0_FINAL_IN : integer range 0 to 3; signal INIT_IN : std_logic ; signal COMPTEUR : integer range 0 to 25 ; begin N0_FINAL <= N0_FINAL_IN ; INIT <= INIT_IN ;

-- Gestion des donnees en sortie

P_OPTODAT_O :process( CLK_I ) begin if rising_edge( CLK_I ) then case ETAT is when 0 => for i in DAT_O' RANGE loop -- Initialisation DAT_O (i) <= x"00000000" ; end loop; FINISH <= '0' ;

when 5 => for i in 0 to ( LOH /32 )-1 loop -- DAT_O reçoit la signature DAT_O (( LOH /32 ) -1 - i) <= C_IN (15 - i); end loop; FINISH <= '1' ; -- provenant de C

when others => end case; end if; end process P_OPTODAT_O ;

-- Operations sur les registres A et B

P_OPTOAB :process( CLK_I ) variable A_TEMP : std_logic_vector (31 downto 0); begin if rising_edge( CLK_I ) then case ETAT is when 0 => for i in A_IN' RANGE loop -- Initialisation des registres A_IN (i) <= x"00000000" ; end loop; for i in B_IN' RANGE loop B_IN (i) <= x"00000000" ; end loop;

when 2 => for i in W_IN' RANGE loop -- A xor W A_IN (i) <= A_IN (i) xor W_IN (i) end loop;

for i in B_IN' RANGE loop -- Ajout de M à B B_IN (i) <= to_stdlogicvector(to_bitvector( B_IN (i)+ M_IN (i)) rol 17 );

75

end loop;

TERM <= '0' ; COMPTEUR <= 0;

when 3 => if ( COMPTEUR = 22 ) then TERM <= '1' ; -- TERM à 1 et on incrémente une dernière fois le compteur de la boucle. COMPTEUR <= COMPTEUR + 1; else COMPTEUR <= COMPTEUR + 1; end if;

En raison de l'importante longueur des lignes suivantes, la suite du code se trouve à la page suivante.

76

A_IN (10 ) <= ((to_stdlogicvector(to_bitvector( (to_stdlogicvector((to_bitvector( A_IN (11 )) rol 15 ) sll 2 ) + to_stdlogicvector(to_bitvector( A_IN (11 )) rol 15 )) xor A_IN (0) xor C_IN (8)) sll 1 ) + ((to_stdlogicvector((to_bitvector( A_IN (11 )) rol 15 ) sll 2 ) + to_stdlogicvector(to_bitvector( A_IN (11 )) rol 15 )) xor A_IN (0) xor C_IN (8))) xor M_IN (0)) xor (B_IN (13 ) xor to_stdlogicvector(to_bitvector( B_IN (9)) and (to_bitvector( B_IN (6)) xor x"FFFFFFFF" )));

A_TEMP := ((to_stdlogicvector(to_bitvector( (to_stdlogicvector((to_bitvector( A_IN (11 )) rol 15 ) sll 2 ) + to_stdlogicvector(to_bitvector( A_IN (11 )) rol 15 )) xor A_IN (0) xor C_IN (8)) sll 1 ) + ((to_stdlogicvector((to_bitvector( A_IN (11 )) rol 15 ) sll 2 ) + to_stdlogicvector(to_bitvector( A_IN (11 )) rol 15 )) xor A_IN (0) xor C_IN (8))) xor M_IN (0)) xor (B_IN (13 ) xor to_stdlogicvector(to_bitvector( B_IN (9)) and (to_bitvector( B_IN (6)) xor x"FFFFFFFF" )));

B_IN (14 ) <= ((((to_stdlogicvector(to_bitvector( (to_stdlogicvector((to_bitvector( A_IN (11 )) rol 15 ) sll 2 ) + to_stdlogicvector(to_bitvector( A_IN (11 )) rol 15 )) xor A_IN (0) xor C_IN (8)) sll 1 ) + ((to_stdlogicvector((to_bitvector( A_IN (11 )) rol 15 ) sll 2 ) + to_stdlogicvector(to_bitvector( A_IN (11 )) rol 15 )) xor A_IN (0) xor C_IN (8))) xor M_IN (0)) xor (B_IN (13 ) xor to_stdlogicvector(to_bitvector( B_IN (9)) and (to_bitvector( B_IN (6)) xor x"FFFFFFFF" )))) xor x"FFFFFFFF" ) xor (to_stdlogicvector(to_bitvector( B_IN (0)) rol 1 ));

A_IN (11 ) <= ((to_stdlogicvector(to_bitvector( (to_stdlogicvector((to_bitvector( A_TEMP ) rol 15 ) sll 2 ) + to_stdlogicvector(to_bitvector( A_TEMP ) rol 15 )) xor A_IN (1) xor C_IN (7)) sll 1 ) + ((to_stdlogicvector((to_bitvector( A_TEMP ) rol 15 ) sll 2 ) + to_stdlogicvector(to_bitvector( A_TEMP ) rol 15 )) xor A_IN (1) xor C_IN (7))) xor M_IN (1)) xor (B_IN (14 ) xor to_stdlogicvector(to_bitvector( B_IN (10 )) and (to_bitvector( B_IN (7)) xor x"FFFFFFFF" )));

B_IN (15 ) <= (((to_stdlogicvector(to_bitvector( (to_stdlogicvector((to_bitvector( A_TEMP ) rol 15 ) sll 2 ) + to_stdlogicvector(to_bitvector( A_TEMP ) rol 15 )) xor A_IN (1) xor C_IN (7)) sll 1 ) + ((to_stdlogicvector((to_bitvector( A_TEMP ) rol 15 ) sll 2 ) + to_stdlogicvector(to_bitvector( A_TEMP ) rol 15 )) xor A_IN (1) xor C_IN (7))) xor M_IN (1)) xor (B_IN (14 ) xor to_stdlogicvector(to_bitvector( B_IN (10 )) and (to_bitvector( B_IN (7)) xor x"FFFFFFFF" ))) xor x"FFFFFFFF" ) xor (to_stdlogicvector(to_bitvector( B_IN (1)) rol 1 ));

77

A_IN (9 downto 0) <= A_IN (11 downto 2); -- Double décalage de A B_IN (13 downto 0) <= B_IN (15 downto 2); -- Double décalage de B

when 4 => -- Soustraction de C à A A_IN (0) <= A_IN (0) + C_IN (3) + C_IN (11 ) + C_IN (15 ); A_IN (1) <= A_IN (1) + C_IN (4) + C_IN (12 ) + C_IN (0); A_IN (2) <= A_IN (2) + C_IN (5) + C_IN (13 ) + C_IN (1); A_IN (3) <= A_IN (3) + C_IN (6) + C_IN (14 ) + C_IN (2); A_IN (4) <= A_IN (4) + C_IN (7) + C_IN (15 ) + C_IN (3); A_IN (5) <= A_IN (5) + C_IN (8) + C_IN (0) + C_IN (4); A_IN (6) <= A_IN (6) + C_IN (9) + C_IN (1) + C_IN (5); A_IN (7) <= A_IN(7) + C_IN (10 ) + C_IN (2) + C_IN (6); A_IN (8) <= A_IN (8) + C_IN (11 ) + C_IN (3) + C_IN (7); A_IN (9) <= A_IN (9) + C_IN (12 ) + C_IN (4) + C_IN (8); A_IN (10 ) <= A_IN (10 ) + C_IN (13 ) + C_IN (5) + C_IN (9); A_IN (11 ) <= A_IN (11 ) + C_IN (14 ) + C_IN (6) + C_IN (10 );

B_IN <= AUX ; -- B prend le registre auxilaire when others => end case; end if; end process P_OPTOAB ;

-- Operations sur le registre C

P_OPTOC :process( CLK_I , COMPTEUR ) begin if rising_edge( CLK_I ) then case ETAT is when 0 => -- Initialisation de C for i in C_IN' RANGE loop C_IN (i) <= x"00000000" ; end loop;

when 2 => AUX <= C_IN ;

when 3 => -- Double décalage de C C_IN <= C_IN (13 downto 0) & C_IN (15 ) & C_IN (14 );

-- Double soustraction et décalage de AUX if ( COMPTEUR >= 8) and (COMPTEUR < 16 ) then AUX <= ( AUX (1)-M_IN (1)) & (( AUX (0)-M_IN (0)) & AUX (15 downto 2)); end if;

when 4 => C_IN <= B_IN ; -- C reçoit le contenu de B

when others => end case; end if; end process P_OPTOC ;

-- Operations sur le registre M

P_OPTOM :process( CLK_I ,DAT_I ) begin if ( CLK_I' event and CLK_I ='1' ) then case ETAT is when 0 => RDY <= '0' ;

when 1 => -- Initialisation de M pour les cycles de départ if INIT_IN = '0' then for i in sM -1 downto 0 loop M_IN (i) <= ( LOH + i + to_stdlogicvector(to_bitvector( W_IN (0) + x"00000001" ) sll 4 )); end loop; else M_IN <= DAT_I ; -- M prend les données en entrée RDY <= '1' ; -- La routine signale qu'elle prend les valeurs en entrée end if;

when 2 => RDY <= '0' ;

when 3 => -- Double décalage de M M_IN <= M_IN (1) & ( M_IN (0) & M_IN (15 downto 2));

when others => end case; end if; end process P_OPTOM ;

-- Operations sur le registre W - Gestion des indicateurs INIT et F0_FINAL

P_OPTOW :process( CLK_I ) begin if rising_edge( CLK_I ) then case ETAT is when 0 => for i in W_IN' RANGE loop -- Initialisation de W

78

W_IN (i) <= x"FFFFFFFF" ; end loop; N0_FINAL_IN <= 0; INIT_IN <= '0' ;

when 4 => if W_IN (0) = x"00000000" then INIT_IN <= '1' ; end if;

if ( W_IN (0)/= x"00000002" ) then -- Condition d'incrémentation du compteur if ( W_IN (1) = x"FFFFFFFF" ) then W_IN (1) <= W_IN (1) + "000000000000001" ; end if; W_IN (0) <= W_IN (0) + x"00000001" ;

elsif N0_FINAL_IN /= 3 then -- Condition d'incrémentation du compteur final N0_FINAL_IN <= N0_FINAL_IN + 1; end if;

when others => end case; end if; end process P_OPTOW ; end Behavioral ;

79

Annexe B

Résultats Shabal 2.2

80

Annexe C

Code VHDL Shabal 3.1

library ieee ; use ieee .std_logic_1164 .all; use ieee .numeric_std .all; entity shabal is port ( din : in unsigned (63 downto 0); --Entrée 64 bits dout : out unsigned (31 downto 0); --Sortie 32 bits last : in std_logic ; --Indicateur de fin de message rst : in std_logic ; -- Reset clk : in std_logic; -- Clock we : out std_logic -- Write Enable ); end entity; architecture arch of shabal is

subtype word32 is unsigned (31 downto 0); type word32_vector is array( natural range <>) of word32 ;

-- Initialization Vectors constant init_a : word32_vector (0 to 11 ) := ( X"20728DFC" , X"46C0BD53" , X"E782B699" , X"55304632" , X"71B4EF90" , X"0EA9E82C" , X"DBB930F1" , X"FAD06B8B" , X"BE0CAE40" , X"8BD14410" , X"76D2ADAC" , X"28ACAB7F" );

constant init_b : word32_vector (0 to 15 ) := ( X"C1099CB7" , X"07B385F3" , X"E7442C26" , X"CC8AD640" , X"EB6F56C7" , X"1EA81AA9" , X"73B9D314" , X"1DE85D08" , X"48910A5A" , X"893B22DB" , X"C5A0DF44" , X"BBC4324E" , X"72D2F240" , X"75941D99" , X"6D8BDE82" , X"A1A7502B" );

constant init_c : word32_vector (0 to 15 ) := ( X"D9BF68D1" , X"58BAD750" , X"56028CB2" , X"8134F359" , X"B5D469D8" , X"941A8CC2" , X"418B2A6E" , X"04052780" , X"7F07D787" , X"5194358F" , X"3C60D665" , X"BE97D79A" , X"950C3434" , X"AED9A06D" , X"2537DC8D" , X"7CDB5969" );

type state_t is ( sInit , sRun , sLast );

signal state : state_t := sInit ; signal step : natural range 0 to 3 := 2; signal cnt : unsigned (2 downto 0) := "000" ; signal lcnt : unsigned (1 downto 0) := "00" ;

signal w : unsigned (63 downto 0) := to_unsigned( 0, 64 ); signal a : word32_vector (0 to 11 ) := init_a ; signal b : word32_vector (0 to 15 ) := init_c ; signal c : word32_vector (0 to 15 ) := ( 0 to 15 => X"00000000" ); signal d : word32_vector (0 to 15 ) := init_b ; signal m : word32_vector (0 to 15 ) := ( 0 to 15 => X"00000000" );

signal din_be : word32 ; signal din_last : word32 ; signal perm_u : word32 ; signal perm_v : word32 ; signal perm_vac : word32 ; signal perm_a : word32 ; signal perm_b : word32 ;

signal perm_u2 : word32 ; signal perm_v2 : word32 ; signal perm_vac2 : word32 ; signal perm_a2 : word32 ; signal perm_b2 : word32 ;

signal ac : word32_vector (0 to 11 ); signal acw : word32_vector (0 to 11 ); signal d_rot17 : word32_vector (0 to 15 );

81

signal next_state : state_t ; signal next_step : natural range 0 to 3; signal next_cnt : unsigned (2 downto 0); signal next_lcnt : unsigned (1 downto 0); signal next_w : unsigned (63 downto 0); signal next_a : word32_vector (0 to 11 ); signal next_b : word32_vector (0 to 15 ); signal next_c : word32_vector (0 to 15 ); signal next_d : word32_vector (0 to 15 ); signal next_m : word32_vector (0 to 15 ); begin -- Acquisition des données en entrée din_be <= din ( 7 downto 0) & din (15 downto 8) & din (23 downto 16 ) & din (31 downto 24 );

din_last <= din ( 39 downto 32 ) & din (47 downto 40 ) & din (55 downto 48 ) & din (63 downto 56 );

-- Mise à jour des signaux de contrôle et compteurs next_state <= sLast when step = 3 and last = '1' else sRun when step = 3 else state ;

next_step <= step + 1 when step /= 3 and cnt = X"7" else 0 when step = 3 else step ;

next_cnt <= cnt + "001" when step /= 3 and cnt /= "111" else "000" ;

next_lcnt <= lcnt + "01" when step = 3 and state = sLast else lcnt ;

next_w <= w + to_unsigned( 1, 64 ) when step = 2 and cnt = X"7" and state /= sLast else w ;

we <= '1' when step = 2 and state /= sInit else '0' ;

-- Permutation – première étape perm_v <= ( a(11 )( 16 downto 0) & a(11 )( 31 downto 17 )) + ( a(11 )( 14 downto 0) & a(11)( 31 downto 17 ) & "00" );

perm_vac <= perm_v xor a (0) xor c (8);

perm_u <= perm_vac + ( perm_vac (30 downto 0) & "0" );

perm_a <= perm_u xor m (0) xor (( not b (6)) and b (9)) xor b (13 );

perm_b <= ( not perm_a ) xor (b(0)( 30 downto 0) & b(0)( 31 ));

-- Permutation – seconde étape perm_v2 <= ( perm_a (16 downto 0) & perm_a (31 downto 17 )) + ( perm_a (14 downto 0) & perm_a (31 downto 17 ) & "00" );

perm_vac2 <= perm_v2 xor a (1) xor c (7);

perm_u2 <= perm_vac2 + ( perm_vac2 (30 downto 0) & "0" );

perm_a2 <= perm_u2 xor m (1) xor (( not b (7)) and b (10 )) xor b (14 );

perm_b2 <= ( not perm_a2 ) xor (b(1)( 30 downto 0) & b(1)( 31 ));

-- Additions de C à A ac_loop : for i in 0 to 11 generate ac (i) <= a(i) + c(( i+3) mod 16 ) + c(( i+15 ) mod 16 ) + end generate;

-- A xor W acw (0) <= ac (0) xor w (31 downto 0);

acw (1) <= ac (1) xor w (63 downto 32 );

82

acw (2 to 11 ) <= ac (2 to 11 );

-- Rotation de D rot17_loop : for i in 0 to 15 generate d_rot17 (i) <= d(i)( 14 downto 0) & d(i)( 31 downto 15 ); end generate;

-- Mise à jour des registres internes next_a <= a(2 to 11 ) & perm_a & perm_a2 when step /= 3 and state /= sInit else acw when step = 3 and state /= sInit else a ;

next_b <= b(2 to 15 ) & perm_b & perm_b2 when step /= 3 and state /= sInit else d_rot17 when step = 3 else b ;

next_c <= b when step = 3 else c (14 ) & ( c(15 ) & c(0 to 13 ));

next_d <= d(2 to 15 ) & ( d(0) - m(0)) & ( d(1) - m(1)) when step = 1 else d (2 to 15 ) & ( d(0) + m(0)) & ( d(1) + m(1)) when step = 2 and state = sLast else d (2 to 15 ) & ( d(0) + din_last ) & ( d(1) + din_be ) when step = 2 else b when step = 3 else d ;

next_m <= m(2 to 15 ) & din_last & din_be when step = 2 and state /= sLast else m (2 to 15 ) & m(0) & m(1) when step /= 3 else m ;

process( rst , clk ) begin

if rst = '1' then

state <= sInit ; step <= 2; cnt <= "000" ; lcnt <= "00" ; w <= to_unsigned( 0, 64 ); a <= init_a ; b <= init_c ; c <= ( 0 to 15 => X"00000000" ); d <= init_b ; m <= ( 0 to 15 => X"00000000" );

elsif clk' event and clk = '1' then state <= next_state ; step <= next_step ; cnt <= next_cnt ; lcnt <= next_lcnt ; w <= next_w ; a <= next_a ; b <= next_b ; c <= next_c ; d <= next_d ; m <= next_m ;

end if; end process;

-- Mise à jour du bus de sortie dout <= b(15 )( 7 downto 0) & b(15 )( 15 downto 8) & b(15 )( 23 downto 16 ) & b(15 )( 31 downto 24 ); end architecture;

83

Annexe D

Résultats Shabal 3.1

High-Speed Implementation

F = 126,4 MHz

84

Annexe E

Résultats Shabal 3.1

Low-Area Implementation

F = 109,3 MHz