深入理解现代加密技术:c++快速幂运算和扩展欧几里得算法在RSA加密中的应用

创作灵感

在探索计算机科学的广阔领域中,我们经常遇到需要将理论知识应用到实践中的机会。特别是在现代加密技术,如RSA加密算法中,理解其背后的数学原理对于加强我们的技术能力至关重要。本文通过分析一个简洁但功能强大的程序,旨在帮助读者深入理解快速幂运算和扩展欧几里得算法,并展示它们是如何在RSA加密技术中发挥关键作用的。

正文

描述

近日来勒索病毒的事件频繁发生,小Y对它的加密原理非常感兴趣,研究了一番相关知识之后,他就来给你看他的加密程序,并给你一段密文,和你炫耀说就算把程序给你看你也破解不出来

你扫了一眼代码发现加密的公式为b=(a^e)%m其中e是质数。

进一步分析发现m=p*q,p和q都为质树,p!=q.

作为一个计算机高手,你早就对加密算法烂熟于心,一眼就看出这个程序的算法和原理,找到了破解的方法,发现小Y疏忽在于给了你一个不够大的m。

你知道解密的公式与加密对称,为a =(b^d)%m。但是你仍然无法心算解出这个d,因此你需要借助计算机来将密文破解。

输入

第一行有一个整数T表示数据组数。(T<=100)

接着有T组数据,每组数据两行

第一行有四个数e、p、q和n,其中e、p、q如题所描述,n表示需要解密的数字序列长度。第二行是需要解密的数字序列a1..an。1<p,q,e<=10^8,p、q、e为质数且p!=q。关$0<=a_i保证解密的结果即原数列的值小于min(p,q)并大于等于0

1<=n<=100

保证m有且仅有两个不同的质因数p和q,并且一定存在一个题中描述的参数d使得解密公式能够无损解密出所有0~min(p,q)-1范围之间的数字

输出

对于每组数据输出一行,表示解密后的数字序列,数字之间以空格隔开。

样例输入

1

5 19 29 3

335 440 514

样例输出

65 67 77

提示

对于样例,存在d=101使得解密公式成立。

注章m和ai的大小可能超过int的范围

#include <iostream>

// 快速幂运算函数 - 进行模幂运算
long long quick_pow(long long a, long long b, long long m) {
    long long ans = 1;
    a %= m;
    // 加速幂运算
    while(b) {
        // 若b为奇数
        if(b & 1) {
            ans = ans * a % m;  // 更新结果
        }
        b >>= 1;  // 将b除以2
        a = a * a % m;  // 更新底数
    }
    return ans;
}

// 欧几里得算法计算最大公约数
long long gcd(long long a, long long b) { 
    return b ? gcd(b, a % b) : a; 
}

// 扩展欧几里得算法,用于寻找一组x和y使得ax+by=gcd(a,b)
void exgcd(long long a, long long b, long long *x, long long *y) {
    if(!b) {
        *x = 1;
        *y = 0;
        return;
    }
    exgcd(b, a % b, y, x);
    *y -= a / b * (*x);  // 更新y
}

// 计算a关于模m下的逆元
long long inv(long long a, long long m) {
    long long x, y;
    exgcd(a, m, &x, &y);  // 找到一对x和y满足ax+my=1
    // 返回逆元,注意要取模m的余数且结果为正
    return (x % m + m) %m;
}

int main(){
    int T;
    std::cin >> T;  //读取组数据量
    while(T--) {
        long long e, p, q, n;
        std::cin >> e >> p >> q >> n; // 读取数据
        long long phi =(p-1) * (q-1);  // 计算欧拉函数值(公式: φ(pq) = (p-1)(q-1))
        long long d = inv(e, phi);  // 找到e关于phi的模逆元
        long long m = p * q; // 计算m值
        while(n--) {
            long long a;
            std::cin >> a;  // 读取待解密的数字
            std::cout << quick_pow(a, d, m) << " ";  // 解密并输出
        }
        std::cout << "\n";
    }
    return 0;
}

 

 

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值