如果我将样本输入设为p = 61,q = 53,并且如果我为此特定素数集提供介于1和21之间的消息值,则我的程序会成功加密并将消息解密回正确的原始消息。但是如果我输入p = 61,q = 53且消息值大于21,则无法将消息解密回正确的原始消息。
并且不仅仅是这些特定的素数集。对于任何一对素数,只有一定范围的消息值才能被正确加密和解密。那为什么呢?任何人都可以建议如何解决这个问题吗?
class RSA
{
private:
long int p,q;
long int msg,cipherMsg,plainMsg;
long int n,totient;
long int publicKey,privateKey;
public:
RSA();
void ComputeKeys(long int p1,long int p2,long long int message);
void EncryptMessage();
void DecryptMessage();
};
RSA :: RSA()
{
p=0;q=0;
n=0;totient=0;
publicKey=0;privateKey=0;
msg=0;cipherMsg=0;plainMsg=0;
}
void RSA :: EncryptMessage()
{
int y=1;
cout<<"Encrypting Message....."<<endl;
for(long int i=1;i<=publicKey;i++)
{
y=y*msg;
}
msg=y;
cout<<"m^e:"<<msg<<endl;
cipherMsg= msg%n;
cout<<"Encryption Complete!"<<endl;
cout<<"Cipher Message:"<<cipherMsg<<endl;
}
void RSA :: DecryptMessage()
{
long int y= 1,tmp;
cout<<"Decrypting Message...."<<endl;
for(long int i=1;i<=privateKey;i++)
{
y=y*cipherMsg;
tmp=y;
y=fmod(y,n);
}
cout<<"c^d:"<<tmp<<endl;
plainMsg=y;
cout<<"Decryption Complete!"<<endl;
cout<<"Original Message:"<<plainMsg<<endl;
}
int main()
{
RSA obj;
cout<<"\t------RSA Cryptography------"<<endl;
obj.ComputeKeys(61,53,21);
return 0;
}
(注意,由于专有原因,我没有发布我的ComputeKeys()
方法。但我相信我需要进行修改。)
答案 0 :(得分:2)
看起来像整数溢出给我。现在,你正在计算x y ,并且只有当你完成后,才能获得该结果模型。
您通常希望利用这样一个事实:您可以在整个过程中的每个步骤采用模数,以最大限度地减少避免溢出所需的大小。
模块化电源功能的代码可能如下所示:
template <class T>
T mul_mod(T a, T b, T m) {
if (m == 0) return a * b;
T r = T();
while (a > 0) {
if (a & 1)
if ((r += b) > m) r %= m;
a >>= 1;
if ((b <<= 1) > m) b %= m;
}
return r;
}
template <class T>
T pow_mod(T a, T n, T m) {
T r = 1;
while (n > 0) {
if (n & 1)
r = mul_mod(r, a, m);
a = mul_mod(a, a, m);
n >>= 1;
}
return r;
}
根据您使用的类型和值,此 仍然会溢出,但对于给定类型,它会为 更大的值生成正确的结果一个天真的版本。
另请注意,这通过重复平方来提高功率,使其在处理更大数字时更加实用(基本上,它是O(log N)而不是O(N),N =模数)。
我已在another answer发布了更完整的实施方案。