RSA算法中根据公钥求私钥
-
什么是RSA算法
-
选择两个大素数p, q ;
计算n=pq, ø(n) = (p-1) (q-1) ;
-
公钥的产生
随机地选择e,
满足1< e < ø(n),gcd(e, ø(n)) = 1
-
私钥的产生
求解同余方程:
ed ≡ 1 mod ø(n), 0 ≤ d ≤n
-
-
私钥d如何由e计算得出,也就是求e关于ø(n)的乘法逆元
使用下面介绍的扩展欧几里得算法
背景知识
欧几里得算法
问题描述:已知a,b,求gcd(a,b).也就是a与b的最大公约数
算法:辗转相除法
基于gcd(a,b)=gcd(b,a%b)
//java代码
public static int void gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
贝祖定理
如果a、b是整数,那么一定存在整数x、y使得ax+by=gcd(a,b)。
换句话说,如果ax+by=c有解,那么c一定是gcd(a,b)的若干倍。(可以来判断一个这样的式子有没有解)
扩展欧几里得算法
问题描述:整数二元一次不定方程问题。
形如ax+by=c(a,b均不为0)的方程,a,b,c都是整数,求(x,y)的整数解。
x,y其中一个很有可能为负数
算法:
-
判断是否有解,使用贝祖定理
如果有解,可以先求ax+by=gcd(a,b)的解,ax+by=c的解只是前者的c/gcd(a,b)倍而已
当然,如果有解的话肯定不止一对
x = x 0 + b / g c d ( a , b ) ∗ t x = x~0~+b/gcd(a,b)*t x=x 0 +b/gcd(a,b)∗t
y = y 0 − a / g c d ( a , b ) ∗ t y = y~0~ - a/gcd(a,b)*t y=y 0 −a/gcd(a,b)∗t
-
使用扩展欧几里得算法求解(x,y)
① a x + b y = g c d ( a , b ) ax + by = gcd(a,b) ax+by=gcd(a,b)
② b x 1 + ( a % b ) y 1 = g c d ( b , a % b ) bx1 + (a\%b)y1 = gcd(b,a\%b) bx1+(a%b)y1=gcd(b,a%b)
根据a%b = a - a/b*b,替换上式a%b
a/b中的/指的是整除结果
b x 1 + ( a − a / b ∗ b ) y 1 = g c d ( b , a % b ) bx1 + (a-a/b*b)y1 = gcd(b,a\%b) bx1+(a−a/b∗b)y1=gcd(b,a%b)
整理一下得
③ a y 1 + b ( x 1 − a / b ) y 1 = g c d ( b , a % b ) ay1 + b(x1 - a/b)y1 = gcd(b,a\%b) ay1+b(x1−a/b)y1=gcd(b,a%b)
因为 g c d ( a , b ) = g c d ( b , a % b ) gcd(a,b) = gcd(b,a\%b) gcd(a,b)=gcd(b,a%b)
对比①③得
x = y 1 x = y1 x=y1
y = x 1 − a / b ∗ y 1 y = x1 - a/b*y1 y=x1−a/b∗y1
以上过程完全可以用递归实现
基准情形:b=0时
有 a ∗ 1 + b ∗ 0 = g c d a*1 + b*0 = gcd a∗1+b∗0=gcd
一步步返回x1,y1就可以求出最终的特解x,y
import java.util.Arrays; public class ExEuclid { public static void main(String[] args) { long[] longs = exEuclid(7, 20); System.out.println(Arrays.toString(longs)); } public static long[] exEuclid(long a,long b){ long[] result = new long[2]; //基准情况 if(b==0){//a*1 + b*0 = gcd,x=1,y=0 result[0] = 1; result[1] = 0; return result; } long[] tmp = new long[2]; tmp = exEuclid(b,a%b); /* x = y1 y = (x1 - a/b)*y1 */ result[0] = tmp[1]; result[1] = tmp[0] - a/b*tmp[1]; return result; } }
求乘法逆元
上面说了这么多,到底如何求乘法逆元呢?
ed ≡ 1 mod ø(n)如何求d
将上式换一种写法ed + kø(n) =1,是不是有一种熟悉的感觉,这不就是一种特殊的扩展欧几里得嘛。ø(n)已知,而e是自己选的与ø(n)互素的一个数,gcd(e,ø(n))=1。 d就相当于x,k就相当于y, 利用上面的扩展欧几里得算法就可以求出私钥d,当然也能求出k,但这不是我们关心的东西。
最后
终于是搞懂了扩展欧几里得算法,呼!