教学服务系统

 找回密码
 立即注册
搜索
查看: 631|回复: 1

信息计算2019级1班3号刘丹丹

[复制链接]

9

主题

19

帖子

99

积分

注册会员

Rank: 2

积分
99
发表于 2022-5-27 16:55:24 | 显示全部楼层 |阅读模式
本帖最后由 2019-1刘丹丹 于 2022-5-28 09:51 编辑

                                                                                                            ECC-椭圆曲线加密算法一.简介:
椭圆加密算法(ECC)是一种公钥加密体制,最初由Koblitz和Miller两人于1985年提出,其数学基础是利用椭圆曲线上的有理点构成Abel加法群上椭圆离散对数的计算困难性。公钥密码体制根据其所依据的难题一般分为三类:大素数分解问题类、离散对数问题类、椭圆曲线类。有时也把椭圆曲线类归为离散对数类。
ECC的主要优势是在某些情况下它比其他的方法使用更小的密钥——比如RSA加密算法——提供相当的或更高等级的安全。ECC的另一个优势是可以定义群之间的双线性映射,基于Weil对或是Tate对;双线性映射已经在密码学中发现了大量的应用,例如基于身份的加密。不过一个缺点是加密和解密操作的实现比其他机制花费的时间长。

二.基本原理:
设私钥、公钥分别为d、Q,即Q = dG,其中G为基点,椭圆曲线上的已知G和dG,求d是非常困难的,也就是说已知公钥和基点,想要算出私钥是非常困难的。
公钥加密:选择随机数r,将消息M生成密文C,该密文是一个点对,C = {rG, M+rQ},其中Q为公钥。
私钥解密:M + rQ - d(rG) = M + r(dG) - d(rG) = M,其中d、Q分别为私钥、公钥。

椭圆曲线签名算法(ECDSA)。设私钥、公钥分别为d、Q,即Q = dG,其中G为基点。
私钥签名
选择随机数r,计算点rG(x, y)。
根据随机数r、消息M的哈希h、私钥d,计算s = (h + dx)/r。  
将消息M、和签名{rG, s}发给接收方。


公钥验证签名:
接收方收到消息M、以及签名{rG=(x,y), s}。  
根据消息求哈希h。  
使用发送方公钥Q计算:hG/s + xQ/s,并与rG比较,如相等即验签成功。
原理:hG/s + xQ/s = hG/s + x(dG)/s = (h+xd)G/s = r(h+xd)G / (h+dx) = rG



三.运用的数学知识:
1.阿贝尔群     2.椭圆曲线的加法     3.椭圆曲线的二倍运算     4.同余运算     5.有限域        6.乘法逆元
回复

使用道具 举报

9

主题

19

帖子

99

积分

注册会员

Rank: 2

积分
99
 楼主| 发表于 2022-5-27 16:56:12 | 显示全部楼层
