11111010111 1010 1011

Programar por Programar


¿Te gusta programar?
Inicio


Código fuente de BigNum_ltm

El código fuente de la librería BigNum_ltm.dll, un wrapper de C++ para usar libtommath.lib


Publicado: 18/Oct/2007
Actualizado: 22/oct/2007
Autor: Guillermo 'guille' Som


 

Contenido

Aquí tienes el código fuente de BigNum_ltm.cpp, lee esto si quieres explicaciones de cómo compilarlo.


El código de BigNum_ltm.cpp
//-----------------------------------------------------------------------------
// BigNum_ltm                                                       (07/Sep/06)
//
// Librería de C++ para acceder a las funciones BigNum de la librería
// de LibTomMath por Tom St Denis
//
// ©Guillermo 'guille' Som, 2006 (parte del código)
//
// Para compilar con Borland C++ 5.5 (free)
// Usando la librería para los números grandes de LibTomMath
// bcc -WD -P -O2 -IE:\gnuDev\libmath -l libtommath.lib BigNum_ltm.cpp
//
// Usando la versión 0.41                                           (12/Oct/07)
// Para crear la librería y la DLL usando BCC:
// La librería (libtommath.lib)
// 	make -fmakefile.bcc
// Para crear la DLL (BigNum_ltm.dll)
// 	bcc -WD -P -O2 -I"E:\gnuDev\LibTom (bigNum)\libtommath-0.41" 
 	    -l libtommath.lib BigNum_ltm.cpp
//
// En la versión 0.41 no está definido mp_fromdecimal
// Lo he definido junto a la función que lo usa.
//-----------------------------------------------------------------------------

/* LibTomMath, multiple-precision integer library -- Tom St Denis
 *
 * LibTomMath is a library that provides multiple-precision
 * integer arithmetic as well as number theoretic functionality.
 *
 * The library was designed directly after the MPI library by
 * Michael Fromberger but has been written from scratch with
 * additional optimizations in place.
 *
 * The library is free for all purposes without any express
 * guarantee it works.
 *
 * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
 */


/*
	Esta librería la podemos usar desde otros lenguajes como VB6 o .NET
	En realidad esta DLL es un wraper (envolvente) de algunas de las funciones
	definidas en libTomMath.lib
	
	Principalmente están relacionadas con el uso de números grandes (BigNum)
	y la factorización y cálculos de números primos.
*/

#include <windows.h>

#include <tommath.h>

// Macros para acceder a los BigNums
#define BigNum mp_int


//#define BigNumInt extern "C" FAR PASCAL _export mp_int

// Variables locales
char buf[4096];

mp_int a;

// BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
// {
//     return TRUE;
// }
/*
int WINAPI DllMain(int hInstance, int fdwReason, int pvReserved)
//int DllMain(int, int, int)
{
	mp_init(&amp;a);
	return 1;
}
*/

/*
	Inicializar la variable interna
	Esto seguramente acelerará el uso de las funciones
	Si no se llama a este método antes de usar
	cualquier función, el resultado puede no ser el esperado.
*/
/*
extern "C" FAR PASCAL _export void
Inicializar(){
	mp_init(&a);
}
*/

/*
	Devuelve una cadena (acabada en \\0)
	Recibe como parámetro un valor de tipo BigNum
*/
extern "C" FAR PASCAL _export BSTR 
BigNumToString(BigNum n){
    // Convierte el número en un string
    mp_todecimal(&n, buf);
    // Lo devuelve como una cadena BSTR
    return (BSTR)buf;
}


/*
	Inicializa un BigNum
*/
extern "C" FAR PASCAL _export void
BigNumInit(BigNum* n){
    //
    mp_init(n);
}


/*
	Crea un BigNum a partir de un entero de 32 bits
*/
extern "C" FAR PASCAL _export BigNum
BigNumFromInt(unsigned int num){
    //
    //mp_int a;
    mp_init(&a);
    mp_set_int(&a, num);
    return a;
}

/*
	Devuelve un entero de 32 bits (sin signo) a partir de un BigNum
*/
extern "C" FAR PASCAL _export unsigned long
BigNumToUInt(BigNum n){
    // para probar si funciona
    //return 1234;
    return mp_get_int(&n);
}


/* No está definida en la versión 0.41 (12/Oct/07) */
#ifndef mp_fromdecimal
#define mp_fromdecimal(M, S) mp_read_radix((M), (S), 10)
#endif


