这是错误的原因吗

Is there a reason this is wrong?

本文关键字:错误      更新时间:2024-09-23
#include <iostream>
#include <bits/stdc++.h>
#include <numeric>
using namespace std;
int
gcd (int a, int b)
{
if (a == 0)
return b;
return gcd (b % a, a);
}
int
phi (unsigned int n)
{
unsigned int result = 1;
for (int i = 2; i < n; i++)
if (gcd (i, n) == 1)
result++;
return result;
}
int
gen_priv_n (int p1, int p2)
{
int n = phi (p1) * phi (p2);
return n;
}
int
gen_pub_n (int p1, int p2)
{
int n = (p1 * p2);
return n;
}
int
gen_priv_key (int n, int e)
{
int x = (phi (e) * n + 1) / e;
return x;
}
int
encrypt (int n, int e, int data)
{
int crypt_data = int (pow (data, e)) % n;
return crypt_data;
}
int
decrypt (int c, int d, int n)
{
int data = int (pow (c, d)) % n;
return data;
}
int
main ()
{
int ph1 = 53;
int ph2 = 59;
int e = 3;
int message = 89;

int pub_n = gen_pub_n (ph1, ph2);
cout << "PUBN " << pub_n << "n";
int priv_n = gen_priv_n (ph1, ph2);
cout << "PRIVN " << priv_n << "n";
int d = gen_priv_key (gen_priv_n (ph1, ph2), e);
cout << "PRIVKEY " << d << "n";
int c = encrypt (pub_n, e, message);
cout << "ENCRYPTED " << c << "n";
int data = decrypt (c, d, pub_n);
cout << "MESSAGE " << data;
}

PUBN、PRIVN、PRIVKEY和ENCRYPTED都返回预期的数字,但是解密函数应该返回89(消息变量(,但没有。我假设运算的代码顺序有算术错误,但我不确定。这个问题可以指出吗?

变量的结果是:

  • PUBN 3127
  • 私人3016
  • PRIVKEY 2011
  • 加密1394
  • 消息-763<--意外结果,应为89

解密(和加密(函数被破坏了,因为它(a(超出了int的平台表示,(b(首先不必要地使用pow来执行。

在您的琐碎示例中,您应该使用一种名为模链接的技术。关键在于以下几点。

(a * b) % n == ((a % n) * (b % n)) % n

在您的情况下,您正在执行简单的求幂运算。这意味着,例如^2%n将是:

(a * a) % n = ((a % n) * (a % n)) % n

类似地,^3%n是:

(a * a * a) % n = (((a % n) * (a % n)) % n) * (a % n)) % n

只要没有乘积项对超过你的平台表示(在你的情况下没有(,使用模链接可以计算出原本会非常大的乘积计算模N。

整数pow的一个平凡版本如下:

int int_pow_mod(int c, int d, int n)
{
int res = 1;
// may as well only do this once
c %= n;
// now loop.
for (int i=0; i<d; ++i)
res = (res * c) % n;
return res;
}

明白,这不是银弹。你可以很容易地设计出一种c,它仍然能生产出超过INT_MAX的产品,但在你的情况下,由于你对起始材料的选择,这不会发生。一个通用的解决方案将使用一个允许超过平台int表示的大数字库。无论如何,这样做应该会带来你想要的,如下所示:

#include <iostream>
using namespace std;
unsigned int gcd(unsigned int a, unsigned int b)
{
if (a == 0)
return b;
return gcd(b % a, a);
}
int phi(unsigned int n)
{
unsigned int result = 1;
for (unsigned int i = 2; i < n; i++)
if (gcd(i, n) == 1)
result++;
return result;
}
int gen_priv_n(int p1, int p2)
{
int n = phi(p1) * phi(p2);
return n;
}
int gen_pub_n(int p1, int p2)
{
int n = (p1 * p2);
return n;
}
int gen_priv_key(int n, int e)
{
int x = (phi(e) * n + 1) / e;
return x;
}
int int_pow_mod(int c, int d, int n)
{
int res = 1;
// may as well only do this once
c %= n;
// now loop.
for (int i=0; i<d; ++i)
res = (res * c) % n;
return res;
}
int encrypt(int n, int e, int data)
{
int crypt_data = int_pow_mod(data, e, n);
return crypt_data;
}

int decrypt(int c, int d, int n)
{
int data = int_pow_mod(c, d, n);
return data;
}
int main()
{
int ph1 = 53;
int ph2 = 59;
int e = 3;
int message = 89;
int pub_n = gen_pub_n(ph1, ph2);
cout << "PUBN " << pub_n << "n";
int priv_n = gen_priv_n(ph1, ph2);
cout << "PRIVN " << priv_n << "n";
int d = gen_priv_key(gen_priv_n(ph1, ph2), e);
cout << "PRIVKEY " << d << "n";
int c = encrypt(pub_n, e, message);
cout << "ENCRYPTED " << c << "n";
int data = decrypt(c, d, pub_n);
cout << "MESSAGE " << data;
}

输出

PUBN 3127
PRIVN 3016
PRIVKEY 2011
ENCRYPTED 1394
MESSAGE 89