教学服务系统

 找回密码
 立即注册
搜索
查看: 591|回复: 2

信息计算2019级2班25号裴焕权

[复制链接]

8

主题

18

帖子

108

积分

注册会员

Rank: 2

积分
108
发表于 2022-6-2 21:22:59 | 显示全部楼层 |阅读模式
RSA
RSA算法产生密钥的过程: 1.系统产生两个大素数p, q(保密) 2.计算n=pq(公开),欧拉函数Φ(n)=(p-1)(q-1)(保密) 3.随机选择满足gcd(e,Φ(n))=1e作为公钥(公开),加密密钥就是(e,n) 4.计算满足ed=1(modΦ(n))d作为私钥(保密),解密密钥即为(d,n) RSA的加解密过程: 首先将明文分组并数字化,每个数字化分组明文的长度不大于log n,然后对每个明文分组m依次进行加解密运算: 1.加密运算:使用公钥e和要加密的明文m进行c=me(mod n)运算即得密文 2.解密运算:使用私钥d和要加密的明文m进行c=md(mod n)运算即得明文。
  1. p1.x = P0.x; p2.x = P0.x;
  2.         p1.y = P0.y; p2.y = P0.y;
  3.         while (true)
  4.         {
  5.                 p2 = add(p1, p2, a, p);
  6.                 if (p2.x == -1 && p2.y == -1)
  7.                 {
  8.                         break;
  9.                 }
  10.                 number++;
  11.                 if (p2.x == p1.x)
  12.                 {
  13.                         break;
  14.                 }
  15.         }
  16.         pp.x = p1.x;
  17.         pp.y = p1.y;
  18.         int n = ++number;
  19.         return n;
  20. }

  21. //素数判断
  22. bool judge(int num)
  23. {
  24.         bool ret = true;
  25.         int ubound = sqrt(num) + 1;
  26.         for (int i = 2; i < ubound; i++)
  27.         {
  28.                 if (num % i == 0)
  29.                 {
  30.                         ret = false;
  31.                         break;
  32.                 }
  33.         }
  34.         return ret;
  35. }

  36. //计算kG
  37. point cal(point G, int k, int a, int p)
  38. {
  39.         point temp = G;
  40.         for (int i = 0; i < k - 1; i++)
  41.         {
  42.                 temp = add(temp, G, a, p);
  43.         }
  44.         return temp;
  45. }

  46. int main()
  47. {
  48.         srand(time(NULL));
  49.         int a, b, p;
  50.         point generator; int n;
  51.         char SE[10];
  52.         char CR[10];

  53.         cout << "请输入椭圆曲线群(a,b,p):";
  54.         cin >> a >> b >> p;
  55.         cout << "请输入明文:";
  56.         cin >> SE;
  57.         cout << "请输入密钥:";
  58.         cin >> CR;

  59.         //计算所有点
  60.         all_points(a, b, p);
  61.         //选取生成元,直到阶为素数
  62.         do
  63.         {
  64.                 n = jie(generator, a, p);
  65.         } while (judge(n) == false);
  66.         cout << endl << "选取生成元(" << generator.x << "," << generator.y << "),阶为:" << n << endl;
  67.         //选取私钥
  68.         int ka = int(CR[0]) % (n - 1) + 1;//选取使用的密钥
  69.         point pa = cal(generator, ka, a, p);//计算公钥
  70.         cout << "私钥:" << ka << endl;
  71.         cout << "公钥:(" << pa.x << "," << pa.y << ")" << endl;

  72.         //加密
  73.         int k = 0;//随机数k
  74.         k = rand() % (n - 2) + 1;
  75.         point C1 = cal(generator, k, a, p);//计算C1

  76.         //m嵌入到椭圆曲线
  77.         int t = rand() % num; //选择映射点
  78.         point Pt = P[t];
  79.         point P2 = cal(pa, k, a, p);
  80.         point Pm = add(Pt, P2, a, p);
  81.         cout << endl << "要发送的密文:" << endl;
  82.         cout << "kG=(" << C1.x << "," << C1.y << "),pt+kPa=(" << Pm.x << "," << Pm.y << ")";
  83.         int C[100];
  84.         cout << ",C = { ";
  85.         for (int i = 0; i < strlen(SE); i++)
  86.         {
  87.                 C[i] = int(SE[i]) * Pt.x + Pt.y;//选取要加密的明文
  88.                 cout << C[i] << " ";
  89.         }
  90.         cout << "}" << endl;


  91.         //解密
  92.         point temp, temp1;
  93.         int m;
  94.         temp = cal(C1, ka, a, p);
  95.         temp.y = 0 - temp.y;
  96.         temp1 = add(Pm, temp, a, p);//求解Pt
  97.         printf("\n解密结果:\n");
  98.         for (int i = 0; i < strlen(SE); i++)
  99.         {
  100.                 m = (C[i] - temp1.y) / temp1.x;
  101.                 printf("%c", char(m));//输出密文
  102.         }
  103.         printf("\n");

  104.         return 0;
  105. }