/*
	Crea un BigNum a partir de una cadena
*/
extern "C" FAR PASCAL _export BigNum
BigNumFromString(BSTR num){
    //
    //mp_int a;
    mp_init(&a);
    mp_fromdecimal(&a, (char *)num);
    return a;
}


/*
	Multiplica dos BigNum
	devuelve un BigNum
*/
extern "C" FAR PASCAL _export BigNum
BigNumMul(BigNum n1, BigNum n2){
    mp_init(&a);
    mp_mul(&n1, &n2, &a);
    return a;
}

/*
	Divide dos BigNum
	devuelve la parte entera y el resto
	El resto se devuelve como parte de la función
	y la parte entera en el tercer parámetro.
	De esta forma si queremos saber si es una división
	exacta, se comprueba el valor devuelto.
*/
extern "C" FAR PASCAL _export BigNum
BigNumDiv(BigNum n1, BigNum n2, BigNum* num){
    //mp_int r;
    //mp_init(&r);
    //mp_init(&num);
    mp_init(&a);
    mp_div(&n1, &n2, num, &a);
    return a;
}

/*
	Devuelve la suma de dos BigNum
*/
extern "C" FAR PASCAL _export BigNum
BigNumAdd(BigNum n1, BigNum n2){
    mp_init(&a);
    mp_add(&n1, &n2, &a);
    return a;
}

/*
	Devuelve la resta de dos BigNum
*/
extern "C" FAR PASCAL _export BigNum
BigNumSub(BigNum n1, BigNum n2){
    mp_init(&a);
    mp_sub(&n1, &n2, &a);
    return a;
}

/*
	Devuelve el módulo (resto) de dos BigNum
*/
extern "C" FAR PASCAL _export BigNum
BigNumMod(BigNum n1, BigNum n2){
    mp_init(&a);
    mp_mod(&n1, &n2, &a);
    return a;
}

/*
	Devuelve n1 + n2 (mod n3)
*/
extern "C" FAR PASCAL _export BigNum
BigNumAddMod(BigNum n1, BigNum n2, BigNum n3){
    mp_init(&a);
    mp_addmod(&n1, &n2, &n3, &a);
    return a;
}

/*
	Devuelve n1 - n2 (mod n3)
*/
extern "C" FAR PASCAL _export BigNum
BigNumSubMod(BigNum n1, BigNum n2, BigNum n3){
    mp_init(&a);
    mp_submod(&n1, &n2, &n3, &a);
    return a;
}

/*
	Devuelve n1 * n2 (mod n3)
*/
extern "C" FAR PASCAL _export BigNum
BigNumMulMod(BigNum n1, BigNum n2, BigNum n3){
    mp_init(&a);
    mp_mulmod(&n1, &n2, &n3, &a);
    return a;
}

/*
	Devuelve n1 * n1 (mod n2)
*/
extern "C" FAR PASCAL _export BigNum
BigNumSqrMod(BigNum n1, BigNum n2){
    mp_init(&a);
    mp_sqrmod(&n1, &n2, &a);
    return a;
}

/*
	Devuelve 1/n1 (mod n2)
*/
extern "C" FAR PASCAL _export BigNum
BigNumInvMod(BigNum n1, BigNum n2){
    mp_init(&a);
    mp_invmod(&n1, &n2, &a);
    return a;
}

/*
	Devuelve n1 ** n2 (mod n3)
*/
extern "C" FAR PASCAL _export BigNum
BigNumPowMod(BigNum n1, BigNum n2, BigNum n3){
    mp_init(&a);
    mp_exptmod(&n1, &n2, &n3, &a);
    return a;
}


/*
	Devuelve el módulo (resto) de un BigNum
	elevado a la potencia de 2 indicada
	ret = n1 mod 2**pot (n1 mod (2 ^ pot))
*/
extern "C" FAR PASCAL _export BigNum
BigNumModPow2(BigNum n1, int pot){
    mp_init(&a);
    mp_mod_2d(&n1, pot, &a);
    return a;
}


/*
	Devuelve la raíz cuadrada del BigNum indicado
*/
extern "C" FAR PASCAL _export BigNum
BigNumSqrt(BigNum n1){
    mp_init(&a);
    mp_sqrt(&n1, &a);
    return a;
}

/*
	Devuelve 0 ó 1 según n1 sea un cuadrado???
*/
extern "C" FAR PASCAL _export int
BigNumIsSquare(BigNum n1){
    int r;
    mp_is_square(&n1, &r);
    return r;
}

/*
	computes the jacobi c = (a | n) (or Legendre if b is prime)
*/
extern "C" FAR PASCAL _export int
BigNumJacobi(BigNum n1, BigNum n2){
    int r;
    mp_jacobi(&n1, &n2, &r);
    return r;
}


