Stochastique et génération de nombres pseudoaléatoires

Les équations sur ce site sont affichées avec MathJax.

Cette page sera enrichie quand j'en aurai le temps, le sujet étant d'une grande complexité et mon expertise étant très limitée. La référence en la matière est le monumental ouvrage de Donald E. Knuth, The Art of Computer Programming, dont un volume entier est consacré à la question, et dont vous trouverez un chapitre ici : http://www.informit.com/articles/article.aspx?p=2221790

La stochastique est un sujet important en informatique, en particulier pour ce qui touche à la sécurité et à l'intégrité de systèmes. Un attaquant d'un système de loterie ou d'un casino cherchera à prédire les prochaines actions d'un système sur la base des précédentes; c'est l'objectif des systèmes, services et outils décrits ici de réduire les chances de succès de ces attaquants.

En 2013, John Graham-Cumming explique pourquoi ces systèmes dépendent d'une génération de nombres pseudoaléatoires de qualité : https://blog.cloudflare.com/why-randomness-matters/

Article de 2014 par Cory Doctorow montrant les actions prises par un casino lorsque deux individus ont trouvé un bogue dans sa génération de nombres pseudoaléatoires : http://boingboing.net/2014/10/08/sore-losers-how-casinos-went.html

Général / pédagogie

Illustration simpliste

Pour se représenter un générateur de nombres pseudoaléatoires, un bon truc (pas rigoureux, mais illustratif) est de se représenter un ruban, dont la longueur variera selon la qualité du générateur, et sur lequel on aurait écrit des tas de nombres joués à l'aide d'un dé à beaucoup, beaucoup de faces. On cache ce ruban dans une boîte, et on n'en révèle pas la taille.

Au moment où un programme commence à générer des nombres pseudoaléatoires, on pige un nombre « surprenant » (par exemple, le nombre de secondes écoulées depuis un point choisi dans l'histoire, qu'on appelle typiquement l'Epoch) un endroit où commencer à lire sur le ruban, modulo la taille du ruban (exprimée en nombre de nombres qui y sont écrits). Ce nombre surprenant est le germe de la génération, et on ne le choisit qu'une fois.

Le nombre sur le ruban à cet endroit est « surprenant » au sens où il était a priori imprévisible. Vu de l'extérieur du générateur, on ne peut prédire la valeur du prochain nombre sur le ruban, ne sachant pas sa constitution ou sa taille.

Piger des nombres pseudoaléatoires se fait par la suite en avançant sur le ruban, tout simplement.

En pratique, les générateurs nombres pseudoaléatoires utilisent le germe et un autre nombre, caché, pour que les bons sur le ruban soient de taille variable (mais déterministe) à chaque nouvelle pige (à chaque nouvelle lecture du ruban).

Comment les ordinateurs génèrent-ils des nombres pseudoaléatoires?

Générer de véritables nombres aléatoires?

Quelques articles de sources externes :

Génération Splittable

La génération Splittable vise à alimenter deux consommateur (ou plus) de nombres pseudoaléatoires s'exécutant de manière concurrente à partir d'une même source :

Selon les systèmes d'exploitation

Les systèmes d'exploitation sont capables de cumuler de l'entropie basée sur les phénomènes physiques (vibrations du disque rigide, variations de température, fréquence de pression des touches du clavier, etc.) et d'exposer ces données aux générateurs de nombres pseudoaléatoires, typiquement à titre de germe.

Avec Linux

Les articles récents portant que l'entropie et les nombres pseudoaléatoires tient au fait que les systèmes d'exploitation collectent l'entropie sur la base d'événements physiques, incluant les vibrations des disques rigides, or certains périphériques (p. ex. : les disques SSD) ne vibrent essentiellement pas, donc il faut repenser certaines pratiques

Avec MacOSX

Survol des mécanismes disponibles et de leurs qualités respectives, par Mike Ash en 2011 : https://www.mikeash.com/pyblog/friday-qa-2011-03-18-random-numbers.html

Avec Microsoft Windows

Une analyse de la qualité des mécanismes offerts par Microsoft Windows, par Leo Dorrendorf, Zvi Gutterman et Benny Pinkas en 2007 : http://eprint.iacr.org/2007/419.pdf

Selon les langages de programmation

La vaste majorité des langages de programmation offre des services de génération de nombres pseudoaléatoires. La qualité varie bien sûr en fonction du langage et de la plateforme sous-jacente.

Pour un tour d'horizon multilangages, voir ce texte de 2016 : https://paragonie.com/blog/2016/05/how-generate-secure-random-numbers-in-various-programming-languages

Avec C

Selon ce texte de 2015, rand() est moins mauvais que l'on ne le croit, mais on tend à mal l'utiliser : http://eternallyconfuzzled.com/arts/jsw_art_rand.aspx (cependant, il recommande de passer aux outils de C++ 11).

Avec C#

Avec C++

Avec Haskell

Avec Java

Avec JavaScript

En 2016, Douglas Goddard s'amuse à démontrer que le générateur de nombres pseudoaléatoires de JavaScript, du moins sous Chrome et sous Firefox, n'est peut-être pas le meilleur outil pour écrire un logiciel de loterie sérieux : https://medium.com/independent-security-evaluators/hacking-the-javascript-lottery-80cc437e3b7f

Avec Kotlin

Rouler un dé avec Kotlin, par Nicolas Frankel en 2016 : https://blog.frankel.ch/rolling-dice-kotlin

Avec Perl

Avec PHP

Pas facile de générer des nombres pseudoaléatoires. Un bogue soumis en 2015 montre que dans certaines circonstances, cet extrait ne génère que des nombres impairs : http://3v4l.org/dMbat

Avec SQL

Avec Swift

Comparatifs

Examen comparatif de la fonction rand(0,1) de PHP et de la fonction rand() d'OpenSSL sur Debian, en 2008 : http://cod.ifies.com/2008/05/php-rand01-on-windows-openssl-rand-on.html

Étude de 2016 par Falko Strenzke, portant sur quelques manques dans la qualité de l'entropie du générateur de nombres pseudoaléatoires d'OpenSSL : https://eprint.iacr.org/2016/367

Considérations historiques


Valid XHTML 1.0 Transitional

CSS Valide !