我正在实现RSA算法,用于加密和解密,如下所示:

http://www.di-mgt.com.au/rsa_alg.html

但是无法理解 key 生成中随机质数生成部分。
因此,我将两个质数作为用户的输入。我也难以生成e。所以我把它设为常数(e = 17)

某些质数输入在Linux下的gcc中可正常工作(即正确地编码和解码),而在Windows下的devcpp中则不能。 (例如53,61)

这是 key 生成代码:

/* Generates private and public keys and saves into two separate files */
void keygen()
{
    int p,q,phi,d,e,n,s;

    printf("\n Enter two prime numbers: ");
    scanf("%d%d",&p,&q);

    n = p*q;
    phi=(p-1)*(q-1);

    e=17;

    // selec d such that d*e = 1+ k*phi for some integer k.
    d = 0;
    do
    {
        d++;
        s = (d*e)%phi;
    }while(s!=1);

    printf("\n public key: { e=%d n=%d }",e,n);
    printf("\n private key: { d=%d n=%d }\n",d,n);

}

在质数和e代中需要帮助和建议。

最佳答案

所以您已经知道e * d必须等于1 mod phi(n)

由于您知道phi(n),因此可以使用扩展的欧几里得算法(EEA)计算元组(e,d):

为e选择一个整数(通常是一个小整数;这将是公共(public)指数,使用较小的指数加密会更快),它小于phi(n)且大于2(?...我认为)

当您有e的候选者时,计算e和phi(n)的最大公约数(gcd)...应该为1 ...如果不是,请为e选择一个新的候选者并重复(因为将没有模数相反,换句话说,对于此e和phi(n)不存在私有(private)指数d

在知道gcd(e,phi(n))== 1之后,您可以使用EEA计算d(或者作为一种捷径,直接计算EEA,因为它还会提供GCD ...如果不是1,请选择一个新的e的值)

EEA(快速而肮脏的用于计算模逆):

想象一个有3列的表格:

假设这些列被命名为:b,q和t

因此该表的行将如下所示:

b0,q0,t0
b1,q1,t1
...
(等等)

前2行将被初始填充。
对于所有其他行,可以将一条适用于前两行的规则应用于最终两行的值

前两行是:

phi(n),NO_VALUE,0
e,楼板(phi(n)/e),1

创建下一行的命令规则是:(其中[]是用于选择该行的索引运算符)

b [i] = b [i-2] mod b [i-1]
q [i] = b [i-1]/b [i](整数除法,无分数...)
t [i] = t [i-2]-(q [i-1] * t [i-1])

您可以在b [i]变为0或1时中止该方案...最后一行实际上不需要q ...

因此,如果b [i]为0,则b [i-1]不能为1,因为如果计算b [i-1]为1,则应该中止。

如果您达到b [i] == 0,则b [i-1]是您的gcd ...因为它不是1,所以您需要为e输入一个新值

如果b [i] == 1,则您的gcd为1,并且存在一个逆...,即t [i](如果t为负,则添加phi(n))

具有真实值的示例:

假设phi(n)是120
假设我们选择23作为e的候选者

我们的表如下所示:

b     q     t
120   –     0
23    5     1
5     4     -5
3     1     21
2     1     -26
1     2     47

最后计算的b为1,因此=> gcd(23,120)== 1(证明:倒数存在)
最后计算的t为47 => 23 * 47 mod 120 == 1(t为倒数)

10-07 12:10
查看更多