/*
	Devuelve n1 elevado a n1
*/
extern "C" FAR PASCAL _export BigNum
BigNumSqr(BigNum n1){
    mp_init(&a);
    mp_sqr(&n1, &a);
    return a;
}

/*
	Devuelve n1 elevado a n2
*/
extern "C" FAR PASCAL _export BigNum
BigNumPow(BigNum n1, BigNum n2){
    mp_init(&a);
    mp_mul(&n1, &n2, &a);
    return a;
}

/*
	Devuelve un BigNum con
	el valor de 2 elevado a la potencia indicada
	ret = 2 ^ pot (ret = 2**pot)
*/
extern "C" FAR PASCAL _export BigNum
BigNumPow2(int pot){
    mp_init(&a);
    mp_2expt(&a, pot);
    return a;
}

/*
	Devuelve el máximo común divisor de n1 y n2
	ret = (n1, n2)
*/
extern "C" FAR PASCAL _export BigNum
BigNumGCD(BigNum n1, BigNum n2){
    mp_init(&a);
    mp_gcd(&n1, &n2, &a);
    return a;
}
/*
	Devuelve el máximo común divisor
	(iniciales en castellano)
*/
extern "C" FAR PASCAL _export BigNum
BigNumMCD(BigNum n1, BigNum n2){
    mp_init(&a);
    mp_gcd(&n1, &n2, &a);
    return a;
}

/*
	Devuelve el mínimo común múltiplo
	ret = [n1, n2] or (n1*n2)/(n1, n2)
*/
extern "C" FAR PASCAL _export BigNum
BigNumLCM(BigNum n1, BigNum n2){
    mp_init(&a);
    mp_lcm(&n1, &n2, &a);
    return a;
}
/*
	Devuelve el mínimo común múltiplo
	(iniciales en castellano)
*/
extern "C" FAR PASCAL _export BigNum
BigNumMCM(BigNum n1, BigNum n2){
    mp_init(&a);
    mp_lcm(&n1, &n2, &a);
    return a;
}

/*
	Devuelve: ???
	U1*a + U2*b = U3
*/
extern "C" FAR PASCAL _export BigNum
BigNumExtEuclid(BigNum n1, BigNum n2, BigNum U1, BigNum U2){
    mp_init(&a);
    mp_exteuclid(&n1, &n2, &U1, &U2, &a);
    return a;
}



/*
	Devuelve un BigNum aleatorio
	con la cantidad de cifras indicadas.
	En realidad no se si 8 bits es un dígito,
	pero debería serlo.
*/
extern "C" FAR PASCAL _export BigNum
BigNumRand(int digits){
    mp_init(&a);
    mp_rand(&a, (int)(digits / 8));
    return a;
}

/*
	Devuelve un BigNum aleatorio
	con la cantidad de bits indicados
*/
extern "C" FAR PASCAL _export BigNum
BigNumRandBits(int bits){
    mp_init(&a);
    mp_rand(&a, bits);
    return a;
}


/*
	Realiza una operación And con dos BigNum
*/
extern "C" FAR PASCAL _export BigNum
BigNumAnd(BigNum n1, BigNum n2){
    mp_init(&a);
    mp_and(&n1, &n2, &a);
    return a;
}

/*
	Realiza una operación Or con dos BigNum
*/
extern "C" FAR PASCAL _export BigNum
BigNumOr(BigNum n1, BigNum n2){
    mp_init(&a);
    mp_or(&n1, &n2, &a);
    return a;
}

/*
	Realiza una operación Xor con dos BigNum
*/
extern "C" FAR PASCAL _export BigNum
BigNumXor(BigNum n1, BigNum n2){
    mp_init(&a);
    mp_xor(&n1, &n2, &a);
    return a;
}


/*
	Compara dos BigNum
	Devuelve un entero con:
		 0 si son iguales (MP_EQ)
		-1 si el primero es menor (MP_LT)
		 1 si el primero es mayor (MP_GT)
*/
extern "C" FAR PASCAL _export int
BigNumCompare(BigNum n1, BigNum n2){
    return mp_cmp(&n1, &n2);
}


/*
	Copia un BigNum en otro
	Copia el primero en el segundo
	que debe indicarse por referencia.
*/
extern "C" FAR PASCAL _export void
BigNumCopyTo(BigNum n1, BigNum* n2){
    //mp_init(&a);
    mp_copy(&n1, n2);
}

