Procédé de signature
SLH-DSA expliqué mathématiquement
Comment SLH-DSA-SHA2-256f (FIPS 205) signe sans recourir à aucun problème difficile autre que les fonctions de hachage — des chaînes de hachage aux arbres de Merkle, jusqu'à la forêt d'arbres FORS.
Mise à jour : 2026-11-09
1. De quoi il s'agit
Chez McGesund, les clients des formules Avis Premium et Signaux Premium peuvent choisir le niveau de signature PQ-Dual-Diversified. Chaque QR code porte alors, en plus de la signature Ed25519 classique, deux signatures résistantes au quantique : ML-DSA-87 et SLH-DSA-SHA2-256f.
Cet article explique la seconde. Elle est construite différemment de tout ce que nous utilisons par ailleurs.
SLH-DSA n'est pas un chiffrement. Le contenu reste lisible publiquement. SLH-DSA prouve l'origine et l'intégrité — comme toute signature numérique.
SLH-DSA signifie en toutes lettres Stateless Hash-Based Digital Signature Algorithm. Il est issu de SPHINCS+ et a été normalisé en 2024 sous le nom FIPS 205. Le nom trahit déjà sa particularité : le procédé n'utilise que des fonctions de hachage. Pas de réseaux, pas de courbes elliptiques, pas de grands nombres premiers.
2. Qu'est-ce qui est signé exactement ?
Chez McGesund, SLH-DSA signe le même jeu de données que celui couvert par la signature Ed25519 du QR code : le payload du QR code. Il indique notamment à quelle entreprise appartient le code (fid), de quel type il est (typ), quand il a été émis (iat) et jusqu'à quand il est valable (exp) — sous la forme d'une suite d'octets encodée de manière compacte (CBOR).
Cette suite d'octets est notre message . Si quelqu'un modifie après coup un seul bit, plus aucune des signatures ne correspond.
La signature SLH-DSA ne se trouve pas dans le QR code lui-même. Avec environ 49 Ko, elle est bien trop volumineuse pour cela. Elle est conservée sous forme de « sceau » distinct auprès du jeu de données du QR code dans le backend de McGesund, et chargée dans le navigateur lorsque vous cliquez sur « Vérifier l'authenticité ».
3. Pourquoi un procédé fait uniquement de fonctions de hachage ?
Tout procédé de signature repose sur une tâche pratiquement insoluble sans la clé secrète :
| Procédé | La sécurité repose sur |
|---|---|
| Ed25519 | le logarithme discret sur une courbe elliptique |
| FALCON | les vecteurs courts dans les réseaux NTRU |
| ML-DSA | Module-LWE et Module-SIS (réseaux) |
| SLH-DSA | uniquement les propriétés de la fonction de hachage |
Un grand ordinateur quantique casserait Ed25519. FALCON et ML-DSA sont considérés comme résistants au quantique — mais tous deux s'appuient sur des problèmes de réseaux. Si l'on découvrait un jour une attaque fondamentale contre les réseaux, les deux seraient touchés en même temps.
SLH-DSA, en revanche, a seulement besoin que la fonction de hachage fasse ce pour quoi elle a été conçue :
C'est l'hypothèse la plus ancienne et la plus minutieusement étudiée de toute la cryptographie. Même un ordinateur quantique n'y aide que de façon limitée : l'algorithme de Grover divise par deux les bits de sécurité. C'est pourquoi la variante 256 utilise des condensés de octets bits — après Grover, il reste encore 128 bits.
C'est précisément pour cela que le niveau s'appelle Diversified : ML-DSA (réseaux) et SLH-DSA (hachage) appartiennent à des familles mathématiques différentes. Si l'une tombe, l'autre tient.
4. Brique 1 : signer avec des chaînes de hachage (WOTS+)
L'idée de base est étonnamment simple. Commençons par un seul chiffre.
Prenez une valeur aléatoire secrète et hachez-la encore et encore :
La fin de la chaîne, , est publiée. C'est la clé publique pour ce seul chiffre.
Pour signer un chiffre compris entre 0 et 15, on divulgue la valeur de la chaîne à la position :
Qui veut vérifier hache encore fois. S'il obtient exactement , la signature est authentique :
Un mini-exemple
Nous signons le chiffre :
- Le signataire publie .
- Le vérificateur calcule et compare avec . Cela correspond.
Un faussaire qui a vu peut sans peine en déduire , , etc. — et donc signer des chiffres plus grands. Il ne peut pas en signer de plus petits : il lui faudrait pour cela hacher à rebours.
La somme de contrôle contre le « comptage vers le haut »
Pour que personne ne puisse simplement augmenter des chiffres, on signe en plus une somme de contrôle :
Si un faussaire augmente un chiffre du message, devient plus petit — et il lui faudrait alors calculer à rebours dans la chaîne de la somme de contrôle. Les deux directions sont ainsi verrouillées.
Extrapolé à un condensé entier
Un condensé de 32 octets compte 64 chiffres en base 16. S'y ajoutent 3 chiffres de somme de contrôle :
Une telle signature s'appelle WOTS+ (Winternitz One-Time Signature). Son gros défaut est dans son nom : one-time, à usage unique. Qui signe deux messages différents avec la même clé divulgue tant de valeurs de chaîne que des falsifications deviennent possibles.
5. Brique 2 : de nombreuses clés à usage unique sous un même toit (arbre de Merkle)
Si chaque clé ne peut servir qu'une seule fois, il en faut énormément — mais on ne veut publier qu'une seule clé publique.
La solution est un arbre de Merkle : les clés publiques de paires WOTS+ forment les feuilles. Deux voisines sont à chaque fois hachées ensemble, les résultats à nouveau par paires, jusqu'à ce qu'il ne reste en haut qu'une seule racine.
Dans SLH-DSA-SHA2-256f, chaque arbre a une hauteur , soit feuilles.
Pour montrer qu'une feuille donnée appartient à l'arbre, on fournit son chemin d'authentification : les 4 nœuds frères rencontrés en remontant. Grâce à eux, le vérificateur remonte en hachant de la feuille jusqu'à la racine. S'il obtient la racine connue, la feuille fait partie de l'arbre.
6. Brique 3 : des arbres sur des arbres (hyperarbre)
Seize clés à usage unique ne suffisent évidemment pas. SLH-DSA empile donc des arbres les uns sur les autres : la racine d'un arbre est signée avec une clé WOTS+ de l'arbre situé au-dessus. Cette tour s'appelle l'hyperarbre.
SLH-DSA-SHA2-256f compte couches, chacune de hauteur 4 :
Tout en bas, on dispose ainsi de
feuilles. La racine de l'arbre le plus haut s'appelle — c'est la véritable clé publique.
Point important : personne ne calcule ces arbres à l'avance. Toutes les valeurs secrètes sont dérivées à la demande d'une valeur de départ secrète . Seules quatre valeurs de 32 octets chacune sont stockées :
| Partie | Contenu | Taille |
|---|---|---|
| SK.seed | valeur de départ de toutes les valeurs de chaîne secrètes | 32 o |
| SK.prf | valeur de départ de la composante aléatoire | 32 o |
| PK.seed | valeur de départ publique, sépare les paires de clés les unes des autres | 32 o |
| PK.root | racine de l'arbre le plus haut | 32 o |
La clé privée se compose des quatre (128 octets), la clé publique seulement de PK.seed et PK.root (64 octets).
7. Brique 4 : une forêt contre les coïncidences (FORS)
Voici maintenant le vrai problème : comment le signataire sait-il laquelle des feuilles est encore inutilisée ?
Les procédés à base de hachage plus anciens (XMSS, LMS) tiennent pour cela un compteur. Celui-ci ne doit jamais être remis en arrière — ni par une sauvegarde, ni par un second serveur. Si cela arrive malgré tout, une clé à usage unique est utilisée deux fois, et le procédé est cassé. De tels procédés sont dits à état.
SLH-DSA est sans état : la feuille est choisie de façon pseudo-aléatoire à partir du message lui-même. Il peut alors arriver que deux messages tombent sur la même feuille. C'est pourquoi on ne trouve pas tout en bas une signature à usage unique, mais une signature à usage restreint : FORS (Forest of Random Subsets).
FORS se compose de petits arbres de Merkle comptant chacun feuilles. Les feuilles sont des valeurs aléatoires secrètes.
Pour signer, le condensé du message est découpé en 35 nombres de 9 bits chacun. Chaque nombre sélectionne exactement une feuille dans « son » arbre. Pour chaque arbre, la signature contient :
- la valeur secrète de cette feuille
- son chemin d'authentification (9 nœuds)
Pour un autre message, un faussaire devrait tomber, dans les 35 arbres, sur des feuilles dont les secrets ont déjà été divulgués. Même si la même instance FORS a servi quelques fois, c'est sans espoir.
8. Le déroulement complet de la signature
- Composante aléatoire. À partir de , d'un nombre aléatoire frais et du message, on obtient une valeur de 32 octets.
- Condensé du message.
Les 49 octets du digest sont répartis : 40 octets sélectionnent les 35 feuilles FORS, le reste détermine quel arbre (
idx_tree) et quelle feuille (idx_leaf) tout en bas de l'hyperarbre sont utilisés. - Signature FORS sur le message. Il en résulte une clé publique FORS.
- Signature de l'hyperarbre sur cette clé FORS : 17 signatures WOTS+, chacune avec un chemin d'authentification, couche après couche jusqu'à .
La signature finale est simplement la concaténation :
9. Pourquoi la signature pèse 49 856 octets
Avec les paramètres de SLH-DSA-SHA2-256f, la taille se recalcule exactement ( octets par condensé) :
| Partie | Calcul | Octets |
|---|---|---|
| 32 | ||
| FORS | 11 200 | |
| Hyperarbre | 38 624 | |
| Total | 49 856 |
À titre de comparaison : une signature Ed25519 fait 64 octets, une signature ML-DSA-87 4 627 octets. La taille est le prix à payer pour que SLH-DSA se contente de fonctions de hachage.
10. Comment le navigateur vérifie
Avec SLH-DSA, vérifier signifie : refaire les hachages.
- Recalculer le digest à partir de , de la clé publique et du message.
- À partir des 35 feuilles FORS divulguées et de leurs chemins, calculer les 35 racines d'arbre, puis la clé publique FORS.
- Avec chacune des 17 signatures WOTS+, hacher les chaînes jusqu'au bout, former la clé publique WOTS+ et remonter par hachage le long du chemin jusqu'à la racine de l'arbre.
- À la fin, on doit obtenir exactement .
Cela représente quelques milliers d'appels de hachage — une broutille pour un ordinateur. Dans le navigateur, la vérification prend chez nous environ 6 à 12 millisecondes.
11. Que se passe-t-il si quelqu'un modifie le jeu de données ?
Si ne serait-ce qu'un bit du message change, le digest change complètement. Les 35 nombres pointent alors vers d'autres feuilles FORS, et le procédé vers un autre emplacement de l'hyperarbre.
Les secrets divulgués ne correspondent plus : les racines recalculées diffèrent, et l'on n'obtient pas à la fin. La vérification échoue.
Pour construire malgré tout une signature valide, un attaquant devrait connaître des secrets qui n'ont jamais été publiés — autrement dit, inverser une fonction de hachage.
12. Pourquoi précisément 256f ?
FIPS 205 définit douze jeux de paramètres : deux familles de hachage (SHA-2 et SHAKE), trois niveaux de sécurité (128, 192, 256) et, pour chacun, une variante rapide (« f ») et une variante compacte (« s »).
| Variante | Signature | Temps de signature (chez nous) | Vérification |
|---|---|---|---|
| SHA2-256s | 29 792 o | env. 2,6 s | env. 3 ms |
| SHA2-256f | 49 856 o | env. 0,26 s | env. 6 ms |
256 correspond à la catégorie de sécurité NIST 5 — le même niveau que FALCON-1024 et ML-DSA-87.
Nous avons choisi « f » parce que les entreprises peuvent émettre jusqu'à 500 QR codes d'un seul coup. Avec « s », la signature prendrait plus de 20 minutes, avec « f » moins d'une minute. En contrepartie, la signature est plus volumineuse — comme elle ne se trouve pas dans le QR code, c'est acceptable.
SHA-2 plutôt que SHAKE, parce que SHA-256 et SHA-512 sont accélérés sur pratiquement tout matériel.
13. L'aléa lors de la signature
FIPS 205 autorise deux manières de produire :
- déterministe : même message, même signature
- randomisée (« hedged ») : un nombre aléatoire frais entre dans le calcul
Nous utilisons la variante randomisée. Deux signatures sur le même message ont donc un aspect différent — et toutes deux sont valides. Cela complique les attaques qui combinent des mesures sur l'appareil (consommation électrique, temps) avec des signatures répétées.
14. Ce que McGesund en fait concrètement
Le niveau. PQ-Dual-Diversified est disponible dans les formules Avis Premium et Signaux Premium. Un QR code porte alors trois signatures :
| Signature | Famille | Emplacement |
|---|---|---|
| Ed25519 | courbe elliptique | dans le QR code |
| ML-DSA-87 | réseaux | sceau dans le backend |
| SLH-DSA-SHA2-256f | fonctions de hachage | sceau dans le backend |
La signature. Une signature SLH-DSA demande environ un quart de seconde de calcul. Pour que le serveur reste pendant ce temps disponible pour tous les autres, des threads d'arrière-plan dédiés effectuent les calculs.
La vérification. Le navigateur du lecteur charge les deux sceaux et les vérifie avec le même module WASM que toutes les autres signatures PQ. Nous fournissons les données ; le calcul se fait sur l'appareil du visiteur.
La comparaison avec le NIST. Notre module passe les vecteurs de test officiels du NIST pour SLH-DSA-SHA2-256f : à partir des valeurs de départ du NIST, il produit octet pour octet les mêmes clés, et toutes les signatures volontairement manipulées sont rejetées. Vous pouvez le vérifier vous-même dans votre navigateur sur la page de test NIST.
L'ancrage temporel. Comme pour toutes les clés, l'empreinte de la clé SLH-DSA est ancrée dans un bloc Bitcoin via OpenTimestamps.
15. SLH-DSA, ML-DSA et FALCON côte à côte
| Propriété | FALCON (FN-DSA) | ML-DSA-87 | SLH-DSA-SHA2-256f |
|---|---|---|---|
| Fondement | réseaux NTRU | réseaux modulaires | uniquement des fonctions de hachage |
| Norme | FIPS 206 (en cours) | FIPS 204, finalisée | FIPS 205, finalisée |
| Clé publique | 1 793 o | 2 592 o | 64 o |
| Signature | 1 280 o | 4 627 o | 49 856 o |
| Temps de signature | millisecondes | millisecondes | env. 0,26 s |
| Vérification | millisecondes | millisecondes | millisecondes |
| Hypothèse | problème de réseau | problème de réseau | fonction de hachage |
En résumé : SLH-DSA est le plus lent et le plus volumineux des trois procédés — et le plus conservateur. Il ne repose sur rien que toute autre signature ne suppose déjà de toute façon : une fonction de hachage sûre.
16. Une phrase à retenir
Qui possède la valeur de départ secrète signe en un quart de seconde. Qui ne la possède pas devrait inverser SHA-256 ou SHA-512 — même avec un ordinateur quantique.
Pour le lecteur d'un avis, cela signifie : même si toutes les méthodes fondées sur les réseaux devaient tomber un jour, cette signature resterait vérifiable. Il n'a pas besoin de nous croire. Il peut recalculer.