一.MIRACL簡介
MIRACL(Multiprecision Integer and Rational Arithmetic C/c++ Library)是一套由Shamus Software Ltd.所開發的一套關於大數運算函數庫,用來設計與大數運算相關的密碼學之應用,包含了RSA 公開密碼學、Diffie-Hellman密鑰交換(Key Exchange)、AES、DSA數字簽名,還包含了較新的橢圓曲線密碼學(Elliptic Curve Cryptography)等等。運算速度快,並提供源代碼。國外著名密碼學函數庫還有:GMP、NTL、Crypto++、LibTomCrypt(LibTomMath)、OpenSSL等。
二.MIRACL函數庫調用舉例
所需文件:數運算靜態庫文件ms32.lib和頭部文件miracl.h和mirdef.h。
為項目添加如下頭文件的包含,此處使用extern "C"是表示用C的方式編譯,因為ms32.lib是C的庫,不是C++的庫。
extern "C"
{
#include "miracl.h"
#include "mirdef.h"
}
在_tmain函數中插入如下代碼,以測試大數運算情況。
miracl *mip = mirsys(400,10); //初始化一個400位10進制的大數系統
big x,y,z;
x = mirvar(177);
y = mirvar(79);
z = mirvar(0);
divide(x, y, z); //x=x mod y, z=x/y
cotnum(x,stdout); //x=19
cotnum(y,stdout); //y=79
cotnum(z,stdout); //z=2
multiply(x, y, z); //z=x*y
mip->IOBASE=16; //將原來的10進制改為16進制模式
cotnum(z, stdout); //5DD
/* 測試13^-1 mod 2436 = 937
x = mirvar(13);
y = mirvar(2436);
xgcd(x, y, z, z, z);
std::cout<<"z=";
cotnum(z, stdout);
*/
mirkill(x); //釋放大數變量
mirkill(y);
mirkill(z);
三.MIRACL常用函數調用手冊
聲明:此處只列出和大數相關的簡單運算函數,以及產生大數隨機數的函數調用手冊,具體請查看manual.doc文檔。不當之處,請大家批評指正!
函數原型: void absol(big x, big y);
功能說明: 取x的絕對值,y=|x|
函數原型: void add(big x, big y, big z);
功能說明: 兩個大數相加,z=x+y
Example: add(x,x,x); // This doubles the value of x.
函數原型: void bigbits(int n, big x);
功能說明: 產生一個n位的大整數,初始化隨機種子由irand函數實現
Example: bigbits(100,x); //This generates a 100 bit random number
函數原型: int cinstr(big x, char *s);
功能說明: 將大數字符串轉換成大數
返回值: 輸入字符數的個數
Example: mip->IOBASE=16; // input large hex number into big x
cinstr(x,”AF12398065BFE4C96DB723A”);
函數原型: int compare(big x, big y);
功能說明: 比較兩個大數的大小
返回值: x>y時返回+1, x=y時返回0, x<y時返回-1
函數原型: void convert(int n, big x);
功能說明: 將一個整數n轉換成一個大數x
函數原型: void copy(big x, big y);
功能說明: 將一個大數賦值給另一個大數,y=x
函數原型: int cotstr(big x, char *s);
功能說明: 將一個大數根據其進制轉換成一個字符串
返回值: 字符串長度
函數原型: void decr(big x, int n, big z) ;
功能說明: 將一個大數減去一個整數, z=x-n.
函數原型: void divide(big x, big y, big z);
功能說明: 兩個大數相除,z=x/y; x=x mod y,當變量y和z相同時,x為余數,商不返回(即y的值不變);當x和z相同時,x為商,余數不返回。
Example: divide(x,y,y);//x為余數,y值不變
函數原型: BOOL divisible(big x, big y)
功能說明: 測試x能否整除y
返回值: y除x余數為0,返回TRUE,否則返回FALSE
函數原型: int igcd(int x, int y) ;
功能說明: 返回兩個整數的最大公約數
函數原型: void incr(big x, int n, big z);
功能說明: 將一個大數加上一個整數, z=x+n
Example: incr(x,2,x); /* This increments x by 2. */
函數原型: void mirkill(big x);
功能說明: 釋放內存大數所占的內存
函數原型: miracl *mirsys(int nd, int nb);
功能說明: 初始化MIRACL系統,該函數必須在調用MIRACL庫函數之前先執行
Example: miracl *mip=mirsys(500,10);//初始化500位的10進行制數
函數原型: void mirexit();
功能說明: 清除MIRACL系統,釋放所有內部變量
函數原型: void multiply(big x, big y, big z);
功能說明: 兩個大數相乘,z=x.y
函數原型: void negify(big x, big y);
功能說明: 大數取負號,y=-x.
函數原型: int numdig(big x);
功能說明: 返回大數x中數字的個數
函數原型: void premult(big x, int n, big z);
功能說明: 一個大數乘以一個整數,z=n.x
函數原型: int subdiv(big x, int n, big z);
功能說明: 一個大數除以一個整數,z=x/n.
返回值: 余數
函數原型: BOOL subdivisible(big x, int n)
功能說明: 測試n能否整除x
返回值: x除以n余數為0,返回TRUE,否則返回FALSE
函數原型: void bigdig(int n, int b, big x);
功能說明: 產生一個指定長度的進制的隨機數,該函數使用內置的隨機數發生器,初始化種子調用irand函數
Example: bigdig(100,10,x); //產生一個100位的10進制隨機數
函數原型: void bigrand(big w, big x);
功能說明: 使用內置的隨機數發生器,產生一個小於w的大數隨機數,x<w
函數原型: int egcd(big x, big y, big z);
功能說明:計算兩個大數的最大公約數,z=gcd(x,y)
函數原型: void expb2(int n, big x)
功能說明: 計算2的n次方的大數
Example: expb2(1398269,x); //2^1398269
decr(x,1,x); //x = x - 1
mip->IOBASE=10; //使用10進制
cotnum(x,stdout); //輸出到屏幕
This calculates and prints out the largest known prime number (on a true 32-bit computer with lots of memory!)
函數原型: void expint(int b, int n, big x);
功能說明: 計算b的n次方的大數
函數原型: void fft_mult(big x, big y, big z);
功能說明: 使用Fast Fourier算法計算兩個大數乘積,z=x.y
函數原型: unsigned int invers(unsigned int x, unsigned int y);
功能說明:計算兩個無符號整數(要求互素)的模逆,返回x-1 mod y
函數原型: BOOL isprime(big x);
功能說明:判斷一個大數是否為素數,使用概率測試算法
返回值: x為素數返回TRUE,否則返回FALSE
函數原型: void powmod(big x, big y, big z, big w);
功能說明: 模冪運算,w=xy mod z
函數原型: void sftbit(big x, int n, big z);
功能說明:將一個大數左移或右移n位,n為正數時左移,負數時右移
函數原型: int xgcd(big x, big y, big xd, big yd, big z);
功能說明: 計算兩個大數的擴展最大公約數,也可以用來計算模逆,這個函數比mad 函數運算速度稍慢。z=gcd(x,y)=x.xd+y.yd
Example: xgcd(x,p,x,x,x); //計算x^-1 mod p
/* x = 1/x mod p (p is prime) */
四.遇到的問題
無法打開文件“libc.lib”: 如果將用低版本的VC開發的項目,拿到高版本的VC開發環境上去編譯,鏈接時也許會觸發LNK1104錯誤。解決方案是鏈接時忽略此庫,項目->屬性中->配置屬性->鏈接器->輸入->在忽略特定庫中寫入打不開的文件的名稱libc.lib
無法解析的外部符號 __iob :
#ifdef __cplusplus
extern "C"
#endif
FILE _iob[3] = {__iob_func()[0], __iob_func()[1], __iob_func()[2]};