复制代码


回复

使用道具 举报

8

主题

18

帖子

108

积分

注册会员

Rank: 2

积分
108
 楼主| 发表于 2022-6-2 21:23:28 | 显示全部楼层
  1. //RSA解密。
  2.     private String decryption(BigInteger[] c, BigInteger d, BigInteger n) {
  3.         String cPadding = "";
  4.         String mToString = "";
  5.         int mToStringLengthMod = 0;
  6.         BigInteger m = BigInteger.ZERO;
  7.         for (int i = 0; i < c.length; i++) {// 逐组解密
  8.             m = RSA4.expMod(c[i], d, n);
  9.             mToString = m.toString();
  10.             mToStringLengthMod = m.toString().length() % 3;
  11.             if (mToStringLengthMod != 0) {// 由于加密时String转BigInter时前者前面的0并不会计入,所以需要确认并补全
  12.                 for (int j = 0; j < 3 - mToStringLengthMod; j++) {
  13.                     mToString = "0" + mToString;
  14.                 }
  15.             }
  16.             cPadding += mToString;
  17.         }

  18.         int byteNum = cPadding.length() / 3;// 明文总字节数
  19.         byte[] result = new byte[byteNum];
  20.         for (int i = 0; i < byteNum; i++) {// 每三位数转化为byte型并返回该byte数组所表达的字符串
  21.             result[i] = (byte) (Integer.parseInt(cPadding.substring(i * 3, i * 3 + 3)));
  22.         }
  23.         return new String(result);
  24.     }


  25.     //利用扩展欧几里得算法求出私钥d,使得de = kφ(n)+1,k为整数。
  26.     private static BigInteger[] extdGcd(BigInteger e, BigInteger φn) {
  27.         BigInteger[] gdk = new BigInteger[3];

  28.         if (φn.compareTo(BigInteger.ZERO) == 0) {
  29.             gdk[0] = e;
  30.             gdk[1] = BigInteger.ONE;
  31.             gdk[2] = BigInteger.ZERO;
  32.             return gdk;
  33.         } else {
  34.             gdk = extdGcd(φn, e.remainder(φn));
  35.             BigInteger tmp_k = gdk[2];
  36.             gdk[2] = gdk[1].subtract(e.divide(φn).multiply(gdk[2]));
  37.             gdk[1] = tmp_k;
  38.             return gdk;
  39.         }
  40.     }

  41.     // 利用米勒·罗宾算法判断一个数是否是质数。
  42.     private static boolean isPrime(BigInteger p) {
  43.         if (p.compareTo(BigInteger.TWO) == -1) {// 小于2直接返回false
  44.             return false;
  45.         }
  46.         if ((p.compareTo(BigInteger.TWO) != 0) && (p.remainder(BigInteger.TWO).compareTo(BigInteger.ZERO) == 0)) {// 不等于2且是偶数直接返回false
  47.             return false;
  48.         }

  49.         BigInteger p_1 = p.subtract(BigInteger.ONE);
  50.         BigInteger m = p_1;// 找到q和m使得p = 1 + 2^q * m
  51.         int q = m.getLowestSetBit();// 二进制下从右往左返回第一次出现1的索引
  52.         m = m.shiftRight(q);

  53.         for (int i = 0; i < 5; i++) {// 判断的轮数,精度、轮数和时间三者之间成正比关系
  54.             BigInteger b;
  55.             do {// 在区间1~p上生成均匀随机数
  56.                 b = new BigInteger(String.valueOf(p.bitLength()));
  57.             } while (b.compareTo(BigInteger.ONE) <= 0 || b.compareTo(p) >= 0);

  58.             int j = 0;
  59.             BigInteger z = RSA4.expMod(b, m, p);
  60.             while (!((j == 0 && z.equals(BigInteger.ONE)) || z.equals(p_1))) {
  61.                 if ((j > 0 && z.equals(BigInteger.ONE)) || ++j == q) {
  62.                     return false;
  63.                 }
  64.                 z = RSA4.expMod(z, BigInteger.TWO, p);
  65.             }
  66.         }

  67.         return true;
  68.     }

  69.     private static BigInteger generateNBitRandomPrime(int n) {
  70.         BigInteger tmp = new BigInteger("2").pow(n - 1);// 最高位肯定是1
  71.         BigInteger result = new BigInteger("2").pow(n - 1);
  72.         Random random = new Random();
  73.         int r1 = random.nextInt(101);// 产生0-100的整数,用于确定0和1的比例
  74.         int r2;

  75.         while (true) {// 循环产生数,直到该数为素数
  76.             for (int i = n - 2; i >= 0; i--) {// 逐位产生表示数的0和1,并根据所在位计算结果相加起来
  77.                 r2 = random.nextInt(101);
  78.                 if (0 < r2 && r2 < r1) {// 产生的数为1
  79.                     result = result.add(BigInteger.TWO.pow(i));
  80.                 }
  81.                 continue;
  82.             }

  83.             if (RSA4.isPrime(result)) {// 素数判断
  84.                 return result;
  85.             }

  86.             result = tmp;// 重新计算
  87.         }
  88.     }

  89.     //蒙哥马利快速幂模运算,返回base^exponent mod module的结果。
  90.     private static BigInteger expMod(BigInteger base, BigInteger exponent, BigInteger module) {
  91.         BigInteger result = BigInteger.ONE;
  92.         BigInteger tmp = base.mod(module);

  93.         while (exponent.compareTo(BigInteger.ZERO) != 0) {
  94.             if ((exponent.and(BigInteger.ONE).compareTo(BigInteger.ZERO)) != 0) {
  95.                 result = result.multiply(tmp).mod(module);
  96.             }
  97.             tmp = tmp.multiply(tmp).mod(module);
  98.             exponent = exponent.shiftRight(1);
  99.         }
  100.         return result;
  101.     }

  102.     //判断是否互素
  103.     public static boolean fun(BigInteger x, BigInteger y) {
  104.         BigInteger t;
  105.         while (!(y.equals(new BigInteger("0")))) {
  106.             t = x;
  107.             x = y;
  108.             y = t.mod(y);
  109.         }
  110.         if (x.equals(new BigInteger("1")))
  111.             return false;
  112.         else
  113.             return true;
  114.     }

  115.     public BigInteger bigRandom(int numDigits) {
  116.         // 产生一个随机大整数,各位上的数字都是随机产生的,首位不为 0
  117.         StringBuffer s = new StringBuffer("");
  118.         for (int i = 0; i < numDigits; i++)
  119.             if (i == 0)
  120.                 s.append(randomDigit(false));
  121.             else
  122.                 s.append(randomDigit(true));
  123.         return (new BigInteger(s.toString()));
  124.     }

  125.     private StringBuffer randomDigit(boolean isZeroOK) {
  126.         // 产生一个随机的数字(字符串形式的),isZeroOK 决定这个数字是否可以为 0
  127.         int index;
  128.         if (isZeroOK)
  129.             index = (int) Math.floor(Math.random() * 10);
  130.         else
  131.             index = 1 + (int) Math.floor(Math.random() * 9);
  132.         return (digits[index]);
  133.     }

  134.     private static StringBuffer[] digits = {
  135.             new StringBuffer("0"),
  136.             new StringBuffer("1"), new StringBuffer("2"),
  137.             new StringBuffer("3"), new StringBuffer("4"),
  138.             new StringBuffer("5"), new StringBuffer("6"),
  139.             new StringBuffer("7"), new StringBuffer("8"), new StringBuffer("9")};

  140.     public BigInteger nextPrime(BigInteger start) {
  141.         if (isEven(start))
  142.             start = start.add(ONE);
  143.         else
  144.             start = start.add(TWO);
  145.         if (start.isProbablePrime(ERR_VAL))
  146.             return (start);
  147.         else
  148.             return (nextPrime(start));
  149.     }

  150.     private static boolean isEven(BigInteger n) {
  151.         // 测试一个大整数是否为偶数
  152.         return (n.mod(TWO).equals(ZERO));
  153.     }
  154. }
