Cryptographie post-quantique · C2 Réseaux euclidiens · Chapitre 2 · 5 h
LWE et ses variantes
Résoudre un système linéaire bruité : réduction pire cas/cas moyen de Regev, Ring-LWE et Module-LWE, SIS et signatures.
Le chapitre 4 a laissé une lacune, et il faut la nommer avant de la combler. Un réseau euclidien est un bel objet, mais rien n'y indique comment engendrer à la demande une instance difficile dont on connaît le secret. La trappe « base courte contre base longue » y ressemblait, mais nous avons vu que GGH et NTRUSign, qui la mettaient en œuvre littéralement, ont été cassés.
LWE répond exactement à cette question, et il le fait dans un langage que tout étudiant d'un cours d'algèbre linéaire comprend en une phrase.
Résoudre un système linéaire, mais bruité
Voici tout LWE en une image. On vous donne un système d'équations linéaires modulaires :
Vous le résolvez en trente secondes par élimination. Maintenant, on ajoute à chaque second membre une erreur de — une erreur minuscule, sur des valeurs comprises entre 0 et 16. Le système devient :
Appliquez la même élimination et regardez ce qui se passe.
Animation · 7 étapes
Le même Gauss, sans bruit puis avec : q = 17, secret s = (3, 1)
- Sans bruit — les données — 4×3 + 2×1 = 14 et 1×3 + 5×1 = 8. Deux équations exactes, deux inconnues : c'est un exercice de première année.
- Sans bruit — élimination — L1 − 4·L2 supprime s1 : il reste −18·s2 = 14 − 32 = −18.
- Sans bruit — le secret tombe — s2 = 1, puis s1 = 3. Deux équations ont suffi. Un système linéaire modulaire ne protège rien du tout : c'est le point de départ, pas la solution.
- Avec bruit — les mêmes équations, décalées — On ajoute e1 = +1 et e2 = −1 : b1 passe de 14 à 15, b2 de 8 à 7. Deux unités d'écart sur des valeurs comprises entre 0 et 16.
- Avec bruit — l'élimination amplifie — La même combinaison donne −18·s2 = 15 − 28 = −13. Le coefficient 4 utilisé pour éliminer s1 a MULTIPLIÉ l'erreur de la seconde équation : le bruit cumulé vaut 5, pas 1.
- Avec bruit — le résultat est absurde — −s2 ≡ −13 donne s2 ≡ 13 mod 17. La vraie valeur est 1. Un bruit de ±1 sur deux équations a produit une erreur de 12 sur le résultat, dans un modulo de 17 : toute l'information a disparu.
- Pourquoi cela tient en grande dimension — En dimension n, éliminer n−1 inconnues demande des coefficients de l'ordre de q. Le bruit final dépasse q/2 et le résultat est uniformément distribué : il ne contient plus rien. Résoudre LWE demande donc de deviner un secret court AVANT d'éliminer — ce qui ramène exactement au problème de réseau du chapitre 4.
Le résultat n'est pas « approximativement juste », il est absurde : au lieu de 1. La raison est visible à l'étape 5 de l'animation. Pour éliminer , on a multiplié la seconde équation par 4 — et ce coefficient a multiplié son erreur par 4. Le bruit cumulé vaut 5, pas 1, dans un modulo de 17.
Généralisez à la dimension : éliminer inconnues demande des coefficients de l'ordre de , et le bruit final dépasse . Le résultat est alors uniformément distribué sur : il ne contient plus aucune information. C'est là toute l'astuce, et elle tient en une phrase — un bruit infime détruit toute méthode algébrique.
Quiz · 1 question
Pourquoi un bruit de ±1 suffit-il à détruire l'élimination de Gauss modulo q ?
- Parce que les erreurs s'additionnent linéairement et finissent par dépasser 1
- Parce que les coefficients d'élimination, de l'ordre de q, MULTIPLIENT les erreurs
- Parce que la division modulaire n'est pas définie quand il y a du bruit
Réponse : L'élimination ne fait pas qu'additionner : elle combine les lignes avec des coefficients. Multiplier une équation par 4 multiplie son erreur par 4. En dimension n, les coefficients atteignent l'ordre de q, donc le bruit cumulé dépasse q/2 et le résidu devient uniforme sur Z_q. La division modulaire, elle, reste parfaitement définie — c'est bien l'amplification qui tue.
La définition, et sa version décisionnelle
Fixons le vocabulaire. Soient la dimension, le module et une distribution de bruit concentrée près de zéro. Un échantillon LWE de secret est un couple
Le problème de recherche demande de retrouver à partir de échantillons. Le problème décisionnel demande seulement de distinguer une suite d'échantillons LWE d'une suite de couples uniformes. Ces deux problèmes sont équivalents pour les paramètres usuels, et c'est le décisionnel qui sert dans les preuves : il donne directement l'indistinguabilité dont les jeux IND-CPA ont besoin.
Deux paramètres gouvernent la difficulté : la dimension et le rapport bruit sur module . Un bruit trop faible rend le problème facile ; un bruit trop fort rend le déchiffrement impossible. Tout le dimensionnement de ML-KEM tient dans cet équilibre.
La réduction de Regev
Voici ce qui distingue LWE de toutes les hypothèses classiques, et il faut l'énoncer précisément parce que c'est souvent déformé.
Regev a démontré en 2005 que résoudre LWE en moyenne est au moins aussi difficile que résoudre certains problèmes de réseau dans le pire cas — GapSVP et SIVP avec un facteur d'approximation . La réduction originale est quantique ; Peikert en a donné en 2009 une version classique, au prix d'un module plus grand.
Ce que cela signifie, concrètement : si quelqu'un trouve un algorithme qui casse LWE sur des instances tirées au hasard — c'est-à-dire sur les clés que produit votre générateur — alors le même algorithme résout toutes les instances du problème de réseau correspondant, y compris les plus difficiles. Il n'existe donc pas de « clés faibles » à craindre : le tirage aléatoire ne peut pas tomber sur une instance accidentellement facile.
Comparez avec RSA. Personne ne sait montrer que factoriser un module tiré au hasard est aussi difficile que factoriser le pire module possible. On y croit ; on ne le démontre pas.
Deux réserves, pour rester honnête. D'abord, la réduction porte sur des facteurs d'approximation polynomiaux, pour lesquels le problème de réseau n'est ni prouvé NP-difficile ni supposé l'être — c'est la nuance du chapitre 4. Ensuite, elle est lâche : appliquée telle quelle, elle imposerait des paramètres bien plus gros que ceux de ML-KEM. Les paramètres réels sont fixés par l'estimation d'attaque du chapitre 4, pas par la réduction. Celle-ci sert de garantie structurelle, pas de règle de dimensionnement.
De LWE au réseau, et retour
La boucle se referme ici. À partir de échantillons , on construit le réseau -aire
Le vecteur est proche de ce réseau — à distance , qui est petite. Résoudre LWE, c'est donc résoudre CVP sur avec la promesse que la cible est anormalement proche. L'attaque primale plonge le tout dans un réseau où le secret devient un vecteur unique et court, et lance BKZ ; l'attaque duale cherche des vecteurs courts du réseau orthogonal pour distinguer. Dans les deux cas, le coût est celui du chapitre 4 : .
Autrement dit, LWE n'est pas un nouveau problème difficile. C'est une présentation du problème de réseau qui rend l'engendrement d'instances trivial : tirer au hasard, tirer et petits, publier .
Quiz · 1 question
Que garantit exactement la réduction de Regev ?
- Que LWE est NP-difficile
- Que casser LWE sur des instances aléatoires implique résoudre un problème de réseau dans le PIRE cas
- Que les paramètres de ML-KEM sont prouvés sûrs
Réponse : C'est une réduction du pire cas vers le cas moyen : elle interdit l'existence de clés accidentellement faibles. Elle ne dit rien de la NP-difficulté — le facteur d'approximation visé est polynomial, régime pour lequel la NP-difficulté n'est ni établie ni attendue. Et elle est trop lâche pour fixer des paramètres : ceux de ML-KEM viennent de l'estimation de coût de BKZ, pas de la réduction.
Ring-LWE et Module-LWE : ce qu'on gagne, ce qu'on risque
LWE « plein » a un défaut rédhibitoire : la matrice fait éléments. Pour des paramètres réalistes, la clé publique se compte en mégaoctets. C'est inutilisable.
Ring-LWE remplace les vecteurs par des éléments de l'anneau du chapitre 3. Un seul polynôme remplace toute une matrice, parce que la multiplication dans l'anneau encode implicitement une matrice circulante. On gagne un facteur en taille de clé et, grâce à la NTT, un facteur en temps de calcul. Le gain est spectaculaire.
Il n'est pas gratuit. Cette matrice implicite n'est pas quelconque : elle a une structure algébrique, et une structure est toujours une prise potentielle. On sait aujourd'hui que certains problèmes sur les réseaux idéaux — pas Ring-LWE lui-même, mais des cousins proches — admettent des algorithmes quantiques meilleurs que dans le cas général pour certains facteurs d'approximation. Ces résultats ne cassent pas Ring-LWE. Ils démontrent que la structure n'est pas neutre, et qu'elle mérite une prudence que le cas non structuré n'exige pas.
Module-LWE est le compromis, et c'est celui que le NIST a normalisé. On travaille avec des vecteurs de dimension dont les entrées sont des éléments de l'anneau. Pour on retrouve Ring-LWE ; pour on retrouve LWE plein. ML-KEM prend ou avec .
Le bénéfice est double, et le second est le plus intéressant en pratique. D'une part, on réduit la structure algébrique en jouant sur plutôt que sur . D'autre part, changer de niveau de sécurité ne change que : l'anneau reste le même, donc la NTT, les tables et le code d'arithmétique sont identiques pour les trois jeux de paramètres. Une implémentation, trois niveaux.
SIS, le problème dual
LWE sert au chiffrement. Les signatures ont besoin de son pendant, SIS — Short Integer Solution.
Étant donné uniforme, trouver court tel que
Il existe une infinité de solutions dès que ; la difficulté est d'en trouver une petite. Ajtai a démontré dès 1996 la difficulté pire cas vers cas moyen de SIS, ce qui en fait historiquement la première construction de ce type.
L'intuition de la dualité : LWE cache un secret dans du bruit, SIS demande d'exhiber un objet court. Le chiffrement a besoin de cacher, la signature a besoin de prouver qu'on sait produire quelque chose de court sans révéler comment. Le chapitre 7 montre comment ML-DSA convertit cela en signature.
À vous
Exercice de code
Complétez le score de la force brute, puis lisez la dernière colonne : c'est elle qui dit pourquoi la dimension 768 protège et pas la dimension 2.
Point de départ
// LWE en miniature. q = 17, dimension n = 2, secret s = (3, 1).
// Bruit dans {-1, 0, +1}.
const q = 17;
const n = 2;
const SECRET = [3, 1];
const mod = (x) => ((x % q) + q) % q;
const produit = (a, s) => mod(a.reduce((t, ai, i) => t + ai * s[i], 0));
// Un échantillon LWE : (a, b) avec b = <a, s> + e.
function echantillon(bruit) {
const a = Array.from({ length: n }, () => Math.floor(Math.random() * q));
const e = bruit ? Math.floor(Math.random() * 3) - 1 : 0;
return { a, b: mod(produit(a, SECRET) + e), e };
}
// Attaque par force brute : essayer tous les secrets, garder celui qui
// explique le mieux les échantillons.
function forceBrute(echantillons, borne) {
let meilleur = null;
let essais = 0;
for (let s1 = 0; s1 < q; s1++) {
for (let s2 = 0; s2 < q; s2++) {
essais++;
const s = [s1, s2];
// À COMPLÉTER — comptez combien d'échantillons ce candidat explique,
// c'est-à-dire pour lesquels |b - <a,s>| (centré sur 0) est ≤ borne.
const score = 0;
if (!meilleur || score > meilleur.score) meilleur = { s, score };
}
}
return { ...meilleur, essais };
}
// Écart centré : dans Z_q, 16 est à distance 1 de 0, pas 16.
const ecart = (x) => Math.min(mod(x), q - mod(x));
const SANS = Array.from({ length: 8 }, () => echantillon(false));
const AVEC = Array.from({ length: 8 }, () => echantillon(true));
console.log("secret réel :", SECRET);
console.log("sans bruit :", JSON.stringify(forceBrute(SANS, 0)));
console.log("avec bruit :", JSON.stringify(forceBrute(AVEC, 1)));
// Le coût, maintenant. En dimension n, il y a q^n secrets possibles.
console.log("\ncoût de la force brute :");
for (const dim of [2, 4, 8, 256, 768]) {
const bits = dim * Math.log2(q);
console.log(` n = ${String(dim).padStart(3)} → q^n = 2^${bits.toFixed(0)}`);
}
Solution
const q = 17;
const n = 2;
const SECRET = [3, 1];
const mod = (x) => ((x % q) + q) % q;
const produit = (a, s) => mod(a.reduce((t, ai, i) => t + ai * s[i], 0));
function echantillon(bruit) {
const a = Array.from({ length: n }, () => Math.floor(Math.random() * q));
const e = bruit ? Math.floor(Math.random() * 3) - 1 : 0;
return { a, b: mod(produit(a, SECRET) + e), e };
}
const ecart = (x) => Math.min(mod(x), q - mod(x));
function forceBrute(echantillons, borne) {
let meilleur = null;
let essais = 0;
for (let s1 = 0; s1 < q; s1++) {
for (let s2 = 0; s2 < q; s2++) {
essais++;
const s = [s1, s2];
// Un candidat est d'autant meilleur qu'il laisse un résidu PETIT sur
// chaque échantillon. C'est la seule signature du bon secret : le
// mauvais candidat produit des résidus uniformes sur tout Z_q.
const score = echantillons.filter((ech) => ecart(ech.b - produit(ech.a, s)) <= borne).length;
if (!meilleur || score > meilleur.score) meilleur = { s, score };
}
}
return { ...meilleur, essais };
}
const SANS = Array.from({ length: 8 }, () => echantillon(false));
const AVEC = Array.from({ length: 8 }, () => echantillon(true));
console.log("secret réel :", SECRET);
console.log("sans bruit :", JSON.stringify(forceBrute(SANS, 0)));
console.log("avec bruit :", JSON.stringify(forceBrute(AVEC, 1)));
console.log("\ncoût de la force brute :");
for (const dim of [2, 4, 8, 256, 768]) {
const bits = dim * Math.log2(q);
console.log(` n = ${String(dim).padStart(3)} → q^n = 2^${bits.toFixed(0)}`);
}
// Trois observations, dans l'ordre où elles comptent.
//
// 1. La force brute RETROUVE le secret, avec ou sans bruit. LWE n'est pas
// difficile en dimension 2 — 289 candidats, c'est instantané. Le bruit
// ne rend pas le problème insoluble, il supprime seulement les méthodes
// ALGÉBRIQUES (l'élimination de Gauss de l'animation).
//
// 2. Le score du bon secret est 8/8 sans bruit, et 8/8 avec bruit si la
// borne est bien choisie. Trop serrée, on rate le vrai secret ; trop
// lâche, plusieurs candidats deviennent indistinguables. Le rapport
// entre q et l'écart-type du bruit est LE paramètre de sécurité.
//
// 3. La dernière colonne est la vraie leçon. En dimension 768, il y a
// 2^3138 secrets possibles. La force brute est morte, l'élimination est
// morte : il ne reste que la réduction de réseau du chapitre 4, avec le
// coût exponentiel en β qu'on lui connaît.
À retenir
Flashcards · 3 cartes
- Pourquoi le bruit de LWE détruit-il l'élimination de Gauss ?
- Parce que l'élimination combine les lignes avec des coefficients qui MULTIPLIENT les erreurs. En dimension n, ces coefficients sont de l'ordre de q, le bruit cumulé dépasse q/2 et le résidu devient uniforme sur Z_q. Il ne reste aucune méthode algébrique : seule la réduction de réseau s'applique encore.
- Module-LWE : que gagne-t-on par rapport à LWE plein et à Ring-LWE ?
- Par rapport à LWE plein : un polynôme au lieu d'une matrice, donc des clés en kilooctets au lieu de mégaoctets, et la NTT pour la vitesse. Par rapport à Ring-LWE : moins de structure algébrique, réglable par le rang k. Et un bénéfice pratique décisif — changer de niveau de sécurité ne change que k, l'anneau et donc tout le code d'arithmétique restent identiques.
- Quelle est la différence entre LWE et SIS ?
- LWE cache un secret dans du bruit : retrouver s dans b = As + e. SIS demande d'exhiber un objet court : trouver z ≠ 0 petit avec Az = 0 mod q. LWE sert au chiffrement, SIS aux signatures. Tous deux disposent d'une réduction pire cas vers cas moyen — Regev 2005 pour LWE, Ajtai 1996 pour SIS.