Números Aleatorios: la base de la criptografía del siglo 21

Números Aleatorios
Números Aleatorios

Cada computadora que puede comunicarse genera constantemente números aleatorios e inclusive si no se comunica, cada computadora necesita aleatoriedad para distribuir programas en la memoria.

Al mismo tiempo, por supuesto, una computadora, como sistema determinista, no puede crear números aleatorios verdaderos.

Cuando se trata de generadores de números aleatorios (o pseudoaleatorios), la historia siempre se basa en la búsqueda de la verdadera aleatoriedad.

Si bien los matemáticos serios han estado debatiendo durante décadas sobre lo que cuenta como aleatoriedad, en términos prácticos, hace mucho tiempo que aprendimos a usar la entropía “correcta”.

Sin embargo, el ruido es solo la punta del iceberg.

Números Aleatorios

¿Por dónde empezamos si queremos desentrañar la maraña de los algoritmos PRNG y TRNG más potentes?

De hecho, no importa con qué algoritmos estés tratando, todo se reduce a tres pilares: seeds, una tabla de constantes predefinidas y fórmulas matemáticas.

Cualquiera que sea la seed, todavía hay algoritmos involucrados en los verdaderos generadores de números aleatorios, y dichos algoritmos nunca son aleatorios.

¿Qué es la aleatoriedad?

La primera definición adecuada de secuencia aleatoria la dio en 1966 el estadístico sueco Per Martin-Löf, alumno de Andrei Kolmogorov, uno de los más grandes matemáticos del siglo XX.

Previamente, los investigadores intentaron definir una secuencia aleatoria como aquella que pasaba todas las pruebas de aleatoriedad.

La idea principal de Martin-Löf era usar la teoría de la computabilidad para definir formalmente la noción de una prueba de aleatoriedad. Esto contrasta con la idea de aleatoriedad en la probabilidad; en esta teoría, ningún elemento particular del espacio muestral puede llamarse aleatorio.

La “secuencia aleatoria” en las representaciones de Martin-Löf debe ser típica, es decir no debe tener características distintivas individuales.

Se ha demostrado que la aleatoriedad de Martin-Löf admite muchas características equivalentes, cada una de las cuales satisface nuestra intuición sobre las propiedades que deben tener las sucesiones aleatorias:

  • incompresibilidad;
  • pasar pruebas estadísticas de aleatoriedad;
  • la dificultad de hacer predicciones.

La existencia de múltiples definiciones de aleatorización de Martin-Löf y la estabilidad de estas definiciones bajo diferentes modelos computacionales indican que la aleatoriedad de Martin-Löf es una propiedad fundamental de las matemáticas.

Seed: la base de los algoritmos pseudo aleatorios

Los primeros algoritmos para generar números aleatorios realizaban una serie de operaciones aritméticas básicas: multiplicar, dividir, sumar, restar, sacar promedios, etc.

Hoy en día, potentes algoritmos como Fortuna y Yarrow (utilizados en FreeBSD, AIX, Mac OS X, NetBSD) parecen generadores de números aleatorios para los paranoicos.

Fortune, por ejemplo, es un generador criptográfico en el que, para protegerse contra el descrédito.

Números Aleatorios

Después de cada solicitud de datos aleatorios por una cantidad de 220 bytes, se generan otros 256 bits de datos pseudoaleatorios y se utilizan como una nueva clave de cifrado: la antigua la llave se destruye cada vez.

Pasaron años antes de que los algoritmos más simples evolucionaran a generadores de números pseudoaleatorios criptográficamente fuertes.

Parcialmente, este proceso se puede rastrear mediante el ejemplo del trabajo de una función matemática en el lenguaje C.

La función rand() es la más simple de las funciones de generación de números aleatorios en C.

#include <stdio.h>
#include <stdlib.h>

int main()
{
int r,a,b;

     puts("100 Random Numbers");
     for(a=0;a<20;a++)
     {
         for(b=0;b<5;b++)
         {
             r=rand();
             printf("%dt",r);
          }
          putchar('n');
      }
      return(0);
}

Este ejemplo aleatorio utiliza un bucle anidado para mostrar 100 valores aleatorios.

La función rand() es buena para generar muchos valores aleatorios, pero son predecibles.

Para que la salida sea menos predecible, debe agregar una seed al generador de números aleatorios; esto se hace mediante la función srand().

La seed es el número inicial, el punto desde el cual comienza la secuencia de números pseudoaleatorios. El generador de números pseudoaleatorios utiliza un único valor seed, de ahí su pseudoaleatoriedad. 

Un verdadero generador de números aleatorios siempre comienza con un valor aleatorio de alta calidad proporcionado por varias fuentes de entropía.

#include <stdio.h>
#include <stdlib.h>

