Este artigo visa descrever as etapas e os códigos fontes que permitiram vencer o desafio RSA, promovido aqui no VOL, como parte do artigo "Criptografia Assimétrica com o RSA", de Elgio Schlemer.
É, não é tão fácil quando não se tem esses códigos, apenas o conceito. Quinta-feira, 13/08/2009, à tarde, eu e mais alguns participantes, com um pouco de atraso, vimos o tópico do desafio do Prof. Elgio. Aqui começa a aventura. No começo, era fácil. Chaves propositalmente fracas, faziam ficar fácil. A chave 2 quebrou em menos de 20 minutos (usando a primeira versão do código e apenas um core). A chave N1 mal se pode falar, já que é o mesmo exemplo do artigo. Enquanto quebrava a 2 e a 3, eu ia codificando o euclides_ext.py.
Por mais simples que possa parecer, esses passos levaram quase a tarde toda da quinta-feira. Quando é 17:30h, tenho que sair. Tinha compromisso. Deixei 3 computadores processando N4, N5 e N7. Não deixei mais pois não imaginei que as últimas seriam tão difíceis.
Esperava voltar antes das 21h, mas, por problemas que fogem ao nosso alcance, só pude voltar 23h. Já estava quase perdendo as esperanças. Tinha certeza que, mesmo tendo saído com uma vantagem de 506 pra 126 pontos (cada item do desafio tinha pontos, sendo que os mais difíceis pontuavam mais), graças à codificação em python do euclides_estendido, que já tinha me permitido quebrar até D4, esperava que nesse período os outros competidores já teriam me superado.
Pensei então que, para vencê-los, teria que terminar o desafio o mais cedo possível. Deixei 3 computadores processando N6, N7 e N8 de forma direta (do começo para a raiz) durante a noite. Acordava a cada 2h pra ver se algum já tinha terminado. N6 terminou de processar por volta das 4h da manhã. N7 e N8 já estavam há quase 12h processando. De manhã, o prof. Elgio atualizou os dados. Eu estava em segundo!
Nessa hora, gelei. Aff, não posso nadar tanto pra morrer na praia. Por volta das 9h da manhã, N7 terminou de processar. Mas ainda faltava o mais difícil, o N8. Estava extremamente nervoso, pois a parte de processamento pesado já tinha terminado paro o primeiro colocado e para ele faltavam apenas as mensagens. Aprendi multi-threading com python em 15min para tentar agilizar o processo.
Com a dica do professor de fazer o processamento de traz para frente (publicada no fórum do desafio), cancelei tudo que estava fazendo, e coloquei dois computadores de 2 núcleos pra processarem tudo junto, cada núcleo com decrementos de 8.
O resultado saiu com cerca de 30min de processamento. Foi um alívio quando terminou. Calcular o D foi rápido, pois não exige esforço computacional algum, apenas o algoritmo certo, assim como decifrar as mensagens. Só não foi mais rápido do que enviar o e-mail para o professor Elgio. Essa foi muito apertada.
Este desafio foi muito proveitoso, divertido e instrutivo. Aprendi muito com as dificuldades reais e problemas que aparecem todo dia para resolvermos. Agradeço em especial a Deus, por ter me dado a oportunidade de participar de eventos tão legais e compartilhar esse momento com pessoas de tão alto nível quanto vocês.
Quero agradecer em especial ao professor Elgio pela iniciativa. Os artigos são ótimos, e esses desafios só fazem aguçar a curiosidade e interesse dos leitores pelo assunto. Quero parabenizar também os outros participantes, que, por todo esforço e dedicação, também merecem a honra.
Para finalizar, seguem os resultados finais.
Obrigado a todos, e até a próxima. E 86 105 118 97 32 79 32 76 105 110 117 120
[1] Comentário enviado por elgio em 25/08/2009 - 10:52h
O André está de parabéns. Não apenas venceu o desafio, como também topou um outro desafio, este sem ganhar nada, de escrever este artigo. Pretendo, em breve, atualizar o artigo sobre RSA contando o meu lado da estória e citando os outros participantes que se esforçaram muito também.
[2] Comentário enviado por mago_dos_chats em 25/08/2009 - 17:15h
Parabéns Andre, pelo primeiro lugar no desafio e pelo artigo, que ficou bem escrito, descrevendo seu esforço passo a passo pra resolver o problema.
Abraço
[4] Comentário enviado por clovesjr em 25/08/2009 - 22:06h
Quero deixar meus parabéns ao André por ter vencido o desafio de forma magistral...
Muito legal contar sua experiência porque como também participei, encontrei desafios semelhantes aos que você encontrou mas você conseguiu superá-los antes de todos os outros participantes.
Assim que conseguir, também vou escrever uma dica ou um artigo sobre esta experiência porque usei o C como linguagem e inicialmente esbarrei naquele problema do tamanho do número e pretendo mostrar como consegui superar este problema usando o próprio C (sem usar a dica do Prof. Elgio).
[6] Comentário enviado por andre.vmatos em 29/09/2009 - 15:02h
Olá, Thiago. Tem razão. Normalmente, preservo essas técnicas de boa programação nos programas que faço, entretanto, estes usavam realmente estes nomes para as variáveis. Por exemplo, no RSA, a mensagem criptografada é realmente chamada de "c", por isso usei letras como variáveis nos meus programas, também, as mesmas utilizadas pelo Prof. Elgio nos programas dele. Mas obrigado mesmo assim. Qualquer coisa, estamos ai pra tirar qqr dúvida. Abçss
[8] Comentário enviado por elgio em 03/10/2009 - 12:28h
Oi Thiago.
Só para lhe dar uma resposta, escolher nomes de variáveis PEQUENOS, como i, j, k, vai de acordo com a sugestão "Coding Style" de K&R (capítulo 4, nomes de variáveis).
Ela é uma crítica a outros padrões e sugere que se coloque nomes curtos, preferencialmente UMA ÚNICA LETRA, para variáveis locais, que não devem ser muitas (se forem, então tu não dividiu corretamente teu código em funções).
Sugere que variáveis Globais (Argh) tenham sua primeira letra maiúscula e que estas sim tenham um nome que digam o que ela é. E sugere que constantes sejam todas maiúsculas.
Assim, neste formato de codificação, este seria um PÉSSIMO exemplo:
int f;
int soma (int variavelIntSoma1, int VariavelIntSoma2)
{
int resultadoSoma;
..
}
Mas esta seria ideal:
int Configuracao;
int soma (int x, int y)
{
int s;
[9] Comentário enviado por andre.vmatos em 16/12/2009 - 19:45h
Se alguém se interessar em aprofundar-se um pouco mais na teoria dos números na qual me baseei pra gerar o algorítimo de divisão de números grandes (congruência), pode estar dando uma lida nesse material: http://www.rumoaoita.com/site/index.php?option=com_content&view=article&id=65:apostila-de-congruenci...
É bastante teórico, mas pra quem gosta, pode ser interessante. Na época do desafio, não usei esse material, pq não o conhecia ainda, então, usei explicações bem mais simples, mas que foram suficientes. Então, essa semana, estudando pro vestibular do ITA, que está ocorrendo agora, entre os dais 15 e 18 de dezembro, do qual estou participando, encontrei essa apostila, no site Rumo ao ITA. Pode ser útil a alguém. T+
[11] Comentário enviado por maurisilvestre em 28/05/2010 - 10:45h
Ótimo artigo André, parabéns em dobro, primeiro por vencer o desafio e segundo por compartilhar conosco, assim todos podem ter um material de apoio para aprendizado.
t+ Fica com Deus e boa sorte nos próximos desafios =)
[13] Comentário enviado por removido em 26/09/2011 - 11:36h
Olá. (celestina23love@yahoo.com)
Fiquei muito impressionado ao seu perfil em (vivaolinux.com.br) e eu sinto como ter uma boa amizade com você, meu nome é Celestina, eu gosto de você para me escrever de volta com o meu e-mail(celestina23love@yahoo.com) para que eu possa enviar-lhe uma foto e dizer mais sobre mim, obrigado por acolher o meu pedido de amizade, eu estarei esperando por sua resposta ao meu endereço de email.
Celestina.
Hello. ( celestina23love@yahoo.com )
I was very impressed to your profile at ( vivaolinux.com.br ) and i feel like to have a good friendship with you, My Name is Celestina, i will like you to write me back with my email
( celestina23love@yahoo.com ) so that i can send you a picture and tell you more about me, thanks for welcome my friendship request, i will be waiting for your respond at my mail address.
Celestina .
[16] Comentário enviado por nandobravo06 em 19/11/2011 - 01:11h
Um meio interessante de conseguir um desempenho extra no algoritmo de força bruta, é ao invés de tentar todos os ímpares (3, 5, 7, 9, 11, 13...), é só observar que tirando o 2 e o 3, todos os demais números primos é fruto da multiplicação de (x por 6) + ou - 1...
x=1:
5 = (1 * 6) - 1
7 = (1 * 6) + 1
x=2:
11 = (2 * 6) - 1
13 = (2 * 6) + 1
Isso não significa que x * 6 + ou - 1 sempre vá gerar números primos, mas significa uma redução de UM TERÇO do processamento em relação ao algoritmo que testa todos os ímpares.
Uma outra observação é que, sendo N um número gigante, se ((N+1)%6 !=0)&&((N-1)%6 !=0), Se essa condição for verdadeira, SEGURAMENTE O NÚMERO É COMPOSTO!
[17] Comentário enviado por elgio em 19/11/2011 - 13:55h
Que dica maravilhosa Fernando.
Se tiver mais dicas sobre números primos, manda.
Eu, particularmente, levei um pau no passado para descobrir e implementar o euclides extendido para calcular o D do RSA. Não é algo que se encontra de forma clara por ai.