Ouvi dizer que a geração aleatória de números em computadores não é realmente aleatória, mas não existe um algoritmo eficiente para detectá-lo. Como isso pode ser detectado?
Ouvi dizer que a geração aleatória de números em computadores não é realmente aleatória, mas não existe um algoritmo eficiente para detectá-lo. Como isso pode ser detectado?
Respostas:
Computadores sendo realmente aleatórios:
A verdadeira aleatoriedade é impossível para as máquinas de Turing no sentido teórico, e a maioria dos computadores não pode gerar uma saída verdadeiramente aleatória. Portanto, alguns computadores modernos incluem hardware que permite que o computador acesse uma fonte externa que, esperamos, inclua alguma aleatoriedade. Um exemplo de como isso pode ser feito é rastrear pequenas flutuações de temperatura dentro do computador. A aleatoriedade também pode ser obtida de uma fonte externa. Mas pelo tom do seu post, não acho que você esteja interessado em fontes externas de aleatoriedade.
Sementes:
Sem uma adição externa, tudo o que um computador faz é determinístico. Isso leva a um grande problema: se você chamar um programa de geração de números aleatórios, ele fornecerá o mesmo resultado sempre que você fornecer a mesma entrada. Claramente, precisamos de um programa que produza um número aleatório para alterar seu comportamento toda vez que for executado (caso contrário, continuaremos recebendo o mesmo número "aleatório", o que não é particularmente útil). Uma idéia é fornecer alguma entrada ao programa, que muda sempre que o programa é executado, para que um número diferente seja gerado. Chamamos essa entrada de "semente". O gerador de números aleatórios precisa coletar uma semente, executar algumas operações e fornecer um número aleatório.
A hora atual do sistema é um exemplo clássico de uma semente. Isso fornece uma longa sequência com alta entropia e, se o tempo é monitorado de maneira suficientemente granular (ou seja, se o relógio do sistema usa horas, então "o tempo" é uma semente muito ruim)), é improvável que você alimente o número pseudoaleatório gerador o mesmo número duas vezes.
Algoritmos que são aleatórios o suficiente:
Agora, temos um algoritmo que pelo menos tem alguma maneira de ser diferente cada vez que é executado. Damos a ele uma semente e, embora o algoritmo dê o mesmo número quando solicitado com a mesma semente, queremos que os números que ele gera sejam aleatórios. Isso age como o descrito acima - você recebe algumas entradas e produz algumas (esperançosamente diferentes da entrada para serem "aleatórias").
Agora, digamos que você tenha criado seu próprio algoritmo para fazer isso, e você alega que os números apresentados são bem próximos do aleatório quando você forneceu um monte de sementes diferentes. Como testaríamos como é bom?
Agora queremos um algoritmo que capte uma semente, faça algumas operações e produza um número aleatório. No mais simples, o algoritmo pode apenas gerar a semente - ele não está nos dando o mesmo número de cada vez, e as sementes aleatórias nos fornecem saídas aleatórias. Mas claramente não é isso que queremos. Por outro lado, um algoritmo pode ser bastante complicado, como muitos geradores pseudoaleatórios reais. Como podemos saber quais algoritmos nos dão números "aleatórios" de nossas sementes não necessariamente aleatórias? Se não conseguimos exatamente, como podemos dizer quais são os melhores?
Aleatório o suficiente para enganar um atacante:
Agora, o que você PODE estar se referindo é Geradores Pseudo-Aleatórios Criptograficamente Seguros. Eu acho que a melhor maneira de explicar isso é no contexto acima - aqui, estamos usando nossa aleatoriedade para criptografia; portanto, quando estamos projetando testes, o que realmente importa é que alguém não consiga quebrar nossa segurança, prevendo o número aleatório que escolhemos. Não conheço o seu nível de familiaridade com a criptografia, mas imagine que estamos fazendo um código de substituição simples - cada letra é substituída por outra letra. Queremos escolher essas substituições aleatoriamente, para que eles sejam difíceis de adivinhar. Mas se ele descobrir como meu gerador de números aleatórios funciona, ele será capaz de resolver toda a cifra! Portanto, algoritmos criptográficos requerem geradores de números aleatórios que são especificamente difíceis de adivinhar.
Por esse motivo, os CSPRGs são definidos em termos de quão bem outros algoritmos os resolvem (e é aí que finalmente chegamos à sua pergunta). Especificamente, digamos que eu tenho um CSPRG que chamarei de R. R é um CSPRG se, e somente se, NÃO houver um algoritmo viável que possa adivinhar qual bit será exibido a seguir. Isso é verdade mesmo que você conheça todos os bits anteriores que ele produz!
Então, digamos que os cinco primeiros bits que meu CSPRG produziu são 10100. Você não conhece a entrada que eu usei no programa, mas você tem acesso ao código que eu usei para escrever meu CSPRG. A alegação é de que é impossível escrever um programa para decidir se a próxima saída de bit será 101000 ou 101001.
Portanto, por razões de criptografia, às vezes o desempenho de um gerador de números pseudo-aleatórios é definido em termos de quão previsível é para outros programas. Observe que isso ainda fornece grande parte da intuição de "aleatoriedade", como (digamos), se você souber que todas as saídas aleatórias serão estranhas, não é criptograficamente segura nem passa no teste de aleatoriedade do senso comum.
Recentemente, eu encontrei um bom post sobre aleatoriedade na computação no blog do MIT CSAIL Theory of Computation Group: Você pode dizer se um pouco é aleatório?
O post começa com algumas idéias extraídas da maravilhosa conversa de Avi Wigderson sobre o poder e as limitações da aleatoriedade na computação, pesquisando a bela área de algoritmos aleatórios e a surpreendente conexão entre pseudo-aleatoriedade e intratabilidade computacional .
Em seguida, resume alguns resultados recentes sobre criptografia quântica; em particular, a maneira de testar com eficiência se a saída de um determinado tipo de dispositivo é realmente aleatória (protocolos de expansão de aleatoriedade).
Por exemplo, veja o trabalho recente de Umesh Vazirani, Thomas Vidick, Certum Quantum Dice (ou expansão de aleatoriedade exponencial testável)
Resumo: Introduzimos um protocolo através do qual um par de dispositivos mecânicos quânticos pode ser usado para gerar n bits de aleatoriedade verdadeira a partir de uma semente de O (log n) bits uniformes. Os bits gerados são certificadamente aleatórios com base apenas em um teste estatístico simples que pode ser executado pelo usuário e na suposição de que os dispositivos obedecem ao princípio de não sinalização. Nenhuma outra suposição é colocada no funcionamento interno dos dispositivos ....
Supondo que você esteja falando sobre aleatoriedade estatística - a criptografia tem outras necessidades! - há uma série de testes de qualidade de ajuste que podem detectar se uma sequência de números se encaixa em uma determinada distribuição. Você pode usá-los para testar se um gerador de números aleatórios (pseudo) é sólido (até a qualidade do seu teste e o significado escolhido).
Os conjuntos de testes rígidos combinam métodos diferentes.
Este é um tópico amplo / complexo em ciência da computação que a outra resposta do SamM aborda alguns. Sua pergunta específica parece ser sobre se os computadores têm o que é chamado de PRNGs , ou seja, geradores de números pseudo-aleatórios, como detectar isso?
A resposta curta é que PRNGs não triviais são criados para que seus algoritmos não possam ser detectados (derivados). Em geral, se o PRNG é chamado de "seguro", mesmo que um invasor conheça o algoritmo usado para gerar a sequência pseudo-aleatória, não poderá adivinhar os parâmetros específicos usados para gerar a sequência. Dessa maneira, a pseudo-aleatoriedade tem muitos vínculos profundos com a criptografia, e pode-se falar em "quebrar" um PRNG da mesma maneira que um algoritmo criptográfico pode ser "quebrado". Existem muitos trabalhos de pesquisa nessa área, é uma área ativa na vanguarda da criptografia.
Para PRNGs "triviais", por exemplo, digamos um gerador congruencial linear , se o invasor conhece o algoritmo usado para gerá-lo e não é gerado com "bignums" , o espaço de pesquisa é "relativamente pequeno" e o invasor também poderia, teoricamente, encontrar os parâmetros usado pelo PRNG particular basicamente pela força bruta e tentando todas as combinações.
Os PRNGs podem ser quebrados na prática (novamente dependendo de sua "segurança") em alguns casos, executando um grande conjunto de testes estatísticos de aleatoriedade contra eles. por exemplo, esta é a lógica do programa "Dieharder" (de Brown). Há também uma suíte NIST .
A dificuldade / dureza intrínseca de quebrar PRNGs ainda não está estritamente comprovada teoricamente, mas está basicamente associada ao que é chamado de "alçapão" ou "funções de mão única" que podem ser computadas eficientemente em uma direção, mas que são "difíceis de inverter" (inverter) . Existem alguns problemas em aberto na criptografia sobre dureza aleatória. Essas questões estão intimamente relacionadas às separações de classes de complexidade, por exemplo, a famosa questão P =? NP.
As perguntas sobre a quebra de PRNGs também se relacionam à complexidade de Kolmogorov , um campo que estuda as menores Máquinas de Turing que podem gerar sequências. quebrar o PRNG também se relaciona estreitamente com a descoberta do programa "mais curto" para calcular uma sequência pseudo-aleatória. E a complexidade de Kolmogorov é indecidível para calcular em geral.
Como Gilles aponta em um comentário, existem RNGs baseados em hardware, construídos a partir de processos eletrônicos físicos, como os relacionados ao ruído quântico. estes se projetados corretamente são inquebráveis.
De fato, tudo o que um computador clássico faz é determinístico, no sentido de que, quando você executa algumas tarefas, ele as segue de maneira determinística. Portanto, se você quiser ter um número aleatório, poderá calculá-lo de acordo com o tempo (com base no tempo de entrada do usuário), mas se desejar ter um conjunto de números aleatórios, não poderá usar o tempo para os próximos números, porque o os números não seriam mais independentes.
O que as pessoas fazem é usar geradores pseudoaleatórios que possuem uma semente, isto é, um número usado para calcular todos os números do gerador de números pseudoaleatórios (em alguns casos mais sofisticados de simulação ou outras tarefas, mais sementes podem ser necessárias , se for necessário mais de um conjunto de números aleatórios independentemente). A semente geralmente é 0 ou um número específico, se você deseja resultados reproduzíveis, ou o tempo, se você, e resultados diferentes não reproduzíveis.
O fato de os geradores de números pseudoaleatórios serem bons o suficiente reside no fato de seguirem "as características básicas de uma geração de números pseudoaleatórios", para serem computados com eficiência e se comportarem como números aleatórios reais:
A partir de cada número da sequência de números pseudo-aleatórios, um novo número é calculado (geralmente trabalhamos com números inteiros). No entanto, há um período, n, em uma sequência de geradores de números pseudo-aleatórios preparados para trabalhar em uma base específica com número finito de bits disponíveis para expressar os números (por exemplo, binários). Se esse n não fosse grande o suficiente, haveria problemas sérios, mas não se preocupe, os cientistas da computação escolhem bem as sementes e outros parâmetros dos geradores pseudo-aleatórios, para obter um bom n.
Por exemplo, um possível gerador de números pseudo-aleatórios, com o método linear congruencial, que é um dos algoritmos de geradores de números pseudo-aleatórios mais antigos e mais conhecidos, pode ser definido de acordo com:
possui quatro valores:
- x_0 ≥ 0
- a ≥ 0
- c ≥ 0
- m> x_0, em que:
x0 é o valor inicial, a, ce são constantes em que: m> a, m> c, e produz a sequência com a fornula:
x_ {i + 1} = (a * x_i + c) MOD m
Os valores para essas constantes devem ser cuidadosamente escolhidos. Uma possibilidade é:
x_ {i + 1} = (1664525 * x_i + 1013904223) MOD 2 ^ 32, refs. [1-2]
Existem outros algoritmos mais sofisticados para gerar números aleatórios, que evitam alguns dos problemas dos algoritmos anteriores, que incluem: [3]
- períodos mais curtos do que o esperado para alguns estados de semente (esses estados de semente podem ser chamados de 'fracos' neste contexto);
- falta de uniformidade de distribuição para grandes quantidades de números gerados;
- correlação de valores sucessivos;
- má distribuição dimensional da sequência de saída;
- as distâncias entre onde certos valores ocorrem são distribuídas diferentemente daquelas em uma distribuição de sequência aleatória.
No futuro, os computadores clássicos podem se unir a sistemas quânticos que podem fornecer números realmente aleatórios e entregá-los. [4]
referências:
[1] http://en.wikipedia.org/wiki/linear_congruential_generator
[2] William H., et al. (1992). "Receitas numéricas no fortran 77: A arte da computação científica" (2ª ed.). ISBN 0-521-43064-X.
[3] http://en.wikipedia.org/wiki/pseudorandom_number_generator
[4] http://www.technologyreview.com/view/418445/first-evidence-that-quantum-processes-generate-truly-random-numbers /