/*
	Devuelve una copia del número indicado
*/
extern "C" FAR PASCAL _export BigNum
BigNumCopy(BigNum n1){
    mp_init(&a);
    mp_copy(&n1, &a);
    return a;
}


/*
	Devuelve 0 ó 1 según sea cero o no
*/
extern "C" FAR PASCAL _export int
BigNumIsZero(BigNum n1){
    return mp_iszero(&n1);
}

/*
	Devuelve 0 ó 1 según sea par o no
*/
extern "C" FAR PASCAL _export int
BigNumIsEven(BigNum n1){
    return mp_iseven(&n1);
}

/*
	Devuelve 0 ó 1 según sea impar o no
*/
extern "C" FAR PASCAL _export int
BigNumIsOdd(BigNum n1){
    return mp_isodd(&n1);
}


/*
	Pone a cero el BigNum indicado por referencia
*/
extern "C" FAR PASCAL _export void
BigNumSetToZero(BigNum* n1){
    mp_zero(n1);
}

/*
	Devuelve un valor BigNum cero
*/
extern "C" FAR PASCAL _export BigNum
BigNumZero(){
    mp_init(&a);
    mp_zero(&a);
    return a;
}

/*
	Devuelve un valor BigNum uno
*/
extern "C" FAR PASCAL _export BigNum
BigNumOne(){
    mp_init(&a);
    mp_set_int(&a, 1);
    return a;
}

/*
	Devuelve un valor BigNum dos
*/
extern "C" FAR PASCAL _export BigNum
BigNumTwo(){
    mp_init(&a);
    mp_set_int(&a, 2);
    return a;
}

/*
	Devuelve -n1
*/
extern "C" FAR PASCAL _export BigNum
BigNumNeg(BigNum n1){
    mp_init(&a);
    mp_neg(&n1, &a);
    return a;
}

/*
	Devuelve el valor absoluto de n1
*/
extern "C" FAR PASCAL _export BigNum
BigNumAbs(BigNum n1){
    mp_init(&a);
    mp_abs(&n1, &a);
    return a;
}


/*
	Devuelve 1 si n1 es divisible por
	uno de los 256 (PRIME_SIZE) primeros primos
*/
extern "C" FAR PASCAL _export int
BigNumPrimeIsDivisible(BigNum n1){
    int r;
    mp_prime_is_divisible(&n1, &r);
    return r;
}

/*
	Devuelve 1 si n1 puede ser un número primo
	usando el algoritmo de Fermat con base n2
	
	performs one Fermat test of "a" using base "b".
 	Sets result to 0 if composite or 1 if probable prime
*/
extern "C" FAR PASCAL _export int
BigNumPrimeIsFermat(BigNum n1, BigNum n2){
    int r;
    mp_prime_fermat(&n1, &n2, &r);
    return r;
}

/*
	Devuelve 1 si n1 puede ser un número primo
	usando el algoritmo de Miller-Rabin con base n2
	
	performs one Miller-Rabin test of "a" using base "b".
	Sets result to 0 if composite or 1 if probable prime
*/
extern "C" FAR PASCAL _export int
BigNumPrimeIsMillerRabin(BigNum n1, BigNum n2){
    int r;
    mp_prime_miller_rabin(&n1, &n2, &r);
    return r;
}

/*
	Hace un test Miller-Rabin con t pruebas
	El valor de t no debería ser superior a 100
	
	performs t rounds of Miller-Rabin on "a" using the first
	t prime bases.  Also performs an initial sieve of trial
	division.  Determines if "a" is prime with probability
	of error no more than (1/4)**t.
	
	Sets result to 1 if probably prime, 0 otherwise
*/
extern "C" FAR PASCAL _export int
BigNumPrimeIsPrime(BigNum n1, int t){
    int r;
    mp_prime_is_prime(&n1, t, &r);
    return r;
}

/*
	Devuelve el siguiente primo a partir de n1
	
	finds the next prime after the number "n1" using "t" trials
	of Miller-Rabin.
	
	bbs_style = 1 means the prime must be congruent to 3 mod 4
*/
extern "C" FAR PASCAL _export BigNum
BigNumPrimeNextPrime(BigNum n1, int t, int bbs_style){
    mp_init(&a);
    mp_copy(&n1, &a);
    mp_prime_next_prime(&a, t, bbs_style);
    return a;
}


Programar por programar... ¡porque te gusta programar!
Ir al índice principal
Ir al sitio del Guille - Ir a los foros del Guille

Has entrado usando el host www.programarporprogramar.org