//-----------------------------------------------------------------------------
// 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(&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;
}