Segue implementação do Teorema Fundamental da Aritmética em BIGNUM do OpenSSL:
---------- tfa.c ----------
/* Kryptonia - Cryptography Intelligent Research.
* http://www.securitylabs.com.br/
*
* Projeto Zahlen - Teorema Fundamental da Aritmetica.
*
* Glaudson Ocampos <glaudson@securitylabs.com.br>
*
* Compile com:
*
* $ gcc -o tfa tfa.c -lssl -lcrypto -Wall
*
*
* Implementamos apenas trial division para checar novos primos.
* Como se trata apenas de algo conceitual, nao recomendo a utilizacao
* de numeros gigantes.
*
*/
/*
* Teorema Fundamental da Aritmetica declara que todos os numeros
* inteiros maiores que 1 podem ser decompostos em um produto de numeros
* primos.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <openssl/bn.h>
#include <openssl/err.h>
#define VERSAO "0.1"
#define ERRO -1
void
uso(char *progname){
fprintf(stdout,"Projeto Zahlen - versao %s\n",VERSAO);
fprintf(stdout,"Uso: %s <numero>\n\n",progname);
fprintf(stdout,"Exemplo:\n\n");
fprintf(stdout,"./%s <513>\n\n",progname);
fflush(stdout);
}
int
main(int argc, char *argv[]){
BIGNUM *N = NULL, *p=NULL, *dv=NULL, *rem=NULL, *a=NULL, *r=NULL, *n=NULL;
BN_CTX *ctx = NULL;
char *numero = NULL;
if(argc < 2){
uso(argv[0]);
_exit(0);
}
N = BN_new();
if(N == NULL){
fprintf(stderr,"Erro na criacao de bignum!\n");
fprintf(stderr,"%s\n",ERR_error_string(ERR_get_error(),NULL));
fflush(stderr);
_exit(ERRO);
}
fprintf(stdout,"*** Setando valor para Bignum...");
numero = argv[1];
if(BN_dec2bn(&N, numero) == 0){
fprintf(stderr,"Erro em setar valor para BN!\n");
fprintf(stderr,"%s\n",ERR_error_string(ERR_get_error(),NULL));
fflush(stderr);
_exit(ERRO);
}
fprintf(stdout,"OK.\n");
fprintf(stdout,"*** Checando se numero eh primo...");
/* checamos se o numero eh primo, se for, a gente jah para a execucao */
if(BN_is_prime(N, 100, NULL, NULL, NULL) == 0){
fprintf(stdout," Numero composto.\n");
fflush(stdout);
} else {
fprintf(stdout," Numero primo.\n");
fflush(stdout);
_exit(0);
}
/* dividimos N e analisamos se deixa resto */
p = BN_new();
if(p == NULL){
fprintf(stderr,"Erro na criacao de bignum - p!\n");
fprintf(stderr,"%s\n",ERR_error_string(ERR_get_error(),NULL));
fflush(stderr);
_exit(ERRO);
}
dv = BN_new();
if(dv == NULL){
fprintf(stderr,"Erro na criacao de bignum - dv!\n");
fprintf(stderr,"%s\n",ERR_error_string(ERR_get_error(),NULL));
fflush(stderr);
_exit(ERRO);
}
rem = BN_new();
if(rem == NULL){
fprintf(stderr,"Erro na criacao de bignum - rem!\n");
fprintf(stderr,"%s\n",ERR_error_string(ERR_get_error(),NULL));
fflush(stderr);
_exit(ERRO);
}
/* comecamos a divisao com o primeiro numero primo */
if(BN_dec2bn(&p, "2") == 0){
fprintf(stderr,"Erro em setar valor para p!\n");
fprintf(stderr,"%s\n",ERR_error_string(ERR_get_error(),NULL));
fflush(stderr);
_exit(ERRO);
}
a = BN_new();
if(a == NULL){
fprintf(stderr,"Erro na criacao de bignum - a!\n");
fprintf(stderr,"%s\n",ERR_error_string(ERR_get_error(),NULL));
fflush(stderr);
_exit(ERRO);
}
if(BN_dec2bn(&a, "1") == 0){
fprintf(stderr,"Erro em setar valor 1 para a!\n");
fprintf(stderr,"%s\n",ERR_error_string(ERR_get_error(),NULL));
fflush(stderr);
_exit(ERRO);
}
r = BN_new();
if(r == NULL){
fprintf(stderr,"Erro na criacao de bignum - r!\n");
fprintf(stderr,"%s\n",ERR_error_string(ERR_get_error(),NULL));
fflush(stderr);
_exit(ERRO);
}
n = BN_new();
if(n == NULL){
fprintf(stderr,"Erro na criacao de bignum - n!\n");
fprintf(stderr,"%s\n",ERR_error_string(ERR_get_error(),NULL));
fflush(stderr);
_exit(ERRO);
}
ctx = BN_CTX_new();
if(ctx == NULL){
fprintf(stderr,"Erro na criacao de BN_ctx!\n");
fprintf(stderr,"%s\n",ERR_error_string(ERR_get_error(),NULL));
fflush(stderr);
_exit(ERRO);
}
/* */
fprintf(stdout,"*** Primos: \n");
fflush(stdout);
n = N;
while(1){
BN_div(dv,rem, n, p, ctx);
// fprintf(stdout,"n = %s - primo = %s - dv = %s - resto = %s\n", BN_bn2dec(n),BN_bn2dec(p),BN_bn2dec(dv),BN_bn2dec(rem));
if(atoi(BN_bn2dec(dv)) == 1) {
fprintf(stdout,"%s ",BN_bn2dec(p));
fflush(stdout);
break;
}
if(atoi(BN_bn2dec(rem)) == 0){
fprintf(stdout,"%s ",BN_bn2dec(p));
fflush(stdout);
}
if((BN_is_prime(dv, 100, NULL, ctx, NULL) == 1) && (atoi(BN_bn2dec(rem)) == 0)){
fprintf(stdout,"%s",BN_bn2dec(dv));
fflush(stdout);
break;
}
if(atoi(BN_bn2dec(rem)) > 0){
n = N;
while(1){
BN_add(r, p, a);
p = r;
if(BN_is_prime(p, 100, NULL, ctx, NULL) == 1){
break;
}
}
}
else {
BN_add(n, dv, rem);
}
}
fprintf(stdout,"\n\n");
fflush(stdout);
BN_free(N);
BN_free(p);
BN_free(rem);
BN_free(dv);
BN_free(a);
// BN_free(r); // ponteiro - double free
// BN_free(n); // ponteiro - double free
BN_CTX_free(ctx);
return 0;
}
----------
Nenhum comentário:
Postar um comentário
Comentários são moderados visando evitar spams e permitir discussões sadias.