当前位置:   article > 正文

ECC算法C语言实现

ecc算法c语言实现

密码学实验:ECC算法实现

1.实验内容

                  

2.运行结果: 

1.椭圆曲线上的点集

                    

2.椭圆曲线生成元以及对应的阶

                     

3.加解密算法

                     

代码如下: 

  1. /*
  2. (1)编程计算该椭圆曲线上所有在有限域GF(89)上的点;
  3. (2)编程实现椭圆曲线上任意一个点P(例如P=(12,5))的倍点运算的递归算法,即计算k*P( k=2,3,…);(重点!)
  4. (3)利用此递归算法找出椭圆曲线上的所有生成元G以及它们的阶n,即满足n*G=O;
  5. (4)设计实现某一用户B的公钥、私钥算法,即得到public key=(n, G, PB, Ep(a, b))
  6. secure key=nB(小于n)
  7. (5)假如用户A发送明文消息“yes”并加密传输给用户B,用户B接收消息后要能解密为明文。试用ECC密码体制实现此功能。
  8. */
  9. #include<stdio.h>
  10. #include<stdlib.h>
  11. #include<string.h>
  12. #include<math.h>
  13. #include<time.h>
  14. #define MAX 100
  15. typedef struct point{
  16. int point_x;
  17. int point_y;
  18. }Point;
  19. typedef struct ecc{
  20. struct point p[MAX];
  21. int len;
  22. }ECCPoint;
  23. typedef struct generator{
  24. Point p;
  25. int p_class;
  26. }GENE_SET;
  27. void get_all_points();
  28. int int_sqrt(int s);
  29. Point timesPiont(int k,Point p);
  30. Point add_two_points(Point p1,Point p2);
  31. int inverse(int n,int b);
  32. void get_generetor_class();
  33. void encrypt_ecc();
  34. void decrypt_ecc();
  35. int mod_p(int s);
  36. void print();
  37. int isPrime(int n);
  38. char alphabet[26]="abcdefghijklmnopqrstuvwxyz";
  39. int a=-1,b=0,p=89;//椭圆曲线为E89(-1,0): y2=x3-x (mod 89)
  40. ECCPoint eccPoint;
  41. GENE_SET geneSet[MAX];
  42. int geneLen;
  43. char plain[]="yes";
  44. int m[MAX];
  45. int cipher[MAX];
  46. int nB;//私钥
  47. Point P1,P2,Pt,G,PB;
  48. Point Pm;
  49. int C[MAX];
  50. int main()
  51. {
  52. get_generetor_class();
  53. encrypt_ecc();
  54. decrypt_ecc();
  55. return 0;
  56. }
  57. //task4:加密
  58. void encrypt_ecc()
  59. {
  60. int num,i,j;
  61. int gene_class;
  62. int num_t;
  63. int k;
  64. srand(time(NULL));
  65. //明文转换过程
  66. for(i=0;i<strlen(plain);i++)
  67. {
  68. for(j=0;j<26;j++) //for(j=0;j<26;j++)
  69. {
  70. if(plain[i]==alphabet[j])
  71. {
  72. m[i]=j;//将字符串明文换成数字,并存到整型数组m里面
  73. }
  74. }
  75. }
  76. //选择生成元
  77. num=rand()%geneLen;
  78. gene_class=geneSet[num].p_class;
  79. while(isPrime(gene_class)==-1)//不是素数
  80. {
  81. num=rand()%(geneLen-3)+3;
  82. gene_class=geneSet[num].p_class;
  83. }
  84. //printf("gene_class=%d\n",gene_class);
  85. G=geneSet[num].p;
  86. //printf("G:(%d,%d)\n",geneSet[num].p.point_x,geneSet[num].p.point_y);
  87. nB=rand()%(gene_class-1)+1;//选择私钥
  88. PB=timesPiont(nB,G);
  89. printf("\n公钥:\n");
  90. printf("{y^2=x^3%d*x+%d,%d,(%d,%d),(%d,%d)}\n",a,b,gene_class,G.point_x,G.point_y,PB.point_x,PB.point_y);
  91. printf("私钥:\n");
  92. printf("nB=%d\n",nB);
  93. //加密
  94. //
  95. k=rand()%(gene_class-2)+1;
  96. P1=timesPiont(k,G);
  97. //
  98. num_t=rand()%eccPoint.len; //选择映射点
  99. Pt=eccPoint.p[num_t];
  100. //printf("Pt:(%d,%d)\n",Pt.point_x,Pt.point_y);
  101. P2=timesPiont(k,PB);
  102. Pm=add_two_points(Pt,P2);
  103. printf("加密数据:\n");
  104. printf("kG=(%d,%d),Pt+kPB=(%d,%d),C={",P1.point_x,P1.point_y,Pm.point_x,Pm.point_y);
  105. for(i=0;i<strlen(plain);i++)
  106. {
  107. // num_t=rand()%eccPoint.len; //选择映射点
  108. // Pt=eccPoint.p[num_t];
  109. C[i]=m[i]*Pt.point_x+Pt.point_y;
  110. printf("{%d}",C[i]);
  111. }
  112. printf("}\n");
  113. }
  114. //task5:解密
  115. void decrypt_ecc()
  116. {
  117. Point temp,temp1;
  118. int m,i;
  119. temp=timesPiont(nB,P1);
  120. temp.point_y=0-temp.point_y;
  121. temp1=add_two_points(Pm,temp);//求解Pt
  122. // printf("(%d,%d)\n",temp.point_x,temp.point_y);
  123. // printf("(%d,%d)\n",temp1.point_x,temp1.point_y);
  124. printf("\n解密结果:\n");
  125. for(i=0;i<strlen(plain);i++)
  126. {
  127. m=(C[i]-temp1.point_y)/temp1.point_x;
  128. printf("%c",alphabet[m]);//输出密文
  129. }
  130. printf("\n");
  131. }
  132. //判断是否为素数
  133. int isPrime(int n)
  134. {
  135. int i,k;
  136. k = sqrt(n);
  137. for (i = 2; i <= k;i++)
  138. {
  139. if (n%i == 0)
  140. break;
  141. }
  142. if (i <=k){
  143. return -1;
  144. }
  145. else {
  146. return 0;
  147. }
  148. }
  149. //task3:求生成元以及阶
  150. void get_generetor_class()
  151. {
  152. int i,j=0;
  153. int count=1;
  154. Point p1,p2;
  155. get_all_points();
  156. // p1.point_x=p2.point_x=3;
  157. // p1.point_y=p2.point_y=2;
  158. // while(1)
  159. // {
  160. // printf("(%d,%d)+(%d,%d)---%d\n",p1.point_x,p1.point_y,p2.point_x,p2.point_y,count);
  161. // p2=add_two_points(p1,p2);
  162. // count++;
  163. // if(p2.point_x==-1 && p2.point_y==-1)
  164. // {
  165. // break;
  166. // }
  167. // }
  168. // printf("\n\n(%d,%d)---%d\n",p1.point_x,p1.point_y,count);
  169. //
  170. // do{
  171. // printf("(%d,%d)+(%d,%d)---%d\n",p1.point_x,p1.point_y,p2.point_x,p2.point_y,count);
  172. // p2=add_two_points(p1,p2);
  173. // count++;
  174. //
  175. // } while(!((p2.point_x==p1.point_x)&&(p2.point_y==p1.point_y)));
  176. // printf("(%d,%d)+(%d,%d)---%d\n",p1.point_x,p1.point_y,p2.point_x,p2.point_y,count);
  177. // count ++ ;
  178. // printf("\n\n(%d,%d)---%d\n",p1.point_x,p1.point_y,count);
  179. printf("\n**********************************输出生成元以及阶:*************************************\n");
  180. for(i=0;i<eccPoint.len;i++)
  181. {
  182. count=1;
  183. p1.point_x=p2.point_x=eccPoint.p[i].point_x;
  184. p1.point_y=p2.point_y=eccPoint.p[i].point_y;
  185. while(1)
  186. {
  187. p2=add_two_points(p1,p2);
  188. if(p2.point_x==-1 && p2.point_y==-1)
  189. {
  190. break;
  191. }
  192. count++;
  193. if(p2.point_x==p1.point_x)
  194. {
  195. break;
  196. }
  197. }
  198. count++;
  199. if(count<=eccPoint.len+1)
  200. {
  201. geneSet[j].p.point_x=p1.point_x;
  202. geneSet[j].p.point_y=p1.point_y;
  203. geneSet[j].p_class=count;
  204. printf("(%d,%d)--->>%d\t",geneSet[j].p.point_x,geneSet[j].p.point_y,geneSet[j].p_class);
  205. j++;
  206. if(j % 6 ==0){
  207. printf("\n");
  208. }
  209. }
  210. geneLen=j;
  211. }
  212. }
  213. //task2:倍点运算的递归算法
  214. Point timesPiont(int k,Point p0)
  215. {
  216. if(k==1){
  217. return p0;
  218. }
  219. else if(k==2){
  220. return add_two_points(p0,p0);
  221. }else{
  222. return add_two_points(p0,timesPiont(k-1,p0));
  223. }
  224. }
  225. //两点的加法运算
  226. Point add_two_points(Point p1,Point p2)
  227. {
  228. long t;
  229. int x1=p1.point_x;
  230. int y1=p1.point_y;
  231. int x2=p2.point_x;
  232. int y2=p2.point_y;
  233. int tx,ty;
  234. int x3,y3;
  235. int flag=0;
  236. //求
  237. if((x2==x1)&& (y2==y1) )
  238. {
  239. //相同点相加
  240. if(y1==0)
  241. {
  242. flag=1;
  243. }else{
  244. t=(3*x1*x1+a)*inverse(p,2*y1) % p;
  245. }
  246. //printf("inverse(p,2*y1)=%d\n",inverse(p,2*y1));
  247. }else{
  248. //不同点相加
  249. ty=y2-y1;
  250. tx=x2-x1;
  251. while(ty<0)
  252. {
  253. ty+=p;
  254. }
  255. while(tx<0)
  256. {
  257. tx+=p;
  258. }
  259. if(tx==0 && ty !=0)
  260. {
  261. flag=1;
  262. }else{
  263. t=ty*inverse(p,tx) % p;
  264. }
  265. }
  266. if(flag==1)
  267. {
  268. p2.point_x=-1;
  269. p2.point_y=-1;
  270. }else{
  271. x3=(t*t-x1-x2) % p;
  272. y3=(t*(x1-x3)-y1) % p;
  273. //使结果在有限域GF(P)上
  274. while(x3<0)
  275. {
  276. x3+=p;
  277. }
  278. while(y3<0)
  279. {
  280. y3+=p;
  281. }
  282. p2.point_x=x3;
  283. p2.point_y=y3;
  284. }
  285. return p2;
  286. }
  287. //求b关于n的逆元
  288. int inverse(int n,int b)
  289. {
  290. int q,r,r1=n,r2=b,t,t1=0,t2=1,i=1;
  291. while(r2>0)
  292. {
  293. q=r1/r2;
  294. r=r1%r2;
  295. r1=r2;
  296. r2=r;
  297. t=t1-q*t2;
  298. t1=t2;
  299. t2=t;
  300. }
  301. if(t1>=0)
  302. return t1%n;
  303. else{
  304. while((t1+i*n)<0)
  305. i++;
  306. return t1+i*n;
  307. }
  308. }
  309. //task1:求出椭圆曲线上所有点
  310. void get_all_points()
  311. {
  312. int i=0;
  313. int j=0;
  314. int s,y=0;
  315. int n=0,q=0;
  316. int modsqrt=0;
  317. int flag=0;
  318. if (4 * a * a * a + 27 * b * b != 0)
  319. {
  320. for(i=0;i<=p-1;i++)
  321. {
  322. flag=0;
  323. n=1;
  324. y=0;
  325. s= i * i * i + a * i + b;
  326. while(s<0)
  327. {
  328. s+=p;
  329. }
  330. s=mod_p(s);
  331. modsqrt=int_sqrt(s);
  332. if(modsqrt!=-1)
  333. {
  334. flag=1;
  335. y=modsqrt;
  336. }else{
  337. while(n<=p-1)
  338. {
  339. q=s+n*p;
  340. modsqrt=int_sqrt(q);
  341. if(modsqrt!=-1)
  342. {
  343. y=modsqrt;
  344. flag=1;
  345. break;
  346. }
  347. flag=0;
  348. n++;
  349. }
  350. }
  351. if(flag==1)
  352. {
  353. eccPoint.p[j].point_x=i;
  354. eccPoint.p[j].point_y=y;
  355. j++;
  356. if(y!=0)
  357. {
  358. eccPoint.p[j].point_x=i;
  359. eccPoint.p[j].point_y=(p-y) % p;
  360. j++;
  361. }
  362. }
  363. }
  364. eccPoint.len=j;//点集个数
  365. print(); //打印点集
  366. }
  367. }
  368. //取模函数
  369. int mod_p(int s)
  370. {
  371. int i; //保存s/p的倍数
  372. int result; //模运算的结果
  373. i = s / p;
  374. result = s - i * p;
  375. if (result >= 0)
  376. {
  377. return result;
  378. }
  379. else
  380. {
  381. return result + p;
  382. }
  383. }
  384. //判断平方根是否为整数
  385. int int_sqrt(int s)
  386. {
  387. int temp;
  388. temp=(int)sqrt(s);//转为整型
  389. if(temp*temp==s)
  390. {
  391. return temp;
  392. }else{
  393. return -1;
  394. }
  395. }
  396. //打印点集
  397. void print()
  398. {
  399. int i;
  400. int len=eccPoint.len;
  401. printf("\n该椭圆曲线上共有%d个点(包含无穷远点)\n",len+1);
  402. for(i=0;i<len;i++)
  403. {
  404. if(i % 8==0)
  405. {
  406. printf("\n");
  407. }
  408. printf("(%2d,%2d)\t",eccPoint.p[i].point_x,eccPoint.p[i].point_y);
  409. }
  410. printf("\n");
  411. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/731277
推荐阅读
相关标签
  

闽ICP备14008679号