Outils pour utilisateurs

Outils du site


nsi:tds:cryptographie:ecc

Ceci est une ancienne révision du document !



Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172

Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172

Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172

Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 149

Warning: Trying to access array offset on value of type null in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 149

Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214

Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214

Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214

Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214

Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214

Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214

Cryptographie sur les courbes elliptiques

Présentation rapide

Calcul sur des points

On connaît des techniques cryptographique exploitant les propriétés des nombres entiers, comme RSA ou encore ElGamal. Avec les courbes elliptiques on reprend des idées semblables à ceci près que l'on fait les calculs sur les points d'une courbe.

On définit ce que cela signifie que de calculer $P + Q$. On obtient des tables de calcul plus compliquées que celles des nombres entiers d'autant que ces tables vont dépendre de la courbe choisie.

Courbes elliptiques

Les courbes elliptiques sont des courbes du plan définies dans un repère $(O;x,y)$ par une équation de forme $$(E): y^2 = x^3 + a\cdot x + b$$

Une ellipse a une équation plutôt de la forme $\frac{x^2}{a^2} + \frac{y^2}{b^2} = 1$.

Les courbes elliptiques tiennent leur nom du fait qu'elles sont apparues au XIXe siècle dans des travaux de Weierstrass sur la circonférence des ellipses. Depuis elles se sont avérées très fécondes : elles permettent de décrire le mouvement d'une toupie, elles ont été utilisées dans la démonstration du théorème de Fermat et, ce qui nous intéresse maintenant, elles sont utilisées en cryptographie.

Une courbe particulière

Quand on fait de la cryptographie, choisir les valeurs de a et b fait partie du choix de clé. La seule contrainte est qu'il faut $4\cdot a^3 + 27\cdot b^2 \neq 0$ pour que la courbe soit suffisamment régulière.

Dans le cadre de ce TD, on choisira $a = -1$ et $b = 1$, donc : $$(E) : y^2 = x^3 - x + 1$$

Addition sur des points

Pour deux points $P$ et $Q$ de la courbe, on définit l'opération $P + Q$ :

  • tracer la droite $(PQ)$,
  • relever la 3e intersection de cette droite avec la courbe,
  • prendre le symétrique de ce point sur la courbe. On le nomme $R$.
  • On définit : $R = P + Q$

Cela peut sembler une façon étrange de concevoir l'addition et pourtant, cette addition a de bonnes propriétés :

  • Elle est associative : $(P + Q) + R = P + (Q + R)$ – autrement dit, on peut enlever les parenthèses.
  • Elle est commutative : $P + Q = Q + P$

Élément neutre

Supposons que l'on prenne $P$ et $Q$ symétriques sur la courbe.

La droite $(PQ)$ est verticale et n'a pas d'autre intersection avec la courbe. On définit alors un point $P_0$ qui est en quelque sorte à l'infini. On dit que dans ce cas là, $(PQ)$ coupe la courbe en l'infini, donc en $P_0$ et alors $P + Q = P_0$.

On définit aussi que $P_0$ est l'élément neutre de notre addition, c'est à dire le $0$. Autrement dit, on a toujours $P + P_0 = P$ – de même que l'on dirait $x + 0 = x$.

Ainsi notre addition a deux nouvelles propriétés essentielles :

  • $P_0$ est l'élément neutre tel que pour tout $P$, $P + P_0 = P$.
  • Soit $P$ un point de la courbe, son symétrique par rapport à $(Ox)$ est $Q$ et on a a $P + Q = P_0$. On note donc $Q = - P$ ce qui signifie que tout $P$ a un opposé $-P$ qui est son symétrique.

Sommer un point avec lui même

Notre addition $P + Q$ suppose de tracer $(PQ)$ ce qui sera impossible si $P = Q$. Dans ce cas particulier, au lieu de tracer $(PQ)$, on utilise la tangente à la courbe en $P$.

Ainsi, nous pouvons obtenir $P + P = 2P$ et son opposé $-2p$. Partant de là on pourra calculer $P + 2P = 3P$ et déduire $-3P$. Etc.

Ainsi, on a donné un sens à $n\cdot P, n\in\mathbb{Z}$.

Une arithmétique de points

Notre addition a toutes les propriétés nécessaires et tous les calculs que l'on a envie de faire sont valables : Par exemple $2\cdot(3P + Q) = 6P + 2Q$.

  1. Concrètement pour le premier calcul, $3P$ s'obtient en calculant $P+P = 2P$ puis $P + 2P = 3P$. Ensuite On cherche un point $Z = 3P + Q$. Enfin on cherche $Z + Z = 2Z$. Nous avons défini chacun de ces calculs élémentaires.
  2. Pour le second calcul, on calculerait $2P = P+P$, puis $4P = 2P + 2P$, puis $6P = 4P + 2P$, puis $2Q = Q + Q$ et enfin $4P + 2Q$.

