RSA算法思想
bool isprime_Miller_Rabin(ZZ p)
{
if (p == 2)return true;
if (p <= 1)return false;
ZZ d = p - 1;
long s = 0;
while (d % 2 == 0) {
d /= 2;
s++;
}
for (long i = 0; i < 100; i++) {
ZZ a;
RandomBnd(a, p - 2);
a++;
if (GCD(a, p) != 1)
return false;
ZZ x = PowerMod(a, d, p);
if (x == 1 || x == p - 1)
continue;
for (long r = 0; r <= s - 1; r++) {
x = PowerMod(a, pow(2, r) * d, p);
if (x == p - 1)
break;
if (x == 1)
return false;
}
if (x != p - 1)
return false;
}
return true;
}
2. 模幂运算函数
函数接受底数 a,指数 b 和模数 m。在函数中创建一个大整数类型变量 r,并初始化为 1。使用循环,从 i = 0 开始,循环条件为 i < b,即执行 b 次循环。在每次循环中,将 r 更新为 r * a mod m。循环结束后,返回最终的结果 r。r 即为 a 的 b 次幂模 m 的结果。
ZZ powermod(ZZ a, ZZ b, ZZ m)
{
ZZ r = ZZ(1);
for (ZZ i = ZZ(0);i < b;i++)
{
r = r * a % m;
}
return r;
}
3.power函数
ZZ pow(ZZ a, ZZ b)
{
ZZ r = ZZ(1);
for (ZZ i = ZZ(0);i < b;i++)
{
r = r * a;
}
return r;
}
4.生成大素数
ZZ get_prime()
{
while (1)
{
ZZ a = GenPrime_ZZ(1024);
if (isprime_Miller_Rabin(a))
return a;
}
}
5.得到fn
ZZ get_fn(ZZ p, ZZ q)
{
ZZ fn = (p - 1) * (q - 1);
return fn;
}
6.得到公钥
函数输入参数 fn 是欧拉函数φ(n)的值,其中 n 是两个质数 p 和 q 的乘积。在函数中使用了一个无限循环,并在每次循环中生成一个随机数 e,范围限定在 [0, fn-1] 之间(包括 0 和 fn-1)。然后通过判断条件来筛选出符合要求的 e 值。使用 GCD(e, fn) 函数计算 e 和 fn 的最大公约数。首先判断最大公约数是否等于 1,即 e 和 fn 是否互质。然后判断 e 是否等于 1,因为 e 不能等于 1。如果满足上述两个条件,则将找到的 e 值作为结果返回。
ZZ get_e(ZZ fn)
{
while (1)
{
ZZ e = RandomBnd(fn);
if (GCD(e, fn) == 1 && e != 1)
return e;
}
}
7.得到私钥
函数输入参数 e 是公钥的指数值,而 fn 是欧拉函数φ(n)的值,其中 n 是两个质数 p 和 q 的乘积。RSA 加密算法中,私钥由两个参数组成:n 和 d。其中,n 是两个质数 p 和 q 的乘积,而 d 是满足以下条件的整数:e * d ≡ 1 (mod φ(n)),0 < d < φ(n)。在这个函数中,使用了 InvMod(e, fn) 函数来计算 e 在模 fn 下的逆元。根据扩展欧几里得算法的原理,e 和 fn 互质时,InvMod(e, fn) 函数可以计算出使得 e * d ≡ 1 (mod fn) 成立的最小正整数 d。这个最小正整数就是私钥参数 d 的值。最后返回d。
ZZ get_d(ZZ fn, ZZ e)
{
ZZ d = InvMod(e, fn);
return d;
}
8.得到n=p*q
ZZ get_pq(ZZ p, ZZ q)
{
ZZ n = p * q;
return n;
}
9.加密算法
加密函数传入明文m,公钥e和n。在函数中,使用PowerMod函数进行幂模运算,将明文m用指数e进行加密,并将结果存储在变量c中。然后将c作为函数的返回值。
ZZ encrypt(ZZ m, ZZ e, ZZ n)
{
ZZ c = PowerMod(m, e, n);
return c;
}
10.解密算法
函数传入参数c是明文结果加密的的密文,私钥对(d,n)。使用 PowerMod 函数来计算密文 c 的 d 次方模 n 的结果,得到的结果存储在变量 M 中。然后使用 to_int 函数将 ZZ 类型的 M 转换为 int 类型的 MM,并将其作为结果返回。
int decrypt(ZZ c, ZZ d, ZZ n)
{
ZZ M = PowerMod(c, d, n);
int MM = to_int(M);
return MM;
}
主函数👇
int main() {
ZZ p = get_prime();
ZZ q = get_prime();
ZZ fn = get_fn(p, q);
ZZ e = get_e(fn);
ZZ d = get_d(fn, e);
ZZ n = get_pq(p, q);
cout << "p:" << p << "\n" << "q:" << q << "\n" << "fn:" << fn << "\n" << "e:" << e << "\n" << "d:" << d << "\n" << "n:" << n << endl;
int m[x] = { ...};//自己定义一个明文,x是明文的位数
int l = 9;
cout<<endl;
for (int i = 0;i < l;i++)
{
cout << m[i];
}
cout << endl;
ZZ* c = new ZZ[l];
//encrypting
auto start_time = std::chrono::high_resolution_clock::now();
for (int i = 0;i < l;i++)
{
ZZ C = PowerMod(ZZ(m[i]), e, n);
c[i] = C;
}
auto end_time = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
std::cout << "Running time: " << duration.count() << " ms" << std::endl;
cout<<endl;
for (int i = 0;i < l;i++)
{
cout << c[i];
}
cout << endl;
//decrypt
auto start_time1 = std::chrono::high_resolution_clock::now();
int* MM = new int[l];
for (int i = 0;i < l;i++)
{
int mm = decrypt(c[i], d, n);
MM[i] = mm;
}
cout << endl;
auto end_time1 = std::chrono::high_resolution_clock::now();
auto duration1 = std::chrono::duration_cast<std::chrono::milliseconds>(end_time1 - start_time1);
std::cout << "Running time: " << duration1.count() << " ms" << std::endl;
cout<<endl;
for (int i = 0;i < l;i++)
{
cout << MM[i];
}
cout << endl;
return 0;
}
本文详细介绍了RSA算法的工作原理,涉及素性检测、模幂运算、大素数生成、公钥和私钥的生成,以及加密和解密的具体步骤,展示了RSA算法在信息安全中的关键作用。
3965

被折叠的 条评论
为什么被折叠?



