RESEARCH REPORT J.M. ROBERT. Univ. Perpignan Via Domitia, Digits, Architectures et Logiciels Informatiques, F-66860,Perpignan, France



Documents pareils
Arithmétique binaire. Chapitre. 5.1 Notions Bit Mot

Cryptographie et fonctions à sens unique

Représentation des Nombres

Représentation d un entier en base b

La mémoire. Un ordinateur. L'octet. Le bit

Nombres premiers. Comment reconnaître un nombre premier? Mais...

Introduction à l étude des Corps Finis

Problèmes arithmétiques issus de la cryptographie reposant sur les réseaux

De même, le périmètre P d un cercle de rayon 1 vaut P = 2π (par définition de π). Mais, on peut démontrer (difficilement!) que

Exercices - Polynômes : corrigé. Opérations sur les polynômes

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Panorama de la cryptographie des courbes elliptiques

Conversion d un entier. Méthode par soustraction

Cours 1 : Introduction Ordinateurs - Langages de haut niveau - Application

UEO11 COURS/TD 1. nombres entiers et réels codés en mémoire centrale. Caractères alphabétiques et caractères spéciaux.

V- Manipulations de nombres en binaire

Informatique Générale

Cryptographie. Cours 3/8 - Chiffrement asymétrique

IV- Comment fonctionne un ordinateur?

Algorithme. Table des matières

ÉPREUVE COMMUNE DE TIPE Partie D

IFT2880 Organisation des ordinateurs et systèmes

Calculateur quantique: factorisation des entiers

La cryptographie du futur

Logiciel de Base. I. Représentation des nombres

Chapitre 10 Arithmétique réelle

Corrigé des TD 1 à 5

DU BINAIRE AU MICROPROCESSEUR - D ANGELIS CIRCUITS CONFIGURABLES NOTION DE PROGRAMMATION

Etude de fonctions: procédure et exemple

Cryptologie. Algorithmes à clé publique. Jean-Marc Robert. Génie logiciel et des TI

MICROINFORMATIQUE NOTE D APPLICATION 1 (REV. 2011) ARITHMETIQUE EN ASSEMBLEUR ET EN C

Cours Informatique 1. Monsieur SADOUNI Salheddine

Introduction à MATLAB R

Cryptographie RSA. Introduction Opérations Attaques. Cryptographie RSA NGUYEN Tuong Lan - LIU Yi 1

Quelques tests de primalité

Polynômes à plusieurs variables. Résultant

Licence Sciences et Technologies Examen janvier 2010

Chapitre 2 Le problème de l unicité des solutions

Cours d Analyse. Fonctions de plusieurs variables

SOCLE COMMUN - La Compétence 3 Les principaux éléments de mathématiques et la culture scientifique et technologique

1 Définition et premières propriétés des congruences

DOCM Solutions officielles = n 2 10.

Rappels d architecture

Cours 1 : La compilation

Programmation C. Apprendre à développer des programmes simples dans le langage C

Les algorithmes de base du graphisme

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

Calcul matriciel. Définition 1 Une matrice de format (m,n) est un tableau rectangulaire de mn éléments, rangés en m lignes et n colonnes.

Définition 0,752 = 0,7 + 0,05 + 0,002 SYSTÈMES DE NUMÉRATION POSITIONNELS =

Première partie. Préliminaires : noyaux itérés. MPSI B 6 juin 2015

Fonction de hachage et signatures électroniques

Calculer avec Sage. Revision : 417 du 1 er juillet 2010

CRYPTOGRAPHIE. Signature électronique. E. Bresson. SGDN/DCSSI Laboratoire de cryptographie

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

Grandes lignes ASTRÉE. Logiciels critiques. Outils de certification classiques. Inspection manuelle. Definition. Test

Les opérations binaires

Nom de l application

Continuité en un point

Éléments d informatique Cours 3 La programmation structurée en langage C L instruction de contrôle if

ASR1 TD7 : Un microprocesseur RISC 16 bits

Cryptologie et physique quantique : Espoirs et menaces. Objectifs 2. distribué sous licence creative common détails sur

Complément d information concernant la fiche de concordance

Pour l épreuve d algèbre, les calculatrices sont interdites.

Logiciel Libre Cours 3 Fondements: Génie Logiciel

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

Sommaire Introduction Les bases de la cryptographie Introduction aux concepts d infrastructure à clés publiques Conclusions Références

Sujet proposé par Yves M. LEROY. Cet examen se compose d un exercice et de deux problèmes. Ces trois parties sont indépendantes.

Exercices - Fonctions de plusieurs variables : corrigé. Pour commencer

Cours d initiation à la programmation en C++ Johann Cuenin

IN SYSTEM. Préconisations techniques pour Sage 100 Windows, MAC/OS, et pour Sage 100 pour SQL Server V16. Objectif :

# let rec concat l1 l2 = match l1 with [] -> l2 x::l 1 -> x::(concat l 1 l2);; val concat : a list -> a list -> a list = <fun>

Conservation des documents numériques

Reproductibilité des expériences de l article "Analyse et réduction du chemin critique dans l exécution d une application"

Théorème du point fixe - Théorème de l inversion locale

Université Paris-Dauphine DUMI2E 1ère année, Applications

Chapitre 7. Récurrences

Présentation du cours de mathématiques de D.A.E.U. B, remise à niveau

t 100. = 8 ; le pourcentage de réduction est : 8 % 1 t Le pourcentage d'évolution (appelé aussi taux d'évolution) est le nombre :

CH.3 SYSTÈMES D'EXPLOITATION

Exercices types Algorithmique et simulation numérique Oral Mathématiques et algorithmique Banque PT

Chapitre VI- La validation de la composition.

Architecture des ordinateurs TD1 - Portes logiques et premiers circuits

STAGE IREM 0- Premiers pas en Python

Compilation (INF 564)

La fonction exponentielle

Résolution de systèmes linéaires par des méthodes directes

Chapitre 1 I:\ Soyez courageux!

Table des matières PRESENTATION DU LANGAGE DS2 ET DE SES APPLICATIONS. Introduction

Recherche dans un tableau

Les indices à surplus constant

Chapitre 1 : Évolution COURS

Initiation à l algorithmique

Continuité et dérivabilité d une fonction

INF 4420: Sécurité Informatique Cryptographie II

3 Approximation de solutions d équations

I00 Éléments d architecture

0x700. Cryptologie Pearson France Techniques de hacking, 2e éd. Jon Erickson

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

Architecture matérielle des systèmes informatiques

Calcul fonctionnel holomorphe dans les algèbres de Banach

Transcription:

RESEARCH REPORT Rapport de Stage MASTER 2 EAI Informatique Implémentation et évaluation de techniques d optimisation pour l arithmétique des courbes elliptiques J.M. ROBERT Univ. Perpignan Via Domitia, Digits, Architectures et Logiciels Informatiques, F-66860,Perpignan, France Univ.Montpellier II, Laboratoire d Informatique Robotique et de Microélectronique de Montpellier, UMR 5506, F-34095, Montpellier, France CNRS, Laboratoire d Informatique Robotique et de Microélectronique de Montpellier, UMR 5506, F-34095, Montpellier, France

Rapport de stage MASTER 2 EAI Informatique J.M. ROBERT 23/05/2012 Stage réalisé sous la conduite de Christophe Nègre, UPVD, DALI, LIRMM