Ce qui est remarquable, c'est que ces deux constructions graphiques produiront le même résultat. C'est pour cette raison que l'on peut parler d'addition : l'addition ainsi définie a les bonnes propriétés.

Les formules

Pour le calcul de $P + Q$ On peut trouver toutes les formules utiles sur cette page Wikipedia. Je les reprends ici, avec $P(x_P;y_P)$ et $Q(x_Q;y_Q)$.

Cas 1, $x_P \neq x_Q$

L'équation de $(PQ)$ est de la forme $y=m\cdot x + p$ avec $m = \frac{y_P - y_Q}{x_P - x_Q}$ et $p = \frac{x_P\cdot y_Q - x_Q\cdot y_P}{x_P - x_Q}$. On peut calculer ensuite : $$x_{P+Q} = m^2 - x_P - x_Q \quad ; \quad y_{P+Q} = - m\cdot x_{P+Q} - p$$

Cas 2, $x_P = x_Q$ et $y_P = - y_Q$

Il s'agit de deux points opposés. Dans ce cas, $P + Q = P_0$.

Cas 3, $x_P = x_Q$ et $y_P \neq - y_Q$

La seule possibilité est que $P = Q$ et dans ce cas on cherche $2P$ en utilisant la tangente.

La tangente a pour équation $y = m\cdot x + p$ avec $m = \frac{3\cdot x_P^2 + a}{2y_P}$ et $p = y_P - m\cdot x_P$. On peut calculer ensuite : $$x_{2P} = m^2 - 2\cdot x_P \quad ; \quad y_{2P} = -m\cdot x_{2P} - p$$

Dans le cadre du TD, on a $a = -1$.

Cas modulaire

Redéfinition

Comme avec les nombres entiers, il est plus intéressant de travailler avec modulo :

  • Les calculs seront exclusivement sur des nombres entiers ce qui facilitera les choses,
  • comme avec les nombres entiers, les modulos “embrouillent” un peu les calculs ce qui est idéal pour la cryptographie.

On modifie un peut la définition :

  • On choisit un premier $p$, en situation réelle on le prend assez grand.
  • Les points considérés ont des coordonnées $(x ; y)$ entières.
  • On considère que deux points $P_1(x_1;y_1)$ et $P_2(x_2;y_2)$ sont identiques si $x_1 \equiv x_2 [p]$ et $y_1 \equiv y_2 [p]$
  • L'équation de la courbe est maintenant $(E): y^2 \equiv x^3 + a\cdot x + b [p]$
  • La contrainte devient $4\cdot a^3 + 27 \cdot b^2 \not\equiv 0 [p]$

Dans le cadre de ce TD, on prendra $p = 13$ et toujours $a=-1$ et $b=1$.

Formules

Tenant compte de ces nouvelles définition, notre addition fonctionne toujours et a toujours les bonnes propriété !

Les formules présentées plus haut sont toujours valides à ceci près que toutes les quantités sont calculées modulo $p$. De plus, vous pouvez voir des divisions. On n'utilisera pas l'opérateur de division, mais on utilisera l'inverse modulaire.

Implémentation

Puisque toute la technique consiste à inventer une addition sur des objets qui normalement ne s'additionnent pas, il me parait pertinent d'utiliser des classes et d'utiliser des méthodes magiques qui vont nous permettre de définir ce que sera l'addition.

Cas particulier du calcul de n.P

L'algorithme de chiffrement que l'on envisagera ensuite repose sur le fait qu'il peut être très rapide de calculer $n \cdot P = \overbrace{P + P + \cdots + P}^{n\times}$ mais très long de trouver le $n$ vérifiant $n\cdot P = Q$. Il est donc très important de disposer d'un algorithme rapide pour calculer $n\cdot P$.

On retrouve exactement le même principe que l'exponentiation rapide.

Approche naïve
Entrée : n un entier positif, P un point
Sortie : n*P
    Q = P0 (point nul)
    RÉPÉTER n FOIS
        Q = Q + P
    FIN
    RENVOYER Q

La boucle se répète $n$ fois, mais dans le cas cryptographique, $n$ est un très grand nombre.

Approche rapide
Entrée : n un entier positif, P un point
Sortie : n*P
    Q = P0 (point nul)
    S = P
    TANT QUE n > 0:
        SI n % 2 = 1 ALORS
            Q = Q + S
        FIN
        S = S + S
        n = n // 2    
    FIN
    RENVOYER Q

Fichier de base

Je vous propose la structure suivante.

# module ecc.py

