Connaître n'est pas faire. Faire n'est pas sécuriser.
Aristote a distingué trois formes de connaissance. L'episteme est le savoir théorique — savoir que quelque chose est vrai. La techne est le savoir productif — savoir comment faire quelque chose. La phronesis est le savoir pratique — savoir quoi faire dans une situation concrète.
La cryptographie exige les trois. Et la distance entre elles est l'espace où se produisent la plupart des vulnérabilités.
Episteme : le papier
Kyber est une réussite de l'episteme. Le papier de Bos et al. (2018) décrit un schéma d'encapsulation de clés basé sur Module-LWE, avec des démonstrations de sécurité, des paramètres justifiés, une analyse des attaques connues. C'est la connaissance théorique dans sa forme la plus épurée : elle définit, démontre, conclut.
Lire le papier et le comprendre produit la sensation d'avoir capturé quelque chose d'important. La structure est élégante : la matrice A est générée à partir d'une graine publique, le secret s est échantillonné avec une distribution binomiale centrée, le ciphertext est compressé à 3 bits par coefficient, le FO transform assure IND-CCA2. Tout s'emboîte.
Mais l'episteme a une limite : le papier démontre que si les composants sont exécutés correctement, alors le schéma est sécurisé. La proposition conditionnelle est vraie. Mais le monde réel n'évalue pas des conditionnelles ; il exécute du code.
Episteme (le papier) : Si (NTT correcte ∧ temps constant ∧ FO correct)
alors le schéma est IND-CCA2 sécurisé.
Techne (le code) : NTT correcte ? OK Temps constant ? ? FO correct ? OK
La variable qui n'apparaît pas dans la prémisse
est celle qui détermine la sécurité réelle.
Techne : l'implémentation
Pendant ma phase d'apprentissage, j'ai implémenté Kyber en Dart/Flutter — xkyber_crypto — en suivant FIPS 203 à la lettre. La techne de traduire le papier en code a ses propres exigences : choisir des représentations de données, gérer la mémoire, implémenter SHAKE128 à partir de zéro, organiser la multiplication de polynômes dans le domaine NTT.
Chaque décision d'implémentation révèle quelque chose que le papier ne dit pas :
Le papier écrit : "Sample s ← β_η^k"
L'implémentation écrit :
void cbd(Poly r, Uint8List buf) { for (int i = 0; i < KYBER_N ~/ 8; i++) { int t = buf[2 * i] | (buf[2 * i + 1] << 8); for (int j = 0; j < 8; j++) { int aj = (t >> j) & 1; int bj = (t >> (j + 8)) & 1; r.coeffs[8 * i + j] = aj - bj; } } }Le papier ne spécifie pas l'ordre des bits. Il ne dit pas si la boucle doit être parallélisable. Il ne mentionne pas que chaque accès à
r.coeffs[...]en Dart exécute une vérification de bornes que la VM ne peut pas élider, et que chaque vérification de bornes est une opportunité pour que le temps varie.
L'implémentation était fonctionnellement correcte. Tous les vecteurs de test passaient. Mais la techne a révélé quelque chose que l'episteme ne pouvait pas : le langage importe. Dart n'a pas été conçu pour la cryptographie à haute assurance. Il n'y a pas de garantie que la VM compile une boucle sans branchements dépendant des données. Il n'y a aucun moyen de s'assurer que la réduction de Montgomery soit constante dans le temps quand ~/ 65536 peut être compilé comme une division ou comme un décalage selon la phase d'optimisation JIT.
La comparaison de ciphertexts dans le FO transform — le point le plus critique — illustre l'abîme :
// Est-ce constant dans le temps ?
bool verify(Uint8List a, Uint8List b) {
if (a.length != b.length) return false;
int r = 0;
for (int i = 0; i < a.length; i++) {
r |= a[i] ^ b[i];
}
return r == 0;
}
En C, cette fonction se compile en instructions qu'un expert peut inspecter et vérifier. En Dart, le compilateur JIT peut réordonner la boucle, fusionner des itérations, appliquer l'élimination de code mort s'il déduit que r n'est pas utilisé, ou insérer des barrières GC dans les écritures. Il n'y a pas de volatile. Pas de __attribute__((const)). Aucun moyen de dire à la VM : "ceci doit s'exécuter exactement comme écrit, sans optimisations, sans réordonnancements, sans surprises".
La techne de l'implémentation de Kyber en Dart s'est heurtée à une limite matérielle : le langage ne fournit pas les outils que la cryptographie exige.
Phronesis : l'archivage
Arrivé à ce point, la phronesis — le savoir pratique de quoi faire — impose une décision. L'implémentation fonctionne. Les tests passent. Mais la sécurité ne se démontre pas avec des tests qui passent : elle se démontre avec des propriétés qui sont garanties.
Il n'y avait aucun moyen de garantir un temps constant dans Dart VM. Il n'y avait aucun moyen d'inspecter l'assembly généré par le compilateur AOT pour vérifier que les boucles restaient sans branchement. Il n'y avait aucun moyen de s'assurer que le ramasse-miettes n'introduirait pas de pauses mesurables au moment exact de la comparaison du FO transform.
La décision a été d'archiver le dépôt. Non par échec technique — l'implémentation était correcte — mais par honnêteté intellectuelle :
La décision d'archiver :
Ça fonctionne ? Oui. Les tests passent.
Est-ce sécurisé ? On ne peut pas le démontrer.
Peut-il le devenir ? Non sans réécrire en C/Rust et lier par FFI.
Apporte-t-il de la valeur Oui, comme exemple de jusqu'où va
comme référence ? la techne sans l'infrastructure adéquate.
Aristote a écrit que la phronesis n'est ni science ni art : c'est la capacité de délibérer correctement sur ce qui est bon ou mauvais pour l'être humain. En cryptographie, la phronesis est de savoir reconnaître quand une implémentation n'est pas sécurisée, même lorsque tous les tests disent qu'elle est correcte.
Ce qu'enseigne le faire
La série "La distance du secret" a exploré cinq distances :
- I : la distance entre la conjecture de LWE et la démonstration de sécurité
- II : la distance entre l'algorithme et son implémentation constante dans le temps
- III : la distance entre la sécurité computationnelle et la limite physique de Landauer
- IV : la distance entre la protection présente et la menace future (harvest now)
- V : la distance entre la confiance institutionnelle et la diversité mathématique
VI ajoute une distance plus fondamentale : la distance entre savoir et faire.
Le papier de Kyber est une connaissance vraie. L'implémentation en Dart était une connaissance productive. Mais la sécurité réelle — celle qui résiste à une attaque réelle, pas à un test unitaire — nécessite quelque chose qu'aucun des deux ne fournit séparément : la capacité de reconnaître qu'un système peut être fonctionnellement correct et cryptographiquement non sécurisé en même temps.
Cela ne s'apprend pas dans le papier. Cela s'apprend en implémentant, en échouant, en archivant.
Avec "Le savoir et le faire" se clôt le cycle de "La distance du secret". L'exploration a commencé en demandant quand nous pouvons dire que quelque chose est sécurisé. La réponse, après six essais, est : jamais complètement. Mais nous pouvons nous approcher — en combinant la théorie qui démontre, la pratique qui construit et la sagesse qui reconnaît les limites des deux.
Références croisées avec la recherche :
- Implémentation en Dart — Code extrait de xkyber_crypto, contraste avec FIPS 203
- Temps constant en Dart — Limitations de la VM, points critiques
- Implémentation — Détails algorithmiques du schéma
- Conclusions — Synthèse finale de la recherche