Résumé Implémentation et évaluation de techniques d optimisation pour l arithmétique des courbes elliptiques Les calculs cryptographiques nécessitent d effectuer des opérations sur des corps finis avec les règles arithmétiques correspondantes. Le développement de la cryptographie sur les courbes elliptiques (ECC, Elliptic Curve Cryptography), et plus particulièrement celles définies sur les corps binaires (F 2 m), implique d implémenter ces opérations à l aide d algorithmes de plus en plus performants, et de tirer parti des plates-formes disposant des processeurs ayant un jeu d instruction étendu à l arithmétique des polynômes de ces corps binaires. Après avoir rappelé les fondements de l arithmétique sur les courbes elliptiques ainsi que pour les opérations sur les corps binaires, on fera l inventaire des algorithmes les plus performants proposés dans la littérature scientifique, pour les plates-formes modernes. L implémentation de ces derniers algorithmes permet d atteindre les meilleures performances publiées et d être au niveau de l état de l art. Peut-on aller plus loin? Certaines combinaisons d opérations, lorsque des opérandes sont communes ou donnent lieu à des simplifications, peuvent-elles apporter un gain supplémentaire? L examen d optimisations prenant en compte des opérations combinées fait l objet d expérimentations. La combinatoire des cas (taille des corps binaires finis et type des variables manipulées par les implémentations) est partiellement explorée. Les expérimentations menées laissent encore la question ouverte, mais tracent la voie à des développements ultérieurs. Mots clés : crytographie, courbes elliptiques, polynômes binaires, multiplication Carry-less, échange de clés 1

Remerciements Je tiens à remercier en premier lieu Christophe Nègre pour m avoir fait confiance et donné l opportunité d effectuer mon stage de Master 2 au sein de l équipe DALI (Digits, Architecture et Logiciels Informatiques) du Laboratoire d Informatique, de Robotique et de Microélectronique de Montpellier (LIRMM) et de l Université de Perpignan Via Domitia (UPVD). Je tiens aussi plus particulièrement à le remercier pour sa disponibilité, sa gentillesse et son soutien tout au long de mon stage. Pendant ces cinq mois et demi, il a effectivement su m aider et me guider dans mon travail. Pour finir, je tiens à remercier Matthieu Martel pour son accueil et son soutien, et plus généralement l ensemble de l équipe DALI pour sa bienveillance. 2

Table des matières Introduction 5 1 Elliptic Curve Cryptography 7 1.1 Généralités......................................... 7 1.1.1 Cryptographie basée sur courbe elliptique.................. 7 1.1.2 Opérations sur le groupe des points de la courbe elliptique......... 10 2 Algorithmes et matériel 12 2.0.3 Utilisation du Dell Optiplex 990........................ 12 2.1 Opérations sur le corps binaire F 2 m........................... 13 2.1.1 Addition...................................... 13 2.1.2 Multiplication................................... 14 2.1.3 Réduction modulaire dans F 2 m......................... 22 2.1.4 Élévation au carré................................ 26 2.1.5 Inversion...................................... 29 2.1.6 Conclusion sur les opérations sur le corps binaire F 2 m............ 33 2.2 Opérations sur le groupe des points de courbe elliptique.............. 34 2.2.1 Généralités sur ces opérations.......................... 34 2.2.2 Implémentation du doublement et de l addition de points de courbe elliptique....................................... 37 3 Implémentation du produit scalaire 39 3.1 Produits scalaires..................................... 39 3.1.1 L état de l art pour le produit scalaire..................... 40 3.1.2 Influence sur le produit scalaire des différents algorithmes de multiplication........................................ 40 3.1.3 Implémentation des NAF et W-NAF...................... 43 3.1.4 Influence sur le produit scalaire du type de mots utilisés pour le codage des polynômes (64 bits ou 128 bits)....................... 48 3.1.5 Comparaison des additions et doublements de [5] et [8] et influence sur le produit scalaire................................. 49 3.1.6 Le juste nécessaire pour la réduction modulaire............... 50 3.2 Un essai d optimisation avec opérations combinées de type AB, AC ou AB + CD 51 3.2.1 Optimisation de AB, AC............................. 51 3.2.2 Optimisation de AB + CD........................... 52 3.2.3 Produit scalaire optimisé............................ 56 3.2.4 Synthèse des travaux sur l optimisation de type AB, AC ou AB + CD.. 60 Conclusion 61 3

Bibliographie 64 4

Introduction La sécurité informatique est un domaine toujours en développement. La lutte séculaire entre le bouclier du chiffrement et le glaive de la cryptanalyse se poursuit sans répit. Le bouclier se perfectionne depuis les années soixante-dix et les travaux de Diffie-Hellmann qui ont proposé les premiers une procédure d échange de clés secrètes. Chaque partie envoie à son partenaire des données publiques qui permettent de calculer la clé secrète. Pour un adversaire qui écoute les conversations, reconstituer la clé secrète est une instance du problème du logarithme discret, problème difficile en ce sens que les meilleurs algorithmes connus de cryptanalyse ont une complexité exponentielle (ou quasi). Par ailleurs Diffie-Hellmann ont aussi formalisé dès 1976 les crypto-systèmes à clés publiques, sans toutefois en expliciter des implémentations possibles. À la suite de Diffie-Hellmann, Rivest, Shamir et Adlemann (en 1977) ont proposé le premier système de chiffrement à clé publique, opérant sur un anneau de type Z/pqZ. L opération de base du chiffrement est l exponentiation modulo pq. C est le système RSA, dont la sécurité repose sur la difficulté de factoriser de grands nombres. Il suffit alors de choisir deux nombres p et q premiers suffisamment grands. Mais depuis les années soixante-dix, les pirates et autres malveillants, mais aussi les chercheurs consciencieux et soucieux de démontrer la sûreté de ces systèmes cryptographiques, ont trouvé des techniques qui permettent de mettre à mal la sécurité des communications. Avec l accroissement prodigieux des performances des systèmes de calculs d une part, les progrès des algorithmes de factorisation d autre part, le déchiffrement malveillant d un message crypté devient possible en temps raisonnable, même avec des méthodes primitives (dites de force brute) : en 2009, la possibilité de casser une clé codée sur 768 bits a été démontrée. Les clés utilisées dans le système RSA sont codées sur 1024 à 2048 bits de façon courante et depuis bien longtemps. Certains experts pensent toutefois que les clés sur 1024 bits pourraient bientôt s avérer insuffisantes. On peut bien sûr encore augmenter la taille des nombres premiers utilisés et celle des clés. Mais le volume des calculs pour effectuer un chiffrement en pâtit. En 1985, Victor Miller (alors chercheur chez IBM) et Neal Koblitz (Université de Washington) ont proposé indépendamment l un de l autre de changer de groupe pour le chiffrement. En lieu et place de Z/pqZ comme anneau, l utilisation du groupe formé de l ensemble des points d une courbe elliptique muni d une loi d addition et d un élément neutre présente certains intérêts. Le premier, c est d augmenter le niveau de sécurité des échanges de par la complexité accrue de ce groupe. Ainsi, la taille des clés peut être réduite à 160 bits pour un niveau de sécurité équivalent. Un deuxième intérêt, sur lequel nous n avons pas porté nos efforts dans ce présent travail, c est la possibilité de définir et d utiliser un opérateur bilinéaire pour des chiffrements basés sur l identité de l expéditeur. Par ailleurs, la complexité des calculs pour effectuer un chiffrement/déchiffrement n est pas inférieure aux autres systèmes, bien au contraire. La nécessité d augmenter les niveaux de sécurité conduit donc à des temps de calculs significatifs et le besoin d optimisation reste important. Dans le même temps, nos ordinateurs n ont cessés de progresser et de voir leur puissance 5

