Procédé de signature

Ed25519 expliqué mathématiquement

La signature attachée à chaque avis McGesund — de la courbe à la clé, jusqu'à l'équation que le navigateur du lecteur recalcule lui-même.

Mise à jour : 2026-09-07

1. De quoi il s'agit

Un avis publié sur McGesund n'est pas un simple champ de texte dans une base de données qu'il faudrait croire sur parole. Il est signé numériquement au moment de son envoi, et chaque visiteur peut ensuite recalculer cette signature dans son propre navigateur.

Pour cette signature, nous utilisons Ed25519. Contrairement à FALCON et ML-DSA, qui peuvent être apposés à côté sous forme de sceaux supplémentaires, Ed25519 n'est pas une option : chaque avis signé la porte, quels que soient la formule tarifaire et le mode de dépôt.

Un point important d'emblée :

Ed25519 n'est pas un chiffrement. Le texte de l'avis est justement fait pour être lu. La signature ne prouve pas la confidentialité, mais l'origine et l'intégrité.


2. Ce qui est signé exactement

Ce n'est pas le texte courant qui est signé, mais un objet de données compact qui fixe sans ambiguïté le texte et tout le reste :

{
  "v":   1,
  "typ": "rev-comment",
  "f":   "<ID de l'entreprise>",
  "c":   "<ID de l'avis>",
  "h":   "<SHA-256 du texte de l'avis>",
  "rh":  "<SHA-256 de l'ensemble du jeu de données soumis>",
  "rv":  1,
  "qh":  "<SHA-256 de l'enveloppe QR, uniquement pour les avis par QR>",
  "kid": "<ID de la clé>",
  "iat": 1757203200
}

Cet objet est encodé en CBOR. Cette suite d'octets — et non sa jolie représentation ci-dessus — constitue notre message mm. Signature et message voyagent ensemble dans une enveloppe :

Envelope=MCG1:    base64url(CBOR[3,  m,  σ])\text{Envelope} = \texttt{MCG1:} \;\|\; \mathrm{base64url}\bigl(\mathrm{CBOR}[\,3,\; m,\; \sigma\,]\bigr)

Le 33 est la version du format. Il n'y a rien de plus à l'intérieur — en particulier aucune signature post-quantique : celle-ci, lorsqu'elle existe, est stockée à côté du jeu de données et non dans l'enveloppe.


3. Ce que la signature doit garantir

Un lecteur qui arrive sur le profil d'une entreprise se pose deux questions :

  1. Cet avis provient-il réellement du système McGesund ?
  2. A-t-il été modifié après coup ?

Pour cela, il existe une paire de clés :

  • une clé privée — elle reste dans le service de signature
  • une clé publique — tout le monde peut l'avoir ; elle est adressée par l'identifiant de clé (kid) présent dans le payload

La signature se fait avec la clé privée. La vérification se fait avec la clé publique — et ce dans le navigateur du lecteur, pas sur notre serveur. C'est là tout l'enjeu : une vérification que nous effectuerions nous-mêmes et dont nous communiquerions le résultat ne serait pas une vérification, mais une affirmation.


4. Pourquoi une courbe elliptique ?

Toute signature a besoin d'un calcul facile dans un sens et pratiquement impossible dans l'autre. Pour Ed25519, il s'agit de la multiplication scalaire sur une courbe elliptique :

a    A=aB.a \;\longmapsto\; A = a\cdot B.

Calculer le point public AA à partir du nombre secret aa coûte quelques microsecondes. Remonter de AA vers aa revient à résoudre le problème du logarithme discret — aucune méthode connue n'en vient à bout à cette taille dans des délais humains.

Le gain pratique par rapport à des procédés plus anciens comme RSA, c'est la taille :

clé publiquesignature
RSA-3072384 o384 o
Ed2551932 o64 o

À niveau de sécurité comparable. 64 octets par avis ne représentent pas, même avec des millions d'avis, une taille sur laquelle il faille réfléchir.


5. La courbe edwards25519

Les calculs se font modulo un nombre premier :

p=225519.p = 2^{255}-19.

D'où le nom. La courbe est une courbe d'Edwards tordue :

x2+y2  =  1+dx2y2,d=121665121666modp.-x^2+y^2 \;=\; 1 + d\,x^2y^2, \qquad d = -\frac{121665}{121666} \bmod p.