int main()
{
    unsigned seed;
    int r,a,b;

    printf("Input a random number seed: ");
    scanf("%u",&seed);
    srand(seed);
    for(a=0;a<20;a++)
    {
        for(b=0;b<5;b++)
        {
            r=rand();
            printf("%dt",r);
         }
         putchar('n');
     }  
     return(0);
}

srand() toma un número y lo establece como punto de partida. Si la seed no está configurada, cada vez que se inicia el programa, recibiremos los mismos números aleatorios.

Aquí hay un ejemplo de una fórmula simple de números aleatorios del libro “clásico” “El lenguaje de programación C” de Kernighan y Ritchie, cuya primera edición ya se publicó en 1978:

int rand() { random_seed = random_seed * 1103515245 +12345;  
return (unsigned int)(random_seed / 65536) % 32768; }

 

Esta fórmula asume la existencia de una variable llamada random_seed, inicialmente establecida en algún número. La variable random_seed se multiplica por 1,103,535,245 y luego se suma 12,345 al resultado; random_seed luego se reemplaza con este nuevo valor.

En realidad, es un generador de números pseudoaleatorios bastante bueno. Si lo usa para generar números aleatorios del 0 al 9, entonces los primeros 20 valores que devolverá con seed = 10 serán:

44607423505664567674

Si tenes 10.000 valores del 0 al 9, entonces la distribución sería:

0 – 10151 – 10242 – 10483 – 9964 – 9885 – 10016 – 9967 – 10068 – 9659 – 961

Cualquier fórmula de número pseudoaleatorio depende del valor inicial.

Si proporciona la función rand() con la seed 10 en una máquina y observa el flujo de números que produce, el resultado será idéntico a la “secuencia aleatoria” generada en cualquier otra máquina seed 10.

Desafortunadamente, el generador de números aleatorios tiene otra debilidad: siempre puedes predecir lo que sucederá a continuación en función de lo que sucedió antes.

Para obtener el siguiente número en la secuencia, siempre debemos recordar el último estado interno del generador, el llamado estado.

Sin estado, volveremos a hacer las mismas matemáticas con los mismos números para obtener la misma respuesta.

¿Cómo hacer seed única para cada caso?

La solución más obvia es agregar la hora actual del sistema a los cálculos.

Puedes hacer esto con la función time().

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
    int r,a,b;

    srand((unsigned)time(NULL));
    for(a=0;a<20;a++)
    {
        for(b=0;b<5;b++)
        {
            r=rand();
            printf("%dt",r);
         }
         putchar('n');
     }
     return(0);
}

La función time() devuelve información sobre la hora actual del día, un valor que cambia constantemente.

Sin embargo, el método de encasillamiento asegura que el valor devuelto por la función time() sea un número entero.

Entonces, como resultado de agregar el tiempo del sistema “aleatorio”, la función rand() genera valores que son más aleatorios que los que obtuvimos en el primer ejemplo.

Sin embargo, en este caso, la seed se puede adivinar conociendo la hora del sistema o la hora de inicio de la aplicación.

Como regla, para aplicaciones donde los números aleatorios son absolutamente críticos, es mejor encontrar una solución alternativa.

El .net framework cuenta con la función System.Security.Cryptography. RandomNumberGenerator , donde en los cálculos se tienen en cuenta los siguientes factores:

  • ID del proceso actual;
  • ID de hilo actual;
  • número de lecturas desde la carga;
  • tiempo actual;
  • varios contadores de rendimiento de CPU de alta precisión;
  • Hash MD4 del entorno del usuario (nombre de usuario, nombre de la computadora, etc.).

Pero, de nuevo, todos estos números no son aleatorios.

Lo mejor que puede hacer con los generadores de números pseudoaleatorios deterministas es agregar entropía a los fenómenos físicos.

Generador de períodos (ciclos)

Uno de los métodos más utilizados para generar números pseudoaleatorios son varias modificaciones del método congruencial lineal , cuyo esquema fue propuesto por Derrick Lehmer allá por 1949:

n+1 = (aX n + c) mod m, donde m es el módulo, a es el multiplicador, c es el incremento, mod es la operación de sacar el resto de la división. Además, m > 0, 0 < a ≤ m, 0 < c ≤ m, también se establece el valor inicial de X 0 : 0 < X ​​0 ≤ m.

El método lineal congruente nos da secuencias repetitivas: una secuencia congruente siempre forma “bucles”.

Este ciclo (período), que se repite un número infinito de veces, es una propiedad de todas las sucesiones de la forma X n+1 = f(n).

En C, el método lineal congruente se implementa en la conocida función rand():

