跨越千年的RSA算法.docx
《跨越千年的RSA算法.docx》由会员分享,可在线阅读,更多相关《跨越千年的RSA算法.docx(30页珍藏版)》请在冰豆网上搜索。
跨越千年的RSA算法
跨越千年的RSA算法
大升刷票整理
数论,数学中的皇冠,最纯粹的数学。
早在古希腊时代,人们就开始痴迷地研究数字,沉浸于这个几乎没有任何实用价值的思维游戏中。
直到计算机诞生之后,几千年来的数论研究成果突然有了实际的应用,这个过程可以说是最为激动人心的数学话题之一。
最近我在《程序员》杂志上连载了《跨越千年的RSA算法》,但受篇幅限制,只有一万字左右的内容。
其实,从数论到RSA算法,里面的数学之美哪里是一万字能扯完的?
在写作的过程中,我查了很多资料,找到了很多漂亮的例子,也积累了很多个人的思考,但最终都因为篇幅原因没有加进《程序员》的文章中。
今天,我想重新梳理一下线索,把所有值得分享的内容一次性地呈现在这篇长文中,希望大家会有所收获。
需要注意的是,本文有意为了照顾可读性而牺牲了严谨性。
很多具体内容都仅作了直观解释,一些“显然如此”的细节实际上是需要证明的。
如果你希望看到有关定理及其证明的严格表述,可以参见任意一本初等数论的书。
把本文作为初等数论的学习读物是非常危险的。
最后,希望大家能够积极指出文章中的缺陷,我会不断地做出修改。
=======更新记录=======
2012年12月15日:
发布全文。
========目录========
(一)可公度线段
(二)中国剩余定理
(三)扩展的辗转相除
(四)Fermat小定理
(五)公钥加密的可能性
(六)RSA算法
(一)可公度线段
Euclid,中文译作“欧几里得”,古希腊数学家。
他用公理化系统的方法归纳整理了当时的几何理论,并写成了伟大的数学著作《几何原本》,因而被后人称作“几何学之父”。
有趣的是,《几何原本》一书里并不全讲的几何。
全书共有十三卷,第七卷到第十卷所讨论的实际上是数论问题——只不过是以几何的方式来描述的。
在《几何原本》中,数的大小用线段的长度来表示,越长的线段就表示越大的数。
很多数字与数字之间的简单关系,在《几何原本》中都有对应的几何语言。
例如,若数字a是数字b的整倍数,在《几何原本》中就表达为,长度为a的线段可以用长度为b的线段来度量。
比方说,黑板的长度是2.7米,一支铅笔的长度是18厘米,你会发现黑板的长度正好等于15个铅笔的长度。
我们就说,铅笔的长度可以用来度量黑板的长度。
如果一张课桌的长度是117厘米,那么6个铅笔的长度不够课桌长,7个铅笔的长度又超过了课桌长,因而我们就无法用铅笔来度量课桌的长度了。
哦,当然,实际上课桌长相当于6.5个铅笔长,但是铅笔上又没有刻度,我们用铅笔来度量课桌时,怎么知道最终结果是6.5个铅笔长呢?
因而,只有a恰好是b的整数倍时,我们才说b可以度量a。
给定两条长度不同的线段a和b,如果能够找到第三条线段c,它既可以度量a,又可以度量b,我们就说a和b是可公度的(commensurable,也叫做可通约的),c就是a和b的一个公度单位。
举个例子:
1英寸和1厘米是可公度的吗?
历史上,英寸和厘米的换算关系不断在变,但现在,英寸已经有了一个明确的定义:
1英寸精确地等于2.54厘米。
因此,我们可以把0.2毫米当作单位长度,它就可以同时用于度量1英寸和1厘米:
1英寸将正好等于127个单位长度,1厘米将正好等于50个单位长度。
实际上,0.1毫米、0.04毫米、(0.2/3)毫米也都可以用作1英寸和1厘米的公度单位,不过0.2毫米是最大的公度单位。
等等,我们怎么知道0.2毫米是最大的公度单位?
更一般地,任意给定两条线段后,我们怎么求出这两条线段的最大公度单位呢?
在《几何原本》第七卷的命题2当中,Euclid给出了一种求最大公度单位的通用算法,这就是后来所说的Euclid算法。
这种方法其实非常直观。
假如我们要求线段a和线段b的最大公度单位,不妨假设a比b更长。
如果b正好能度量a,那么考虑到b当然也能度量它自身,因而b就是a和b的一个公度单位;如果b不能度量a,这说明a的长度等于b的某个整倍数,再加上一个零头。
我们不妨把这个零头的长度记作c。
如果有某条线段能够同时度量b和c,那么它显然也就能度量a。
也就是说,为了找到a和b的公度单位,我们只需要去寻找b和c的公度单位即可。
怎样找呢?
我们故技重施,看看c是否能正好度量b。
如果c正好能度量b,c就是b和c的公度单位,从而也就是a和b的公度单位;如果c不能度量b,那看一看b被c度量之后剩余的零头,把它记作d,然后继续用d度量c,并不断这样继续下去,直到某一步没有零头了为止。
我们还是来看一个实际的例子吧。
让我们试着找出690和2202的公度单位。
显然,1是它们的一个公度单位,2也是它们的一个公度单位。
我们希望用Euclid的算法求出它们的最大公度单位。
首先,用690去度量2202,结果发现3个690等于2070,度量2202时会有一个大小为132的零头。
接下来,我们用132去度量690,这将会产生一个690-132×5=30的零头。
用30去度量132,仍然会有一个大小为132-30×4=12零头。
再用12去度量30,零头为30-12×2=6。
最后,我们用6去度量12,你会发现这回终于没有零头了。
因此,6就是6和12的一个公度单位,从而是12和30的公度单位,从而是30和132的公度单位,从而是132和690的公度单位,从而是690和2202的公度单位。
我们不妨把Euclid算法对a和b进行这番折腾后得到的结果记作x。
从上面的描述中我们看出,x确实是a和b的公度单位。
不过,它为什么一定是最大的公度单位呢?
为了说明这一点,下面我们来证明,事实上,a和b的任意一个公度单位一定能够度量x,从而不会超过x。
如果某条长为y的线段能同时度量a和b,那么注意到,它能度量b就意味着它能度量b的任意整倍数,要想让它也能度量a的话,只需而且必需让它能够度量c。
于是,y也就能够同时度量b和c,根据同样的道理,这又可以推出y一定能度量d……因此,最后你会发现,y一定能度量x。
用现在的话来讲,求两条线段的最大公度单位,实际上就是求两个数的最大公约数——最大的能同时整除这两个数的数。
用现在的话来描述Euclid算法也会简明得多:
假设刚开始的两个数是a和b,其中a>b,那么把a除以b的余数记作c,把b除以c的余数记作d,c除以d余e,d除以e余f,等等等等,不断拿上一步的除数去除以上一步的余数。
直到某一次除法余数为0了,那么此时的除数就是最终结果。
因此,Euclid算法又有一个形象的名字,叫做“辗转相除法”。
辗转相除法的效率非常高,刚才大家已经看到了,计算690和2202的最大公约数时,我们依次得到的余数是132,30,12,6,做第5次除法时就除尽了。
实际上,我们可以大致估计出辗转相除法的效率。
第一次做除法时,我们是用a来除以b,把余数记作c。
如果b的值不超过a的一半,那么c更不会超过a的一半(因为余数小于除数);如果b的值超过了a的一半,那么显然c直接就等于a-b,同样小于a的一半。
因此,不管怎样,c都会小于a的一半。
下一步轮到b除以c,根据同样的道理,所得的余数d会小于b的一半。
接下来,e将小于c的一半,f将小于d的一半,等等等等。
按照这种速度递减下去的话,即使最开始的数是上百位的大数,不到1000次除法就会变成一位数(如果算法没有提前结束的话),交给计算机来执行的话保证秒杀。
用专业的说法就是,辗转相除法的运算次数是对数级别的。
很长一段时间里,古希腊人都认为,任意两条线段都是可以公度的,我们只需要做一遍辗转相除便能把这个公度单位给找出来。
事实真的如此吗?
辗转相除法有可能失效吗?
我们至少能想到一种可能:
会不会有两条长度关系非常特殊的线段,让辗转相除永远达不到终止的条件,从而根本不能算出一个“最终结果”?
注意,线段的长度不一定(也几乎不可能)恰好是整数或者有限小数,它们往往是一些根本不能用有限的方式精确表示出来的数。
考虑到这一点,两条线段不可公度完全是有可能的。
为了让两条线段辗转相除永远除不尽,我们有一种绝妙的构造思路:
让线段a和b的比值恰好等于线段b和c的比值。
这样,辗转相除一次后,两数的关系又回到了起点。
今后每一次辗转相除,余数总会占据除数的某个相同的比例,于是永远不会出现除尽的情况。
不妨假设一种最为简单的情况,即a最多只能包含一个b的长度,此时c等于a-b。
解方程a/b=b/(a-b)可以得到a:
b=1:
(√5 -1)/2,约等于一个大家非常熟悉的比值1:
0.618。
于是我们马上得出:
成黄金比例的两条线段是不可公度的。
更典型的例子则是,正方形的边长和对角线是不可公度的。
让我们画个图来说明这一点。
如图,我们试着用辗转相除求出边长AB和对角线AC的最大公度单位。
按照规则,第一步我们应该用AB去度量AC,假设所得的零头是EC。
下一步,我们应该用EC去度量AB,或者说用EC去度量BC(反正正方形各边都相等)。
让我们以EC为边作一个小正方形CEFG,容易看出F点将正好落在BC上,同时三角形AEF和三角形ABF将会由于HL全等。
因此,EC=EF=BF。
注意到BC上已经有一段BF和EC是相等的了,因而我们用EC去度量BC所剩的零头,也就相当于用EC去度量FC所剩的零头。
结果又回到了最初的局面——寻找正方形的边长和对角线的公度单位。
因而,辗转相除永远不会结束。
线段AB的长度和线段AC的长度不能公度,它们处于两个不同的世界中。
如果正方形ABCD的边长1,正方形的面积也就是1。
从上图中可以看到,若以对角线AC为边做一个大正方形,它的面积就该是2。
因而,AC就应该是一个与自身相乘之后恰好等于2的数,我们通常把这个数记作√2 。
《几何原本》的第十卷专门研究不可公度量,其中就有一段1和√2 不可公度的证明,但所用的方法不是我们上面讲的这种,而更接近于课本上的证明:
设√2 =p/q,其中p/q已是最简分数,但推着推着就发现,这将意味着p和q都是偶数,与最简分数的假设矛盾。
用今天的话来讲,1和√2 不可公度,实际上相当于是说√2 是无理数。
因此,古希腊人发现了无理数,这确实当属不争的事实。
奇怪的是,无理数的发现常常会几乎毫无根据地归功于一个史料记载严重不足的古希腊数学家Hippasus。
根据各种不靠谱的描述,Hippasus的发现触犯了Pythagoras(古希腊哲学家)的教条,最后被溺死在了海里。
可公度线段和不可公度线段的概念与有理数和无理数的概念非常接近,我们甚至可以说明这两个概念是等价的——它们之间有一种很巧妙的等价关系。
注意到,即使a和b本身都是无理数,a和b还是有可能被公度的,例如a=√2 并且b=2·√2 的时候。
不过,有一件事我们可以肯定:
a和b的比值一定是一个有理数。
事实上,可以证明,线段a和b是可公度的,当且仅当a/b是一个有理数。
线段a和b是可公度的,说明存在一个c以及两个整数m和n,使得a=m·c,并且b=n·c。
于是a/b=(m·c)/(n·c)=m/n,这是一个有理数。
反过来,如果a/b是一个有理数,说明存在整数m和n使得a/b=m/n,等式变形后可得a/m=b/n,令这个商为c,那么c就可以作为a和b的公度单位。
有时候,“是否可以公度”的说法甚至比“是否有理”更好一些,因为这是一个相对的概念,不是一个绝对的概念。
当我们遇到生活当中的某个物理量时,我们绝不能指着它就说“这是一个有理的量”或者“这是一个无理的量”,我们只能说,以某某某(比如1厘米、1英寸、0.2毫米或者一支铅笔的长度等等)作为单位来衡量时,这是一个有理的量或者无理的量。
考虑到所选用的单位长度本身也是由另一个物理量定义出来的(比如1米被定义为光在真空中1秒走过的路程的1/299792458),因而在讨论一个物理量是否是有理数时,我们讨论的其实是两个物理量是否可以被公度。
(二)中国剩余定理
如果两个正整数的最大公约数为1,我们就说这两个数是互质的。
这是一个非常重要的概念。
如果a和b互质,这就意味着分数a/b已经不能再约分了,意味着a×b的棋盘的对角线不会经过中间的任何交叉点,意味着循环长度分别为a和b的两个周期性事件一同上演,则新的循环长度最短为a·b。
最后一点可能需要一些解释。
让我们来举些例子。
假如有1路和2路两种公交车,其中1路车每6分钟一班,2路车每8分钟一班。
如果你刚刚错过两路公交车同时出发的壮景,那么下一次再遇到这样的事情是多少分钟之后呢?
当然,6×8=48分钟,这是一个正确的答案,此时1路公交车正好是第8班,2路公交车正好是第6班。
不过,实际上,在第24分钟就已经出现了两车再次同发的情况了,此时1路车正好是第4班,2路车正好是第3班。
但是,如果把例子中的6分钟和8分钟分别改成4分钟和7分钟,那么要想等到两车再次同发,等到第4×7=28分钟是必需的。
类似的,假如某一首歌的长度正好是6分钟,另一首歌的长度正好是8分钟,让两首歌各自循环播放,6×8=48分钟之后你听到的“合声”将会重复,但实际上第24分钟就已经开始重复了。
但若两首歌的长度分别是4分钟和7分钟,则必需到第4×7=28分钟之后才有重复,循环现象不会提前发生。
究其原因,其实就是,对于任意两个数,两个数的乘积一定是它们的一个公倍数,但若这两个数互质,则它们的乘积一定是它们的最小公倍数。
事实上,我们还能证明一个更强的结论:
a和b的最大公约数和最小公倍数的乘积,一定等于a和b的乘积。
在第四节中,我们会给出一个证明。
很多更复杂的数学现象也都跟互质有关。
《孙子算经》卷下第二十六问:
“今有物,不知其数。
三、三数之,剩二;五、五数之,剩三;七、七数之,剩二。
问物几何?
答曰:
二十三。
”翻译过来,就是有一堆东西,三个三个数余2,五个五个数余3,七个七个数余2,问这堆东西有多少个?
《孙子算经》给出的答案是23个。
当然,这个问题还有很多其他的解。
由于105=3×5×7,因而105这个数被3除、被5除、被7除都能除尽。
所以,在23的基础上额外加上一个105,得到的128也是满足要求的解。
当然,我们还可以在23的基础上加上2个105,加上3个105,等等,所得的数都满足要求。
除了形如23+105n的数以外,还有别的解吗?
没有了。
事实上,不管物体总数除以3的余数、除以5的余数以及除以7的余数分别是多少,在0到104当中总存在唯一解;在这个解的基础上再加上105的整倍数后,可以得到其他所有的正整数解。
后人将其表述为“中国剩余定理”:
给出m个两两互质的整数,它们的乘积为P;假设有一个未知数M,如果我们已知M分别除以这m个数所得的余数,那么在0到P-1的范围内,我们可以唯一地确定这个M。
这可以看作是M的一个特解。
其他所有满足要求的M,则正好是那些除以P之后余数等于这个特解的数。
注意,除数互质的条件是必需的,否则结论就不成立了。
比如说,在0到7的范围内,除以4余1并且除以2也余1的数有2个,除以4余1并且除以2余0的数则一个也没有。
从某种角度来说,中国剩余定理几乎是显然的。
让我们以两个除数的情况为例,来说明中国剩余定理背后的直觉吧。
假设两个除数分别是4和7。
下表显示的就是各自然数除以4和除以7的余数情况,其中xmody表示x除以y的余数,这个记号后面还会用到。
i
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
imod4
0
1
2
3
0
1
2
3
0
1
2
3
0
1
2
3
0
1
2
3
imod7
0
1
2
3
4
5
6
0
1
2
3
4
5
6
0
1
2
3
4
5
i
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
imod4
0
1
2
3
0
1
2
3
0
1
2
3
0
1
2
3
0
1
2
3
imod7
6
0
1
2
3
4
5
6
0
1
2
3
4
5
6
0
1
2
3
4
imod4的值显然是以4为周期在循环,imod7的值显然是以7为周期在循环。
由于4和7是互质的,它们的最小公倍数是4×7=28,因而(imod4,imod7)的循环周期是28,不会更短。
因此,当i从0增加到27时,(imod4,imod7)的值始终没有出现重复。
但是,(imod4,imod7)也就只有4×7=28种不同的取值,因而它们正好既无重复又无遗漏地分给了0到27之间的数。
这说明,每个特定的余数组合都在前28项中出现过,并且都只出现过一次。
在此之后,余数组合将产生长度为28的循环,于是每个特定的余数组合都将会以28为周期重复出现。
这正是中国剩余定理的内容。
中国剩余定理有很多漂亮的应用,这里我想说一个我最喜欢的。
设想这样一个场景:
总部打算把一份秘密文件发送给5名特工,但直接把文件原封不动地发给每个人,很难保障安全性。
万一有特工背叛或者被捕,把秘密泄露给了敌人怎么办?
于是就有了电影和小说中经常出现的情节:
把绝密文件拆成5份,5名特工各自只持有文件的1/5。
不过,原来的问题并没有彻底解决,我们只能祈祷坏人窃取到的并不是最关键的文件片段。
因此,更好的做法是对原文件进行加密,每名特工只持有密码的1/5,这5名特工需要同时在场才能获取文件全文。
但这也有一个隐患:
如果真的有特工被抓了,当坏人们发现只拿到其中一份密码没有任何用处的同时,特工们也会因为少一份密码无法解开全文而烦恼。
此时,你或许会想,是否有什么办法能够让特工们仍然可以恢复原文,即使一部分特工被抓住了?
换句话说,有没有什么密文发布方式,使得只要5个人中半数以上的人在场就可以解开绝密文件?
这样的话,坏人必须要能操纵半数以上的特工才可能对秘密文件造成实质性的影响。
这种秘密共享方式被称为(3,5)门限方案,意即5个人中至少3人在场才能解开密文。
利用中国剩余定理,我们可以得到一种巧妙的方案。
回想中国剩余定理的内容:
给定m个两两互质的整数,它们的乘积为P;假设有一个未知数M,如果我们已知M分别除以这m个数所得的余数,那么在0到P-1的范围内,我们可以唯一地确定这个M。
我们可以想办法构造这样一种情况,n个数之中任意m个的乘积都比M大,但是任意m-1个数的乘积就比M小。
这样,任意m个除数就能唯一地确定M,但m-1个数就不足以求出M来。
Mignotte门限方案就用到了这样一个思路。
我们选取n个两两互质的数,使得最小的m个数的乘积比最大的m-1个数的乘积还大。
例如,在(3,5)门限方案中,我们可以取53、59、64、67、71这5个数,前面3个数乘起来得200128,而后面两个数相乘才得4757。
我们把文件的密码设为一个4757和200128之间的整数,比如123456。
分别算出123456除以上面那5个数的余数,得到19、28、0、42、58。
然后,把(53,19)、(59,28)、(64,0)、(67,42)、(71,58)分别告诉5名特工,也就是说特工1只知道密码除以53余19,特工2只知道密码除以59余28,等等。
这样,根据中国剩余定理,任意3名特工碰头后就可以唯一地确定出123456,但根据2名特工手中的信息只能得到成百上千个不定解。
例如,假设我们知道了x除以59余28,也知道了x除以67余42,那么我们只能确定在0和59×67-1之间有一个解913,在913的基础上加上59×67的整倍数,可以得到其他满足要求的x,而真正的M则可以是其中的任意一个数。
不过,为了让Mignotte门限方案真正可行,我们还需要一种根据余数信息反推出M的方法。
换句话说,我们需要有一种通用的方法,能够回答《孙子算经》中提出的那个问题。
我们会在下一节中讲到。
(三)扩展的辗转相除
中国剩余定理是一个很基本的定理。
很多数学现象都可以用中国剩余定理来解释。
背九九乘法口诀表时,你或许会发现,写下3×1,3×2,...,3×9,它们的个位数正好遍历了1到9所有的情况。
7的倍数、9的倍数也是如此,但2、4、5、6、8就不行。
3、7、9这三个数究竟有什么特别的地方呢?
秘密就在于,3、7、9都是和10互质的。
比如说3,由于3和10是互质的,那么根据中国剩余定理,在0到29之间一定有这样一个数,它除以3余0,并且除以10余1。
它将会是3的某个整倍数,并且个位为1。
同样的,在0到29之间也一定有一个3的整倍数,它的个位是2;在0到29之间也一定有一个3的整倍数,它的个位是3……而在0到29之间,除掉0以外,3的整倍数正好有9个,于是它们的末位就正好既无重复又无遗漏地取遍了1到9所有的数字。
这表明,如果a和n互质,那么a·xmodn=1、a·xmodn=2等所有方程都是有解的。
18世纪的法国数学家ÉtienneBézout曾经证明了一个基本上与