Un « point » est un couple de nombres (x,y)(x,y) pris dans {0,,p1}\{0,\dots,p-1\} et vérifiant cette équation. Il n'y a aucune courbe à voir — le dessin de la section suivante est une aide visuelle sur les nombres réels, pas une image de l'espace de calcul réel.

Deux grandeurs viennent s'y ajouter :

  • un point de base BB fixé par convention,
  • l'ordre \ell du sous-groupe engendré par BB :
=2252+27742317777372353535851937790883648493.\ell = 2^{252} + 27742317777372353535851937790883648493.

\ell est premier. Cela signifie qu'en additionnant BB à lui-même encore et encore, on parcourt exactement \ell points distincts avant de revenir au point de départ. Tous les calculs portant sur des scalaires se font donc modulo \ell, tous ceux portant sur des coordonnées modulo pp. Confondre ces deux nombres est l'erreur classique du débutant.


6. Additionner des points

Deux points se combinent en un troisième selon une formule fixe :

x3=x1y2+y1x21+dx1x2y1y2,y3=y1y2x1x21dx1x2y1y2.x_3=\frac{x_1y_2+y_1x_2}{1+d\,x_1x_2y_1y_2}, \qquad y_3=\frac{y_1y_2-x_1x_2}{1-d\,x_1x_2y_1y_2}.

L'élément neutre est (0,1)(0,1) — le point où le calcul commence.

Cette formule possède une propriété qui ne saute pas aux yeux et qui compte plus, pour la sécurité, que n'importe quelle constante : elle est complète. Elle fonctionne pour toutes les entrées, sans cas particulier du type « les deux points sont identiques » ou « le résultat est l'élément neutre ». Les courbes de Weierstrass plus anciennes connaissent ces cas particuliers, et chacun d'eux est une branche dans le programme — une branche dont le temps d'exécution se mesure. Qui mesure la durée d'une signature apprend, avec de tels procédés, quelque chose sur la clé secrète.

Formules complètes signifie : toujours le même chemin de calcul, toujours la même durée, rien à mesurer.


7. La multiplication scalaire — le sens unique

nBn\cdot B signifie : additionner BB à lui-même exactement nn fois. Pour un nn de 253 bits, ce serait un travail absurdement long — d'où le recours au doublement :

B2B4B8BB \to 2B \to 4B \to 8B \to \dots

puis à la recomposition du nn voulu à partir de ces résultats intermédiaires. Environ 253 doublements suffisent pour n'importe quel nn. C'est le chemin aller.

Dans l'autre sens, ce raccourci n'existe pas. Déterminer le nombre aa à partir du point AA revient à résoudre le problème du logarithme discret.

(0,1) — élément neutreB2B3B4B5B6B
Une courbe d'Edwards avec les premiers multiples du point de base, calculés selon la véritable loi d'addition. Sur les nombres réels, ils se déplacent encore le long de la courbe dans un ordre visible — on pourrait remonter le chemin. Modulo p, c'est exactement cet ordre qui disparaît, et c'est là-dessus que repose la sécurité.

Dans le procédé réel, les calculs se font modulo pp. Là, il n'y a ni « gauche », ni « droite », ni proximité : 17B17\,B et 18B18\,B deviennent deux couples de nombres sans la moindre parenté visible.


8. La paire de clés du service de signature

Au départ, il y a 32 octets aléatoires, la graine (seed). Tout le reste en découle :

h=SHA-512(Seed),h=h0..31  a    h32..63preˊfixe.h = \mathrm{SHA\text{-}512}(\text{Seed}), \qquad h = \underbrace{h_{0..31}}_{\to\;a}\;\|\;\underbrace{h_{32..63}}_{\text{préfixe}}.

La première moitié donne le scalaire secret aa, mais pas telle quelle. Trois bits sont mis à un ou à zéro — c'est ce qu'on appelle le clamping :

  • les trois bits de poids faible sont mis à zéro : aa devient ainsi un multiple de 8. La raison en est le cofacteur 8 de la courbe — le groupe complet de points est huit fois plus grand que le sous-groupe d'ordre \ell. Un aa divisible par 8 atterrit à coup sûr dans le bon sous-groupe et ne révèle rien via des points de petit ordre.
  • le bit de poids fort est mis à zéro, l'avant-dernier à un : aa a ainsi toujours la même longueur en bits. Un aa plus court demanderait moins de doublements — et, là encore, le temps d'exécution en dirait quelque chose.

