rapport de stage - gsii.frgsii.fr/publications/rapport.pdf · le développement du code vhdl...
TRANSCRIPT
CHAPITRE 1 Le groupe EADS
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
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
Introduction
1. Le groupe EADS
1.1 Présentation du groupe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.1 Histoire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.2 Organisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2 Defence and Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3 Defence and Communications Systems . . . . . . . . . . . . . . . . . . . . . . .
2. Fonction de hachage
2.1 Définition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1.1 Généralités . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1.2 Description générale d'une fonction de hachage séquentielle itérative . . .
2.1.3 Exemples de constructions . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2 Quelques algorithmes de référence . . . . . . . . . . . . . . . . . . . . . . . . .
2.2.1 Secure Hash Algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2.2 Message Digest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2.3 Whirpool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2.4 Autres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3 La compétition SHA-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3. L'algorithme Shabal
3.1 Etude . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.1.1 Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.1.2 Mode Opératoire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.1.3 Spécifications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.1.4 Première approche en terme de ressources . . . . . . . . . . . . . . . . . .
3.2 Développement VHDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2.1 Outils . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2.2 Description générale du système . . . . . . . . . . . . . . . . . . . . . . .
3.2.3 Entité d'interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2.4 Entité de séquencement . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
7
8
8
8
8
10
11
13
13
13
17
19
21
21
21
22
22
24
25
25
25
27
31
33
34
34
34
36
37
4
3.2.5 Entité de calcul . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2.6 La permutation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3 Optimisations et Résultats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3.1 Paramètres déterminants . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3.2 Optimisations successives . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3.3 Résultats et observations . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.4 SHABAL 3.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.4.1 Description du code VHDL . . . . . . . . . . . . . . . . . . . . . . . . .
3.4.2 Résultats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.4.3 L'apport EADS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4. Algorithmes concurrents et comparatif
4.1 Etapes de la compétition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2 Algorithmes concurrents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2.1 CubeHash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2.2 Grøstl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2.3 Lane . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2.4 Spectral Hash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3 Comparatif . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.1 Eléments de comparaison . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.2 Représentations et observations . . . . . . . . . . . . . . . . . . . . . .
Conclusion
Bibliographie
Annexe A – Code Shabal 2.2
A.1 Package.vhd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
A.2 System.vhd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
A.3 Prebloc_32bits.vhd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
A.4 Hash.vhd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
A.5 Sequenceur.vhd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
A.6 Operation.vhd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Annexe B – Résultats Shabal 2.2
Annexe C – Code Shabal 3.1
Annexe D – Résultats Shabal 3.1 (High-Speed Implementation)
39
40
41
41
43
46
48
48
51
51
51
51
52
52
53
55
57
59
59
59
66
67
68
68
69
70
72
73
74
79
80
83
84 Annexe E – Résultats Shabal 3.1 (Low-Area Implementation)
5
Table des figures
1.1 Effectifs de EADS au 31 décembre 2008 . . . . . . . . . . . . . . . . . . . . . . . .
1.2 Répartition des effectifs de EADS par secteur d'activité . . . . . . . . . . . . . . .
1.3 Evolution du chiffre d'affaire de EADS (en millions d'euros). . . . . . . . . . . . . .
1.4 Hiérarchie directe de Hardware & RF . . . . . . . . . . . . . . . . . . . . . . . . .
2.1 Construction générale d'une fonction de hachage itérative . . . . . . . . . . . . . .
2.2 Construction de Davies-Meyer . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3 Construction de Matyas-Meyer-Oseas . . . . . . . . . . . . . . . . . . . . . . . . .
2.4 Construction de Miyaguchi-Preneel . . . . . . . . . . . . . . . . . . . . . . . . . .
3.1 Mode opératoire de Shabal : routine de traitement . . . . . . . . . . . . . . . . . .
3.2 Finalisation de Shabal : première approche . . . . . . . . . . . . . . . . . . . . . .
3.3 Finalisation de Shabal : seconde approche . . . . . . . . . . . . . . . . . . . . . . .
3.4 Schématique de l'architecture externe de Shabal . . . . . . . . . . . . . . . . . . . .
3.5 Schématique de l'architecture interne de Shabal . . . . . . . . . . . . . . . . . . . .
3.6 GRAFCET de Shabal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.7 Schématique de la permutation de Shabal . . . . . . . . . . . . . . . . . . . . . . .
3.8 Première étape du double décalage dans la permutation de Shabal . . . . . . . . . .
3.9 Première étape du double décalage dans la permutation de Shabal . . . . . . . . . .
3.10 Evolution des performances de Shabal . . . . . . . . . . . . . . . . . . . . . . . .
4.1 Schématique de la fonction de permutation de CubeHash. . . . . . . . . . . . . . . .
4.2 Fonction de compression de Grøstl . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3 Permutations P et Q de Grøstl . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4 Fonction de compression de Lane . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.5 Schématique de la permutation Pi /Qj de Lane . . . . . . . . . . . . . . . . . . . . .
4.6 Schématique de la fonction de compression de Spectral Hash . . . . . . . . . . . . .
4.7 High-Speed Implementation Results. . . . . . . . . . . . . . . . . . . . . . . . . .
4.8 Performances des algorithmes de hachage (High-Speed Implementation). . . . . . . . .
4.9 TP/slice des algorithmes de hachage (High-Speed Implementation) . . . . . . . . . . . .
4.10 Low-Area Implementation Results . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.11 Performances des algorithmes de hachage (Low-Area Implementation) . . . . . . .
9
9
10
12
18
19
20
20
27
27
28
35
35
38
40
44
45
47
53
54
54
56
56
57
61
62
63
64
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.
Introduction
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.
CHAPITRE 1 Le groupe EADS
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.
1.1 Présentation du groupe
CHAPITRE 1 Le groupe EADS
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.
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.
France Allemagne Espagne Royaume-Uni Monde
États -Unis 2 555
(2,2 %)
Autres pays 4 497
(3,8 %)
Total : 118 349
44 380 (37,5 %)
42 987 (36,3 %)
10 104 (8,5 %)
13 826 (11,7 %)
FIG 1.1 – Effectifs de EADS au 31 décembre 2008
Eurocopter 15667 (13%)
Defence and Security 27779 (23%)
Astrium 13674 (12%)
Airbus 58816 (50%)
Siège social & autres activités
2413 (2%)
FIG 1.2 – Répartition des effectifs de EADS par secteur d'activité
1.1 Présentation du groupe
CHAPITRE 1 Le groupe EADS
10
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
40 000
30 000
20 000
10 000
0
2000
24 208
30 798 29 901 30 133 31 761
34 206
2001 2002 2003 2004 2005
39 434
2006
39 123
2007 2008
43 300
FIG 1.3 – Evolution du chiffre d'affaire de EADS (en millions d'euros)
1.2 Defence and Security
CHAPITRE 1 Le groupe EADS
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.
1.3 Defence and Communications Systems
CHAPITRE 1 Le groupe EADS
12
FIG 1.4 – Hiérarchie directe de Hardware & RF
Defence
& Communications Systems
Defence & Security
Security
& Communication Solutions
Product Line Networks
Network R&D
Hardware & RF
EADS
Core Platform Projects
Defence Electronics
Military Air Systems
Integrated Systems
Product Line Security
DSP Software
Integration, Vérification & Maintenance
Product Line Applications
Tetrapol Networks Projects
Airbus
Eurocopter
Astrium
Eurofighter
MBDA
CHAPITRE 2 Fonction de hachage
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.
2.1 Définition
CHAPITRE 2 Fonction de hachage
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...)
2.1 Définition
CHAPITRE 2 Fonction de hachage
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 (message
authentication 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
2.1 Définition
CHAPITRE 2 Fonction de hachage
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 2n 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 2n/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 256
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.
2.1 Définition
CHAPITRE 2 Fonction de hachage
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 0SSi = .
• Routine de traitement des blocs messages : pour i allant de 1 à k, M est inséré dans
1−iS et on calcule iS à l'aide d'une fonction de compression ),(: 1−= iii SMRSR . Ce
modèle est appelé Merkle-Damgård.
• Discontinuité : on effectue une transformation finale après le dernier calcul :
)(1 kk SFS =+ .
• Obtention de la valeur hachée : pour j allant de 1 à t :
- On extrait une valeur hachée Hj du buffer interne d'état jkS + : )( jkj SextH +=
- On met à jour le buffer interne à l'aide d'une fonction T : )(1 jkjk STS +++ =
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.
2.1 Définition
CHAPITRE 2 Fonction de hachage
18
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é.
FIG 2.1 – Construction générale d'une fonction de hachage itérative
2.1 Définition
CHAPITRE 2 Fonction de hachage
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.
E 1−iH iH
iM
FIG 2.2 – Construction de Davies-Meyer
R
2.1 Définition
CHAPITRE 2 Fonction de hachage
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 1−iH est traitée par une fonctiong 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.
Construction de Miyaguchi-Preneel
Elle propose un fonctionnement similaire à la construction de Matyas-Meyer-Oseas à
ceci près que 1−iH 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.
iM
FIG 2.3 – Construction de Matyas-Meyer-Oseas
E 1−iH iH
R
g
iM
FIG 2.4 – Construction de Miyaguchi-Preneel
E 1−iH iH
R
g
2.2 Quelques algorithmes de référence
CHAPITRE 2 Fonction de hachage
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.
2.2 Quelques algorithmes de référence
CHAPITRE 2 Fonction de hachage
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 2256 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
2.2 Quelques algorithmes de référence
CHAPITRE 2 Fonction de hachage
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 Joan Daemen 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.
2.3 La compétition SHA-3
CHAPITRE 2 Fonction de hachage
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 3 L'algorithme SHABAL
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 à 273 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.
3.2 Développement VHDL
CHAPITRE 3 L'algorithme SHABAL
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 C0, C1, C2 et C3 (chacun d'entre eux compris entre 0
et 255), la valeur du mot est donnée par : C0 + 28C1 + 216C2 + 224C3.
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.
3.2 Développement VHDL
CHAPITRE 3 L'algorithme SHABAL
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 A0,
B0, C0. 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 :
),,,(),(),(: ,, CBAMPBAPBAP CMCM =→
FIG 3.1 – Mode opératoire de Shabal : routine de traitement
FIG 3.2 – Finalisation de Shabal : première approche
3.2 Développement VHDL
CHAPITRE 3 L'algorithme SHABAL
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
3.2 Développement VHDL
CHAPITRE 3 L'algorithme SHABAL
29
Initialisation : )1,,,(),,,( 000 CBAWCBA ←
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 ( ]0[]1[.232 WWw += ) on fait :
• add : le bloc message est introduit.
wMBB +←
Il s'agit ici d'une addition mot à mot, comme expliqué précédent, sans propagation de retenue.
• counter : XOR le compteur avec ]0[A et ]1[A .
],0[]0[]0[ WAA ⊕← ]1[]1[]1[ WAA ⊕←
• permute : on applique la permutation P .
),(),( , BAPBA CM←
• sub : on soustrait le message à C.
wMCC −←
Il s'agit ici d'une soustraction mot à mot
• swap : on interchange B et C .
),(),( BCCB ← 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é kM . Pendant cette phase, le
compteur w reste figé à la valeur k . Sortie : Les mots allant de ]32/16[ hlC − à ]15[C constituent le message de sortie –
avec hl la longueur de sortie désirée.
Description du mode opératoire
3.2 Développement VHDL
CHAPITRE 3 L'algorithme SHABAL
30
Vue de haut niveau
Voici une approche plus synthétique de l'algorithme Shabal.
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.
Initialisation : )1,,,(),,,( 000 CBAWCBA ←
Routine de traitement : kMMM ,...,1=
For w from 1 to k do
1. wMBB +←
2. wAA ⊕← 3. ),(),( , BAPBA CM←
4. wMCC −←
5. ),(),( BCCB ← End do
Finalisation : For i from 1 to 2 do
1. wMBB +←
2. wAA ⊕← 3. ),(),( , BAPBA CM←
4. wMCC −←
5. ),(),( BCCB ← End do
Sortie : )(CmsbH lh=
3.2 Développement VHDL
CHAPITRE 3 L'algorithme SHABAL
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 512=ml bits exclusivement. Le buffer
interne, composé des registres A , B et C , est configurable à l'aide de deux paramètres de
sécurité : 2≥p et 2≥r . Il est donc de longueur )321024( 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 rla 32= . 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 2−M et 1−M 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 : lhIVCBA =),,( avec lhIV : 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, 322mod3: xxU ×→ et 322mod5: xxV ×→ sont utilisées comme
fonctions non linéaires.
3.2 Développement VHDL
CHAPITRE 3 L'algorithme SHABAL
32
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).
Entrée : CBAM ,,,
Sortie : BA, Déroulement :
1. For i from 1 to 15 do 17][][ <<<← iBiB
End do
2. For j from 1 to 1−p do
For i from 0 to 15 do
• Compute
][
)]16mod[]16mod[(
]16mod[
])16mod8[
)15]mod161[()]mod16[(]mod16[
32
1
iM
oiBoiB
oiB
iC
rjiAVrjiAUrjiA
⊕+∧+⊕
+⊕−⊕
<<<+−⊕+←+
où )6,9,13(),,( 321 =ooo sont des valeurs d'offset nécessaires à une meilleure
diffusion dans la permutation.
• ]mod16[)1][(][ rjiAiBiB +⊕<<<← End do End do
3. For j from 0 to 35 do
]16mod3[]mod[]mod[ ++← jCrjArjA
End do
Permutation P interne de Shabal
3.2 Développement VHDL
CHAPITRE 3 L'algorithme SHABAL
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.
AAA +<<=× )2(5
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…
3.2 Développement VHDL
CHAPITRE 3 L'algorithme SHABAL
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.
3.2 Développement VHDL
CHAPITRE 3 L'algorithme SHABAL
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
3.2 Développement VHDL
CHAPITRE 3 L'algorithme SHABAL
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.
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é.
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.
in
out
3.2 Développement VHDL
CHAPITRE 3 L'algorithme SHABAL
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
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.
ETAT : Etat du séquenceur.
Internes
ETAT_IN : Etat du séquenceur.
in
out
3.2 Développement VHDL
CHAPITRE 3 L'algorithme SHABAL
38
N0 FINAL /= 3
0
1
2
3
4
5
6
INITIALISATION1
M <= DAT I or M <= PREFIXE
START = '1' or N0 FINAL /= 0
or INIT = '0'
A xor W B <= (B + M) <<<171
PERMUTATION
TERM = '1'
A <= A + C C <= C - M 1
B <> C W++
N0 FINAL = 3
DAT_O <= C
FIG 3.6 – GRAFCET de Shabal
3.2 Développement VHDL
CHAPITRE 3 L'algorithme SHABAL
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.
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.
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.
in
out
3.2 Développement VHDL
CHAPITRE 3 L'algorithme SHABAL
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
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.
FIG 3.7 – Schématique de la permutation de Shabal
3.3 Optimisations et Résultats
CHAPITRE 3 L'algorithme SHABAL
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
3.3 Optimisations et Résultats
CHAPITRE 3 L'algorithme SHABAL
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 :
messageblocparehordcyclesnb
fréquencemessageblocparbitsnbTP
log'max×=
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).
3.3 Optimisations et Résultats
CHAPITRE 3 L'algorithme SHABAL
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
3.3 Optimisations et Résultats
CHAPITRE 3 L'algorithme SHABAL
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
3.3 Optimisations et Résultats
CHAPITRE 3 L'algorithme SHABAL
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.
*dans le sens de la permutation du registre
FIG 3.9 – Première étape du double décalage dans la permutation de Shabal
3.3 Optimisations et Résultats
CHAPITRE 3 L'algorithme SHABAL
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 : )115(&))0()0(( downtoAUXMAUXAUX −<=
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
Evolution des performances de Shabal FIG 3.10 – Evolution des performances de Shabal
0
500
1000
1500
2000
2500
3000
1 2 3 4 5 6 7
Slices (nb) TP (Mbps) TP/slice (kbps/slice)
3.4 SHABAL 3.0
CHAPITRE 3 L'algorithme SHABAL
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.
3.4 SHABAL 3.0
CHAPITRE 3 L'algorithme SHABAL
49
Conditions initiales : kMM <=
WAA ⊕<=
17)( <<<+<= kMBB
CDCC <=<= ; 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 ))0()0((&)151( MDtoDD −<= [...] Cycle 31 : itération de la permutation
))0()0((&)151( MDtoDD −<= À 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 )0(&)151( 1+<= kMtoMM
))0()0((&)151( 1+−<= kMDtoDD
Cycle 33 : itération de la permutation
)1(&)151( 1+<= kMtoMM
))1()0((&)151( 1+−<= kMDtoDD
[...] Cycle 47 : itération de la permutation )15(&)151( 1+<= kMtoMM
))15()0((&)151( 1+−<= kMDtoDD
++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 16mod)15(()16mod)11(()16mod)3(()()( ++++++<= iCiCiCiAiA
End do • WAA ⊕<=
• DCDB <=<= ;
• )17( <<<<= DB
À 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.
Permutation P interne de Shabal 3.0
3.4 SHABAL 3.0
CHAPITRE 3 L'algorithme SHABAL
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
(slices)
Fréquence
(MHz)
#Cycles
TP
(Mbps)
TP/Area
(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 :
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).
Area
(slices)
Fréquence
(MHz)
#Cycles
TP
(Mbps)
TP/Area
(kbps/slice)
1171
126.4
25
2588
2210
CHAPITRE 4 Algorithmes concurrents et comparatif
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 Skein. 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.
4.2 Algorithmes concurrents
CHAPITRE 4 Algorithmes concurrents et comparatif
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 10r 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 Mi 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 MN-1 traité, l'entier 1 est XORé avec le
dernier mot du registre d'état et on lui applique à nouveau la fonction de compression
10r 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.
4.2 Algorithmes concurrents
CHAPITRE 4 Algorithmes concurrents et comparatif
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.
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 Mi, 0<= i <=
N – 1.
3. Compression du message. Chaque bloc message Mi est combiné avec le précédent
résultat Hi-1 et traité par la permutation P. Dans le même temps, la permutation Q est
FIG 4.1 – Schématique de la fonction de permutation de CubeHash
4.2 Algorithmes concurrents
CHAPITRE 4 Algorithmes concurrents et comparatif
54
appliquée à Mi. La fonction de sortie Hi est le résultat d'un XOR entre Hi-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 HN-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
4.2 Algorithmes concurrents
CHAPITRE 4 Algorithmes concurrents et comparatif
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 Hi-1 et traité avec un
certain nombre de tours (contrôlés par un compteur) de transformations basées sur le
chiffrement AES.
4.2 Algorithmes concurrents
CHAPITRE 4 Algorithmes concurrents et comparatif
56
4. Finalisation et sortie. On repasse HN-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ù Mi est combiné avec Hi-1 et comprend des XOR et
concaténations successifs. Le résultat de cette étape se compose de 6 mots de 256 bits.
Le reste de la fonction se compose de 5 XORs et huit lignes de permutations : Pi (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.4 – Fonction de compression de Lane
FIG 4.5 – Schématique de la permutation Pi /Qj de Lane
4.2 Algorithmes concurrents
CHAPITRE 4 Algorithmes concurrents et comparatif
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 Pi. Deux de ces circuits peuvent
ensuite servir pour Qj.
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 Mi, le
résultat du hachage du précédent message Hi-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 M1. Le résultat de
l'état précédent sont mis à 0 et stocké dans h-prism.
2. Compression du message. Mi est placé dans un s-prism de mots de 4 bits, et traité avec
Hi-1 et Pi.
4.2 Algorithmes concurrents
CHAPITRE 4 Algorithmes concurrents et comparatif
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.
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.
FIG 4.6 – Schématique de la fonction de compression de Spectral Hash
4.3 Comparatif
CHAPITRE 4 Algorithmes concurrents et 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.
4.3 Comparatif
CHAPITRE 4 Algorithmes concurrents et 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.
61
# Algorithme Area (slices) Max. Freq. (Mhz) # Cycles TP (Mbps) TP/Area (kbps/s lice)
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
(1) cf. chapitre 5.2.2 – Fonction de compression
(2) Fully autonomous : inclus aussi le système d'interface
FIG 4.7 – High-Speed Implementation Results
62
Performances des algorithmes de hachage
0
2 000
4 000
6 000
8 000
10 000
12 000
14 000
16 000
18 000
20 000
1 2 3 4 5 6 7 8 9 10 11 12 13
Slices (nb)
TP (Mbps)
FIG 4.8 – Performances des algorithmes de hachage (High-Speed Implementation)
63
Throughput par slice
0
500
1000
1500
2000
2500
3000
3500
4000
4500
5000
1 2 3 4 5 6 7 8 9 10 11 12 13
Algorithme
TP
/slic
e (k
bps/
slic
e)FIG 4.9 – TP/slice des algorithmes de hachage
(High-Speed Implementation)
64
# Algorithme Area (slices) Max. Freq. (Mhz) # Cycle s 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
0
200
400
600
800
1 000
1 200
1 400
1 600
1 800
2 000
6 7 8 13
Slices (nb)
TP (Mbps)TP/slice (kbps/slice)
FIG 4.11 – Performances des algorithmes de hachage (Low-Area Implementation Results)
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é REINHARD : Sécurité et Analyse des Primitives de Hachage Innovantes et Récentes – Analyse des Attaques Existantes. 2006 [2] Pierre-Alain FOUQUE, Gilles PIRET : 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 FOUQUE : Sécurité et Analyse des Primitives de Hachage Innovantes et Récentes – Synthèse des nouvelles conceptions. 2009 [4] Anne CANTEAUT, Benoît CHEVALLIER-MAMES, Aline GOUGET, Pascal PAILLIER , Thomas PORNIN : Shabal, a Submission to NIST's Cryptographic Hash Algorithm Competition. 2008 [5] Gaëtan LEURENT : SIMD Is a Message Digest. 2009 [6] Brian BALDWIN , Andrew BYRNE, Mark HAMILTON , Neil HANLEY , Robert P. MCEVOY, Weibo PAN and William P. MARNANE – Claude Shannon Institute for Discrete Mathematics, Coding and Cryptography.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 GENET : Conception synchrone. 2005 [9] Daniel GENET : Initiation au langage VHDL. 2006 [10] Encyclopédie en ligne : http://fr.wikipedia.org [11] Sébastien VARRETTE : Fonctions de Hachage et Signatures Electroniques. 2008 [12] Daniel J. BERNSTEIN : CubeHash Specifications. 2008 [13] Sebastiaan INDESTEEGE, Elena ANDREEVA, Christophe De CANNIERE, Orr DUNKLEMAN , Emilia KASPER, Svetla NIKOVA , Bart PRENEEL, and Elmar TISCHHAUSER : 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 mag asin 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 magas in 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 m ise à 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 mess age 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 indic ateurs 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 ;
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;