我是靠谱客的博主 超帅抽屉,最近开发中收集的这篇文章主要介绍miracl实现sm2,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

没有被注释掉的是miracl实现的sm2,被注释掉的是ECDSA,加解密没对上,不知道哪里出了问题。不想debug了。
我要抓紧时间写毕设。
就调个linux下面的sm2练练手吧。

伤心。

以下代码是win上写的。linux下面稍微有些不同。

Win环境的代码如下

#include <stdio.h>
#include "big.h"
#include "miracl.h"
#include "ecn.h"
#include "string.h"
#include "mirdef.h"
#include <time.h>
#include "typedef.h"
#include <ctime>
typedef struct
{
big r;
big s;
}digital_sign;//签名的结果的结构体
//定义参数
static const char sm2_p[] = "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF";
static const char sm2_a[] = "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC";
static const char sm2_b[] = "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93";
static const char sm2_n[] = "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123";
static const char sm2_Gx[] = "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7";
static const char sm2_Gy[] = "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0";
//声明静态变量 全局变量
static big g_p;
static big g_a;
static big g_b;
static big g_n;
static big g_nb;
//私钥
static epoint* g_Q;//公钥
static epoint* g_G;//椭圆曲线的基点
void ECDSA_Initialize(miracl* pm)
{
pm->IOBASE = 16;//说明是十六进制
g_p = mirvar(0);
g_a = mirvar(0);
g_b = mirvar(0);
g_n = mirvar(0);
cinstr(g_p, (char*)sm2_p);
cinstr(g_a, (char*)sm2_a);
cinstr(g_b, (char*)sm2_b);
cinstr(g_n, (char*)sm2_n);
ecurve_init(g_a, g_b, g_p, MR_AFFINE);
big tmp_x = mirvar(0);
big tmp_y = mirvar(0);
cinstr(tmp_x, (char*)sm2_Gx);
cinstr(tmp_y, (char*)sm2_Gy);
g_G = epoint_init();//将内存分配给GF(p)椭圆曲线上的一个点,并将其初始化为“无穷大点”。
if (!epoint_set(tmp_x, tmp_y, 1, g_G))
{
exit(0);
}
//私钥
g_nb = mirvar(0);
irand(time(NULL));
bigbits(256, g_nb);//256bit
while (mr_compare(g_nb, g_n) >= 0)//私钥nb要比n小
{
bigbits(256, g_nb);
}
//公钥
g_Q = epoint_init();
ecurve_mult(g_nb, g_G, g_Q);
//FILE* stream;//输入到文件中,用于生成含有用户标识的za
//stream = fopen("transfer.txt", "r+");
//otnum(g_a, stream);
//otnum(g_b, stream);
//otnum(g_G->X, stream);
//otnum(g_G->Y, stream);
//otnum(g_Q->X, stream);
//otnum(g_Q->Y, stream);
//fclose(stream);
//FILE* stream2;//私钥保存
//stream2 = fopen("secret.txt", "r+");
//otnum(g_nb, stream2);
//fclose(stream2);
}
void ShaTest()
{
sha256 sha123;
shs256_init(&sha123);
char lpStr[] = "1234567890abcdef1234567890abcdef优雅人生www.dllhook.com";
char szSha[32] = { 0 };
char* lpStr_ = lpStr;
printf("明文:%sn", lpStr);
while (*lpStr_ != 0)
shs_process(&sha123, *lpStr_++);
shs_hash(&sha123, szSha);
printf("SHA256:");
for (int i = 0; i < 32; i++)
{
if (szSha[i] == 0)
break;
printf("%.2X", (unsigned char)szSha[i]);
}
printf("n");
}
//digital_sign ECDSA_Sign( miracl* pm, big e_b)
//{
//
//
//	big k = mirvar(0);//A3:用随机数发生器产生随机数k ∈[1,n-1];
//	irand(time(NULL));
//	bigrand(g_n, k);
//
//	epoint* kk = epoint_init();
//	ecurve_mult(k, g_G, kk);// A4:计算椭圆曲线点(x 1, y 1) = [k]G
//	big z = mirvar(0);
//	z = kk->X;
//	divide(z, g_n, g_n);
//	while (z == 0) //计算r=z modn,若r=0则返回第一步;
//	{
//
irand(time(NULL));
//
bigrand(g_n, k);
//
ecurve_mult(k, g_G, kk);
//
z = kk->X;
//
divide(z, g_n, g_n);
//	}
//	digital_sign a;
//	a.r = mirvar(0);
//	a.s = mirvar(0);
//	//big e_b = mirvar(0);
//	pm->IOBASE = 16;//说明是十六进制//r计算完毕
//	
//	big tmp_rd = mirvar(0);
//
//	multiply(g_nb, a.r, tmp_rd);//计算s = k(e+dr)mod n
//	add(tmp_rd, e_b, tmp_rd);
//	multiply(k, tmp_rd, tmp_rd);
//	divide(tmp_rd, g_n, g_n);//mod n
//	a.s = tmp_rd;
//	while (0 == a.s) //A6:若s=0则返回A3;
//	{
//
irand(time(NULL));
//
bigrand(g_n, k);
//
ecurve_mult(k, g_G, kk);
//
z = kk->X;
//
divide(z, g_n, g_n);
//
while (z == 0) //计算r=z modn,若r=0则返回第一步;
//
{
//
irand(time(NULL));
//
bigrand(g_n, k);
//
ecurve_mult(k, g_G, kk);
//
z = kk->X;
//
divide(z, g_n, g_n);
//
}
//
multiply(g_nb, a.r, tmp_rd);//计算s = k(e+dr)mod n
//
add(tmp_rd, e_b, tmp_rd);
//
multiply(k, tmp_rd, tmp_rd);
//
divide(tmp_rd, g_n, g_n);//mod n
//
a.s = tmp_rd;
//	}//r/s计算完毕 
//
add(a.s, g_n, a.s);
//	divide(a.s, g_n, g_n);
//	return a;
//}
digital_sign ECDSA_Sign(miracl* pm, big e_b)
{
big k = mirvar(0);//A3:用随机数发生器产生随机数k ∈[1,n-1];
irand(time(NULL));
bigrand(g_n, k);
epoint* kk = epoint_init();
ecurve_mult(k, g_G, kk);// A4:计算椭圆曲线点(x 1, y 1) = [k]G
digital_sign a;//A5:计算r=(e+x 1 ) modn,若r=0或r+k=n则返回A3;
a.r = mirvar(0);
a.s = mirvar(0);
//big e_b = mirvar(0);
pm->IOBASE = 16;//说明是十六进制
//getchar();
//bigdig(32, 16, e_b);
//cinstr(e_b, e);
add(e_b, kk->X, a.r);
big tmp_rk = mirvar(0);
add(a.r, k, tmp_rk);
divide(a.r, g_n, g_n);
while (0 == a.r || tmp_rk == g_n) //A5:计算r=(e+x 1 ) modn,若r=0或r+k=n则返回A3;
{
irand(time(NULL));
bigrand(g_n, k);
ecurve_mult(k, g_G, kk);
add(e_b, kk->X, a.r);
add(a.r, k, tmp_rk);
divide(a.r, g_n, g_n);
}//r计算完毕
big tmp_rd = mirvar(0);
big tmp6 = mirvar(0);
multiply(g_nb, a.r, tmp_rd);//A6:计算s = ((1 + d A ) −1 · (k − r · d A )) modn,若s=0则返回A3;
multiply(g_n, k, tmp_rk);//n*k+k-nb*r
add(tmp_rk, k, tmp_rk);
subtract(tmp_rk, tmp_rd, tmp6);
divide(tmp6, g_n, g_n);//先mod n
big tmp_s = mirvar(0);
incr(g_nb, 1, tmp_s);
xgcd(tmp_s, g_n, tmp_s, tmp_s, tmp_s);
multiply(tmp_s, tmp6, a.s);
divide(a.s, g_n, g_n);
while (0 == a.s) //A6:若s=0则返回A3;
{
irand(time(NULL));
bigrand(g_n, k);//A3:用随机数发生器产生随机数k ∈[1,n-1];
ecurve_mult(k, g_G, kk);// A4:计算椭圆曲线点(x 1, y 1) = [k]G
add(e_b, kk->X, a.r);
add(a.r, k, tmp_rk);
divide(a.r, g_n, g_n);
while (0 == a.r || tmp_rk == g_n)//A5:计算r=(e+x 1 ) modn,若r=0或r+k=n则返回A3;
{
irand(time(NULL));
bigrand(g_n, k);
ecurve_mult(k, g_G, kk);
add(e_b, kk->X, a.r);
add(a.r, k, tmp_rk);
divide(a.r, g_n, g_n);
}
multiply(g_nb, a.r, tmp_rk);//A6:计算s = ((1 + d A ) −1 · (k − r · d A )) modn,若s=0则返回A3;
subtract(k, tmp_rk, tmp6);
divide(tmp6, g_n, g_n);
add(tmp6, g_n, a.s);//处理负号
divide(tmp6, g_n, g_n);
incr(g_nb, 1, tmp_s);
xgcd(tmp_s, g_n, tmp_s, tmp_s, tmp_s);
multiply(tmp_s, tmp6, a.s);
divide(a.s, g_n, g_n);
}//r/s计算完毕 
add(a.s, g_n, a.s);
divide(a.s, g_n, g_n);
return a;
}
int ECDSA_verify(digital_sign a, miracl* pm, big e_b)
{
if (!(a.r > 0 && mr_compare(g_n, a.r))) //B1:检验r'∈[1,n-1]是否成立,若不成立则验证不通过;
{
return 0;
}
if (!(a.s > 0 && mr_compare(g_n, a.s)))//B2:检验s'∈[1,n-1]是否成立,若不成立则验证不通过;
{
return 0;
}
big t = mirvar(0);//B5:计算t = (r'+ s') mod n	若t = 0,则验证不通过;
add(a.r, a.s, t);
divide(t, g_n, g_n);
if (0 == t)
{
return 0;
}
epoint* g_xy1;//B6:计算椭圆曲线点(x'1 ,y'1 ) = [s']G + [t]P A ;
g_xy1 = epoint_init();
ecurve_mult(a.s, g_G, g_xy1);
epoint* g_xy2;
g_xy2 = epoint_init();
ecurve_mult(t, g_Q, g_xy2);
ecurve_add(g_xy1, g_xy2);
//big e_b = mirvar(0);//将获得的hash 值e转换为数字big
//cinstr(e_b, e);
big R = mirvar(0);//B7:计算R = (e'+ x'1 ) modn,检验R = r'是否成立,若成立则验证通过;否则验证不通过。
add(e_b, g_xy2->X, R);
divide(R, g_n, g_n);
if (!mr_compare(R, a.r))
{
return 1;
}
return 0;
}
//bool ECDSA_verify(digital_sign a, miracl* pm, big e_b)
//{
//	if (!(a.r > 0 && mr_compare(g_n, a.r))) //B1:检验r'∈[1,n-1]是否成立,若不成立则验证不通过;
//	{
//
return false;
//	}
//	if (!(a.s > 0 && mr_compare(g_n, a.s)))//B2:检验s'∈[1,n-1]是否成立,若不成立则验证不通过;
//	{
//
return false;
//	}
//	big w = mirvar(0);
//	w = a.s;
//	xgcd(w, g_n, w, w, w );//w取逆
//	big u1 = mirvar(0);
//	multiply(e_b, w, u1);
//	divide(u1, g_n, g_n);
//	big u2 = mirvar(0);
//	multiply(a.r, w, u2);
//	divide(u2, g_n, g_n);
//	epoint* g_xy1;//计算椭圆曲线点(x'1 ,y'1 ) = [u2]G + [u1]P A ;
//	g_xy1 = epoint_init();
//	ecurve_mult(u2, g_G, g_xy1);
//	epoint* g_xy2;
//	g_xy2 = epoint_init();
//	ecurve_mult(u1, g_Q, g_xy2);
//	ecurve_add(g_xy1, g_xy2);
//
//	//big e_b = mirvar(0);//将获得的hash 值e转换为数字big
//	//cinstr(e_b, e);
//	big R = mirvar(0);//B7:计算R =
x'1
modn,检验R = r'是否成立,若成立则验证通过;否则验证不通过。
//	R = g_xy2->X;
//	divide(R, g_n, g_n);
//	if (!mr_compare(R, a.r))
//	{
//
return true;
//	}
//	printf("nohere n");
//
//	return false;
//}
int main()
{
miracl *pm = mirsys(500, 16);//初始化miracl系统,该函数必须在调用miracl库函数之前先执行
//example:
miracl *mip = mirsys(500, 10);
//初始化500位的10进行制数
big e_b = mirvar(0);
double
duration;
bigdig(32, 16, e_b);//加密的输入
clock_t start, finish;
start = clock();
ECDSA_Initialize(pm);//生成
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf("KeyGen: %f secondsn", duration);
start = clock();
digital_sign a = ECDSA_Sign(pm, e_b);
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf("Sign: %f secondsn", duration);
start = clock();
int r = ECDSA_verify(a, pm,e_b);
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf("Verify: %f secondsn", duration);
if (1 == r)
{
printf("OKn");
}
else
{
printf("no n");
}
//ShaTest();
printf("n输入任意字符回车后退出……");
getchar();
return 0;
}

