函数原型: int e(big x, big y, big z);功能说明:计算两个大数的最大公约数,z=(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 x(big x, big y, big xd, big yd, big z);
功能说明: 计算两个大数的扩展最大公约数,也可以用来计算模逆,这个函数比mad 函数运算速度稍慢。z=(x,y)=x.xd+y.yd
Example: x(x,p,x,x,x); //计算x^-1 mod p
/* x = 1/x mod p (p is prime) */
三.MIRACL函数库调用举例
1.使用微软的VS.NET 2003中文版
.
.
(1)启动Microsoft Visual Studio .NET 2003,选择“文件”→“新建”→“项目”命令,如图1-1所示;
图1-1 新建项目
(2)打开“新建项目”对话框,选择“Win32控制台项目”模板,在“名称”文本框中输入“TestMircal”,如图1-2所示,单击“确定”按钮;
.
.
图1-2 选择模板
(3)单击“完成”按钮,完成新建项目;
(4)将大数运算静态库文件ms32.lib和头部文件miracl.h和mirdef.h拷贝到项目所在文件夹,本例中为“C:\\Temp\\TestMiracl”,如图1-3所示;
.
.
图1-3 拷贝大数运算库所需文件
(5)将大数运算静态库文件ms32.lib文件添加到项目中,操作方法是:右击“TestMircal”,选择快捷菜单中的“添加”→“添加现有项”命令,如图1-4所示;
.
.
图1-4 打开添加现有项对话框
(6)打开“添加现有项-TestMircal”对话框,选择文件类型为“所有文件(*.*)”,双击“ms32.lib”文件,将其添加到项目中,如图1-5所示;
.
.
图1-5 添加ms32.lib库文件
(7)右击“TestMircal”,选择快捷菜单中的“添加”命令,打开“属性页”对话框,单击“C/C++”配置属性,选择“预编译头”选项,设置为“不使用编译头”,如图1-6所示,单击“确定”按钮;
.
.
图1-6 不使用预编译头
(7)为项目添加如下头文件的包含,此处使用extern \"C\"是表示用C的方式编译,因为ms32.lib是C的库,不是C++的库,如图1-7所示;
extern \"C\"
{
#include \"miracl.h\"
.
.
#include \"mirdef.h\"
}
(8)在_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);
x(x, y, z, z, z);
std::cout<<\"z=\";
cotnum(z, stdout);
*/
mirkill(x); //释放大数变量
mirkill(y);
mirkill(z);
//========================================================
//下面进行RSA算法加密和解密运算
char OutStr[500];
.
.
char mStr[]=\"Computer\";
big m=mirvar(0); //m 明文
big c=mirvar(0); //c 密文
big p=mirvar(0); //大素数p
big q=mirvar(0); //大素数q
big n=mirvar(0); //n 模数
big pn=mirvar(0); //欧拉函数值pn = (p - 1)(q - 1)
big d=mirvar(0); //d 私钥
big e=mirvar(0); //e 公钥
mip->IOBASE=10; //将原来的16进制改为10进制模式
expb2(500, p); //计算2的500次方, 2^1024 ~= 1.8 * 10^308
.
.
nxprime(p, p); //找一个比2的500次方大的素数
std::cout<<\"p=\";
cotnum(p, stdout);
//还是测试一下是否为素数
if ( isprime(p) ) std::cout<<\"p is a prime!\"<<\"\\n\";
premult(p, 2, q); //q=p*2
nxprime(q, q); //找一个比p*2大的素数
std::cout<<\"q=\";
cotnum(q, stdout);
//还是测试一下是否为素数
if ( isprime(q) ) std::cout<<\"q is a prime!\"<<\"\\n\";
.
.
multiply(p, q, n); //n = (p - 1)(q - 1)
//以下计算欧拉函数值pn
decr(p, 1, p); //p = p - 1
decr(q, 1, q); //q = q - 1
multiply(p, q, pn); //pn = (p - 1)(q - 1)
convert(65537, e); //取e公钥为2的16次方加1
//cinstr(e,\"65537\"); //取e公钥为2的16次方加1
x(e, pn, d, d, d); //计算d = e^-1 mod n
std::cout<<\"d=\";
cotnum(d, stdout);
bytes_to_big(8, mStr, m); //将8个字符的明文,转换成大数
.
.
std::cout<<\"m=\";
cotnum(m, stdout);
//加密
powmod(m,e,n,c); //计算c=m^e mod n
std::cout<<\"c=\";
cotnum(c, stdout);
//解密
powmod(c,d,n,m); //计算m=c^d mod n
std::cout<<\"m=\";
cotnum(m, stdout);
big_to_bytes(256,m,OutStr,FALSE); //将m转换成数组写入temp
.
.
OutStr[8] = '\\0';
std::cout<<\"OutStr=\"<mirkill(m); mirkill(c);mirkill(p);
mirkill(q);
mirkill(d);
mirkill(e);
mirkill(n);
mirkill(pn);
mirexit();
.
//释放大数变量
.
2.使用微软的VC++V6.0英文版
使用VC++V6.0和VS.NET2003的区别主要在创建项目和项目属性设置有点不一样。关键就是要把MS32.LIB静态库文件添加到project中,还有就是project的项目属性中的编译选项不要用“预编译头文件”。详细情况请参见msvisual.txt文档。
.