/* 1、用户A选定一条适合加密的椭圆曲线Ep(a,b)(如:y2=x3+ax+b),并取椭圆曲线上一点,作为基点G。
2、用户A选择一个私有密钥k,并生成公开密钥K=kG。
3、用户A将Ep(a,b)和点K,G传给用户B。
4、用户B接到信息后 ,将待传输的明文编码到Ep(a,b)上一点M,并产生一个随机整数r(r<n)。
5、用户B计算点C1=M+rK;C2=rG。
6、用户B将C1、C2传给用户A。
7、用户A接到信息后,计算C1-kC2,结果就是点M。因为
C1-kC2=M+rK-k(rG)=M+rK-r(kG)=M
再对点M进行解码就可以得到明文。
密码学中,描述一条Fp上的椭圆曲线,常用到六个参量:
T=(p,a,b,G,n,h)。
(p 、a 、b 用来确定一条椭圆曲线,G为基点,n为点G的阶,h 是椭圆曲线上所有点的个数m与n相除的整数部分)
这几个参量取值的选择,直接影响了加密的安全性。参量值一般要求满足以下几个条件:
1、p 当然越大越安全,但越大,计算速度会变慢,200位左右可以满足一般安全要求;
2、p≠n×h;
3、pt≠1 (mod n),1≤t<20;
4、4a3+27b2≠0 (mod p);
5、n 为素数;
6、h≤4。
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream.h>
#include "tommath.h"
#include <time.h>
#define BIT_LEN 800
#define KEY_LONG 128 //私钥比特长
#define P_LONG 200 //有限域P比特长
#define EN_LONG 40 //一次取明文字节数(x,20)(y,20)
//得到lon比特长素数
int GetPrime(mp_int *m,int lon);
//得到B和G点X坐标G点Y坐标
void Get_B_X_Y(mp_int *x1,mp_int *y1,mp_int *b, mp_int *a, mp_int *p);
//点乘
bool Ecc_points_mul(mp_int *qx,mp_int *qy, mp_int *px, mp_int *py,mp_int *d,mp_int *a,mp_int *p);
//点加
int Two_points_add(mp_int *x1,mp_int *y1,mp_int *x2,mp_int *y2,mp_int *x3,mp_int *y3,mp_int *a,bool zero,mp_int *p);
//二进制存储密文
int chmistore(mp_int *a,FILE *fp);
//把读取的字符存入mp_int型数
int putin(mp_int *a,char *ch,int chlong);
//ECC加密
void Ecc_encipher(mp_int *qx,mp_int *qy, mp_int *px, mp_int *py,mp_int *a,mp_int *p);
//ECC解密
void Ecc_decipher(mp_int *k, mp_int *a,mp_int *p);
//实现将mp_int数a中的比特串还原为字符串并赋给字符串ch:
int chdraw(mp_int *a,char *ch);
//取密文
int miwendraw(mp_int *a,char *ch,int chlong);
unsigned int SDBMHash16(char *str);//对输入的字符串计算Hash值,输出为一个32位的整数
//CString IntToString(int& number);//将一个整数转换为一个字符串
unsigned int SDBMHash32(char *str);
void NumToStr(unsigned __int64 a,char z[100]);
void Hashstring(char temphash[800],unsigned __int64 *hash,int n1);
int myrng(unsigned char *dst, int len, void *dat)
{
int x;
for (x = 0; x < len; x++) dst[x] = rand() & 0xFF;
return len;
}
void main(){
cout<<"\n---------------------------------------------------";
cout<<"\n 本程序实现SM2的加密解密";
cout<<"\n---------------------------------------------------\n"<<endl;
clock_t t_start,t_end; //统计时间
mp_int GX;
mp_int GY;
mp_int K;//私有密钥
mp_int A;
mp_int B;
mp_int QX;
mp_int QY;
mp_int P;//Fp中的p(有限域P)
mp_int c1x,c1y;
mp_int c2x,c2y;
mp_int r;
mp_int tempx,tempy;
//mp_int m;//随机待加密明文
mp_int temp1;
//mp_int mx;
mp_init(&GX);
mp_init(&GY);
mp_init(&K);
mp_init(&A);
mp_init(&B);
mp_init(&QX);
mp_init(&QY);
mp_init(&P);
mp_init(&c1x);
mp_init(&c1y);
mp_init(&c2x);
mp_init(&c2y);
mp_init(&r);
mp_init(&tempx);
mp_init(&tempy);
//mp_init(&m);
mp_init(&temp1);
//mp_init(&mx);
FILE *fp,*fq;
char fin_name[40],fout1_name[40],fout2_name[40];
unsigned __int64 buffer[20000];
char test[20000];
//short buffer[20000],mingwen[20000],buffer1[20000];
//unsigned __int64 m=9146744073709451615;
unsigned __int64 hash;
unsigned __int64 e;
unsigned __int64 c3,c31;
int len;
char z1[100]={0};
char z2[100]={0};
//printf("\n\n%I64d\n\n",m);
//GetPrime(&m,32);
time_t t;
srand( (unsigned) time( &t ) );
t_start=clock();
printf("SM2椭圆曲线的参数如下(以十进制显示):\n");
GetPrime(&P,P_LONG);//获取素数P,存入P中,长度为P_LONGbit
printf("有限域 P 是:\n");
char temp[800]={0};
mp_toradix(&P,temp,10);//将素数P存入temp中
printf("%s\n",temp);//对素数P进行输出
GetPrime(&A,30);
char tempA[800]={0};
printf("曲线参数 A 是:\n");
mp_toradix(&A,tempA,10);
printf("%s\n",tempA);
Get_B_X_Y(&GX,&GY,&B,&A,&P);
char tempB[800]={0};
printf("曲线参数 B 是:\n");
mp_toradix(&B,tempB,10);
printf("%s\n",tempB);
char tempGX[800]={0};
printf("曲线G点X坐标是:\n");
mp_toradix(&GX,tempGX,10);
printf("%s\n",tempGX);
char tempGY[800]={0};
printf("曲线G点Y坐标是:\n");
mp_toradix(&GY,tempGY,10);
printf("%s\n",tempGY);
//------------------------------------------------------------------
GetPrime(&K,KEY_LONG);
char tempK[800]={0};
printf("私钥 dB 是:\n");
mp_toradix(&K,tempK,10);
printf("%s\n",tempK);
Ecc_points_mul(&QX,&QY,&GX,&GY,&K,&A,&P);
char tempQX[800]={0};
printf("公钥X坐标是:\n");
mp_toradix(&QX,tempQX,10);
printf("%s\n",tempQX);
char tempQY[800]={0};
printf("公钥Y坐标是:\n");
mp_toradix(&QY,tempQY,10);
printf("%s\n",tempQY);
printf("请输入待加密文件(例如:D:\\test.txt):");
cin>>fin_name;
cout<<"请输入密文存放文件(例如:D:\\test密文.txt):";
cin>>fout1_name;
cout<<"请输入解密后明文存放文件(例如:D:\\test解密后明文.txt):";
cin>>fout2_name;
/*printf("\n\n待加密明文m 是:\n");
char tempm[800]={0};
mp_toradix(&m,tempm,10);//将素数P存入temp中
printf("%s\n",tempm);//对素数P进行输出 */
if((fp=fopen(fin_name,"rb"))==NULL)
{
printf("can not open the file!");
exit(1);
}
fq=fopen(fout1_name,"wb+");
/*if(fq==NULL)
{
puts("加密文件正在创建。。。\n");
//getchar();
}*/
len=fread(buffer,8,10005,fp);
char tempc1x[800]={0};
char tempc1y[800]={0};
char temphash1[800]={0};
char tempmhash[800]={0};
char temphash2[800]={0};
printf("\n开始加密明文... \n");
for(int i=0;i<len;i++)
{
GetPrime(&r,100);
memset(tempmhash,0,800);
memset(temphash1,0,800);
memset(temphash2,0,800);
Ecc_points_mul(&c1x,&c1y,&GX,&GY,&r,&A,&P);//加密C1=[r]G r为选取的随机数.
Ecc_points_mul(&c2x,&c2y,&QX,&QY,&r,&A,&P);//加密C2=[r]Q r为选取的随机数.
mp_toradix(&c2x,temphash1,10);//将c2x存入temphash中
mp_toradix(&c2y,temphash2,10);
strcat(tempmhash,temphash1);
strcat(tempmhash,temphash2);
hash=SDBMHash32(tempmhash);
//Hashstring(tempmhash,hash,sizeof(buffer[i]));
e=buffer[i]^hash;
NumToStr(buffer[i],z1);
strcat(temphash1,z1);
strcat(temphash1,temphash2);
c3=SDBMHash32(temphash1);
chmistore(&c1x,fq);
chmistore(&c1y,fq);
fwrite(&e,1,8,fq);
fwrite(&c3,1,4,fq);
}
fclose(fp);
fclose(fq);
cout<<"加密结束!"<<endl;
printf("\n\n\n开始解密密文... \n\n\n");
if((fp=fopen(fout1_name,"rb"))==NULL)
{
printf("can not open the file!");
exit(1);
}
fq=fopen(fout2_name,"wb+");
char tempd[800]={0};
char tempc11x[800]={0};
char tempc11y[800]={0};
int j=0;
mp_int tempzero;
mp_init(&tempzero);
char stemp[700]={0};
while(!feof(fp))
{
i=0;
while(1)
{
stemp[i]=fgetc(fp);
if(i%4==0)
{
if(int(stemp[i]&0xFF) == 255 ) goto L1;
}
i++;
}
L1: miwendraw(&c1x, stemp, i);
i=0;
while(1)
{
stemp[i]=fgetc(fp);
if(i%4==0)
{
if(int(stemp[i]&0xFF) == 255 ) goto L2;
}
i++;
}
L2: miwendraw(&c1y, stemp, i);
mp_zero(&tempzero);
if(mp_cmp(&c1x, &tempzero)==0) break;
fread(&e,1,8,fp);
fread(&c3,1,4,fp);
memset(tempd,0,800);
memset(tempc11x,0,800);
mp_toradix(&c1x,tempc1x,10);
mp_toradix(&c1y,tempc1y,10);
Ecc_points_mul(&tempx,&tempy,&c1x,&c1y,&K,&A,&P);
mp_toradix(&tempx,tempc11x,10);
mp_toradix(&tempy,tempc11y,10);
strcat(tempd,tempc11x);
strcat(tempd,tempc11y);
//printf("需要计算Hash值得字符串:%s\n",tempd);
//Has
SM2算法C语言实现
4星 · 超过85%的资源 需积分: 50 19 浏览量
2014-06-10
10:36:06
上传
评论 4
收藏 669KB ZIP 举报
joy91269
- 粉丝: 2
- 资源: 4
最新资源
- HandTrackingModule.py
- Python基于卷积神经网络的鸟类识别项目源代码,ipynb文件
- 批量将py编译为pyd文件.atbx
- Python项目-学生管理系统
- 图像处理基于matlab图像RGB三色合成分离【含Matlab源码第1发】
- verilog HDL硬件语法设计包括算术运算三人表决器Verilog的阻塞和非阻塞赋值源码例程quartus13.1工程合集
- 【文章话题分类论文】OpenAlex Topic Classification Whitepaper
- linux学习常用命令
- 功率拓扑快速参考指南-ti,TI官方出品
- 开源2023电赛国赛运动目标控制(E题)视觉部分
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
- 1
- 2
- 3
- 4
- 5
- 6
前往页