教学服务系统

 找回密码
 立即注册
搜索
查看: 623|回复: 0

信息计算2019陆慧明

[复制链接]

9

主题

18

帖子

77

积分

注册会员

Rank: 2

积分
77
发表于 2022-6-3 01:46:37 | 显示全部楼层 |阅读模式
  1. #include <stdio.h>
  2. #include <math.h>
  3. int xy[22];

  4. #define N 23
  5. #define A 1
  6. //#define M 29
  7. #define a1 1
  8. #define b1 4
  9. typedef struct point{
  10.         int x;
  11.         int y;
  12. }Point;
  13. typedef struct ecc{
  14.         struct point p[100];
  15.         int len;
  16. }ECCPoint;
  17. typedef struct generator{
  18.         Point p;
  19.         int p_class;
  20. }GENE_SET;
  21. ECCPoint eccPoint;
  22. Point mul(Point p1,Point p2);
  23. Point add_two_points(Point p1,Point p2);
  24. GENE_SET geneSet[100];
  25. int geneLen;
  26. //判断平方根是否为整数
  27. int int_sqrt(int s)
  28. {
  29.         int temp;
  30.         temp=(int)sqrt(s);//转为整型
  31.         if(temp*temp==s)
  32.         {
  33.                 return temp;
  34.         }else{
  35.                 return -1;
  36.         }
  37. }
  38. //取模函数
  39. int mod_p(int s)
  40. {
  41.         int i;        //保存s/p的倍数
  42.         int result;        //模运算的结果
  43.         i = s / N;
  44.         result = s - i * N;
  45.         if (result >= 0)
  46.         {
  47.                 return result;
  48.         }
  49.         else
  50.         {
  51.                 return result + N;
  52.         }
  53. }
  54. //打印点集
  55. void print()
  56. {
  57.         int i;
  58.         int len=eccPoint.len;
  59.         printf("\n该椭圆曲线上共有%d个点(包含无穷远点)\n",len+1);
  60.         for(i=0;i<len;i++)
  61.         {
  62.                 if(i % 8==0)
  63.                 {
  64.                         printf("\n");
  65.                 }
  66.                 printf("(%2d,%2d)\t",eccPoint.p[i].x,eccPoint.p[i].y);
  67.         }
  68.         printf("\n");
  69. }
  70. //task1:求出椭圆曲线上所有点
  71. void get_all_points()
  72. {
  73.         int i=0;
  74.         int j=0;
  75.         int s,y=0;
  76.         int n=0,q=0;
  77.         int modsqrt=0;
  78.         int flag=0;
  79.         if ( a1 * a1 * a1 + b1 * b1+4 != 0)
  80.         {
  81.                 for(i=0;i<=N-1;i++)
  82.                 {
  83.                         flag=0;
  84.                         n=1;
  85.                         y=0;
  86.                         s= i * i * i + a1 * i + b1;
  87.                         while(s<0)
  88.                         {
  89.                                 s+=N;
  90.                         }
  91.                         s=mod_p(s);
  92.                         modsqrt=int_sqrt(s);
  93.                         if(modsqrt!=-1)
  94.                         {
  95.                                 flag=1;
  96.                                 y=modsqrt;
  97.                         }else{
  98.                                 while(n<=N-1)
  99.                                 {
  100.                                         q=s+n*N;
  101.                                         modsqrt=int_sqrt(q);
  102.                                         if(modsqrt!=-1)
  103.                                         {
  104.                                                 y=modsqrt;
  105.                                                 flag=1;
  106.                                                 break;
  107.                                         }
  108.                                                 flag=0;
  109.                                                 n++;
  110.                                 }
  111.                         }
  112.                         if(flag==1)
  113.                         {
  114.                                 eccPoint.p[j].x=i;
  115.                                 eccPoint.p[j].y=y;
  116.                                 j++;
  117.                                 if(y!=0)
  118.                                 {
  119.                                         eccPoint.p[j].x=i;
  120.                                         eccPoint.p[j].y=(N-y) % N;
  121.                                         j++;
  122.                                 }                               
  123.                         }
  124.                 }
  125.                 eccPoint.len=j;//点集个数
  126.                 print(); //打印点集
  127.         }       
  128. }

  129. //task3:求生成元以及阶
  130. void get_generetor_class()
  131. {       
  132.         int i,j=0;
  133.         int count=1;
  134.         Point p1,p2;
  135.         get_all_points();       
  136.         printf("\n**********************************输出生成元以及阶:*************************************\n");
  137.         for(i=0;i<eccPoint.len;i++)
  138.         {
  139.                 count=1;
  140.                 p1.x=p2.x=eccPoint.p[i].x;
  141.                 p1.y=p2.y=eccPoint.p[i].y;               
  142.                 while(1)
  143.                 {       
  144.                         p2=add_two_points(p1,p2);                                       
  145.                         if(p2.x==-1 && p2.y==-1)
  146.                         {
  147.                                 break;
  148.                         }
  149.                         count++;
  150.                         if(p2.x==p1.x)
  151.                         {
  152.                                 break;
  153.                         }                                               
  154.                 }
  155.                 count++;
  156.                 if(count<=eccPoint.len+1)
  157.                 {
  158.                         geneSet[j].p.x=p1.x;
  159.                         geneSet[j].p.y=p1.y;
  160.                         geneSet[j].p_class=count;
  161.                         printf("(%d,%d)--->>%d\t",geneSet[j].p.x,geneSet[j].p.y,geneSet[j].p_class);
  162.                         j++;
  163.                         if(j % 6 ==0){
  164.                                 printf("\n");
  165.                         }
  166.                 }
  167.                 geneLen=j;       
  168.         }
  169. }

  170. // 求 a mod b 的逆元
  171. void exGcd(int a, int b) {
  172.     if (b == 0) {
  173.         xy[0] = 1;
  174.         xy[1] = 0;
  175.     } else {
  176.         exGcd(b, a % b);
  177.         int x = xy[0];
  178.         xy[0] = xy[1];
  179.         xy[1] = x - (a / b) * xy[1];
  180.     }
  181.         }
  182. int calculate3(int y,int k,int p){

  183.         int l=1;
  184.         for(int i = 0;i<k;i++){
  185.                 l=l*y;
  186.                 l=l%p;
  187.         }

  188.         return l;
  189. }

  190. Point eccmutiply(int n,Point p){
  191.         int a,b,l,k,m;
  192.         a=p.x;
  193.         b=p.y;
  194.         for(int i = 0;i<n-1;i++){
  195.                
  196.                 if(a==p.x&&b==p.y){
  197.                         exGcd(2*p.y,N);
  198.                         k=xy[0];
  199.                         if(k<0)k=k+N;
  200.                         printf("逆元=%d\n",k);
  201.                         l=(3*p.x*p.x+A)*k;
  202.                         l=calculate3(l,1,N);
  203.                         if(l<0){
  204.                                 l=l+N;
  205.                         }
  206.                 }else{
  207.                         exGcd(a-p.x+N,N);
  208.                         k=xy[0];
  209.                         if(k<0)k=k+N;
  210.                         printf("else逆元=%d\n",k);
  211.                         l=(b-p.y)*k;
  212.                         l=calculate3(l,1,N);
  213.                         if(l<0){
  214.                                 l=l+N;
  215.                         }
  216.                         printf("l=%d\n",l);
  217.                 }
  218.                 m=p.x;
  219.                 a=l*l-a-p.x;
  220.                 a=calculate3(a,1,N);
  221.                 if(a<0){
  222.                         a=a+N;
  223.                 }
  224.                 b=l*(m-a)-p.y;
  225.                 b=calculate3(b,1,N);
  226.        
  227.                 if(b<0){
  228.                         b=b+N;
  229.                 }
  230.                 printf("%d(a,b)=(%d,%d)\n",i+2,a,b);
  231.                 //if(a==4&&b==5)break;
  232.         }
  233.         Point p3;
  234.         p3.x=a;
  235.         p3.y=b;
  236.         return p3;
  237. }
  238. Point mul(Point p1,Point p2){
  239.         int k,l;
  240.         exGcd(p2.x-p1.x+N,N);
  241.         k=xy[0];
  242.         if(k<0)k=k+N;
  243.         //printf("else逆元=%d\n",k);
  244.         l=(p2.y-p1.y)*k;
  245.         l=calculate3(l,1,N);
  246.         if(l<0){
  247.                 l=l+N;
  248.         }
  249.         //printf("l=%d\n",l);       
  250.         Point p3;
  251.         p3.x=l*l-p1.x-p2.x;
  252.         p3.x=calculate3(p3.x,1,N);
  253.         if(p3.x<0)p3.x=p3.x+N;
  254.        
  255.         p3.y=l*(p1.x-p3.x)-p1.y;
  256.         p3.y=calculate3(p3.y,1,N);
  257.         if(p3.y<0)p3.y=p3.y+N;
  258.         return p3;
  259. }

  260. //求b关于n的逆元
  261. int inverse(int n,int b)
  262. {
  263.         int q,r,r1=n,r2=b,t,t1=0,t2=1,i=1;
  264.         while(r2>0)
  265.         {
  266.                 q=r1/r2;
  267.                 r=r1%r2;
  268.                 r1=r2;
  269.                 r2=r;
  270.                 t=t1-q*t2;
  271.                 t1=t2;
  272.                 t2=t;
  273.         }
  274.         if(t1>=0)
  275.                 return t1%n;
  276.         else{  
  277.                 while((t1+i*n)<0)
  278.                         i++;
  279.                 return t1+i*n;
  280.         }
  281. }
  282. //两点的加法运算
  283. Point add_two_points(Point p1,Point p2)
  284. {
  285.         long t;
  286.         int x1=p1.x;
  287.         int y1=p1.y;
  288.         int x2=p2.x;
  289.         int y2=p2.y;
  290.         int tx,ty;
  291.         int x3,y3;
  292.         int flag=0;
  293.         //求
  294.         if((x2==x1)&& (y2==y1) )
  295.         {
  296.                 //相同点相加
  297.                 if(y1==0)
  298.                 {
  299.                         flag=1;
  300.                 }else{
  301.                         t=(3*x1*x1+a1)*inverse(N,2*y1) % N;
  302.                 }
  303.                 //printf("inverse(p,2*y1)=%d\n",inverse(p,2*y1));
  304.         }else{
  305.                 //不同点相加
  306.                 ty=y2-y1;
  307.                 tx=x2-x1;
  308.                 while(ty<0)
  309.                 {
  310.                         ty+=N;
  311.                 }
  312.                 while(tx<0)
  313.                 {
  314.                         tx+=N;
  315.                 }
  316.                 if(tx==0 && ty !=0)
  317.                 {
  318.                         flag=1;
  319.                 }else{
  320.                         t=ty*inverse(N,tx) % N;
  321.                 }
  322.         }
  323.         if(flag==1)
  324.         {
  325.                 p2.x=-1;
  326.                 p2.y=-1;
  327.         }else{
  328.                 x3=(t*t-x1-x2) % N;
  329.                 y3=(t*(x1-x3)-y1) % N;
  330.         //使结果在有限域GF(P)上
  331.                 while(x3<0)
  332.                 {
  333.                         x3+=N;
  334.                 }
  335.                 while(y3<0)
  336.                 {
  337.                         y3+=N;
  338.                 }
  339.                 p2.x=x3;
  340.                 p2.y=y3;
  341.         }       
  342.         return p2;
  343. }
  344. //task2:倍点运算的递归算法
  345. Point timesPiont(int k,Point p0)
  346. {
  347.         if(k==1){
  348.                 return p0;
  349.         }                
  350.         else if(k==2){
  351.                 return add_two_points(p0,p0);
  352.         }else{
  353.                 return add_two_points(p0,timesPiont(k-1,p0));
  354.         }
  355. }
  356. main(){
  357.         get_generetor_class();
  358.         Point p1,p2,p,p4,p5,p6,p7,p8,p9,p10;
  359.         int na,k,h,r,s,u1,u2;
  360.         printf("选择生成元");
  361.         scanf("%d%d",&p1.x,&p1.y);
  362.         int j=0;
  363.         while(j<N){

  364.                 if(geneSet[j].p.x==p1.x&&geneSet[j].p.y==p1.y){
  365.                         break;
  366.                 }
  367.                 printf("j=%d\n",j);
  368.                 ++j;
  369.         }
  370.         int M = geneSet[j].p_class;
  371.         printf("M=%d",M);
  372. //        p1.x=0;//
  373. //        p1.y=2;//
  374. //        p.x=20;//
  375. //        p.y=1;//
  376.         printf("请输入私钥");
  377.         scanf("%d",&na);
  378.         p2=eccmutiply(na,p1);
  379.         printf("公钥为(%d,%d)",p2.x,p2.y);
  380.         p2=mul(p,p1);//
  381.        
  382. //        printf("(%d,%d)",p2.x,p2.y);//
  383.        
  384.         //签名过程
  385.         printf("输入随机数k\n");
  386.         scanf("%d",&k);
  387.         printf("输入hash\n");
  388.         scanf("%d",&h);
  389.        
  390.        
  391.         p4=eccmutiply(k,p1);
  392.         r=calculate3(p4.x,1,N);
  393.         if(r<0)r=r+N;
  394.         s=inverse(M,k)*(h+na*r)%M;
  395.         if(s<0)s=s+N;
  396.         printf("签名为(%d,%d)\n",r,s);
  397.         printf("========================");
  398.         //验证过程
  399.         u1=h*inverse(M,s)%M;
  400.        
  401.         if(u1<0)u1=u1+M;
  402.         u2=r*inverse(M,s)%M;

  403.         if(u2<0)u2=u2+M;

  404.         printf("u1u2=%d,%d\n",u1,u2);
  405.        
  406.         p5=eccmutiply(u1,p1);
  407.         printf("sG=(%d,%d)\n",p5.x,p5.y);
  408.        
  409.         p6=eccmutiply(u2,p2);
  410.         printf("HP=(%d,%d)\n",p6.x,p6.y);

  411.         p7=add_two_points(p5,p6);
  412.         printf("sG+HP=(%d,%d)\n",p7.x,p7.y);
  413.         if(calculate3(p7.x,1,N)==r){
  414.                 printf("通过");
  415.         }else{
  416.                 printf("失败");
  417.         }
  418.          
  419. }
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

教学服务系统

GMT+8, 2025-4-30 16:31 , Processed in 0.017571 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表