公钥密码加密解密(RSA,ELGamal,ECC椭圆曲线)

以下是RSA加解密的python实现

 

 1 import math
 2 
 3 #欧拉函数
 4 def euler_phi(n):
 5     return sum(math.gcd(n, i) == 1 for i in range(1, n+1))
 6 
 7 #扩展欧几里得
 8 def exgcd(a, b):
 9     if b == 0:
10         return 1, 0, a
11     else:
12         x, y, q = exgcd(b, a % b)
13         x, y = y, x - (a//b) * y
14         return x, y, q
15 
16 def encrypt(plaintext):
17     c = (int(plaintext) ** e) % n
18     return c
19 
20 def decrypt(cryptotext):
21     ming = (int(cryptotext) ** d) % n
22     return ming
23 
24 
25 p=int(input("请输入P:"))
26 q=int(input("请输入Q:"))
27 n=p*q
28 f_n=(p-1)*(q-1)
29 e=int(input("请输入公钥e:"))
30 d,a,b=exgcd(e,f_n)
31 d = (d % f_n + f_n) % f_n   # 防止出现负数
32 print("私钥是:"+str(d))
33 m=input("请输入明文:")
34 cryptotext=encrypt(m)
35 plaintext=decrypt(cryptotext)
36 print("密文是:",cryptotext)
37 print("解密后的明文是:",plaintext)

 

  下图是运行及结果

 

 

=======================================================================================================================

以下是ELGamal加解密的python实现

 1 p=int(input("请输入素数p:"))
 2 g=int(input("请输入生成元g:"))
 3 x=int(input("请输入私钥x∈(1,p-1):"))
 4 y=(g**x) % p
 5 print("公钥为(" + str(y) +','+ str(g) +','+ str(p) + ')'+'\n'+"私钥为:"+str(x))
 6 k=int(input("请输入随机数k∈(1,p-1):"))
 7 m=int(input("请输入明文m:"))
 8 
 9 # 加密函数
10 def encrypt(m):
11  c1=(g**k)%p
12  c2=(m*(y**k))%p
13  return (c1,c2)
14 
15 #分数模运算
16 def calculateMod(numerator, denominator, p):
17     numerator_mod_p = (numerator % p + p) % p  # 处理负数情况
18     denominator_mod_p = (denominator % p + p) % p
19 
20     # 计算逆元
21     denominator_inverse = 1
22     for i in range(1, p):
23         # 判断i是否为分母的逆元
24         if (denominator_mod_p * i) % p == 1:
25             denominator_inverse = i
26             break
27 
28     result = (numerator_mod_p * denominator_inverse) % p
29     return result
30 
31 c1,c2=encrypt(m)    #获得密文
32 #解密函数
33 def decrypt(c1,c2):
34     plaintext=calculateMod(c2,c1**x,p)
35     return plaintext
36 
37 print("密文为:"+str(encrypt(m)))
38 print("解密后的明文为:"+str(decrypt(c1,c2)))

 

 

  下图是运行及结果

 

 

 

======================================================================================

下面是ECC椭圆曲线的加解密实现(C++)

  1 #include <vector>
  2 #include <iostream>
  3 #include <cmath>
  4 using namespace std;
  5 
  6 class ellipse         //定义椭圆类
  7 {
  8 public:
  9     int a;             //椭圆的长半轴
 10     int b;            //椭圆的短半轴
 11     int p;           //椭圆所在的有限域Fp
 12     ellipse(int u, int i, int o)   //构造函数
 13     {
 14         a = u;
 15         b = i;
 16         p = o;
 17     };
 18     int count = 0;   //记录点的个数,初始化为0
 19     typedef struct point     //定义点的数据结构
 20     {
 21         int x = 0;
 22         int y = 0;
 23     }Point;
 24     Point P[100];         //储存100个点
 25     void showPoint();     //显示点的函数
 26 };
 27 void ellipse::showPoint()   //显示点的函数定义
 28 {
 29     for (int x = 0; x < p; x++)   //遍历Fp域中的x值
 30     {
 31         int temp = (x * x * x + a * x + b) % p;  //计算y的平方根的值
 32         for (int y = 0; y <= p; y++)   //遍历Fp域中的y值
 33         {
 34             if ((y * y - temp) % p == 0)   //如果y满足椭圆方程
 35             {
 36                 P[count].x = x;            //记录点的x坐标
 37                 P[count].y = y;           //记录点的y坐标
 38                 count++;                  //点的个数加1
 39             }
 40         }
 41     }
 42     //输出点的坐标
 43     for (int j = 0; j < count; j++)
 44     {
 45         cout << "(" << P[j].x << "," << P[j].y << ")";
 46     }
 47 }
 48 
 49 // 计算最大公约数  
 50 int get_gcd(int a, int b) {
 51     if (b == 0)
 52         return a;
 53     return get_gcd(b, a % b);
 54 }
 55 
 56 //分数模运算
 57 int calculateMod(int numerator, int denominator, int p) {
 58     int numeratorModP = (numerator % p + p) % p; // 处理负数情况
 59     int denominatorModP = (denominator % p + p) % p;
 60 
 61     // 计算逆元
 62     int denominatorInverse = 1;
 63     for (int i = 1; i < p; ++i)
 64     {//判断i是否为分母的逆元
 65         if ((denominatorModP * i) % p == 1) {
 66             denominatorInverse = i;
 67             break;
 68         }
 69     }
 70 
 71     int result = (numeratorModP * denominatorInverse) % p;
 72     return result;
 73 }
 74 
 75 // 计算P+Q函数 
 76 vector<int> calculate_p_q(int x1, int y1, int x2, int y2, int a, int b, int p) {
 77     int flag = 1;               //标记PQ是否同号,1为同号,-1为异号
 78     int member;                  //PQ的分子
 79     int denominator;           //PQ的分母
 80     if (x1 == x2 && y1 == y2) {    //P、Q重合,则P+Q=3P       
 81         member = 3 * (x1 * x1) + a;
 82         denominator = 2 * y1;
 83     }
 84     else {                       //P、Q不重合
 85         member = y2 - y1;
 86         denominator = x2 - x1;
 87 
 88     }
 89 
 90     //将分子和分母化为最简
 91     int gcd_value = get_gcd(member, denominator);
 92     member = member / gcd_value;
 93     denominator = denominator / gcd_value;
 94 
 95     // 计算x3,y3 
 96     int x3 = calculateMod(member * member - x1 * denominator * denominator - x2 * denominator * denominator, denominator * denominator, p);
 97     int y3 = calculateMod(member * (x1 - x3) - denominator * y1, denominator, p);
 98     vector<int> result;  //定义一个向量用于返回值
 99     result.push_back(x3);  //将x3的值添加到result中
100     result.push_back(y3);  //将y3的值添加到result中
101     return result;      //返回result
102 }
103 
104 // 计算nP函数
105 vector<int> calculate_np(int x, int y, int n, int a, int b, int p) {
106     // 记录P的坐标
107     int x_old = x;
108     int y_old = y;
109     vector<int> result;  // 用于返回P的值
110     for (int i = 0; i < n - 1; i++) {
111         // 调用calculate_p_q()函数计算P+P的值
112         vector<int> P_add_P = calculate_p_q(x_old, y_old, x_old, y_old, a, b, p);
113         // 更新P的坐标值为P+P
114         x_old = P_add_P[0];
115         y_old = P_add_P[1];
116     }
117     // 将P的新坐标添加到result中
118     result.push_back(x_old);
119     result.push_back(y_old);
120     return result;
121 }
122 vector<int> encrypt(int g1,int g2,int d,int a,int b,int p)
123 {
124     //加密过程
125     vector<int> publickey = calculate_np(g1, g2, d, a, b, p);//计算公钥
126     cout << "公钥为:" << '(' << publickey[0] << ',' << publickey[1] << ')' << endl;
127     int k;
128     cout << "请输入随机数k:";
129     cin >> k;
130     vector<int> kY = calculate_np(publickey[0], publickey[1], k, a, b, p);
131     vector<int> c1, c2;//密文
132     c1 = calculate_np(g1, g2, k, a, b, p);//计算c1
133     int x, y;
134     cout << "请输入明文x, y:";
135     cin >> x >> y;
136     c2 = calculate_p_q(x, y, kY[0], kY[1], a, b, p);//计算c2
137     //储存密文
138     vector<int> result;
139     result.push_back(c1[0]); result.push_back(c1[1]); result.push_back(c2[0]); result.push_back(c2[1]);
140     return result;
141 }
142 
143 //解密过程
144 vector<int> decrypt(vector<int> c,int d,int a,int b,int p)
145 {
146     vector<int> dc1 = calculate_np(c[0], c[1], d, a, b, p);
147     dc1[1] = -dc1[1];   // -dc1
148     vector<int> result;
149     result = calculate_p_q(c[2],c[3],dc1[0],dc1[1], a, b, p);
150     return result;
151 }
152 
153 
154 int main()
155 {
156     int a, b, p;
157     cout << "请输入a,b,p:";//生成元
158     cin >> a >> b >> p;
159     ellipse A(a, b, p);
160     cout << "椭圆曲线上的点集为:";
161     A.showPoint();
162     int g1, g2;
163     cout << endl << "请输入生成元:";
164     cin >> g1 >> g2;
165     int d;//私钥
166     cout << "请输入私钥d:";
167     cin >> d;
168     //加密过程
169     vector<int> c= encrypt(g1, g2, d, a, b, p);
170     cout << "密文为:" << endl;
171     cout << '(' << c[0] << ',' << c[1] << ')';
172     cout << '(' << c[2] << ',' << c[3] << ')';
173 
174     //解密过程
175     vector<int>m= decrypt(c,d, a, b, p);
176     cout <<endl <<"明文为:" << endl;
177     cout << '(' << m[0] << ',' << m[1] << ')';
178 }

 

  下图是运行及结果

 

重邮信息安全应用密码学请自取(doge)

posted @ 2023-06-01 22:41  gaifa_gafin  阅读(251)  评论(0编辑  收藏  举报