de calcul s accroître. A l époque où le système RSA apparaît, les ordinateurs personnels balbutient avec leur processeurs 8 bits, l Internet domestique n existe pas encore, et les communications sécurisées ne concernent que les applications professionnelles (transactions financières) ou militaires, sur des réseaux qui sont parfois privés. Mais on se souvient du premier IBM PC en 1981, avec un processeur 16 bits, puis rapidement, les années 90 voient se généraliser les machines 32 bits (INTEL 80386), puis 64 bits avant même les années 2000. Parallèlement, point n est besoin de rappeler que les capacités en mémoire de tout niveau (mémoire de masse, mémoire vive, mémoire cache de chaque niveau) ont également progressé. Les processeurs ont aussi vu leur jeu d instructions s accroître. Ainsi, dans le domaine qui nous intéresse, les processeurs INTEL CORE i3, i5, et i7 disposent d une instruction de multiplication sans retenue, c est à dire une opération sur polynômes binaires de F 2 [x], dans lesquels nous codons les coordonnées des points de courbe elliptique. Ceci est de nature à changer la face des performances du chiffrement/déchiffrement. L optimisation peut se faire par deux approches. La première, c est la voie algorithmique, que l on découvre dans les publications scientifiques. Les algorithmes permettant d effectuer le plus efficacement et avec le moins d opérations élémentaires les transactions cryptographiques sont décrits dans un certain nombre d articles. La deuxième voie, c est d essayer d exploiter au maximum les possibilités des plate-formes modernes et de profiter des progrès technologiques. Dans ce domaine là encore, les articles ne manquent pas. Dans notre travail, nous avons donc suivi ces deux voies. Après avoir rappelé les fondements théoriques de l arithmétique des courbes elliptiques, nous détaillerons les algorithmes de références pour chaque opération élémentaire. Nous proposerons aussi pour chacune de ces opérations une implémentation en C optimisée. Dans une troisième partie, nous exposerons les résultats de performances de simulations d échange de clés réalisées durant le stage, avec pour objectif d atteindre (ou dépasser si possible) l état de l art en la matière, et avons proposé quelques pistes d optimisations, encore infructueuses, mais qui pourraient s avérer rentables selon l évolution des matériels. Comme on le verra cependant, ces deux voies d optimisations ne sont pas totalement indépendantes l une de l autre : tel algorithme plus performant sur le papier pâtit des limitations du matériel et du compilateur. De même, certaines possibilités du matériel ne donnent pas toujours les résultats attendus. Nous n échapperons donc pas à un examen critique en profondeur de nos solutions pour chaque opération élémentaire et au delà : l optimisation d une opération et le gain qu elle apporte doivent être confrontés aux conséquences parfois négatives qui se répercutent sur d autres opérations. 6

Chapitre 1 Elliptic Curve Cryptography 1.1 Généralités 1.1.1 Cryptographie basée sur courbe elliptique Pour effectuer des communications cryptées, on peut utiliser un chiffrement/déchiffrement à clé publique ou à clé secrète. L utilisation de clés publiques présente l avantage d être souple tout en étant sûr. Chaque partie publie sa clé publique et génère le chiffrement à partir de la clé de l interlocuteur, qui est le seul à pouvoir déchiffrer à l aide de la partie secrète de sa clé. Tout le monde peut donc écrire un message chiffré au destinataire, mais lui seul peut lire ces messages. Pour séduisant qu est ce procédé, il s avère gourmand en calcul, et donc peu adapté à des communications intensives ou en temps réel, comme le chiffrement de communications téléphoniques, par exemple. De même, dans des applications embarquées, la limitation de la puissance des appareils risque de poser problème. C est le cas de l authentification des cartes à puces, par exemple, dont le développement en France dès les années 80 a eu l importance que l on sait. L utilisation d un système de cryptographie symétrique ne nécessite en comparaison que peu de calculs, tant pour le chiffrement que pour le déchiffrement. Malheureusement, le point faible de ce procédé réside dans l obligation, à un moment ou à un autre, pour les deux parties, d échanger une clé secrète. Et cet échange pose des problèmes de sécurité et de non divulgation. La tendance actuelle est donc d utiliser un procédé à clé publique pour échanger la clé secrète, puis de communiquer à l aide de cette clé secrète possédée par chacune des deux parties. Diffie et Hellmann ont publié en 1976 une procédure d échange de clé qui marque un tournant dans la cryptographie moderne. Voici ce processus 1 : 1. tiré de http ://fr.wikipedia.org/wiki/fichier :Diffie-Hellman-Schlüsselaustausch.png 7

Alice et Bob, les deux partenaires les plus sollicités des ouvrages de cryptographie, se sont ici mis d accord sur le groupe fini (Z/pZ) muni de la multiplication. Les opérations effectuées sont des exponentiations. A la fin, Alice et Bob partagent la même clé. La suggestion de Victor Miller et Neal Koblitz d utiliser le groupe des points d une courbe elliptique définie sur un corps fini ne modifie pas fondamentalement ce processus 2. Alice et Bob se mettent d accord au préalable sur une courbe elliptique et un élément générateur de ce groupe P, c est à dire un point de la courbe. Pour partager une clé secrète, Alice et Bob vont maintenant utiliser la méthode suivante : Alice génère un nombre aléatoire a N, calcule la grandeur a P et l envoie à Bob ; Bob génère un nombre aléatoire b N, calcule la grandeur b P et l envoie à Alice ; Alice calcule alors a (b P ), et de même, Bob calcule b (a P ). A la fin, Alice et Bob partagent donc la même clé secrète a (b P ) = b (a P ). Un adversaire qui écoute les communications ne peut reconstituer la clé, car retrouver a ou b est un problème difficile, qu on appelle problème du logarithme discret. Les opérations effectuées pour le chiffrement et le déchiffrement sont maintenant des produits scalaires sur les points de la courbe elliptique (et non plus des exponentiations modulo p de nombres entiers). Ainsi, un échange de clé se traduit par deux produits scalaires successifs, pour chacune des parties, le premier pour calculer la partie publique de la clé, et le second pour obtenir la clé secrète, à partir de la partie publique de la clé du partenaire. Les courbes elliptiques à utiliser font l objet d un travail de normalisation publié par le NIST (National Institute of Standards and Technology) dans des documents périodiques que nous avons exploités, notamment les Federal Information Processing Standards Publications (FIPS). Plusieurs possibilités sont offertes là encore. En effet, les courbes elliptiques peuvent avoir pour support différents corps (Z/pZ avec p premier, F 2 m, également avec m premier...) Les corps binaires F 2 m présentent l avantage de faciliter l implémentation sur nos ordinateurs pour d évidentes raisons de cohérence et de compatibilité entre leur représentation 2. On en trouve la description par les auteurs dans [7], section 5.3.1, pages 292-295. 8

