Miracl是什么
MIRACL(Multiprecision Integer and Rational Arithmetic C/c++ Library)是一套由Shamus Software Ltd.所开发的一套关于大数运算函数库,用来设计与大数运算相关的密码学之应用,包含了RSA 公开密码学、Diffie-Hellman密钥交换(Key Exchange)、AES、DSA数字签名,还包含了较新的椭圆曲线密码学(Elliptic Curve Cryptography)等等。
安装流程
- github下载软件包
- 本地生成静态库lib文件
- 函数中即可调用
步骤一:
注意:下载ZIP,而不是直接clone下来
步骤二:
新建文件夹,把下载文件移动到新建文件夹下,命令行进入该文件夹执行命令:
unzip -j -aa -L MIRACL-master.zip
执行命令后出现上图,再次输入(注意是大写的,我之前小写n一直不行):N
解压已经完毕,所有文件都解压在同一目录下。
步骤三:
mac和linux64均可以使用此命令生成C的静态库
bash linux64
如果是32位,则用
bash linux32
如果想要cpp的可以使用
bash linux64_cpp
步骤四:
测试,执行下列命令
./pk-demo
成功会出现下图:
使用1
我这里用的是C语言,参考了LINUX下编译并使用MIRACL密码库
1、 源码编译完后的必需的文件是两个头文件miracl.h和mirdef.h以及编译后的静态函数库miracl.a,需要在自己写的C程序中使用。
2、 输入如下代码,命名为main.c
#include "miracl.h"
void main()
{
big a, b, c;
miracl *mip = mirsys(5000, 16);
a=mirvar(8);
b=mirvar(7);
c=mirvar(0);
add(a, b, c);
cotnum(c, stdout);
}
将miracl.a, miracl.h, mirdef.h拷贝到与main.c所在目录(很关键)
3、 gcc编译并输出main执行程序
gcc main.c miracl.a -o main
./main
使用2
我这里测试了ECC,p,q为160bit下的点加、点乘等操作时间,编写ectime.c
#include "miracl.h"
#include <stdio.h>
#include <time.h>
// 最小时间和最小迭代次数
#define MIN_TIME 10.0
#define MIN_ITERS 20
big p; // 定义全局变量 p,表示曲线的模数
// 测试点加法时间
void test_point_addition() {
clock_t start;
double elapsed;
int iterations = 0;
big x = mirvar(0);
big y = mirvar(0);
epoint *P = epoint_init(); // 初始化点
epoint *Q = epoint_init();
// 生成随机点 P 和 Q
bigrand(p, x);
bigrand(p, y);
epoint_set(x, y, 0, P);
bigrand(p, x);
bigrand(p, y);
epoint_set(x, y, 0, Q);
// 测量点加法时间
start = clock();
do {
ecurve_add(P, Q); // P + Q
iterations++;
elapsed = (double)(clock() - start) / CLOCKS_PER_SEC;
} while (elapsed < MIN_TIME || iterations < MIN_ITERS);
elapsed = 1000000.0 * elapsed / iterations; // 平均时间(毫秒)
printf("Point Addition - %d iterations, %8.2lf µs per iteration\n", iterations, elapsed);
}
// 测试点乘法时间
void test_point_multiplication() {
clock_t start;
double elapsed;
int iterations = 0;
big k = mirvar(0);
big x = mirvar(0);
big y = mirvar(0);
epoint *P = epoint_init(); // 初始化点
// 生成随机点 P
bigrand(p, x);
bigrand(p, y);
epoint_set(x, y, 0, P);
// 测量点乘法时间
start = clock();
do {
bigrand(p, k); // 生成随机标量 k
ecurve_mult(k, P, P); // k * P
iterations++;
elapsed = (double)(clock() - start) / CLOCKS_PER_SEC;
} while (elapsed < MIN_TIME || iterations < MIN_ITERS);
elapsed = 1000000.0 * elapsed / iterations; // 平均时间(毫秒)
printf("Point Multiplication - %d iterations, %8.2lf µs per iteration\n", iterations, elapsed);
}
void calculate_power_of_two(int l, big result) {
zero(result); // 初始化为 0
convert(1, result); // 设置 result = 1
expint(2, l, result); // 计算 2^l
}
// 测试小标量点乘法时间
void test_small_scalar_multiplication(int l) {
clock_t start;
double elapsed;
int iterations = 0;
big k = mirvar(0);
big x = mirvar(0);
big y = mirvar(0);
big upper_bound = mirvar(0);
epoint *P = epoint_init(); // 初始化点
// 生成随机点 P
bigrand(p, x);
bigrand(p, y);
epoint_set(x, y, 0, P);
// 计算 2^l
calculate_power_of_two(l, upper_bound);
// 测量小标量点乘法时间
start = clock();
do {
bigrand(upper_bound, k); // 生成范围内的随机标量 k
ecurve_mult(k, P, P); // k * P
iterations++;
elapsed = (double)(clock() - start) / CLOCKS_PER_SEC;
} while (elapsed < MIN_TIME || iterations < MIN_ITERS);
elapsed = 1000000.0 * elapsed / iterations; // 平均时间(微秒)
printf("Small Scalar Multiplication (k ∈ [1, 2^%d]) - %d iterations, %8.2lf µs per iteration\n", l, iterations, elapsed);
}
// 测试单向哈希时间
void test_oneway_hash() {
clock_t start;
double elapsed;
int iterations = 0;
char data[] = "test message";
sha256 sh;
char hash_output[32]; // 256-bit 哈希输出
// 测试单向哈希时间
start = clock();
do {
shs256_init(&sh);
for (size_t i = 0; i < sizeof(data) - 1; i++) {
shs256_process(&sh, data[i]); // 逐字节处理
}
shs256_hash(&sh, hash_output); // 完成哈希计算
iterations++;
elapsed = (double)(clock() - start) / CLOCKS_PER_SEC;
} while (elapsed < MIN_TIME || iterations < MIN_ITERS);
elapsed = 1000000.0 * elapsed / iterations; // 平均时间(毫秒)
printf("One-Way Hash - %d iterations, %8.2lf µs per iteration\n", iterations, elapsed);
}
// 测试 MapToPoint 哈希时间
void test_map_to_point() {
clock_t start;
double elapsed;
int iterations = 0;
big x = mirvar(0);
epoint *P = epoint_init();
// 测试 MapToPoint 时间
start = clock();
do {
bigrand(p, x); // 随机生成输入值
epoint_set(x, x, 0, P); // 将输入值映射到椭圆曲线点
iterations++;
elapsed = (double)(clock() - start) / CLOCKS_PER_SEC;
} while (elapsed < MIN_TIME || iterations < MIN_ITERS);
elapsed = 1000000.0 * elapsed / iterations; // 平均时间(毫秒)
printf("MapToPoint Hash - %d iterations, %8.2lf µs per iteration\n", iterations, elapsed);
}
int main() {
miracl *mip = mirsys(5000, 10); // 初始化 MIRACL 环境
mip->IOBASE = 16;
big a = mirvar(0); // 椭圆曲线参数 a
big b = mirvar(0); // 椭圆曲线参数 b
// 初始化椭圆曲线参数
p = mirvar(0); // p 作为全局变量使用
cinstr(p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73"); // secp160r1 的 p
cinstr(a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70"); // secp160r1 的 a
cinstr(b, "B4E134D3FB59EB8BAB57274904664D5AF50388BA"); // secp160r1 的 b
ecurve_init(a, b, p, MR_PROJECTIVE); // 初始化椭圆曲线
// 测试点加法、点乘、单向哈希和 MapToPoint
test_point_addition();
test_point_multiplication();
test_small_scalar_multiplication(20); // 测试 l=20 的小标量点乘
test_oneway_hash();
test_map_to_point();
return 0;
}
结果如下:
小结
我之前没有使用经验,如果测试方法有问题,希望友友们评论告诉我其他测试方法~