ElGamal加密体制的公私密钥生成过程如下:
1.加密过程
2.解密过程
输入
加密:
第一行输入0,表示加密操作
第二行输入素数p
第三行输入生成元g
第四行输入私钥
第五行输入明文(明文中的字母按照英文字母表a=00,b=01,…,z=25编码)
第六行输入对应的随机数
解密:
第一行输入1,表示解密操作
第一行输入素数p
第二行输入私钥x
第三行输入密文
输出
加密:
第一行输出公钥中的y
第二行输出密文
解密:
输出明文
输入样例1 <-复制
0
13171
2
23
bupt
31 16
输出样例1
11852
(4782,8218) (12852,4511)
输入样例2 <-复制
1
13171
23
(4782,8218) (12852,4511)
输出样例2
bupt
提示
数据格式为十进制
#include <iostream>
#include <string>
#include <stack>
using namespace std;
int getlen(int num_1) {
int num = num_1;
int count = 0;
while (num != 0) {
num /= 10;
count++;
}
return count;
}
void extend_gcd(long long a, long long b, long long& x, long long& y) { //求逆元的调用方法
if (b == 0) {
x = 1, y = 0;
return;
}
extend_gcd(b, a % b, x, y);
long long tmp = x;
x = y;
y = tmp - (a / b) * y;
}
long long mod_inverse(long long a, long long mod) {//求逆元的外部调用函数
long long x, y;
extend_gcd(a, mod, x, y);
while (x < 0) {
x = x + mod;
}
return x;
}
int main() {
int operate, p, g, x, y, c1, c2;
string ming;
cin >> operate;
if (operate == 0) {
cin >> p >> g >> x >> ming;
y = g;
for (int i = 1; i < x; i++) {
y = y * g;
y %= p;
}
cout << y << endl;
int len_1 = ming.length();
int len = getlen(p) - 1;
int group = len_1 * 2 / len;
int* r = new int[group];
for (int i = 0; i < group; i++) {
cin >> r[i];
}
for (int i = 0; i < group; i++) {
int c, c_1, c_2;
c = 0;
for (int j = i * len / 2; j < (i + 1) * len / 2; j++) {
int num = ming[j] - 'a';
c = c * 100 + num;
}
c_1 = g;
for (int j = 1; j < r[i]; j++) {
c_1 = c_1 * g;
c_1 %= p;
}
c_2 = c * y;
c_2 %= p;
for (int j = 1; j < r[i]; j++) {
c_2 = c_2 * y;
c_2 %= p;
}
if (i != group) {
cout << "(" << c_1 << "," << c_2 << ") ";
}
else {
cout << "(" << c_1 << "," << c_2 << ")";
}
}
}
else if (operate == 1) {
string Miwen;
cin >> p >> x;
getchar();
getline(cin, Miwen);
int len = Miwen.length();
int len_1 = getlen(p) - 1;
int flag = 0;
int num = 0;
int c1, c2;
for (int i = 0; i < len; i++) {
if (Miwen[i] >= '0' && Miwen[i] <= '9') {
num = num * 10 + (Miwen[i] - '0');
}
if (Miwen[i] == ',') {
c1 = num;
num = 0;
}
if (Miwen[i] == ')') {
c2 = num;
num = 0;
int fenmu = c1;
for (int j = 1; j < x; j++) {
fenmu = fenmu * c1;
fenmu %= p;
}
fenmu = mod_inverse(fenmu, p);
int m = (c2 * fenmu) % p;
string newmi = to_string(m);
int newlen = newmi.length();
stack<char> chnum;
for (int i = newlen - 1; i >= 0; i-=2) {
if (i != 0) {
int number = 0;
number = (newmi[i-1] - '0') * 10 + (newmi[i] - '0');
char ch = 'a' + number;
chnum.push(ch);
if (i == 1) {
while (!chnum.empty()) {
char ch = chnum.top();
chnum.pop();
cout << ch;
}
}
}
else if(i==0){
int number = 0;
number = newmi[i] - '0';
char ch = 'a' + number;
chnum.push(ch);
while (!chnum.empty()) {
char ch = chnum.top();
chnum.pop();
cout << ch;
}
}
}
}
}
}
}