LINUX的环境下面跑的代码是这样的
主体没有变,就头文件还有main函数变了。
自己摸索开发好费劲,好想加入师兄师姐每个星期的讨论会啊啊啊啊啊啊啊啊啊啊啊
啊啊啊啊啊啊啊
还是一起学还有有人带入门快一点
忧伤。

#include <stdio.h>
#include "miracl.h"
#include "mirdef.h"
#include <time.h>
#include <stdlib.h>
typedef struct
{
big r;
big s;
}digital_sign;//签名的结果的结构体
//定义参数
static const char sm2_p[] = "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF";
static const char sm2_a[] = "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC";
static const char sm2_b[] = "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93";
static const char sm2_n[] = "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123";
static const char sm2_Gx[] = "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7";
static const char sm2_Gy[] = "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0";
//声明静态变量 全局变量
static big g_p;
static big g_a;
static big g_b;
static big g_n;
static big g_nb;
//私钥
static epoint* g_Q;//公钥
static epoint* g_G;//椭圆曲线的基点
void ECDSA_Initialize(miracl* pm)
{
pm->IOBASE = 16;//说明是十六进制
g_p = mirvar(0);
g_a = mirvar(0);
g_b = mirvar(0);
g_n = mirvar(0);
cinstr(g_p, (char*)sm2_p);
cinstr(g_a, (char*)sm2_a);
cinstr(g_b, (char*)sm2_b);
cinstr(g_n, (char*)sm2_n);
ecurve_init(g_a, g_b, g_p, MR_AFFINE);
big tmp_x = mirvar(0);
big tmp_y = mirvar(0);
cinstr(tmp_x, (char*)sm2_Gx);
cinstr(tmp_y, (char*)sm2_Gy);
g_G = epoint_init();//将内存分配给GF(p)椭圆曲线上的一个点,并将其初始化为“无穷大点”。
if (!epoint_set(tmp_x, tmp_y, 1, g_G))
{
exit(0);
}
//私钥
g_nb = mirvar(0);
irand(time(NULL));
bigbits(256, g_nb);//256bit
while (mr_compare(g_nb, g_n) >= 0)//私钥nb要比n小
{
bigbits(256, g_nb);
}
//公钥
g_Q = epoint_init();
ecurve_mult(g_nb, g_G, g_Q);
//FILE* stream;//输入到文件中,用于生成含有用户标识的za
//stream = fopen("transfer.txt", "r+");
//otnum(g_a, stream);
//otnum(g_b, stream);
//otnum(g_G->X, stream);
//otnum(g_G->Y, stream);
//otnum(g_Q->X, stream);
//otnum(g_Q->Y, stream);
//fclose(stream);
//FILE* stream2;//私钥保存
//stream2 = fopen("secret.txt", "r+");
//otnum(g_nb, stream2);
//fclose(stream2);
}
void ShaTest()
{
sha256 sha123;
shs256_init(&sha123);
char lpStr[] = "1234567890abcdef1234567890abcdef优雅人生www.dllhook.com";
char szSha[32] = { 0 };
char* lpStr_ = lpStr;
printf("明文:%sn", lpStr);
while (*lpStr_ != 0)
shs_process(&sha123, *lpStr_++);
shs_hash(&sha123, szSha);
printf("SHA256:");
for (int i = 0; i < 32; i++)
{
if (szSha[i] == 0)
break;
printf("%.2X", (unsigned char)szSha[i]);
}
printf("n");
}
//digital_sign ECDSA_Sign( miracl* pm, big e_b)
//{
//
//
//	big k = mirvar(0);//A3:用随机数发生器产生随机数k ∈[1,n-1];
//	irand(time(NULL));
//	bigrand(g_n, k);
//
//	epoint* kk = epoint_init();
//	ecurve_mult(k, g_G, kk);// A4:计算椭圆曲线点(x 1, y 1) = [k]G
//	big z = mirvar(0);
//	z = kk->X;
//	divide(z, g_n, g_n);
//	while (z == 0) //计算r=z modn,若r=0则返回第一步;
//	{
//
irand(time(NULL));
//
bigrand(g_n, k);
//
ecurve_mult(k, g_G, kk);
//
z = kk->X;
//
divide(z, g_n, g_n);
//	}
//	digital_sign a;
//	a.r = mirvar(0);
//	a.s = mirvar(0);
//	//big e_b = mirvar(0);
//	pm->IOBASE = 16;//说明是十六进制//r计算完毕
//	
//	big tmp_rd = mirvar(0);
//
//	multiply(g_nb, a.r, tmp_rd);//计算s = k(e+dr)mod n
//	add(tmp_rd, e_b, tmp_rd);
//	multiply(k, tmp_rd, tmp_rd);
//	divide(tmp_rd, g_n, g_n);//mod n
//	a.s = tmp_rd;
//	while (0 == a.s) //A6:若s=0则返回A3;
//	{
//
irand(time(NULL));
//
bigrand(g_n, k);
//
ecurve_mult(k, g_G, kk);
//
z = kk->X;
//
divide(z, g_n, g_n);
//
while (z == 0) //计算r=z modn,若r=0则返回第一步;
//
{
//
irand(time(NULL));
//
bigrand(g_n, k);
//
ecurve_mult(k, g_G, kk);
//
z = kk->X;
//
divide(z, g_n, g_n);
//
}
//
multiply(g_nb, a.r, tmp_rd);//计算s = k(e+dr)mod n
//
add(tmp_rd, e_b, tmp_rd);
//
multiply(k, tmp_rd, tmp_rd);
//
divide(tmp_rd, g_n, g_n);//mod n
//
a.s = tmp_rd;
//	}//r/s计算完毕 
//
add(a.s, g_n, a.s);
//	divide(a.s, g_n, g_n);
//	return a;
//}
digital_sign ECDSA_Sign(miracl* pm, big e_b)
{
big k = mirvar(0);//A3:用随机数发生器产生随机数k ∈[1,n-1];
irand(time(NULL));
bigrand(g_n, k);
epoint* kk = epoint_init();
ecurve_mult(k, g_G, kk);// A4:计算椭圆曲线点(x 1, y 1) = [k]G
digital_sign a;//A5:计算r=(e+x 1 ) modn,若r=0或r+k=n则返回A3;
a.r = mirvar(0);
a.s = mirvar(0);
//big e_b = mirvar(0);
pm->IOBASE = 16;//说明是十六进制
//getchar();
//bigdig(32, 16, e_b);
//cinstr(e_b, e);
add(e_b, kk->X, a.r);
big tmp_rk = mirvar(0);
add(a.r, k, tmp_rk);
divide(a.r, g_n, g_n);
while (0 == a.r || tmp_rk == g_n) //A5:计算r=(e+x 1 ) modn,若r=0或r+k=n则返回A3;
{
irand(time(NULL));
bigrand(g_n, k);
ecurve_mult(k, g_G, kk);
add(e_b, kk->X, a.r);
add(a.r, k, tmp_rk);
divide(a.r, g_n, g_n);
}//r计算完毕
big tmp_rd = mirvar(0);
big tmp6 = mirvar(0);
multiply(g_nb, a.r, tmp_rd);//A6:计算s = ((1 + d A ) −1 · (k − r · d A )) modn,若s=0则返回A3;
multiply(g_n, k, tmp_rk);//n*k+k-nb*r
add(tmp_rk, k, tmp_rk);
subtract(tmp_rk, tmp_rd, tmp6);
divide(tmp6, g_n, g_n);//先mod n
big tmp_s = mirvar(0);
incr(g_nb, 1, tmp_s);
xgcd(tmp_s, g_n, tmp_s, tmp_s, tmp_s);
multiply(tmp_s, tmp6, a.s);
divide(a.s, g_n, g_n);
while (0 == a.s) //A6:若s=0则返回A3;
{
irand(time(NULL));
bigrand(g_n, k);//A3:用随机数发生器产生随机数k ∈[1,n-1];
ecurve_mult(k, g_G, kk);// A4:计算椭圆曲线点(x 1, y 1) = [k]G
add(e_b, kk->X, a.r);
add(a.r, k, tmp_rk);
divide(a.r, g_n, g_n);
while (0 == a.r || tmp_rk == g_n)//A5:计算r=(e+x 1 ) modn,若r=0或r+k=n则返回A3;
{
irand(time(NULL));
bigrand(g_n, k);
ecurve_mult(k, g_G, kk);
add(e_b, kk->X, a.r);
add(a.r, k, tmp_rk);
divide(a.r, g_n, g_n);
}
multiply(g_nb, a.r, tmp_rk);//A6:计算s = ((1 + d A ) −1 · (k − r · d A )) modn,若s=0则返回A3;
subtract(k, tmp_rk, tmp6);
divide(tmp6, g_n, g_n);
add(tmp6, g_n, a.s);//处理负号
divide(tmp6, g_n, g_n);
incr(g_nb, 1, tmp_s);
xgcd(tmp_s, g_n, tmp_s, tmp_s, tmp_s);
multiply(tmp_s, tmp6, a.s);
divide(a.s, g_n, g_n);
}//r/s计算完毕 
add(a.s, g_n, a.s);
divide(a.s, g_n, g_n);
return a;
}
int ECDSA_verify(digital_sign a, miracl* pm, big e_b)
{
if (!(a.r > 0 && mr_compare(g_n, a.r))) //B1:检验r'∈[1,n-1]是否成立,若不成立则验证不通过;
{
return 0;
}
if (!(a.s > 0 && mr_compare(g_n, a.s)))//B2:检验s'∈[1,n-1]是否成立,若不成立则验证不通过;
{
return 0;
}
big t = mirvar(0);//B5:计算t = (r'+ s') mod n	若t = 0,则验证不通过;
add(a.r, a.s, t);
divide(t, g_n, g_n);
if (0 == t)
{
return 0;
}
epoint* g_xy1;//B6:计算椭圆曲线点(x'1 ,y'1 ) = [s']G + [t]P A ;
g_xy1 = epoint_init();
ecurve_mult(a.s, g_G, g_xy1);
epoint* g_xy2;
g_xy2 = epoint_init();
ecurve_mult(t, g_Q, g_xy2);
ecurve_add(g_xy1, g_xy2);
//big e_b = mirvar(0);//将获得的hash 值e转换为数字big
//cinstr(e_b, e);
big R = mirvar(0);//B7:计算R = (e'+ x'1 ) modn,检验R = r'是否成立,若成立则验证通过;否则验证不通过。
add(e_b, g_xy2->X, R);
divide(R, g_n, g_n);
if (!mr_compare(R, a.r))
{
return 1;
}
return 0;
}
//bool ECDSA_verify(digital_sign a, miracl* pm, big e_b)
//{
//	if (!(a.r > 0 && mr_compare(g_n, a.r))) //B1:检验r'∈[1,n-1]是否成立,若不成立则验证不通过;
//	{
//
return false;
//	}
//	if (!(a.s > 0 && mr_compare(g_n, a.s)))//B2:检验s'∈[1,n-1]是否成立,若不成立则验证不通过;
//	{
//
return false;
//	}
//	big w = mirvar(0);
//	w = a.s;
//	xgcd(w, g_n, w, w, w );//w取逆
//	big u1 = mirvar(0);
//	multiply(e_b, w, u1);
//	divide(u1, g_n, g_n);
//	big u2 = mirvar(0);
//	multiply(a.r, w, u2);
//	divide(u2, g_n, g_n);
//	epoint* g_xy1;//计算椭圆曲线点(x'1 ,y'1 ) = [u2]G + [u1]P A ;
//	g_xy1 = epoint_init();
//	ecurve_mult(u2, g_G, g_xy1);
//	epoint* g_xy2;
//	g_xy2 = epoint_init();
//	ecurve_mult(u1, g_Q, g_xy2);
//	ecurve_add(g_xy1, g_xy2);
//
//	//big e_b = mirvar(0);//将获得的hash 值e转换为数字big
//	//cinstr(e_b, e);
//	big R = mirvar(0);//B7:计算R =
x'1
modn,检验R = r'是否成立,若成立则验证通过;否则验证不通过。
//	R = g_xy2->X;
//	divide(R, g_n, g_n);
//	if (!mr_compare(R, a.r))
//	{
//
return true;
//	}
//	printf("nohere n");
//
//	return false;
//}
int main()
{
miracl *pm = mirsys(500, 16);//初始化miracl系统,该函数必须在调用miracl库函数之前先执行
//example:
miracl *mip = mirsys(500, 10);
//初始化500位的10进行制数
big e_b = mirvar(0);
double
duration;
bigdig(32, 16, e_b);//加密的输入
clock_t start, finish;
start = clock();
ECDSA_Initialize(pm);//生成
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf("KeyGen: %f secondsn", duration);
start = clock();
digital_sign a = ECDSA_Sign(pm, e_b);
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf("Sign: %f secondsn", duration);
printf("r:");
cotnum(a.r,stdout);
printf("s:");
cotnum(a.s,stdout);
start = clock();
int r = ECDSA_verify(a, pm,e_b);
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf("Verify: %f secondsn", duration);
if (1 == r)
{
printf("Seccessn");
}
else
{
printf("ERROR n");
}
//ShaTest();
printf("n输入任意字符回车后退出……");
getchar();
return 0;
}

最后来一个linux下面跑起来的截图
linux下面跑代码

最后

以上就是超帅抽屉为你收集整理的miracl实现sm2的全部内容,希望文章能够帮你解决miracl实现sm2所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(38)

评论列表共有 0 条评论

立即
投稿
返回
顶部