四.代码
  1. # include <stdio.h>
  2. # include <math.h>
  3. using System.Drawing;

  4. int xy[22];

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

  140. //task3:求生成元以及阶
  141. void get_generetor_class()
  142. {
  143.         int i, j = 0;
  144.         int count = 1;
  145.         Point p1, p2;
  146.         get_all_points();
  147.         printf("\n**********************************输出生成元以及阶:*************************************\n");
  148.         for (i = 0; i < eccPoint.len; i++)
  149.         {
  150.                 count = 1;
  151.                 p1.x = p2.x = eccPoint.p[i].x;
  152.                 p1.y = p2.y = eccPoint.p[i].y;
  153.                 while (1)
  154.                 {
  155.                         p2 = add_two_points(p1, p2);
  156.                         if (p2.x == -1 && p2.y == -1)
  157.                         {
  158.                                 break;
  159.                         }
  160.                         count++;
  161.                         if (p2.x == p1.x)
  162.                         {
  163.                                 break;
  164.                         }
  165.                 }
  166.                 count++;
  167.                 if (count <= eccPoint.len + 1)
  168.                 {
  169.                         geneSet[j].p.x = p1.x;
  170.                         geneSet[j].p.y = p1.y;
  171.                         geneSet[j].p_class = count;
  172.                         printf("(%d,%d)--->>%d\t", geneSet[j].p.x, geneSet[j].p.y, geneSet[j].p_class);
  173.                         j++;
  174.                         if (j % 6 == 0)
  175.                         {
  176.                                 printf("\n");
  177.                         }
  178.                 }
  179.                 geneLen = j;
  180.         }
  181. }

  182. // 求 a mod b 的逆元
  183. void exGcd(int a, int b)
  184. {
  185.         if (b == 0)
  186.         {
  187.                 xy[0] = 1;
  188.                 xy[1] = 0;
  189.         }
  190.         else
  191.         {
  192.                 exGcd(b, a % b);
  193.                 int x = xy[0];
  194.                 xy[0] = xy[1];
  195.                 xy[1] = x - (a / b) * xy[1];
  196.         }

  197. }
  198. int calculate3(int y, int k, int p)
  199. {

  200.         int l = 1;
  201.         for (int i = 0; i < k; i++)
  202.         {
  203.                 l = l * y;
  204.                 l = l % p;
  205.         }

  206.         return l;
  207. }

  208. Point eccmutiply(int n, Point p)
  209. {
  210.         int a, b, l, k, m;
  211.         a = p.x;
  212.         b = p.y;
  213.         for (int i = 0; i < n - 1; i++)
  214.         {

  215.                 if (a == p.x && b == p.y)
  216.                 {
  217.                         exGcd(2 * p.y, N);
  218.                         k = xy[0];
  219.                         if (k < 0) k = k + N;
  220.                         printf("逆元=%d\n", k);
  221.                         l = (3 * p.x * p.x + A) * k;
  222.                         l = calculate3(l, 1, N);
  223.                         if (l < 0)
  224.                         {
  225.                                 l = l + N;
  226.                         }
  227.                 }
  228.                 else
  229.                 {
  230.                         exGcd(a - p.x + N, N);
  231.                         k = xy[0];
  232.                         if (k < 0) k = k + N;
  233.                         printf("else逆元=%d\n", k);
  234.                         l = (b - p.y) * k;
  235.                         l = calculate3(l, 1, N);
  236.                         if (l < 0)
  237.                         {
  238.                                 l = l + N;
  239.                         }
  240.                         printf("l=%d\n", l);
  241.                 }
  242.                 m = p.x;
  243.                 a = l * l - a - p.x;
  244.                 a = calculate3(a, 1, N);
  245.                 if (a < 0)
  246.                 {
  247.                         a = a + N;
  248.                 }
  249.                 b = l * (m - a) - p.y;
  250.                 b = calculate3(b, 1, N);

  251.                 if (b < 0)
  252.                 {
  253.                         b = b + N;
  254.                 }
  255.                 printf("%d(a,b)=(%d,%d)\n", i + 2, a, b);
  256.                 //if(a==4&&b==5)break;
  257.         }
  258.         Point p3;
  259.         p3.x = a;
  260.         p3.y = b;
  261.         return p3;
  262. }
  263. Point mul(Point p1, Point p2)
  264. {
  265.         int k, l;
  266.         exGcd(p2.x - p1.x + N, N);
  267.         k = xy[0];
  268.         if (k < 0) k = k + N;
  269.         //printf("else逆元=%d\n",k);
  270.         l = (p2.y - p1.y) * k;
  271.         l = calculate3(l, 1, N);
  272.         if (l < 0)
  273.         {
  274.                 l = l + N;
  275.         }
  276.         //printf("l=%d\n",l);       
  277.         Point p3;
  278.         p3.x = l * l - p1.x - p2.x;
  279.         p3.x = calculate3(p3.x, 1, N);
  280.         if (p3.x < 0) p3.x = p3.x + N;

  281.         p3.y = l * (p1.x - p3.x) - p1.y;
  282.         p3.y = calculate3(p3.y, 1, N);
  283.         if (p3.y < 0) p3.y = p3.y + N;
  284.         return p3;
  285. }

  286. //求b关于n的逆元
  287. int inverse(int n, int b)
  288. {
  289.         int q, r, r1 = n, r2 = b, t, t1 = 0, t2 = 1, i = 1;
  290.         while (r2 > 0)
  291.         {
  292.                 q = r1 / r2;
  293.                 r = r1 % r2;
  294.                 r1 = r2;
  295.                 r2 = r;
  296.                 t = t1 - q * t2;
  297.                 t1 = t2;
  298.                 t2 = t;
  299.         }
  300.         if (t1 >= 0)
  301.                 return t1 % n;
  302.         else
  303.         {
  304.                 while ((t1 + i * n) < 0)
  305.                         i++;
  306.                 return t1 + i * n;
  307.         }
  308. }
  309. //两点的加法运算
  310. Point add_two_points(Point p1, Point p2)
  311. {
  312.         long t;
  313.         int x1 = p1.x;
  314.         int y1 = p1.y;
  315.         int x2 = p2.x;
  316.         int y2 = p2.y;
  317.         int tx, ty;
  318.         int x3, y3;
  319.         int flag = 0;
  320.         //求
  321.         if ((x2 == x1) && (y2 == y1))
  322.         {
  323.                 //相同点相加
  324.                 if (y1 == 0)
  325.                 {
  326.                         flag = 1;
  327.                 }
  328.                 else
  329.                 {
  330.                         t = (3 * x1 * x1 + a1) * inverse(N, 2 * y1) % N;
  331.                 }
  332.                 //printf("inverse(p,2*y1)=%d\n",inverse(p,2*y1));
  333.         }
  334.         else
  335.         {
  336.                 //不同点相加
  337.                 ty = y2 - y1;
  338.                 tx = x2 - x1;
  339.                 while (ty < 0)
  340.                 {
  341.                         ty += N;
  342.                 }
  343.                 while (tx < 0)
  344.                 {
  345.                         tx += N;
  346.                 }
  347.                 if (tx == 0 && ty != 0)
  348.                 {
  349.                         flag = 1;
  350.                 }
  351.                 else
  352.                 {
  353.                         t = ty * inverse(N, tx) % N;
  354.                 }
  355.         }
  356.         if (flag == 1)
  357.         {
  358.                 p2.x = -1;
  359.                 p2.y = -1;
  360.         }
  361.         else
  362.         {
  363.                 x3 = (t * t - x1 - x2) % N;
  364.                 y3 = (t * (x1 - x3) - y1) % N;
  365.                 //使结果在有限域GF(P)上
  366.                 while (x3 < 0)
  367.                 {
  368.                         x3 += N;
  369.                 }
  370.                 while (y3 < 0)
  371.                 {
  372.                         y3 += N;
  373.                 }
  374.                 p2.x = x3;
  375.                 p2.y = y3;
  376.         }
  377.         return p2;
  378. }
  379. //task2:倍点运算的递归算法
  380. Point timesPiont(int k, Point p0)
  381. {
  382.         if (k == 1)
  383.         {
  384.                 return p0;
  385.         }
  386.         else if (k == 2)
  387.         {
  388.                 return add_two_points(p0, p0);
  389.         }
  390.         else
  391.         {
  392.                 return add_two_points(p0, timesPiont(k - 1, p0));
  393.         }
  394. }
  395. main(){
  396.         get_generetor_class();
  397.         Point p1, p2, p, p4, p5, p6, p7, p8, p9, p10;
  398.         int na, k, h, r, s, u1, u2;
  399.         printf("选择生成元");
  400.         scanf("%d%d", &p1.x, &p1.y);
  401.         int j = 0;
  402.         while (j < N)
  403.         {

  404.                 if (geneSet[j].p.x == p1.x && geneSet[j].p.y == p1.y)
  405.                 {
  406.                         break;
  407.                 }
  408.                 printf("j=%d\n", j);
  409.                 ++j;
  410.         }
  411.         int M = geneSet[j].p_class;
  412.         printf("M=%d", M);
  413.         //        p1.x=0;
  414.         //        p1.y=2;
  415.         //p.x=20;
  416.         //p.y=1;
  417.         printf("请输入私钥");
  418.         scanf("%d", &na);
  419.         p2 = eccmutiply(na, p1);
  420.         printf("公钥为(%d,%d)", p2.x, p2.y);
  421.         //p2=mul(p,p1);

  422.         //printf("(%d,%d)",p2.x,p2.y);

  423.         //签名过程
  424.         printf("输入随机数k\n");
  425.         scanf("%d", &k);
  426.         printf("输入hash\n");
  427.         scanf("%d", &h);


  428.         p4 = eccmutiply(k, p1);
  429.         r = calculate3(p4.x, 1, N);
  430.         if (r < 0) r = r + N;
  431.         s = inverse(M, k) * (h + na * r) % M;
  432.         if (s < 0) s = s + N;
  433.         printf("签名为(%d,%d)\n", r, s);
  434.         printf("========================");
  435.         //验证过程
  436.         u1 = h * inverse(M, s) % M;

  437.         if (u1 < 0) u1 = u1 + M;
  438.         u2 = r * inverse(M, s) % M;

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

  440.         printf("u1u2=%d,%d\n", u1, u2);

  441.         p5 = eccmutiply(u1, p1);
  442.         printf("sG=(%d,%d)\n", p5.x, p5.y);

  443.         p6 = eccmutiply(u2, p2);
  444.         printf("HP=(%d,%d)\n", p6.x, p6.y);

  445.         p7 = add_two_points(p5, p6);
  446.         printf("sG+HP=(%d,%d)\n", p7.x, p7.y);
  447.         if (calculate3(p7.x, 1, N) == r)
  448.         {
  449.                 printf("通过");
  450.         }
  451.         else
  452.         {
  453.                 printf("失败");
  454.         }

  455. }
复制代码


回复

使用道具 举报

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

本版积分规则

教学服务系统

GMT+8, 2025-4-30 07:38 , Processed in 0.018956 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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