La clé publique est alors simplement

A=aB,A = a\cdot B,

stockée sur 32 octets : la coordonnée yy, et dans le bit de poids fort le signe de xx. Le xx, le vérificateur le recalcule lui-même à partir de l'équation de la courbe — les deux solutions ne diffèrent que par le signe, et ce bit unique indique laquelle est visée.

La seconde moitié du condensé, le préfixe, n'est pas nécessaire à la clé. Elle entre en jeu dans la section suivante.


9. Pourquoi le hasard n'en est pas un ici

Toute signature de ce type a besoin d'une valeur à usage unique rr, souvent appelée nonce. Elle ne doit jamais se répéter : qui dispose de deux signatures utilisant le même rr peut retrouver la clé secrète avec de l'algèbre de niveau lycée.

C'est précisément là-dessus que des systèmes réels ont échoué. Le cas le plus connu est la vérification de signature d'une console de jeu dont le constructeur utilisait, en 2010, toujours le même nonce — la clé privée était dès lors reconstructible publiquement.

Ed25519 résout le problème en n'utilisant aucun hasard :

r=SHA-512(preˊfixe    m)mod.r = \mathrm{SHA\text{-}512}(\text{préfixe}\;\|\;m) \bmod \ell.

Le nonce dépend du préfixe secret et du message. Il en découle deux choses :

  • Deux avis différents donnent, avec une probabilité écrasante, des rr différents — le cas de répétition ne se produit pas.
  • Un même avis donne toujours la même signature. Une opération de signature devient ainsi reproductible, et un mauvais générateur d'aléa sur le serveur ne peut rien casser, puisqu'aucun n'est nécessaire.

Pour une plateforme d'avis qui produit de nombreuses signatures par jour, ce n'est pas un avantage académique. C'est la différence entre « une défaillance de la source d'aléa serait fatale » et « il n'existe aucune source d'aléa susceptible de défaillir ».


10. Signer

Trois lignes, pas davantage :

r=H(preˊfixe    m)mod,R=rB,r = H(\text{préfixe}\;\|\;m) \bmod \ell, \qquad R = r\cdot B,
k=H(R    A    m)mod,k = H(R \;\|\; A \;\|\; m) \bmod \ell,
S=(r+ka)mod.S = (r + k\,a) \bmod \ell.

La signature est le couple

σ=(R,S),\sigma = (R,\,S),

32 octets pour le point RR, 32 octets pour le nombre SS — soit 64 octets au total.

La deuxième ligne mérite attention : dans kk entrent RR, la clé publique AA et le message. Que AA soit haché avec le reste n'est pas un accessoire — cela empêche les attaques consistant à réinterpréter une signature comme portant sur une autre clé.


11. Vérifier

Le navigateur du lecteur connaît : l'avis mm, la signature (R,S)(R,S) et la clé publique AA. Il recalcule kk et vérifie une seule équation :

SB  =  R+kA\boxed{S\cdot B \;=\; R + k\cdot A}

Si elle est vérifiée, la signature est valide. La RFC 8032 autorise en outre la variante multipliée par le cofacteur, 8SB=8R+8kA8S\cdot B = 8R + 8k\cdot A, qui traite certains cas limites avec plus de souplesse.

Aucun serveur n'est interrogé, aucun service n'a besoin d'être disponible. La clé publique suffit.


12. Pourquoi l'équation est vérifiée

Il suffit de substituer :

SB=(r+ka)B=rB+k(aB)=R+kA.S\cdot B = (r + k\,a)\cdot B = r\cdot B + k\,(a\cdot B) = R + k\cdot A.

Toute l'astuce tient dans la transformation du milieu : la multiplication scalaire est compatible avec l'addition. Qui connaît aa peut calculer un SS vérifiant l'équation. Qui ne connaît pas aa devrait trouver, pour un kk choisi par lui-même, un SS adapté — c'est-à-dire résoudre le logarithme discret.


13. Un mini-exemple entièrement calculé

Avec les vrais nombres, il n'y a rien à recalculer — des valeurs de 253 bits ne se vérifient pas de tête. D'où le même procédé dans un groupe minuscule, où chaque étape se contrôle à la calculatrice.

Étape 1 : le groupe

Nous calculons avec les restes modulo 2323 et prenons g=2g = 2. On a

