04 如何去掉sm2加密结果_大结局---Miracl库下完全实现SM2加密算法

1 int main(){ //前面定义很多变量,不再一一介绍,后面用到再提

2 big a,b,p,Gx,Gy,n,db,k;3 big x1,y1,x2,y2;4 intkbitlen;5 char plain[1024]={0}; //存放文件中读取的明文字符串

6 char plain_bin[8192]={0}; //存放明文的二进制字符串

7 char C2_bin[8192]={0}; //存放解密出明文的二进制字符串

8 char sm3_dgst[33]={0}; //存放 sm3 32字节的杂凑摘要

9 char crypt[3072]={0}; //存放加密生成的密文的二进制形式

10 char Hexstring1[65]={0};11 char Hexstring2[65]={0};12 char Hexstring3[2048]={0};13 char HexTemp[2048]={0};14 char t1[8192]={0};15 char Binarystring1[257]={0};16 char Binarystring2[257]={0};17 char Binarystring3[513]={0};18 FILE *fp; //存放的文件存放推荐的参数a、b、p、Gx、Gy、n等等

19 FILE *input_string;//存放明文

20 epoint* G=NULL; //基点G

21 epoint* Pb=NULL; //公钥点Pb

22 epoint* T1=NULL; //点T1(x1,y1)=[k]G

23 epoint* T2=NULL;24 epoint* D1=NULL;25 epoint* D2=NULL;26 miracl* mip=mirsys(1000,16);//初始化大数库

27 a=mirvar(0);28 b=mirvar(0);29 p=mirvar(0); //p 256 bits

30 Gx=mirvar(0);31 Gy=mirvar(0);32 n=mirvar(0);33 k=mirvar(0);34 db=mirvar(0);//用户私钥数字

35 x1=mirvar(0);36 y1=mirvar(0);37 x2=mirvar(0);38 y2=mirvar(0);39 fp=fopen("abp.txt","r+"); //fp指向同目录下存放参数的文件

40 if(fp==0)41 {42 printf("文件打开失败!");43 exit(1);44 }45 mip->IOBASE=16;//下面依次读取十六进制的参数

46 cinnum(a,fp);47 cinnum(b,fp);48 cinnum(p,fp);49 cinnum(Gx,fp);50 cinnum(Gy,fp);51 cinnum(n,fp);52 fclose(fp);//关闭参数文件指针

53 system("color E");54 printf("---------参数生成---------\n"); //打印已知参数

55 printf("参数a=");56 cotnum(a,stdout);57 printf("参数b=");58 cotnum(b,stdout);59 printf("有限域素数p=");60 cotnum(p,stdout);61 printf("基点横坐标Gx=");62 cotnum(Gx,stdout);63 printf("基点纵坐标Gy=");64 cotnum(Gy,stdout);65 printf("基点的阶n=");66 cotnum(n,stdout);67 bigrand(n,db); //db

68 printf("选取私钥数字db=");69 cotnum(db,stdout);70 ecurve_init(a,b,p,MR_PROJECTIVE);//定义、初始化曲线方程

71 G=epoint_init();72 Pb=epoint_init();//初始化重要的点

73 T1=epoint_init();74 T2=epoint_init();75 if(epoint_set(Gx,Gy,0,G)) //验证、生成基点 G

76 printf("基点G生成成功\n");77 else{78 printf("基点G生成失败!\n"); return 1;79 }80 ecurve_mult(db,G,Pb); //Pb=db * G ,倍点运算----点的乘法函数

81 printf("公钥点Pb生成成功!\n");82 printf("--------------加密过程---------------\n");83 bigrand(n,k); //k

84 printf("选取随机数k=");85 cotnum(k,stdout);86 ecurve_mult(k,G,T1); //生成点T1坐标(x1,y1)=[k]G

87 printf("点T1生成成功!\n");88 epoint_get(T1,x1,y1);//获取点x1、y1坐标

89 cotstr(x1,Hexstring1);//x1存入十六进制字符串数组

90 cotstr(y1,Hexstring2);//y1存入十六进制字符串数组91 //用函数把十六进制转成二进制

92 Hex2Bin(Hexstring1,Binarystring1,strlen(Hexstring1));93 Hex2Bin(Hexstring2,Binarystring2,strlen(Hexstring2));94 //把C1 即x1|y1填入密文二进制数组最开始的部分

95 sprintf(crypt,"%s%s",Binarystring1,Binarystring2);96 printf("\n目前的密文长度为:%d,内容:\n",strlen(crypt));97 puts(crypt);98 bzero(Hexstring1,sizeof(Hexstring1));//清空一下用过的中间数组

99 bzero(Hexstring2,sizeof(Hexstring2));100 bzero(Binarystring1,sizeof(Binarystring1));101 bzero(Binarystring2,sizeof(Binarystring2));102 input_string=fopen("input.txt","r+");//从文件读取明文字符串

103 fgets(plain,sizeof(plain),input_string);104 fclose(input_string);105 //printf("请输入明文字符串:");//可以自己输入106 //gets(plain);

107 kbitlen=strlen(plain)*8; //明文bit长度

108 printf("输入明文是%s,明文比特长度为%d.\n",plain,kbitlen);109 //将明文以二进制形式填充进plain_bin字符串内

110 Str2Hex(plain,Hexstring3,strlen(plain));111 //Hexstring3只是一个中间媒介,存放明文16进制信息,后面用得到!!!

112 Hex2Bin(Hexstring3,plain_bin,strlen(Hexstring3));113 ecurve_mult(k,Pb,T2); //T2坐标(x2,y2)=[k]Pb

114 printf("点T2生成成功!\n");115 epoint_get(T2,x2,y2);116 cotstr(x2,Hexstring1);117 cotstr(y2,Hexstring2);118 //HexTemp存放十六进制形式的 x2|M|y2

119 sprintf(HexTemp,"%s%s%s",Hexstring1,Hexstring3,Hexstring2);120 Hex2Bin(Hexstring1,Binarystring1,strlen(Hexstring1));121 Hex2Bin(Hexstring2,Binarystring2,strlen(Hexstring2));122 //Binarystring3目前存放x2|y2,用于后面的KDF计算

123 sprintf(Binarystring3,"%s%s",Binarystring1,Binarystring2);124 bzero(Hexstring1,sizeof(Hexstring1)); //清空一波

125 bzero(Hexstring2,sizeof(Hexstring2));126 bzero(Hexstring3,sizeof(Hexstring3));127 bzero(Binarystring1,sizeof(Binarystring1));128 bzero(Binarystring2,sizeof(Binarystring2));129 //返回结果t1存放kbitlen长度的密钥

130 KDF(Binarystring3,512,kbitlen,t1);131 if(strlen(plain_bin)==strlen(t1))132 printf("长度一致,可以进行异或!\n");133 //把C2 = t1^M 填充到最后的密文中,如果成功返回值应该是0

134 if(Bin_XOR(plain_bin,t1,crypt+strlen(crypt))!=0)135 printf("异或出错!");136 printf("\n目前的密文长度为:%d,内容:\n",strlen(crypt));137 puts(crypt);138 bzero(t1,sizeof(t1));139 bzero(plain,sizeof(plain));//销毁明文字符串数组,保证解密准确性140 //暂时拿plain存放byte形式的C2:x2|M|y2

141 Hex2Byte(HexTemp,plain,strlen(HexTemp));142 bzero(HexTemp,sizeof(HexTemp));143 //计算sm3哈希值C3 = Hash(x2 ∥ M ∥ y2),存放到sm3_dgst byte类型

144 SM3Calc(plain,strlen(plain),sm3_dgst);145 Str2Hex(sm3_dgst,Hexstring1,strlen(sm3_dgst));146 //哈希结果转二进制类型,写入密文crypt的中间部分

147 Hex2Bin(Hexstring1,crypt+strlen(crypt),strlen(Hexstring1));148 bzero(Hexstring1,sizeof(Hexstring1));149 printf("\n目前的密文长度为:%d,至此,加密成功!密文内容:\n",strlen(crypt));150 puts(crypt);151 //后续处理,清空一切不需要的数组,只保留必要的信息

152 bzero(plain,sizeof(plain)); bzero(plain_bin,sizeof(plain_bin));153 bzero(sm3_dgst,sizeof(sm3_dgst));154 epoint_free(T1);155 epoint_free(T2);//释放epoint类型点坐标

156 x1=mirvar(0);157 y1=mirvar(0);//坐标值清零,后面还会用到

158 x2=mirvar(0);159 y2=mirvar(0);160 printf("------------解密过程--------------\n");161 printf("现在知道的信息有:收到的密文crypt\n C1部分长度为512bits,分别存储x1、y1的坐标信息\n kbitlen:代表明文的比特长度,对应密文C2部分的长度\n 解密者自己的私钥db\n");162 strncpy(Binarystring1,crypt,256); //x1二进制

163 strncpy(Binarystring2,crypt+256,256); //y1二进制

164 Bin2Hex(Binarystring1,Hexstring1,256); //x1十六进制

165 Bin2Hex(Binarystring2,Hexstring2,256); //y1十六进制

166 mip->IOBASE=16;167 cinstr(x1,Hexstring1);168 cinstr(y1,Hexstring2);169 bzero(Binarystring1,sizeof(Binarystring1));170 bzero(Binarystring2,sizeof(Binarystring2));171 bzero(Hexstring1,sizeof(Hexstring1));172 bzero(Hexstring2,sizeof(Hexstring2));173 D1=epoint_init(); //初始化解密过程中将要用到的点

174 D2=epoint_init();175 if(epoint_set(x1,y1,0,D1))176 printf("点D1生成成功\n");177 else{178 printf("点D1生成失败!\n");179 return 0;180 }181 ecurve_mult(db,D1,D2); //点乘得到D2,解密非常关键的一步!!!

182 epoint_get(D2,x2,y2); //获取D2坐标信息一直转到二进制类型

183 cotstr(x2,Hexstring1); cotstr(y2,Hexstring2);184 Hex2Bin(Hexstring1,Binarystring1,strlen(Hexstring1));185 Hex2Bin(Hexstring2,Binarystring2,strlen(Hexstring2));186 sprintf(Binarystring3,"%s%s",Binarystring1,Binarystring2);//Binarystring3目前存放x2|y2

187 bzero(Hexstring3,sizeof(Hexstring3));188 bzero(Binarystring1,sizeof(Binarystring1));189 bzero(Binarystring2,sizeof(Binarystring2));190 //计算t1=KDF(x2' ∥ y2', klen)

191 KDF(Binarystring3,512,kbitlen,t1);192 bzero(Binarystring3,sizeof(Binarystring3));193 //从C中取出比特串C2bin,计算M ′ = C2 ⊕ t'

194 strncpy(C2_bin,crypt+512,kbitlen);195 Bin_XOR(t1,C2_bin,plain_bin); //M'是 二进制 plain_bin196 //M'是 十六进制 Hexstring3

197 Bin2Hex(plain_bin,Hexstring3,strlen(plain_bin));198 //HexTemp 存放hex形式的 x2|M'|y2

199 sprintf(HexTemp,"%s%s%s",Hexstring1,Hexstring3,Hexstring2);200 bzero(Hexstring1,sizeof(Hexstring1));201 bzero(Hexstring2,sizeof(Hexstring2));202 //拿plain存放字符串形式的C2:x2|M'|y2

203 Hex2Byte(HexTemp,plain,strlen(HexTemp));204 //u = Hash(x2 ∥ M '∥ y2) 还是存在变量sm3_dgst内

205 SM3Calc(plain,strlen(plain),sm3_dgst);206 //u转成16进制hash值

207 Str2Hex(sm3_dgst,Hexstring1,strlen(sm3_dgst));208 //u转成二进制 256 bits hash值

209 Hex2Bin(Hexstring1,Binarystring1,strlen(Hexstring1));210 //从密文里面提取出最后的一部分信息赋给Binarystring2

211 strncpy(Binarystring2,crypt+512+kbitlen,256);212 if(strcmp(Binarystring1,Binarystring2)==0){ //匹配

213 printf("*********************匹配成功!!!!**********************\n");214 bzero(plain,sizeof(plain));215 Hex2Byte(Hexstring3,plain,strlen(Hexstring3));216 printf("解密得到:\n");217 puts(plain);218 }219 bzero(Hexstring3,sizeof(Hexstring3));220 bzero(Hexstring1,sizeof(Hexstring1));221 bzero(plain,sizeof(plain));222 bzero(Binarystring1,sizeof(Binarystring1));223 printf("----------------------------结束----------------------------\n"); //后续处理

224 mirkill(a);225 mirkill(b);226 mirkill(p);227 mirkill(n);228 mirkill(Gx);229 mirkill(Gy);230 mirkill(db);231 mirkill(k);232 mirkill(x1);233 mirkill(x2);234 mirkill(y1);235 mirkill(y2);236 epoint_free(G);237 epoint_free(Pb);238 epoint_free(D1);239 epoint_free(D2);240 mirexit();241 return 0;242 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值