binaire et la technologie informatique. Le NIST préconise les valeurs 163, 233, 283, 409 et 571 pour m. Les éléments de F 2 [x] sont des polynômes binaires a(x), c est à dire : a F 2 [x], on peut écrire a(x) = n a i x i avec : a i {0, 1}. Cette suite de coefficients a i peut être codée comme une suite de bits, dans des mots d une taille judicieusement choisie pour la plate-forme sur laquelle s effectuent les calculs. Par exemple : peut se représenter comme suit : i=0 a(x) = x 7 + x 4 + x 2 + x + 1 A = (1, 0, 0, 1, 0, 1, 1, 1) = 1001 0111 2 = 97 16 sur 8 bits. Nous pouvons ainsi noter les polynômes binaires sous la forme d entiers hexadécimaux. Les éléments du corps binaire F 2 m sont des polynômes. Or, lors d un produit de polynôme par exemple, le résultat est un polynôme dont le degré est la somme des degrés des opérandes. Ce cas se présente aussi pour l élévation au carré. Pour des raisons de commodité aisées à comprendre (la taille du stockage, c est à dire des entiers hexadécimaux notant les polynômes), il est utile de manipuler la réduction modulaire des polynômes lors des calculs, c est à dire de limiter leur degré à m 1. Cette opération de réduction modulaire nécessite de disposer d un polynôme de réduction de degré m. Nous nous plaçons donc dans le cas où notre courbe elliptique est supportée par un corps binaire F 2 m, spécifiée dans le document FIPS 186-3 de juin 2009 [11]. Ce document définit également le point générateur de la courbe à utiliser, le point P = (G x, G y ) ainsi que le polynôme de réduction f(x). A titre d exemple, nous montrons ici la courbe préconisée pour F 2 233 3 : L équation de la courbe est E : y 2 + xy = x 3 + ax 2 + b avec : { a = 1 b = 066 647ede6c 332c7f8c 0923bb58 213b333b 20e9ce42 81fe115f 7d8f90ad et le point générateur P = (G x, G y ) est : { Gx = 0fa c9dfcbac 8313bb21 39f1bb75 5fef65bc 391f8b36 f8f8eb73 71fd558b Gy = 100 6a08a419 03350678 e58528be bf8a0bef f867a7ca 36716f7e 01f81052 Le polynôme de réduction f(x) est quant à lui : f(x) = x 233 + x 74 + 1. Les grandeurs a, b, Gx et Gy sont des polynômes binaires de degré au plus égal à 232 susceptibles d être représentées par autant de mots que nécessaires dans nos machines. Ici, nous avons huit mots de 32 bits, soit huit chiffres hexadécimaux chacun. Le mot de poids fort comporte 256 233 = 23 zéros à gauche. 3. [11], FIPS 186-3, p. 93, juin 2009 9

Les machines modernes peuvent travailler sur des mots de 64 bits, voire 128 bits. Dans ce cas, le nombre de mots sera respectivement de 4 ou de 2. Les nombres secrets a et b ((a, b) N 2 ) étant de l ordre de 2 233, nous pourrons les coder dans le même format que les polynômes éléments du corps binaire, F 2 233 dans ce cas. Pour information, le nombre de points de la courbe est le produit h n, où n est l ordre du point de base (n est premier) et h le cofacteur. Pour notre courbe spécifiée, nous avons : { h = 2 n = 6901746346790563787434755862277025555839812737345013555379383634485463 On voit ici que ce nombre est grand! Et ceci garantit la sécurité des échanges. 1.1.2 Opérations sur le groupe des points de la courbe elliptique Un point P = (x, y) appartient à la courbe elliptique choisie si (x, y) F 2 2m satisfait l équation de la courbe : E : y 2 + xy = x 3 + ax 2 + b définie plus haut. Nous ne traitons ici que ce cas. Addition et doublement Ces deux opérations s effectuent entre points d une courbe elliptique, et le résultat est un autre point de la courbe elliptique. Pour plus de détails, le lecteur pourra se reporter aux livre et articles suivants, dont nous tirons les formules ci-après : [7] 4, [5], [6], [8]. L addition entre deux points d une courbe elliptique P 1 et P 2 s écrit : P 3 = P 1 + P 2 avec P 1 = (x 1, y 1 ), P 2 = (x 2, y 2 ), P 3 = (x 3, y 3 ), où : { x3 = λ 2 + λ + x 1 + x 2 + a, y 3 = (x 1 + x 3 )λ + x 3 + y 1, et : λ = y 1+y 2 x 1 +x 2 si P 1 P 2, λ = y 1 x 1 + x 1 si P 1 = P 2. Cette opération est commutative et associative. En revanche, il faut vérifier que notre groupe dispose d un élément neutre. Ceci n est pas le cas du strict point de vue de la courbe elliptique. Les auteurs proposent donc de considérer l ensemble des points de la courbe elliptique en y adjoignant un point "à l infini" noté O, qui sera l élément neutre de notre groupe. Ce qui est important de retenir ici, ce sont les opérations élémentaires sur le corps F 2 m nécessaires pour effectuer cette opération d addition ou de doublement. En voici la liste, déduite des équations ci-dessus : l addition ; la multiplication ; l inversion (une division consiste en une inversion suivie d une multiplication) ; le carré ; 4. Le chapitre 5, intitulé Elliptic Curves and Cryptography, traite exclusivement des courbes elliptiques. 10

sans oublier la réduction modulaire qui accompagne la multiplication, le carré et l inversion ; Nous allons devoir nous attacher maintenant à évaluer le coût relatif de ces opérations, ainsi que le nombre de chacune d entre elles à effectuer. Produit scalaire Pour effectuer un produit scalaire n P, nous pouvons additionner n fois P à lui-même. Nous avons vu que n est grand, et il semble donc peu recommandé de procéder comme cela. Le procédé courant exposé dans la littérature 5, c est l algorithme Left-to-right Double-And- Add : Require: k = (k t 1,..., k 1, k 0 ), P E(F 2 m). Ensure: Q = k P. 1: Q O. 2: for i from t 1 downto 0 do 3: Q 2 Q. 4: if k i = 1 then 5: Q Q + P. 6: end if 7: end for 8: return (Q) Le principe est analogue à celui de l exponentiation rapide (Square-and-multiply), utilisé pour le protocole RSA par exemple. Le problème du logarithme discret 6 s écrit, par analogie entre le groupe des points de la courbe elliptique sur F 2 m muni de l addition et le groupe Z NZ muni de la multiplication : soit : Q = np avec n N, on définit : log P (Q) = n avec n N. Dans nos calculs cryptographiques, la multiplication scalaire de points de courbes elliptiques est l une des principales opérations. Pour avoir une implémentation efficace de la multiplication scalaire, il est nécessaire d avoir des opérations sur le corps F 2 m rapides, ainsi qu une représentation des points de courbes minimisant les nombres d opérations coûteuses (en pratique, nous verrons qu il s agit de la multiplication, mais surtout de l inversion). 5. [5] et [14] notamment. 6. D après les auteurs dans [7], section 5.3, pages 290-296. 11

Chapitre 2 Algorithmes et matériel Nous allons maintenant nous intéresser aux algorithmes et à leur implémentation selon les plate-formes. Nous nous appuyons sur les articles et publications de références [1], [2], [4], [5], [8], [10], [11], [12], [13] et [14]. Ces sources permettent de développer des codes performants. Nous avons développé exclusivement en C, pour des raisons que l on comprendra aisément : nous cherchons la performance, et ce langage d assez bas niveau permet d écrire des codes qui, une fois compilés, s avèrent très proches de ce que l on aurait fait en programmant en assembleur. Nous avons constaté assez souvent, d ailleurs, que sur des fonctions très optimisées, le compilateur utilisé se contente de traduire mot à mot pour ainsi dire, et de façon très littérale, ce qui a été écrit en C. Ceci est compréhensible lorsque l on ne fait qu enchaîner des opérations de bas niveau (des opérations telles que le XOR bit à bit ou le ET logique bit à bit, par exemple), et que l on a déroulé toutes les boucles à la main. Pour ce qui est des types de variables utilisées pour coder les éléments du corps F 2 m, nous utilisons en C les types suivants : unsigned int pour les mots de 32 bits ; unsigned long int pour les mots de 64 bits ; m128i pour les mots de 128 bits. Dans ce dernier cas, il faut utiliser les instructions intrinsic INTEL avec les options de compilations suivantes 1 : -Ox pour le niveau d optimisation nécessaire (il faut x= 2 ou 3) ; -std=c99, option parfois facultative ; -mavx qui inclue toutes les options précédentes (-msse2, -msse3, -msse4, etc.) ; -mpclmul, le cas échéant, pour la multiplication sans retenue ; -g si on désire utiliser un débugger. Les polynômes sont stockés dans des tableaux à un indice, du nombre de mots nécessaire. En C, ceci implique que l on passe un pointeur si on fait appel à des fonctions pour effectuer ces opérations. Il faudra donc faire attention aux dépendances internes, si plusieurs opérandes et/ou le résultat sont référencés par le même pointeur lors de l appel. Après avoir examiné les algorithmes sous toutes leurs coutures, il deviendra alors opportun de vérifier sur plate-forme les performances qu on peut en attendre. 2.0.3 Utilisation du Dell Optiplex 990 L Optiplex 990 est un ordinateur de bureau doté d un processeur Intel i7, disposant de huit cœurs, avec 8Mo (8192 ko) de cache L3. L intérêt ici pour notre sujet, c est de pouvoir disposer 1. pour le compilateur gcc, voir plus bas. 12

d un jeu d instructions étendu, notamment en ce qui concerne les opérations sur les corps binaires. En effet, Intel a implanté sur ce processeur une multiplication sans retenue (carryless multiplier), ce qui revient à notre multiplication de polynômes binaires de degré au plus 63. C est aussi un processeur 64 bits, ce qui nous permet un gain de performance, avec des opérations sur des mots de 64 bits par rapport à 32 bits, mais aussi qui dispose des registres xmm_ 128 bits. Ces registres sont prévus originellement pour effectuer des opérations SIMD 2, c est à dire que l on traite plusieurs mots de 64, 32, 16 ou 8 bits à chaque instruction. On verra que ce point de départ ne sera pas sans conséquences pour nos implémentations. Mais il faudra bien comparer chaque algorithme proposé plus haut pour chacun de ces formats de données. Par ailleurs, les cœurs ont chacun un cache L1 de 32 ko. Cette valeur n est pas si élevée et il faudra sans doute en tenir compte. Le système d exploitation installé est la version 11.10 64 bits de la distribution UBUNTU. C est sur cette machine que nous avons effectué tous nos tests dont sont issus les résultats que nous présentons ci-après. En terme de méthodologie, il est utile de préciser que nous donnons des résultats en nombre de cycles d horloge du processeur, et ceci sur 2000 exécutions successives, et ces mesures étant prises après un nombre équivalent d exécutions préalables. Cela permet de "chauffer les caches". Néanmoins, ces moyennes peuvent varier d un test à l autre pour un même code exécutable, pour des raisons difficiles à identifier, mais probablement imputables au système d exploitation. Ces variations peuvent aussi être dues au jeu de données d entrée, généré de façon aléatoire. Ces variations restent heureusement du second ordre et dépassent rarement 2 % sur les codes les plus importants. Il arrive parfois que sur le test de "petites" fonctions, les variations soient plus importantes. Enfin, et sauf précision contraire, nous avons utilisé le compilateur gcc version 4.6.1 x86_64. 2.1 Opérations sur le corps binaire F 2 m 2.1.1 Addition Cette opération, de par la caractéristique 2 du corps F 2 m considéré, se résume à une opération XOR bit à bit. La table de vérité du XOR bit à bit se présente comme suit : XOR a b S = a b 0 0 0 0 1 1 1 0 1 1 1 0 Lorsque l on additionne deux polynômes A = n i=0 a i x i et B = n i=0 b i x i, on ne propage pas de retenue comme pour une addition arithmétique classique. En effet : A + B = n (a i + b i ) x i. i=0 Ainsi, quel que soit le nombre de monômes d un degré donné que l on additionne, le coefficient de la somme de ces monômes ne peut prendre que deux valeurs, 0 ou 1. 2. Single Instruction Multiple Data 13

Nous remarquons aussi qu additionner ou soustraire revient au même. En effet, la caractéristique 2 implique 2 0. Autrement dit : x F 2 m, on a : x + x = x x = x x = 0. Ceci est à garder en mémoire, notamment lorsque des algorithmes que nous examinerons ultérieurement font intervenir des additions ou des soustractions. D ailleurs, nous l avons déjà sous-entendu dans les formules de l addition et du doublement de points de courbe elliptique données plus haut (voir 1.1.2, page 10). Enfin, dernière remarque, cette opération est implémentée dans les jeux d instructions des processeurs et accessibles également par un opérateur en C ou C++ pour des données de types entier, et des instructions intrinsic pour le format 128 bits, moyennant l utilisation des options de compilation nécessaires. Sans aller plus loin, on comprend donc le faible coût de cette opération a priori. Algorithme pour l addition Le travail sur cette opération se révèle réduit : tous les processeurs disposent d une opération XOR bit à bit. Cette opération n est donc que l exécution sur le nombre de mots nécessaires d autant de XOR bit à bit que nécessaire. Selon la taille des mots, on peut penser légitimement que le temps d exécution d une telle fonction sera d autant plus rapide que cette taille de mots est importante. En effet, pour m = 233, 8 mots de 32 bits sont nécessaires, mais seulement 4 mots de 64 bits ou 2 mots de 128 bits ( m128i). 2.1.2 Multiplication La multiplication de polynômes sur F 2 m présente quelques particularités que nous détaillons ici. Premièrement, il faut rappeler qu il s agit d une multiplication de polynômes binaires, comme précédemment. Ces polynômes s écrivent de la façon suivante : a(x) = a 0 + a 1 x + a 2 x 2 +... + a n 1 x n 1 + a n x n avec a i {0, 1}, i = 0,..., n. Le résultat du produit de deux polynômes a et b de degré n est donc le suivant : a(x) b(x) = n i ( a k b i k )x i + i=0 k=0 2n i=n+1 ( n k=i n a k b i k )x i. Et ce polynôme a pour degré 2n. Pour évaluer un produit de polynômes, il faut donc calculer 2n termes, qui sont chacun la somme de i + 1 produits de coefficients pour les termes de degré i = 0,..., n, et 2n + 1 i produits pour les termes de degré i = n + 1,..., 2n, soit au total n(n + 1) produits. Ce constat permet d ores et déjà de penser qu un algorithme plus élégant que cette "school book method" sera nécessaire. Un corollaire de l utilisation de polynômes binaires représentés comme une suite de bits, c est qu une multiplication d un polynôme par un monôme revient à effectuer un décalage de notre champ de bit. Ainsi, si on note A la représentation binaire de a(x), élément de F 2 m : a(x) x = A << 1, 14

et plus généralement, i N : a(x) x i = A << i. (2.1) Deuxièmement, la multiplication a(x) b(x) donnant un polynôme de degré 2n (dans le cas où le degré de chaque opérande est n), le résultat est donc généralement en dehors du corps des opérandes. Nous serons donc amenés à effectuer des réductions modulaires à l issue des multiplications. Mais nous avions déjà évoqué cette contrainte plus haut. En résumé, une multiplication de polynômes éléments de F 2 m consiste en une combinaison de décalages et de XOR bit à bit, opérations que nos processeurs effectuent avec des instructions de bas niveaux efficaces, et accessibles par des instructions intrinsic en C pour des données de type _m128i, encore une fois. Les choses sérieuses commencent ici. Les auteurs dans [5] décrivent quatre algorithmes, en partie également décrits dans [10]. Ces algorithmes sont présentés pour le cas où l on manipule des mots de 32 bits, mais on en déduit aisément leurs petits frères pour des mots de taille différente (64 ou 128 bits). Algorithme 1 : Right-to-left shift-and-add field multiplication Cet algorithme propose d additionner le polynôme b au résultat, après l avoir décalé (b = b.x), si le coefficient de a correspondant est à 1. Cela revient à écrire : Soit a(x) = n i=0 a i x i et b(x) = n i=0 b i x i, on a alors : a(x) b(x) = n a i (x i b(x)). i=0 Le décalage est fait mot par mot, du mot de poids faible vers les mots de poids fort. On sauvegarde le bit de poids fort d un mot dans une variable (retenue) pour l ajouter au mot suivant après décalage, afin d affecter ce bit au bit de poids faible du mot suivant. Cet algorithme modifie l opérande b à chaque décalage. Il faut donc un tableau intermédiaire supplémentaire si on veut préserver l opérande pour des calculs ultérieurs. Cela permet de conserver le tableau initial en vue de sa réutilisation pour d autres calculs. Algorithm 1 Right-to-left shift-and-add field multiplication Require: Binary polynomials a(x) and b(x) of degree at most m 1. Ensure: c(x) = a(x) b(x) 1: if a 0 = 1 then 2: c b. 3: else 4: c 0. 5: end if 6: for i from 1 to m 1 do 7: b b x. 8: if a i = 1 then 9: c c + b. 10: end if 11: end for 12: return (C). 15

Algorithme 2 : Right-to-left comb method for polynomial multiplication Cet algorithme diffère du premier en ce que la multiplication est effectuée bit par bit sur tous les mots à la suite, et non pas en parcourant tout le polynôme du degré 0 vers le degré le plus élevé (comb signifie "peigne"). On utilise là encore un tableau temporaire pour ne pas affecter b par les décalages. Dans l algorithme, on note C{j} le tableau tronqué (C[n], C[n 1],..., C[j +1], C[j]), en considérant C = (C[n],..., C[2], C[1], C[0]). On note t le nombre de mots qui représentent nos polynômes sur F 2 m. Algorithm 2 Right-to-left comb method for polynomial multiplication Require: Binary polynomials a(x) and b(x) of degree at most m 1. Ensure: c(x) = a(x) b(x). 1: C 0. 2: for k from 0 to 31 do 3: for j from 0 to t 1 do 4: if the kth bit of A[j] is 1 then 5: add B to C{j}. 6: end if 7: end for 8: if k 31 then 9: B B x. 10: end if 11: end for 12: return (C). Algorithme 3 : Left -to-right comb method for polynomial multiplication Cet algorithme est similaire au précédent, mais les mots sont parcourus en sens inverse (Left-to-right). Il ne faut alors pas décaler b. En revanche, à la place, on décale c à chaque pas, ce qui implique un décalage sur un nombre de mots doubles par rapport à l algorithme précédent. Cet algorithme ne modifie pas les opérandes d entrées. Algorithm 3 Left-to-right comb method for polynomial multiplication Require: Binary polynomials a(x) and b(x) of degree at most m 1. Ensure: c(x) = a(x) b(x). 1: C 0. 2: for k from 31 downto 0 do 3: for j from 0 to t 1 do 4: if the kth bit of A[j] is 1 then 5: add B to C{j}. 6: end if 7: end for 8: if k 0 then 9: C C x. 10: end if 11: end for 12: return (C). 16

Algorithme 4 : Left -to-right comb method with windows of width w = 4 Cet algorithme est en fait une optimisation de l algorithme précédent, en faisant une sorte de "blocking" ou "tiling". Les auteurs dans [5] parlent de "window technique". Ici, on a le calcul préliminaire d une table de 15 polynômes, correspondants à u b, où u est un élément de l ensemble des polynômes représentés par un champ de 4 bits (on se passe de calculer le cas u = 0!). Ceci permet dans la suite de traiter les mots par paquets de 4 bits à chaque tour de boucle au lieu du calcul bit par bit. Cette optimisation n est possible que sur l Algorithme 3, du fait de la préservation de b et du décalage sur c. Algorithm 4 Left-to-right comb method with windows of width w = 4 Require: Binary polynomials a(x) and b(x) of degree at most m 1. Ensure: c(x) = a(x) b(x). 1: Compute B u (x) = u(x) b(x) for all polynomials u(x) of degree at most 3. 2: C 0 3: for k from 7 downto 0 do 4: for j from 0 to t 1 do 5: Let u = (u 3, u 2, u 1, u 0 ), where u i is bit (4k + i) of A[j]. Add B u to C{j}. 6: end for 7: if k 0 then 8: C C x 4. 9: end if 10: end for 11: return (C). Les auteurs dans [2] décrivent une variante de cet algorithme travaillant mot à mot, mais nécessitant une phase de réparation ("repair step"). Nous n avons pas implémenté cette variante. Plus intéressante est la proposition faite dans le même [2] concernant le calcul préalable de la table. Nous donnons ici cet algorithme : Require: Binary polynomials b(x) of degree at most m 1. Ensure: B u (x)[2 w ] = u(x) b(x) where u(x) all polynomials of degree at most 3. 1: B u [2 4 ] {0, b, 0,...}. 2: for i from 2 to 2 w 1 by 2 do 3: B u [i] u[i >> 1] << 1. 4: B u [i + 1] B u [i] b. 5: end for 6: return (B u (x)[2 w ]). Les auteurs dans [5] font remarquer que l Algorithme 2 et l Algorithme 3 sont plus rapides que l Algorithme 1. Du fait du décalage sur un nombre de mots moindre, l Algorithme 2 est un peu plus rapide que l Algorithme 3. Mais celui-ci permet l optimisation proposée dans l Algorithme 4, qui est réputé le plus efficace, malgré la nécessité du calcul préalable de la table. 17

Algorithme de Karatsuba Il s agit d un algorithme qui a été proposé par Karatsuba dès 1963, à l origine pour effectuer des multiplications sur des grands entiers. La complexité de l algorithme de Karatsuba est inférieur à la "school book method", en ce que le nombre d opérations élémentaires est inférieur. Le gain peut être chiffré de la façon suivante 3 :...algorithme dit de multiplication rapide de deux nombres de n chiffres en n log 2 (3) opérations élémentaires (tels que produit ou somme de deux chiffres) au lieu de n 2. Pour n = 1000, n log 2 (3) est de l ordre de 50 000 alors que n 2 = 1000000. Dans notre cas, pour la multiplication de polynômes binaires, on peut espérer avoir un gain significatif. Ceci est sans doute vrai pour les grands polynômes. Pour des polynômes de degré plus faible, il faudra envisager, sans doute, un appel récursif à l algorithme de Karatsuba, et faire appel à l algorithme le plus performant pour effectuer les produits élémentaires. L arborescence des calculs doit être compensée par le nombre moindre d opérations, dans ce cas. Dans un premier temps, l implémentation initiale qui a été réalisée donne lieu aux étapes suivantes : Soit A = n 1 i=0 a i x i et B = n 1 i=0 b i x i deux polynômes de degré n 1. On note et A l = n/2 1 i=0 a i x i et A h = n 1 i=n/2 a i x i, B l = n/2 1 i=0 b i x i et B h = n 1 i=n/2 b i x i. Lors de l appel de la fonction Karatsuba, on commence par déclarer trois tableaux D0, D1 et D2 qui contiendront les résultats intermédiaires suivants : D0 = A l.b l, D1 = (A l + A h ).(B l + B h ), D2 = A h.b h. On calcule alors successivement, D0, D1 et D2, soit par un appel récursif, soit, si la taille le permet, par l algorithme de multiplication le plus adapté ; Enfin, on effectue la reconstruction finale pour obtenir C = A.B, soit : C = D0 + (D1 + D2 + D0) x n/2 + D2 x n. On remarque encore une fois qu il n y a que des additions et des décalages dans la reconstruction finale, de par la caractéristique 2 du corps F 2 m. Dans notre cas, nous avons choisi n de façon à avoir un nombre de mots puissance de 2. Ceci simplifie en effet la question des appels récursifs éventuels. En revanche, selon la valeur de m, utiliser un nombre de mots puissance de deux conduit parfois à avoir un nombre de mots plus grand que strictement nécessaire. Les mots de poids fort surnuméraires prendront alors la valeur 0. On le découvre dans la Table 2.1. L algorithme de Karatsuba que nous avons implémenté (pour m = 233 et mots de 64 bits) est l Algorithme 5. 3. tiré de http : //fr.wikipedia.org/wiki/algorithme_de_karatsuba 18

Nombre de mots m = Polynômes de degré m de F 2 m 163 233 409 32 bits 8 dont 2 nuls 8 16 dont 3 nuls 64 bits 4 dont 1 nul 4 8 dont 1 nul 128 bits 2 2 4 TABLE 2.1 Codage des polynômes en fonction de leur degré, nombre d éléments du tableau. Algorithm 5 Algorithme de Karatsuba Require: a(x) and b(x) polynômes sur 4 mots, soit unsigned long int A[4], B[4]. Ensure: c(x) = a(x) b(x), polynôme sur 8 mots, unsigned long intc[8]. 1: (DD0h, DD0l) A[0] B[0]. // résultat DD0 sur 2 mots. 2: (DD2h, DD2l) A[1] B[1]. 3: (DD1h, DD1l) (A[0] A[1]) (B[0] B[1]). {reconstruction de D0, sur 4 mots} 4: D0ll DD0l. 5: D0lh DD0h DD0l DD1l DD2l. 6: D0hl DD2l DD0h DD1h DD2h. 7: D0hh DD2h. 8: (DD0h, DD0l) A[2] B[2]. // résultat DD0 sur 2 mots. 9: (DD2h, DD2l) A[3] B[3]. 10: (DD1h, DD1l) (A[2] A[3]) (B[2] B[3]). {reconstruction de D2, sur 4 mots} 11: D2ll DD0l. 12: D2lh DD0h DD0l DD1l DD2l. 13: D2hl DD2l DD0h DD1h DD2h. 14: D2hh DD2h. 15: (DD0h, DD0l) (A[0] A[2]) (B[0] B[2]). // résultat DD0 sur 2 mots. 16: (DD2h, DD2l) (A[1] A[3]) (B[1] B[3]). 17: (DD1h, DD1l) (A[0] A[1] A[2] A[3]) (B[0] B[1] B[2] B[3]). {reconstruction de D1, sur 4 mots} 18: D1ll DD0l. 19: D1lh DD0h DD0l DD1l DD2l. 20: D1hl DD2l DD0h DD1h DD2h. 21: D1hh DD2h. {reconstruction finale, sur 8 mots} 22: C[0] D0ll. 23: C[1] D0lh. 24: C[2] D0hl D0ll D1ll D2ll. 25: C[3] D0hh D0lh D1lh D2lh. 26: C[4] D2ll D0hl D1hl D2hl. 27: C[5] D2lh D0hh D1hh D2hh. 28: C[6] D2hl. 29: C[7] D2hh. 30: return (C) 19

Les produits élémentaires réalisés dans cet algorithme peuvent être effectués par l Algorithme 4, ou bien à l aide de la multiplication sans retenue du processeur (instruction PCLMULQDQ). Implémentation de la multiplication Nous passons sur toutes les étapes du développement des différents algorithmes. En terme de méthodologie, nous avons validé les résultats de calculs obtenus par nos implémentations en effectuant quelques cas particuliers d une part, puis en croisant les résultats des différents algorithmes d autre part. Lorsque cinq algorithmes différents et indépendants donnent les mêmes résultats, on peut accorder une confiance à l ensemble. L essai de tous les algorithmes n a pas été fait selon toute la combinatoire des degrés de polynômes, tailles de mots, plate-formes... Nous avons cependant veillé à balayer suffisamment de configurations pour en tirer des conclusions les plus solides possibles. Voici les grandes caractéristiques de toutes les implémentations : L ensemble des tableaux représentants les polynômes a fait l objet d allocations statiques uniquement. Ceci se comprend pour deux raisons principalement. Premièrement, lors de l appel de fonctions, si nous avons besoin d un tableau local à la fonction en question, il est plus rapide de procéder ainsi plutôt que de passer par une allocation dynamique. Deuxièmement, la taille des tableaux en question est fixe. L option de compilation relative au niveau d optimisation est -O2 ou -O3 et est précisée à chaque fois. Lorsque les boucles comportent un nombre d itérations réduit (moins de 8) et sauf indications contraires, nous avons déroulé la boucle en question dans notre code. Le compilateur procède à cette optimisation de lui-même avec l option -O3, mais nous avons préféré coder de cette manière pour ne pas en dépendre. Nous avons également testé l instruction des processeurs INTEL de multiplication sans retenue. Son utilisation a été réalisée à l aide de l instruction intrinsic suivante : _mm_clmulepi64_si128( m128i x, m128i y, const int i) Cette instruction prend en argument deux variables de type m128i et un argument immédiat i qui indique quel mot de 64 bits de la variable 128 bits est utilisé pour les opérandes. i peut prendre 4 valeurs : 0 : on multiplie les deux mots de poids faibles de x et y ; 1 : on multiplie le mot de poids fort de x et le mot de poids faible de y ; 2 : on multiplie le mot de poids faible de x et le mot de poids fort de y ; 3 : on multiplie les deux mots de poids forts de x et y. Toutes ces informations sont disponibles dans la documentation INTEL [4]. Voici la transcription d un code minimum qui multiplie deux mots de 64 bits (A et B sont de type unsigned long int) : m128i x = _mm_load_si128( ( m128i const *) &A); m128i y = _mm_load_si128( ( m128i const *) &B); m128i z = _mm_clmulepi64_si128 (x, y, 0); C[0] = * ((unsigned long int *)&z); C[1] = * ((unsigned long int *)&z + 1); 20

Pour les deux dernières lignes, on peut aussi utiliser une instruction intrinsic de prototype _mm_extract_epi64( m128i x, const int i), i valant 0 ou 1 selon que l on veut extraire les 64 bits respectivement de poids faible ou fort de notre variable 128 bits dans un mots de 64 bits. Pour commencer, nous avons travaillé sur le produit de deux mots de 64 bits (des polynômes de degré au plus égal à 63). Ces produits renvoient donc un résultat sur deux mots de 64 bits. Voici les résultats pour l Algorithme 2, une implémentation de l Algorithme 4, et le produit effectué à l aide de l instruction _mm_clmulepi64_si128( m128i x, m128i y, const int i) (nombre de cycles moyens sur 2000 exécutions) : Produits Polynômes de degré 63 Algorithme 2 2023 Algorithme 4 243 _mm_clmulepi64_si128 58 TABLE 2.2 Comparaison des algorithmes de multiplications, pour des polynômes de degré 64, option de compilation -O3. L Algorithme 4 donne des résultats très supérieurs à l Algorithme 2, sans réelle surprise. On remarque aussi la rapidité de la multiplication effectuée à l aide de _mm_clmulepi64_si128, quatre fois plus rapide que l Algorithme 4. Il nous faut maintenant regarder les implémentations pour des degrés supérieurs. Nous avons privilégié deux cas : m = 233 et m = 409. Pour ces deux cas, nous présentons les résultats pour différentes combinaisons : mots de 64 (type unsigned long int) et 128 bits (type m128i) ; l Algorithme 4 ; l Algorithme de Karatsuba utilisant l Algorithme 4 pour les produits élémentaires ; l Algorithme de Karatsuba utilisant _mm_clmulepi64_si128 pour les produits élémentaires. La table (voir Table 2.3, page 22) qui résume tous ces résultats montre que : l Algorithme de Karatsuba utilisant _mm_clmulepi64_si128 pour les produits élémentaires est dans tous les cas le plus performant ; l algorithme de Karatsuba utilisant l Algorithme 4 pour les produits élémentaires est meilleur que l Algorithme 4 seulement pour m = 233 ; l Algorithme de Karatsuba utilisant _mm_clmulepi64_si128 pour les produits élémentaires est meilleur pour des produits sur des tableaux de type m128i que de type unsigned long int ; Pour l Algorithme 4 m = 233, la multiplication sur le type unsigned long int est plus rapide. 21

Produits Polynômes de degré 232 64 bits m128i m = 233 Algorithme 4 2002 2150 Karatsuba Algorithme 4 1761 Karatsuba _mm_clmulepi64_si128 481 219 Polynômes de degré 408 64 bits m128i m = 409 Algorithme 4 2945 Karatsuba Algorithme 4 3166 Karatsuba _mm_clmulepi64_si128 951 616 TABLE 2.3 Comparaison des algorithmes de multiplications, pour des polynômes de degré 64, option de compilation -O3, nombre de cycles moyens sur 2000 exécutions. 2.1.3 Réduction modulaire dans F 2 m Cette opération est nécessaire à l issue de multiplications et d élévations au carré, pour ramener le résultat obtenu de degré au plus 2m 2 à un polynôme de degré m 1. Nous y avons déjà fait allusion : il faut se mettre d accord sur un polynôme de réduction. Le NIST dans [11] 4 nous préconise un polynôme pour chaque degré. Il s agit de trinômes ou de pentanômes. Les voici : pour m = 163 : f(x) = x 163 + x 7 + x 6 + x 3 + 1 ; pour m = 233 : f(x) = x 233 + x 74 + 1 ; pour m = 283 : f(x) = x 283 + x 12 + x 7 + x 5 + 1 ; pour m = 409 : f(x) = x 409 + x 87 + 1 ; pour m = 571 : f(x) = x 571 + x 10 + x 5 + x 2 + 1. Effectuer la réduction modulaire d un polynôme a(x) de degré n m, c est chercher le reste de la division de a(x) par f(x) : a(x) = q(x) f(x) + b(x), où deg(b(x)) < deg(f(x)). On a donc : b(x) a(x) mod f(x). On peut dire que b(x) est le reste de la division de a(x) par f(x). 4. p. 90ss 22

Le reste de cette division se calcule comme suit : Require: Binary polynomials a(x) of degree > m 1. Ensure: b(x) a(x) mod f(x) of degree at most m 1. 1: b(x) a(x). 2: while deg(b(x)) deg(f(x) do 3: j deg(b(x)) deg(f(x). 4: b(x) b(x) x j f(x). 5: end while 6: return (b(x)). En remarquant que la soustraction et l addition sont en fait les mêmes opérations sur notre corps, on peut prévoir que m additions au maximum seront nécessaires pour mener à bien cette opération, dans le cas où l on souhaite utiliser un polynôme irréductible f(x) quelconque. Il y a en effet une contrainte dans le choix de f(x), que respectent les polynômes préconisés par [11], cela va sans dire. En effet, f(x) doit être irréductible, c est à dire divisible uniquement par 1 et par lui-même sur F 2 [x]. Il est important de le noter, car cela veut dire que si l on veut utiliser un autre polynôme que celui préconisé par [11], si l on estime qu un gain en efficacité est possible, il faudra penser à le choisir convenablement. Algorithme général de réduction Les auteurs dans [5] décrivent un algorithme général de réduction, c est à dire avec f(x) de degré m irréductible quelconque (pour des polynômes codés à l aide de mots de 32 bits). Cette façon de faire est décrite dans l Algorithme 6. Pour f(x) le polynôme de réduction de degré m, on note r(x) le polynôme r(x) = f(x) x m. (2.2) Algorithm 6 modular reduction (one bit at a time) Require: A binary polynomials c(x) of degree at most 2m 2. Ensure: c(x) mod f(x) 1: Precomputation u k (x) = x k r(x), k, 0 k 31. 2: for i from 2m 2 downto m do 3: if c i = 1 then 4: Let j = (i m)/32 and k = (i m) 32j. 5: Add u k (x) to C{j}. 6: end if 7: end for 8: return (C[t 1],..., C[1], C[0]) Cet algorithme propose donc d effectuer m 1 tests, et au plus m 1 additions (typiquement (m 1)/2). Une telle façon de procéder semble donc plutôt coûteuse en comparaison de la multiplication, par exemple. Algorithme rapide Plusieurs articles ([5], [13] et [1]) proposent une façon de faire beaucoup plus rapide. Sous réserve que f(x) soit connu à l avance, on peut tirer avantage de la nature du polynôme r(x) défini dans l équation (2.2). NIST[11] préconise des trinômes ou des pentanômes. Plutôt que 23

de raisonner bit par bit du polynôme à réduire c(x), on peut raisonner monôme par monôme de r(x) et effectuer en une fois la réduction par terme de ce polynôme. Plaçons-nous dans le cas où f(x) est un trinôme f(x) = x m + x r + 1. Posons : r(x) = f(x) x m = x r + 1, et : c(x) = c 0 (x) + c 1 (x) x m + c 2 (x) x 2m r où c 0 (x) = m 1 0 c i x i, c 1 (x) = 2m deg(r) 1 m c i x i m, c 2 (x) = 2m 2 2m deg(r) c i x i 2m+r, et respectivement C 0, C 1 et C 2 leur représentation binaire (qui ne sont que des troncatures de C). On remarque que : x m x r + 1 mod f(x), x 2m r x m r + x r + 1 mod f(x). On peut donc remplacer les monômes x r et x 2m r par leur forme réduite modulo f(x) dans l expression de c(x). On a alors : c(x) mod f(x) = c 0 (x) + c 1 (x) (x r + 1) + c 2 (x) (x m r + x r + 1). En terme de représentation binaire, on se souvient (voir équation (2.1), page 15) que multiplier par un monôme, c est décaler à gauche sa représentation binaire du degré du monôme. On en déduit la représentation binaire de c 1 (x) (x r + 1) : et de c 2 (x) (x m r + x r + 1) : (C 1 ) (C 1 << r). (2.3) (C 2 ) (C 2 << r) (C 2 << m r). (2.4) Si on note R la représentation binaire de la réduction modulo f(x) de c(x), on a enfin, avec les représentations (2.3) et (2.4) : R = C 0 C 1 (C 1 << r) C 2 (C 2 << r) (C 2 << (m r)). (2.5) La réduction se résume ainsi à quelques additions (XOR), masquages (AND) et décalages de C avec lui-même. Il ne reste qu à tronquer au degré m 1 pour finir. Le cas où f(x) est un pentanôme n est guère différent dans le principe. Un exemple pour m = 233 avec des mots de 64 bits est présenté dans l Algorithme 7. C est l algorithme que nous avons implémenté. Cet algorithme rapide peut être adapté aux divers degrés et formats de mots. Il se justifie d autant plus que le polynôme de réduction f(x) reste le même tout au long des calculs (notamment le produit scalaire que nous souhaitons exécuter). 24