211=2048=8923+11(mod23),2^{11} = 2048 = 89\cdot 23 + 1 \equiv 1 \pmod{23},

gg engendre donc un sous-groupe d'ordre =11\ell = 11. Les puissances sont :

nn1234567891011
gng^n248169181336121

gg joue le rôle du point de base BB, la multiplication celui de l'addition de points. Les scalaires se calculent modulo 1111, les valeurs modulo 2323.

Étape 2 : la paire de clés

Soit a=6a = 6 le secret. Alors

A=ga=26=6418(mod23).A = g^a = 2^6 = 64 \equiv 18 \pmod{23}.

A=18A = 18 peut être connu de tous.

Étape 3 : nonce et engagement

Supposons que le préfixe et l'avis donnent r=4r = 4. D'où :

R=gr=24=16.R = g^r = 2^4 = 16.

Étape 4 : le défi

Supposons que le condensé calculé sur RR, AA et l'avis donne

k=5.k = 5.

Étape 5 : la signature

S=(r+ka)mod11=(4+56)mod11=34mod11=1.S = (r + k\,a) \bmod 11 = (4 + 5\cdot 6) \bmod 11 = 34 \bmod 11 = 1.

La signature est le couple (R,S)=(16,1)(R,S) = (16,\,1).

Étape 6 : le navigateur vérifie

Il calcule les deux membres. À gauche :

gS=21=2.g^S = 2^1 = 2.

À droite, avec 1853(mod23)18^5 \equiv 3 \pmod{23} :

RAk=163=482(mod23).R\cdot A^{k} = 16\cdot 3 = 48 \equiv 2 \pmod{23}.

Les deux membres valent 22 :

Signature valide\boxed{\text{Signature valide}}

Étape 7 : quelqu'un modifie le texte de l'avis

Le texte entre dans le condensé, donc le défi change — disons qu'il devient k=7k' = 7. La signature reste inchangée à (16,1)(16,1), mais pas le membre de droite. Avec 1876(mod23)18^7 \equiv 6 \pmod{23} :