#define RAND_MAX 32767 
unsigned long next=1; 
int rand(void) 
{ next=next*1103515245+12345; 
return((unsigned int)(next/65536)%RAND_MAX);} 
void srand(unsigned int seed) 
{ next=seed; } 

¿Qué es un ciclo en general en términos de números aleatorios?

El período es la cantidad de números que se generan antes de regresar en la misma secuencia.

Por ejemplo, el número de puntos en el cifrado A5 es de 2 23 en promedio , y la complejidad del ataque es de 240, lo que hace posible descifrarlo en cualquier computadora personal.

Considere el caso donde la seed es 1 y el período es 100 (en Haskell):

random i = (j, ans)
    where j   = 7 * i  `mod` 101
          ans = (j — 1) `mod` 10 + 1 — just the ones place, but 0 means 10

Como resultado, obtendremos la siguiente respuesta:

random 1 —> ( 7, 7)
random 7 —> (49, 9)
random 49 —> (40, 10)
random 40 —> (78, 8)
random 78 —> (41, 1)
random 41 —> (85, 5)
random 85 —> (90, 10)
random 90 —> (24, 4)
random 24 —> (67, 7)
random 67 —> (65, 5)
random 65 —> (51, 1)

Este es solo un ejemplo y una estructura similar no se usa en la vida real.

En Haskell, si desea construir una secuencia aleatoria, puede usar el siguiente código:

random :: StdGen —> (Int, StdGen)

Elegir un Int aleatorio le devuelve un Int y un nuevo StdGen que puede usar para obtener más números pseudoaleatorios.

Muchos lenguajes de programación, incluido Haskell, tienen generadores de números aleatorios que recuerdan automáticamente su estado (en Haskell, esto es randomIO).

IT CONNECT

Información de valor para ejecutivos que toman decisiones de negocios

Cuanto mayor sea el valor del período, más confiable es generar buenos valores aleatorios, pero incluso con miles de millones de ciclos, es esencial usar una seed confiable.

Los generadores de números aleatorios reales generalmente usan ruido atmosférico, pero también podemos engañar programáticamente agregando flujos asíncronos de basura diversa a la seed.

Ya sea la longitud del intervalos entre los últimos flujos de latidos o las expectativas de tiempo de exclusión mutua (o más bien, sume todo junto).

Bits de aleatoriedad verdadera

Entonces, habiendo obtenido una seed con una mezcla de datos de fenómenos físicos reales, estableciendo un estado para proteger contra un valor error de repetición.

Podemos añadir algoritmos criptográficos (o problemas matemáticos complejos), obtendremos un conjunto de datos, que consideraremos una secuencia aleatoria. ¿Que sigue?

Luego volvemos al principio, a uno de los requisitos fundamentales: las pruebas.

El Instituto Nacional de Estándares y Tecnología de EE. UU. ha invertido 15 comprobaciones básicas en el ” Paquete de prueba estadística para generadores de números aleatorios y pseudoaleatorios para aplicaciones criptográficas “.

Puede limitarse a ellos, pero este paquete no es en absoluto el “pináculo” de las pruebas de aleatoriedad.

Una de las pruebas estadísticas más rigurosas fue propuesta por el profesor George Marsaglia de la Universidad Estatal de Florida. Las ” pruebas intransigentes ” incluyen 17 pruebas diferentes, algunas de las cuales requieren secuencias muy largas: un mínimo de 268 megabytes.

La aleatoriedad se puede probar con la biblioteca TestU01 proporcionada por Pierre L’Ecuillet y Richard Simard de la Universidad de Montreal, que incluye pruebas clásicas y algunas originales, y con la biblioteca de dominio público SPRNG .

 

Por Marcelo Lozano – General Publisher IT CONNECT LATAM

 

Lea más

Telcos se transforman en motores tecnológicos del siglo 21

Dell Technologies IT Summit Bogotá 2022

Trabajo remoto: 3 formas generar sentido de pertenencia en los equipos

IBM Z16: procesamiento a escala y seguridad cuántica

Oracle ME: mejorando la experiencia del trabajador siglo 21

Vivamus ac lectus euismod, ultricies nunc eget, tempor neque. Donec vel mattis libero. Donec sed vulputate nisi. Nullam convallis, orci eget efficitur consequat, leo metus convallis orci, maximus sodales purus enim nec lacus. Morbi sed rhoncus libero. Sed tellus mi, sollicitudin ac urna feugiat, tempor consectetur urna. Nunc ultricies ligula lacus. Suspendisse mattis massa turpis, eget finibus est maximus at. Vivamus vitae faucibus massa. Suspendisse accumsan nulla id sapien ullamcorper ultrices egestas sed purus. Proin quis enim dapibus nibh cursus consectetur molestie vitae risus. Sed rhoncus lorem eget facilisis ornare.