class Point:
    P = 13  # premier choisi pour le modulo
    A = -1  # coefficient a
    B = 1   # coefficient b
    @absrtactmethod
    def test(x,y):
        """
        Teste si des coordonnées (x,y) sont bien sur la courbe
        Par exemple ici : Point.test(1,1) renvoie True
        """
        return (x**3 + Point.A * x + Point.B - y**2) % Point.P == 0
        
    def __init__(self, x, y):
        """
        x, y: coordonnées du point
        si x = None ou y = None, c'est le point P0
        """
        if x == None or y == None:
            self.nul = True
            return
        self.nul = False
        self.x = x % self.P
        self.y = y % self.P
        # vérification que (x,y) est bien sur la courbe choisie
        assert Point.test(x,y)
    
    def __add__(P, Q):
        """
        renvoie le point résultat de P + Q
          Sera automatiquement utilisé quand on écrira P + Q
          dans une calcul avec P et Q deux objets Point
        """
        
        # à vous

    def opposite(self):
       """
       renvoie l'opposé d'un point, c'est à dire
       son symétrique par rapport à (Ox)
       """
       if self.nul:
          # si P0, -P0 = P0
          return self
       return Point(self.x, -self.y)

    def __mul__(P,n):
        """
        P: un point
        n: un entier
          Sera automatiquement appelé quand on fera un calcul P*n
          avec P un Point et n un int
        Renvoie n.P
        Utilisez une méthode rapide de préférence.
        """
        assert type(n) == int
        
        # à vous
    
    def __eq__(P, Q):
       """
       Fonction automatiquement appelée quand on testera P == Q
       On veut comparer les coordonnées
       """
       if P.nul or Q.nul:
           # au moins l'un des deux est nul, égaux si les deux nuls
           return P.nul == Q.nul
       # sinon égaux si coordonnées égales
       return P.x == Q.x and P.y == Q.y
    
    def __str__(self):
        """
        Pour affichage en mode texte
        """
        if self.nul:
            return "P0"
        return "({} ; {})".format(self.x, self.y)
    
    def __repr__(self):
        """
        Pour affichage dans la console
        """
        if self.nul:
            return "<P0>"
        return "<{} ; {}>".format(self.x, self.y)
        
if __name__ == "__main__"
    # petit test
    # définition de points se trouvant sur la courbe (avec modulo)
    P = Point(1,1)
    Q = Point(3,5)
    R = Point(4,3)
    
    # exemple de calculs :
    Z = P + Q
    print("P + Q -> {}".format(Z))
    
    W = R*2
    print("2R -> {}".format(W))
    # remarque : pour l'utilisation de __mul__, il faut écrire R*2 et pas 2*R
    
    # vérification des propriétés
    assert (P + Q) + R == P + (Q + R)
    assert P + Q == Q + P
    

Cryptographie ?

Reprenons le chiffrement de ElGamal – on pourrait faire autrement, nos points ont les mêmes capacités que les entiers.

Calcul des clés

Dans le chiffre de ElGamal, Bob choisissait $p$, $d$ et $s$ avec $p$ premier, $1 < d < p$ et $s > 1$ puis il calculait $h = d^s \mod p$.

La clé public était $K_{PU} = (p, d, h)$.

Avec les courbes elliptiques : Bob choisit sa courbe (c'est à dire $a$ et $b$), le nombre premier $p$, un point $D$ de la courbe et un entier $s > 1$. Il calcule $H = s\cdot D$.

La clé public est $K_{PU} = (a, b, p, D, H)$.

Chiffrement

Avec ElGamal, Alice choisissait $a$ entier quelconque et pour transmettre l'entier $m$ elle calculait $r = m\cdot h^a \mod p$ et $t = d^a \mod p$.

Elle envoyait enfin $(r, t)$.

Avec les courbes elliptiques : le message d'Alice est le point $M$. Elle choisit $a$ entier quelconque et elle calcule les points $R = M + a\cdot H$ et $T = a\cdot D$.

Elle envoie $(R, T)$

Déchiffrement

Avec ElGamal, Bob calculait $t^s$, il cherchait $u$ l'inverse de $t^s$ puis il calculait $r\cdot u$ ce qui lui donnait $m$.

Avec les courbes elliptiques : Bob calcule le point $s\cdot T$, il cherche son opposé $-s\cdot T$ – ce qui est très rapide – puis il calcule $R - s\cdot T$ ce qui lui donne $M$.

Comprendre pourquoi ça marche : $T = a\cdot D$ donc $$s\cdot T = s\cdot a \cdot D = a \cdot (s \cdot D) = a \cdot H$$ $$R - s \cdot T = M + a \cdot H - a \cdot H = M$$

Le calcul est même plus simple qu'avec ElGamal, dès lors que l'on ne pense pas trop au fait que l'on calcule avec des points !

À faire

Écrire de plus les fonctions suivantes :

  • calculer_cle_prive(D, s) qui renvoie (D, H)
  • chiffrer(M, D, H) qui renvoie la paire (R, T) du message chiffré
  • dechiffrer(R, T, D, s) qui renvoie M.

La connaissance du nombre premier $p$ et de la courbe choisie sont important mais ces éléments sont déjà contenus dans notre classe Point. On pourra donc supposer que Alice et Bob ont déjà ces informations en main.

Faire le test en choisissant p = 17, d = 5, s = 12 et M = Point(5,11).

nsi/tds/cryptographie/ecc.1678742140.txt.gz · Dernière modification : de goupillwiki