先亮剑,c++的代码实现:
int calc_d(int e, int n) {
if (e == 1||n==1) return 1;
int d1 = calc_d(e%n, n%e);
return d1 - n / e * ((1 - e * d1) / (n%e));
}
RSA算法规定:
p*q =N
(p-1) * (q-1) = n
e*d ≡(1 mod n)
其中在e和n已知的情况下,求d
例:令p=47,q=71,求用RSA算法加密的公钥和私钥。
计算如下:
(1)n=pq=47*71=3337;
(2)φ(n)=(p-1)*(q-1)=46*70=3220;
(3)随机选取e=79(满足与3220互质的条件);
(4)则私钥d应该满足:79*d mod 3220 = 1;
d如何解??
79*d mod 3220 = 1等价于存在一个整数k,使得79*d+3220*k=1
79*d+3220*k=1 拆解为 79*d+(79*40+60)*k=1 化简为79*(d+40*k)+60*k=1 记为79*d1+60*k=1 且d = d1-40*k
也就是说,我只要计算出79*d1+60*k=1的d1和k,就可以计算出79*d+3220*k=1的d和k,计算出d1,d即为d1-40*k
好,我们继续碾转
79*d1+60*k=1 拆解为 (60+19)*d1+60*k=1 化简为19*d1+60*(k+d1)=1 记为19*d1+60*k1=1 且k=k1-d1
19*d1+60*k1=1 拆解为 19*d1+(3*19+3)*k1=1 化简为19*(d1+3*k1)+3*k1=1记为19*d2+3*k1=1 且d1=d2-3*k1
19*d2+3*k1=1 拆解为 (3*6+1)*d2+3*k1=1 化简为d2+3*(k1+6*d2)=1 记为d2+3*k2=1 且k1=k2-6*d2
到此就结束了,最终化为d2+3*k2=1,当k2取0时候,d2其值为1,满足该式子
因此k2=0,d2=1,将其值带入,计算易得k1=0-6*1=-6,d1=1-3*-6=19,k=-6-19=-25,d=19-40*-25=1019
验算下:k=-25,d=1019带入79*d+3220*k=1 ,验算成立
上面的实例是为了入手,现在进行纯粹的公式推导
要想计算关于e,n的对应的d,n和e肯定是互质的,因此不会有0或者n=e这些情况的
问题为:存在整数k,使得e*d+n*k=1,求d
记函数f(e,n)是求d函数,所以d=f(e,n)
下面的/是指整数除法,计算的商向下取整
当假设n比e大
e*d+n*k=1拆解为e*d+(n/e*e+n%e)*k=1 化简为e*(d+n/e*k)+(n%e)*k=1,记为e*d1+(n%e)*k=1,且d=d1-n/e*k
e*d1+(n%e)*k=1用函数表示为d1=f(e,n%e),由于n比e大,可以写为d1 = f(e%n,n%e),d=d1-n/e*k
因为e*d1+(n%e)*k=1,所以k=(1-e*d1)/(n%e), 所以d=d1-n/e*((1-e*d1)/(n%e))
因此d=d1-n/e*((1-e*d1)/(n%e)) => f(e,n)=f(e%n,n%e)-n/e*((1-e*f(e%n,n%e))/(n%e))
当假设n比e小:
e*d+n*k=1拆解为(e/n*n+e%n)*d+n*k=1化简为(e%n)*d+n*(e/n*d+k)=1, 记为(e%n)*d+n*k1=1,且k=k1-e/n*d+k
(e%n)*d+n*k1=1用函数表示为d=f(e%n,n), 由于e比n大,可以写为d=f(e%n,n%e)
因此d=f(e%n,n%e),因为e比n大,所以n/e为0,即d=f(e%n,n%e)=f(e%n,n%e)-n/e*((1-e*f(e%n,n%e))/(n%e))
由此,无论n比e大还是e比n大,其公式都可以用f(e,n)=f(e%n,n%e)-n/e*((1-e*f(e%n,n%e))/(n%e)) 表示
那什么时候结束呢?
这个就是什么时候是显而易见,一眼就可以看出d值的时候,
如e为1时候,k只要取0,e*d+n*k=1,显然d的值为1
如果n为1时候,d取啥整数值都可以,因为都存在k=1-e*d使公式成立,为了方便,d取1好了
因此因为e和n是互质的,e和n在碾转相除的时候,比然会出现一个为1,此时d值取1即可
推导结论:
当n或者e为1时候:d=1
否则d=f(e%n,n%e)-n/e*((1-e*f(e%n,n%e))/(n%e)) ,其中f(e,n)是求d函数,/是除法的商向下取整