Phasellus felis augue, euismod sit amet consectetur non, molestie a ligula. Phasellus vitae orci ante. Praesent molestie facilisis metus, eget interdum augue sodales nec. Etiam blandit egestas libero nec ullamcorper. Nullam blandit, ipsum sit amet convallis varius, tellus nisi ullamcorper ex, sit amet luctus nulla erat sagittis nisl. Vestibulum efficitur a massa et dapibus. Fusce maximus erat tellus, vel tempor dui ornare ac. Cras lacus ex, euismod non justo vel, dignissim blandit diam.

Cras efficitur, mi sit amet condimentum consectetur, nisi mauris iaculis leo, sed rutrum quam diam a tortor. Sed bibendum purus erat, sed varius lacus egestas ut. Mauris fringilla justo lacinia, imperdiet dolor et, dictum purus. Vivamus ultrices tincidunt ante, et semper augue vestibulum vitae. Curabitur consectetur lacus magna, non porta libero porta a. Donec in leo ipsum. Nullam fringilla tellus imperdiet, suscipit metus ut, posuere velit. Cras sed volutpat enim.

Quisque euismod mauris eu arcu fermentum congue. Proin malesuada fermentum feugiat. Donec lobortis scelerisque justo, at malesuada nulla interdum quis. Nullam ex tellus, efficitur non ligula id, accumsan hendrerit sem. In hac habitasse platea dictumst. Etiam placerat, nisl vel commodo faucibus, lacus est ultricies metus, sit amet condimentum nulla tortor ac dolor. Nunc et ligula ac urna vestibulum vestibulum quis in ex. Vivamus eget nunc nec turpis hendrerit pharetra et eget libero. Integer auctor, justo non aliquet rutrum, est elit pretium odio, in consequat sem neque nec ex.

Integer vitae feugiat sem, eget rutrum dui. Suspendisse et maximus neque. Curabitur lectus lacus, blandit vitae nunc ac, pellentesque aliquet leo. Morbi dictum tortor vel mi aliquam, eu auctor turpis placerat.

Sed consectetur bibendum eleifend. In sagittis sagittis dui, eget feugiat eros condimentum et.

Suspendisse sit amet convallis justo, ac venenatis mi. Ut pulvinar consectetur felis sed dignissim.

Donec odio nisl, faucibus gravida convallis at, molestie non ligula. Phasellus nec diam nibh. Nunc tempus dolor ut tempor mattis. Donec leo erat, aliquam pellentesque lectus vitae, tincidunt gravida felis.

Donec dapibus aliquet rutrum. Etiam a sodales mi. Maecenas vitae ligula a ipsum tincidunt gravida. Donec sagittis metus nec orci consectetur, nec congue odio congue.

Duis dignissim vestibulum velit, vel accumsan massa ultricies ac. Donec a eros nisl. Pellentesque pretium risus sit amet lorem tristique, tempor laoreet odio scelerisque. Curabitur interdum consectetur mi.

Aenean eu tristique neque. Donec ac tortor a magna mattis aliquam.

Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Nullam ac ullamcorper lorem. Aliquam auctor et erat sit amet condimentum. Nulla facilisi. Mauris eget elementum orci.

Pellentesque vel est ex. Nullam eu consectetur ex, maximus sodales orci. Vestibulum et quam hendrerit, consectetur tellus non, interdum felis.

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec id nisl lacinia orci venenatis pellentesque.

Nunc id pellentesque dui. Sed lacinia lectus dui, lacinia interdum elit efficitur et. Fusce nec justo a nunc vulputate tempor. In non tempus orci. Pellentesque vitae faucibus augue.

Ut ultrices suscipit porttitor. Nam rhoncus, ipsum quis cursus feugiat, est est tincidunt tellus, quis pretium elit diam at enim.

Vestibulum tristique, ipsum nec ornare pretium, enim diam auctor nulla, eu condimentum nisl lectus sed erat.

Aliquam ultrices nisl nec nisl convallis, sit amet accumsan ante dapibus. Pellentesque vel purus ac risus finibus hendrerit vel ut sapien.

Suspendisse nunc eros, laoreet id enim sit amet, dignissim facilisis ipsum. Nulla facilisis tellus ut risus vehicula aliquet.

Integer posuere massa in massa rutrum, in rutrum augue consectetur. Vivamus risus justo, imperdiet eget blandit non, lacinia eget est. Integer nec consequat turpis, ac vulputate elit. Curabitur vel lobortis nunc.

Nunc non tellus non quam pharetra viverra vitae non odio.

Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.

números aleatorios, números aleatorios, números aleatorios, números aleatorios, números aleatorios, números aleatorios, números aleatorios, números aleatorios, 

números aleatorios, números aleatorios, números aleatorios, números aleatorios,