RAk=166=964(mod23)    2=gSR\cdot A^{k'} = 16\cdot 6 = 96 \equiv 4 \pmod{23} \;\neq\; 2 = g^S
Signature invalide\boxed{\text{Signature invalide}}

Nous pouvons supprimer un avis. Nous ne pouvons pas le modifier sans que cela se voie.

Précision de transparence sur l'exemple

Les calculs ont été faits ici dans le groupe multiplicatif modulo 2323, et non sur une courbe : gSg^S tient lieu de SBS\cdot B, le produit RAkR\cdot A^k tient lieu de l'addition de points R+kAR + k\cdot A. La structure est la même, et c'est bien de cela qu'il s'agit. Ce qui diffère, ce sont les ordres de grandeur : =11\ell = 11 face à 2252\ell \approx 2^{252}, et là, la clé ne se trouve pas en essayant les onze possibilités.


14. Ce qui se passe si quelqu'un modifie l'avis

Supposons que quelqu'un disposant d'un accès à la base de données — y compris quelqu'un chez nous — modifie le texte de l'avis ou l'un des cœurs. Le jeu de données change alors, et avec lui au moins l'un des deux condensés h et rh du payload. mm change donc, et avec lui le défi kk, et avec lui le membre de droite de l'équation de vérification. L'ancienne signature ne correspond plus.

La phrase décisive tient en ceci : nous pouvons supprimer un avis, mais nous ne pouvons pas le modifier sans que cela se remarque. Chez McGesund, la même vérification tourne en outre chaque nuit côté serveur sur l'ensemble du parc — un avis qui ne la passe pas n'entre plus dans la moyenne de l'entreprise.


15. Pourquoi un attaquant échoue

Il connaît la clé publique AA, le point de base BB, la courbe et chaque signature émise jusqu'ici. Ce qui lui manque, c'est aa.

La meilleure attaque classique connue contre le problème du logarithme discret dans un groupe d'ordre \ell demande environ \sqrt{\ell} étapes. Pour 2252\ell \approx 2^{252}, cela fait à peu près

21262^{126}

opérations. À titre de comparaison : même une machine capable d'un milliard de milliards (101810^{18}) d'étapes par seconde y passerait plusieurs fois l'âge de l'univers.

Falsifier sans la clé reviendrait à trouver, pour un kk choisi par soi-même, un SS adapté — la même tâche sous un autre déguisement.


16. Pourquoi Ed25519 et pas ECDSA

Les deux reposent sur le même problème. La différence tient à tout ce qui se passe autour :

ECDSA (courbes NIST)Ed25519
Noncealéa frais nécessairedéterministe, à partir du préfixe et du message
Formulescas particuliers, branches dépendant des donnéescomplètes, un seul chemin de calcul
Paramètres de courbeorigine des constantes jamais entièrement expliquéechoisis selon des critères vérifiables
Taille de signature64 à 72 o, encodage variable64 o fixes
Dans le navigateurdisponible de longue datenatif depuis 2023/2024, sinon via une bibliothèque JS

Pour nous, le nonce a été l'argument décisif. Une plateforme d'avis signe souvent et de façon automatisée ; un procédé où une seule valeur aléatoire faible livre la clé est le mauvais choix pour cet usage.


17. Ce qu'Ed25519 n'apporte pas

Ed25519 repose sur le logarithme discret — et c'est précisément ce problème qu'un ordinateur quantique suffisamment grand résout efficacement avec l'algorithme de Shor. L'existence de telles machines, et sa date, restent ouvertes. Pour un avis qui doit rester vérifiable dans dix ans, c'est malgré tout une question à laquelle il faut répondre aujourd'hui.

C'est pourquoi un sceau résistant au quantique peut venir s'ajouter à la signature Ed25519 :

Aucun des deux ne remplace Ed25519, ils se placent à côté. Si l'un des procédés venait à tomber, l'autre continue de porter.


18. Le déroulement en image

SERVICE DE SIGNATURE (MCGESUND)NAVIGATEUR DU VISITEURscalaire privé a + préfixe (issu de la graine)Payload m = {entreprise, avis, h, rh, iat}r = H(préfixe ‖ m) mod ℓR = r · Bk = H(R ‖ A ‖ m) mod ℓS = (r + k · a) mod ℓSignature σ = (R, S) + kidavis + σ + clé publique Arecalculer k à partir de R, A et mS · B = R + k · A ?valideinvalide
Du payload jusqu'à la coche dans le navigateur. Au-dessus de la ligne de séparation, tout se produit une seule fois lors de l'envoi ; en dessous, chez chaque lecteur à nouveau — sur son appareil, avec la seule clé publique.

19. Ce que McGesund en fait concrètement

L'enveloppe. Chaque avis signé porte une enveloppe MCG1: contenant la version du format, le payload et la signature Ed25519. Le kid du payload indique de quelle clé il s'agit ; le serveur fournit sur demande la clé publique correspondante — elle est publique, il n'y a rien à y protéger.

La vérification dans le navigateur. Chrome et Firefox savent traiter Ed25519 nativement via l'interface WebCrypto depuis 2023/2024. Safari non — l'appel y échoue au lieu de vérifier. Notre code de vérification bascule donc sur une implémentation en JavaScript pur, chargée uniquement là où elle est nécessaire. La vérification de signature aboutit ainsi dans tous les navigateurs, et ce sur l'appareil du lecteur.

L'ancrage temporel. L'empreinte de la clé de signature est ancrée dans un bloc Bitcoin via OpenTimestamps. Cela permet de démontrer non seulement que la signature est authentique, mais aussi que la clé existait déjà à un instant donné — sans que quiconque ait à croire notre horodatage.

Le lien avec le contenu. Le payload porte rh, le condensé de l'ensemble du jeu de données soumis : texte, cœurs, statut géographique, indications de motif et provenance. La signature Ed25519 ne lie donc pas seulement le texte, mais tout ce qui s'affiche à côté de l'avis.


20. Une phrase à retenir

Ed25519 transforme un nombre secret en une eˊquationque chacun peut refaire et que nul ne peut inventer.\boxed{ \begin{array}{c} \text{Ed25519 transforme un nombre secret en une équation}\\ \text{que chacun peut refaire et que nul ne peut inventer.} \end{array}}

Qui possède le scalaire secret signe en quelques microsecondes. Qui ne le possède pas devrait résoudre un logarithme discret dans un groupe d'environ 22522^{252} éléments.

Pour le lecteur d'un avis, cela signifie simplement ceci : il n'a pas besoin de nous croire. Il peut recalculer.