web-dev-qa-db-fra.com

Fissuration d'un générateur congruentiel linéaire

J'écoutais récemment le podcast de sécurité maintenant, et ils ont mentionné en passant que le générateur de congruence linéaire (LCG) est banal à craquer. J'utilise le LCG dans une classe de calcul de statistiques de première année et je pensais que le casser ferait un joli problème "supplémentaire".

Existe-t-il de bonnes façons de casser le LCG qui n'impliquent pas la force brute?


Je ne sais pas si cette question est OT, mais je ne savais pas où poster la question. De plus, mes tags ne sont pas très utiles car je n'ai pas assez de représentants pour créer de nouveaux tags.

34
csgillespie

Oui. Il existe des moyens extrêmement efficaces de casser un générateur linéaire congruentiel.

Un générateur congruentiel linéaire est défini par sn + 1 = a sn + b mod m, où m est le module. Dans sa forme la plus simple, le générateur sort juste sn comme ne numéro pseudo-aléatoire. Si m est connu de l'attaquant et a, b ne sont pas connus, alors Thomas a décrit comment le briser.

Si aucun de a, b, m n'est connu, on peut encore casser un générateur linéaire congruentiel, en récupérant d'abord m. C'est un exercice intéressant pour déterminer comment le faire efficacement; ça peut être fait. Je vais montrer comment ci-dessous; ne lisez pas la suite si vous préférez essayer de le découvrir par vous-même.

Pour récupérer m, définissez tn = sn + 1 - sn et n = |tn + 2 tn - t2n + 1|; alors avec une forte probabilité vous aurez m = gcd (u1, u2, ..., udix). 10 est arbitraire; si vous le faites k, alors la probabilité que cela échoue est exponentiellement petite dans k. Je peux partager un pointeur sur pourquoi cela fonctionne, si quelqu'un est intéressé.

La leçon importante est que le générateur de congruence linéaire est irrémédiablement non sécurisé et complètement inapproprié pour une utilisation cryptographique.


Ajouté: @AviD me déteste encore plus :), mais voici les mathématiques pour lesquelles cela fonctionne, pour ceux qui l'ont demandé.

L'idée clé: tn + 1 = sn + 1 - sn = (a sn - b) - (a sn-1 - b a sn - un sn-1 = a tn) == mod m, et tn + 2 = a2 tn mod m, et tn + 3 = a3 tn mod m. Donc tn + 2 tn - tn + 12 = 0 mod m, c'est-à-dire |tn + 2 tn - tn + 12| est un multiple aléatoire de m. Fait de la théorie des nombres astucieux: le pgcd de deux multiples aléatoires de m sera m avec une probabilité 6/π2 = 0,61; et si vous prenez le pgcd de k d'entre eux, cette probabilité devient très proche de 1 (exponentiellement rapide en k). C'est cool, ou quoi?

36
D.W.

Un générateur congruentiel linéaire est linéaire, ce qui devrait tout dire.

A savoir, vous avez un état s, qui est mis à jour avec: s ← as + b mod w, pour deux constantes a et b, et un module pratique w (généralement 232: s, a et b sont des mots de 32 bits); la sortie consiste en les valeurs successives de s. Si vous avez trois sorties successives (s, s1 et s2), alors vous obtenez deux équations linéaires dans deux inconnues (a et b), qui sont facilement résolues avec l'arithmétique élémentaire.

Cela peut être étendu aux variantes où vous n'obtenez que des parties des valeurs s, éventuellement non consécutives. Si a et b sont deux constantes 32 bits, vous n'avez besoin que d'environ 96 bits de sortie pour recalculer les constantes.

18
Thomas Pornin

Une autre méthode de résolution de m vient de cela papier .

Essentiellement, cette méthode exploite le fait que le générateur congruentiel linéaire échoue considérablement au test des avions. Le déterminant d'une matrice 3x3 utilisant 4 sorties est un multiple de m .

Le pgcd de deux multiples ( n_1 et n_2 de m est m si x_1 = n_1 / m et x_2 = n_2 / m sont co-amorces.

La probabilité que k entiers soient co-premiers est donnée par 1/ζ (k) donc la probabilité que x_1 et x_2 sont co-premiers est 1/ζ (2) ou 6/π ^ 2, environ 61%.

Comme @Thomas l'a dit, une fois m trouvé, le reste du problème est facile.

3
Jon Takagi