复制代码
回复

使用道具 举报

8

主题

18

帖子

108

积分

注册会员

Rank: 2

积分
108
 楼主| 发表于 2022-6-2 21:24:01 | 显示全部楼层
ECC
原理
1、用户A选定一条椭圆曲线Ep(a,b),并取椭圆曲线上一点,作为基点G;
2、用户A选择一个私有密钥k,并生成公开密钥K=kG;
3、用户A将Ep(a,b)和点K,G传给用户B;
4、用户B接到信息后 ,将待传输的明文编码到Ep(a,b)上一点M,并产生一个随机整数r;
5、用户B计算点C1=M+rK,C2=rG;
6、用户B将C1、C2传给用户A;
7、用户A接到信息后,计算C1-kC2,结果就是点M。
  1. #include<iostream>
  2. #include<math.h>
  3. #include<time.h>
  4. using namespace std;

  5. class point
  6. {
  7. public:
  8.         int x;
  9.         int y;
  10. };
  11. point P[100];
  12. int num = 0;

  13. //取模
  14. int my_mod(int a, int p)
  15. {
  16.         int i;
  17.         i = a / p;
  18.         int re = a - i * p;
  19.         if (re >= 0)
  20.         {
  21.                 return re;
  22.         }
  23.         else
  24.         {
  25.                 return re + p;
  26.         }
  27. }

  28. int my_pow(int a, int m, int p)
  29. {
  30.         int result = 1;
  31.         for (int i = 0; i < m; i++)
  32.         {
  33.                 result = (result * a) % p;
  34.         }
  35.         return result;
  36. }

  37. int my_sqrt(int s)
  38. {
  39.         int t;
  40.         t = (int)sqrt(s);
  41.         if (t * t == s)
  42.         {
  43.                 return t;
  44.         }
  45.         else {
  46.                 return -1;
  47.         }
  48. }

  49. void all_points(int a, int b, int p)
  50. {
  51.         for (int i = 0; i < p; i++)
  52.         {
  53.                 int s = i * i * i + a * i + b;
  54.                 while (s < 0)
  55.                 {
  56.                         s += p;
  57.                 }
  58.                 s = my_mod(s, p);

  59.                 int re = my_pow(s, (p - 1) / 2, p);
  60.                 if (re == 1)
  61.                 {
  62.                         //求y
  63.                         int n = 1, y;
  64.                         int f = my_sqrt(s);
  65.                         if (f != -1)
  66.                         {
  67.                                 y = f;
  68.                         }
  69.                         else
  70.                         {
  71.                                 for (; n <= p - 1;)
  72.                                 {
  73.                                         s = s + n * p;
  74.                                         f = my_sqrt(s);
  75.                                         if (f != -1)
  76.                                         {
  77.                                                 y = f;
  78.                                                 break;
  79.                                         }
  80.                                         n++;
  81.                                 }
  82.                         }
  83. y = my_mod(y, p);
  84.                         P[num].x = i;
  85.                         P[num].y = y;
  86.                         num++;
  87.                         if (y != 0)
  88.                         {
  89.                                 P[num].x = i;
  90.                                 P[num].y = (p - y) % p;
  91.                                 num++;
  92.                         }
  93.                 }
  94.         }
  95. }

  96. void show()
  97. {
  98.         for (int i = 0; i < num; i++)
  99.         {
  100.                 cout << P[i].x << " " << P[i].y << endl;
  101.         }
  102. }


  103. int extend(int a, int b, int& x, int& y)
  104. {
  105.         if (b == 0)
  106.         {
  107.                 x = 1;
  108.                 y = 0;
  109.                 return a;
  110.         }
  111.         int r = extend(b, a % b, x, y);
  112.         int t = x;
  113.         x = y;
  114.         y = t - a / b * y;
  115.         return r;
  116. }

  117. //递归扩展欧几里得求逆
  118. int inv(int a, int b)
  119. {
  120.         int x, y;
  121.         int r = extend(a, b, x, y);
  122.         if (r != 1)
  123.         {
  124.                 return 0;
  125.         }
  126.         x = x % b;
  127.         if (x < 0)
  128.         {
  129.                 x = x + b;
  130.         }
  131.         return x;
  132. }


  133. //加法运算
  134. point add(point p1, point p2, int a, int p)
  135. {
  136.         long t; int flag = 0;
  137.         int x1 = p1.x; int y1 = p1.y;
  138.         int x2 = p2.x; int y2 = p2.y;
  139.         int tx, ty; int x3, y3;

  140.         if ((x2 == x1) && (y2 == y1))
  141.         {
  142.                 //相同点
  143.                 if (y1 == 0)
  144.                 {
  145.                         flag = 1;
  146.                 }
  147.                 else
  148.                 {
  149.                         t = (3 * x1 * x1 + a) * inv(2 * y1, p) % p;
  150.                 }
  151.         }
  152.         else
  153.         {
  154.                 //不同点
  155.                 ty = y2 - y1;
  156.                 tx = x2 - x1;
  157.                 while (tx < 0)
  158.                 {
  159.                         tx = tx + p;
  160.                 }
  161.                 while (ty < 0)
  162.                 {
  163.                         ty = ty + p;
  164.                 }

  165.                 if (tx == 0 && ty != 0)
  166.                 {
  167.                         flag = 1;
  168.                 }
  169.                 else
  170.                 {
  171.                         //点不相等
  172.                         t = ty * inv(tx, p) % p;
  173.                 }
  174.         }

  175.         if (flag == 1)
  176.         {
  177.                 //无限点
  178.                 p2.x = -1;
  179.                 p2.y = -1;
  180.         }
  181.         else
  182.         {
  183.                 x3 = (t * t - x1 - x2) % p;
  184.                 y3 = (t * (x1 - x3) - y1) % p;
  185.                 while (x3 < 0)
  186.                 {
  187.                         x3 += p;
  188.                 }
  189.                 while (y3 < 0)
  190.                 {
  191.                         y3 += p;
  192.                 }
  193.                 p2.x = x3;
  194.                 p2.y = y3;
  195.         }
  196.         return p2;
  197. }

  198. //随机选取一个生成元并计算阶
  199. int jie(point& pp, int a, int p)
  200. {
  201.         int ii = rand() % num;
  202.         point P0 = P[ii];
  203.         point p1, p2;
  204.         int number = 1;
  205. p1.x = P0.x; p2.x = P0.x;
  206.         p1.y = P0.y; p2.y = P0.y;
  207.         while (true)
  208.         {
  209.                 p2 = add(p1, p2, a, p);
  210.                 if (p2.x == -1 && p2.y == -1)
  211.                 {
  212.                         break;
  213.                 }
  214.                 number++;
  215.                 if (p2.x == p1.x)
  216.                 {
  217.                         break;
  218.                 }
  219.         }
  220.         pp.x = p1.x;
  221.         pp.y = p1.y;
  222.         int n = ++number;
  223.         return n;
  224. }

  225. //素数判断
  226. bool judge(int num)
  227. {
  228.         bool ret = true;
  229.         int ubound = sqrt(num) + 1;
  230.         for (int i = 2; i < ubound; i++)
  231.         {
  232.                 if (num % i == 0)
  233.                 {
  234.                         ret = false;
  235.                         break;
  236.                 }
  237.         }
  238.         return ret;
  239. }

  240. //计算kG
  241. point cal(point G, int k, int a, int p)
  242. {
  243.         point temp = G;
  244.         for (int i = 0; i < k - 1; i++)
  245.         {
  246.                 temp = add(temp, G, a, p);
  247.         }
  248.         return temp;
  249. }

  250. int main()
  251. {
  252.         srand(time(NULL));
  253.         int a, b, p;
  254.         point generator; int n;
  255.         char SE[10];
  256.         char CR[10];

  257.         cout << "请输入椭圆曲线群(a,b,p):";
  258.         cin >> a >> b >> p;
  259.         cout << "请输入明文:";
  260.         cin >> SE;
  261.         cout << "请输入密钥:";
  262.         cin >> CR;

  263.         //计算所有点
  264.         all_points(a, b, p);
  265.         //选取生成元,直到阶为素数
  266.         do
  267.         {
  268.                 n = jie(generator, a, p);
  269.         } while (judge(n) == false);
  270.         cout << endl << "选取生成元(" << generator.x << "," << generator.y << "),阶为:" << n << endl;
  271.         //选取私钥
  272.         int ka = int(CR[0]) % (n - 1) + 1;//选取使用的密钥
  273.         point pa = cal(generator, ka, a, p);//计算公钥
  274.         cout << "私钥:" << ka << endl;
  275.         cout << "公钥:(" << pa.x << "," << pa.y << ")" << endl;

  276.         //加密
  277.         int k = 0;//随机数k
  278.         k = rand() % (n - 2) + 1;
  279.         point C1 = cal(generator, k, a, p);//计算C1

  280.         //m嵌入到椭圆曲线
  281.         int t = rand() % num; //选择映射点
  282.         point Pt = P[t];
  283.         point P2 = cal(pa, k, a, p);
  284.         point Pm = add(Pt, P2, a, p);
  285.         cout << endl << "要发送的密文:" << endl;
  286.         cout << "kG=(" << C1.x << "," << C1.y << "),pt+kPa=(" << Pm.x << "," << Pm.y << ")";
  287.         int C[100];
  288.         cout << ",C = { ";
  289.         for (int i = 0; i < strlen(SE); i++)
  290.         {
  291.                 C[i] = int(SE[i]) * Pt.x + Pt.y;//选取要加密的明文
  292.                 cout << C[i] << " ";
  293.         }
  294.         cout << "}" << endl;


  295.         //解密
  296.         point temp, temp1;
  297.         int m;
  298.         temp = cal(C1, ka, a, p);
  299.         temp.y = 0 - temp.y;
  300.         temp1 = add(Pm, temp, a, p);//求解Pt
  301.         printf("\n解密结果:\n");
  302.         for (int i = 0; i < strlen(SE); i++)
  303.         {
  304.                 m = (C[i] - temp1.y) / temp1.x;
  305.                 printf("%c", char(m));//输出密文
  306.         }
  307.         printf("\n");

  308.         return 0;
  309. }
复制代码
回复

使用道具 举报

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

本版积分规则

教学服务系统

GMT+8, 2025-4-30 01:29 , Processed in 0.014862 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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