a∗a∗a∗⋯∗a的简记,意为t个元素a一起运算。理解二
此处的“乘法”就是指传统意义上的乘法,“乘法群”即意为群中的二元运算为乘法。
在这种情况下,乘法群和加法群就有更为明确的定义了:
- 一个群(G,∗)如果被称之为“乘法群”,此时(G,∗)就是(G,×)
- 一个群(G,∗)如果被称之为“加法群”,此时(G,∗)就是(G,+)
只不过在大多数情况下,群论都是在研究乘法群,所以一般在无特别说明的情况下,“群”就是指“乘法群”,即二元运算为乘法的群。
所以对于群的各简记符号,在不特别说明群是加法群的情况下,用“×”替换掉"∗"即可。
总结下来,博主认为第二种理解正确的可能性更大些,后面的内容也会按照第二种理解进行推导。
其实到这里我们可以回顾下数论中原根的定义,为什么ad≡1(modm)中的d必须是正整数呢?这里就不得不提到抽象代数对于“原根”的定义了。
我们后面会提到,数论中原根定义中的a在抽象代数的定义中,其实是某种群的一个元素,而既然已经涉及到群的概念了,那ad必然是个简记法,也就意味着d和a不是一个维度的概念,代表a个数的d也必定是正整数。
关于原根在抽象代数中的具体定义后文会有详细的表述,这里先按下不表。
单位元
单位元又称幺元,一般用e表示。
如果群里存在一个元素e,任何元素与e的运算都是元素本身,就称e是群中的一个单位元。
需要注意的是,每个群只有唯一的单位元。
举个简单的例子,在群(Z,+)中,很明显0就是一个单位元,因为0与任何整数相加都等于这个数本身。
而对于单位元的唯一性很好理解。假设群(G,∗)中有两个不相等的单位元e和e′,那么根据单位元定义,任何元素与单位元运算都是它本身,所以通过e是单位元可以得到
e∗e′=e′
通过e′是单位元也可以得到
e∗e′=e
就有
e=e′
与假设条件冲突。
因为群不一定满足交换律,所以若a,e∈G,只有当且仅当e∗a=a∗e=a时才能说e是群G的单位元,否则只能把满足e∗a=a的e称作左单位元,把满足a∗e=a的e称作右单位元。但又因为一个群中只有一个单位元,所以博主也不知道这个左右单位元的区分有何意义,估计是用在集合上的,或者是别的代数结构里的。
逆元
有了单位元的概念,我们就可以讨论逆元了。
如果对于群里每一个元素,都存在一个元素与它的运算结果等同于单位元e,这两个元素就互为逆元。
同样需要注意的是,群里的每个元素只有唯一的逆元。
元素a的逆元一般表示为a−1,有的元素的逆元是它自己,比如单位元e。
需要注意的是,群的定义中,必须每一个元素都能找到自己的逆元才能称作是群。所以代数结构(Q,×)就不是一个群,虽然具有单位元1(因为1与任何有理数相乘也等于它本身),但是元素0找不到逆元,因为0没有倒数。
类似单位元,逆元也有左逆元和右逆元的概念,但我们可以利用单位元的唯一性证明左右逆元是相等的:
假如群(G,∗)中的元素a有一个左逆元al−1和一个右逆元ar−1,则根据单位元的定义和唯一性我们可以得到:
al−1∗aa∗ar−1=e=e
al−1ar−1=al−1∗e=e∗al−1=ar−1∗e=e∗ar−1
根据群的结合律,就有:
al−1=al−1∗e=al−1∗(a∗ar−1)=(al−1∗a)∗ar−1=e∗ar−1=ar−1
由此可证:
al−1=ar−1
即左右逆元是相等的,也即:
a∗a−1=a−1∗a=e
有了左右逆元相等的性质后,逆元的唯一性也可以用类似的方法证明出来了:
假如群(G,∗)中的元素a有两个逆元b和c,则有:
a∗ba∗c=b∗a=e=c∗a=e
此时根据单位元的定义和单位元的唯一性我们可以得到:
bc=b∗e=e∗b=c∗e=e∗c
根据群的结合律,就有:
b=b∗e=b∗(a∗c)=(b∗a)∗c=e∗c=c
由此可证:
b=c
即元素a只有一个逆元。
逆元的概念可能远比我们想象中的重要,因为逆元主要是用来做逆运算的,而逆运算的复杂度,就与后文要讨论的加密算法的安全性息息相关了。
对于二元运算"+"来说,因为有了“相反数”的概念,我们可以通过加法来实现减法,也就是使用a+(−b)来表示a−b。
对于二元运算"×"来说,因为有了“倒数”的概念,我们可以通过乘法来实现除法,也就是使用a×b1来表示a÷b。
而对于群来说,群虽然只定义了一种运算,但我们可以借助“逆元”,来实现另一种运算,也就是群所定义的运算的逆运算。
博主认为,这才是逆元最大的用处。
群的阶
"阶"这个概念在数学中需要指定定语,在不同的定语下阶的意义完全不同(可以类比上文中的欧拉函数),这里先提一下“群的阶”的概念,后面还会提到“元素的阶”。
每个群都关联了一个集合,集合可以分为有限集和无限集两种,而与之相对应的,群也分为有限群和无限群。
若群(G,∗)中集合G为有限集,则称集合G里的元素个数为群G的阶,记为∣G∣。
若群(G,∗)中集合G为无限集,则称群G的阶为无限阶。
子群
因为群的定义和构造都与集合有关,而集合有子集的概念,并且甚至有相应的运算规律,那群也不例外。
设(G,∗)是群,H是G的非空子集,如果(H,∗)是一个群,则称(H,∗)是(G,∗)的子群。
由此可见,子群的定义并不复杂,因为基本是完全对标的子集的定义。
沿用定义中的例子,G的子群主要分以下两种:
- 平凡子群:({e},∗)、(G,∗)。
- 非平凡子群(又称真子群):(H,∗)且H={e},G。
平凡子群其实就两个,一个就是仅有单位元一个元素的群,另一个就是群G本身,除此之外都是真子群。
阿贝尔群
阿贝尔群又称交换群,意思是满足交换律的群。
如果对于群G中∀a,b∈G,都有
a∗b=b∗a
则称群G为阿贝尔群。
阿贝尔群是非常重要的一种群,因为它的运算同时满足交换律和结合律。
我们都知道,在数的运算中,一旦一种运算同时满足交换律和结合律,那么这种运算往往通过交换律和结合律推导出各种各样的性质,比如幂的交换律等等。群的运算也不意外,一旦一个群是阿贝尔群,那么它将满足以下定律:
- (at)m=atm
- at∗am=at+m
- (a−1)t=(at)−1=a−t
- (a∗b)t=at∗bt
其中的t和m均为整数。
循环群
在密码学涉及的群论内容里,循环群是毫无疑问的核心,因为有大量的公钥密码算法和安全协议是以循环群为基础的。
对于任意群,有一种构造子群很简单的方法。我们都知道在一个群中,群具有封闭性(即群里的每个元素各自运算后的结果都会属于这个群),于是就有:
设(G,∗)是群,a∈G,则群({ai∣i∈Z},∗)必定是G的子群,这种群也叫做“由a生成的循环子群”,通常使用<a>表示(即<a>:={ai∣i∈Z},意为由a生成的G的子群)。
至此,我们可以引出循环群的定义了:
设(G,∗)是群,若∃a∈G,使得
G=<a>={ai∣i∈Z}
则称(G,∗)是由a生成的循环子群(简称G是循环群),称a是循环群(G,∗)的生成元。
也就是说,循环群中所有的元素都可以通过a自运算出来,都具有以a为底的格式。
举个简单的例子,整数加法群(Z,+)就是一个循环群,并且这个循环群有两个生成元:1和−1。
元素的阶
群的阶的概念十分简单(其实就是群中的元素个数),但是元素也有阶的概念,并且定义完全不同。
设(G,∗)是群且a∈G,如果n是满足an=e的最小正整数,则称n是元素a的阶。
其实,这个元素的阶的概念非常有意思,换一种角度思考,它描述的是一个元素到单位元e的距离。有的元素可能自己运算仅两次就等于单位元e,就说明这个元素到达单位元e距离很短(元素的阶仅为2),但是有的元素可能运算无限多次也无法到达单位元e,这种阶就成为无限阶。
元素的阶有一个很重要的性质:
- 对于一个有限循环群,如果它的阶是n,则生成元g的阶也是n。
如果一个群是有限循环群,则生成元g的“产量”即决定了群的大小。当g进行了大于n次的运算后,得出的结果必然是群中已有的元素,所以群的阶和g的阶必定都是n。
公钥密码学的数学核心
在我们理解了抽象代数中的一些基本概念之后,我们才有能力去理解接下来的概念。因为本章节的概念都是需要同时利用数论和抽象代数的知识才能理解透彻的,而本章节的概念才是公钥密码学,甚至是整个密码学的核心。
乘法逆元
在对群中的“逆元”概念有充分理解后,博主终于可以引出模运算中非常重要的概念——“乘法逆元”了。
设a∈Z,n∈N,如果存在z使得az≡1(modn),则称z是模n下a的乘法逆元,记作a−1=z。
没错,“乘法逆元”虽然称为逆元,但其实是模运算的概念之一。
当我们理解了逆元以后,乘法逆元的定义就变得通俗易懂了,我们甚至可以简单理解为:乘法逆元就是乘法群中的逆元。
不过既然乘法逆元是模运算的概念,那我们在使用这个概念的时候,就有一个需要注意的点。
在群中,我们一般会称“两个元素互为逆元”,因为逆元就类似倒数,是一个相对的概念,比如我们只能说2是21的倒数,而不会有"2是一个倒数"这样的说法。
而对于乘法逆元,因为是模运算中的概念,所以我们在使用时这个概念时不仅要指出“相互”的关系,还要指定模。
举个例子,对于2×3≡1(mod5),我们可以这样描述:
- 错误说法:2的乘法逆元是3,2和3互为乘法逆元
- 正确说法:在模5下,2的乘法逆元是3,2和3互为乘法逆元
同余类
同余类
同余类又称剩余类,是数论的基本概念之一,指全体整数按照对一个正整数的同余关系而分成的类。
举个例子,对于整个整数集合Z,所有元素在模5下只会产生5种结果,我们把整数大集合Z以这个结果为依据划分为5个不相交的子集:
- 余数为0时,Z0={⋯,−5,0,5,10,15,⋯}
- 余数为1时,Z1={⋯,−4,1,6,11,16,⋯}
- 余数为2时,Z2={⋯,−3,2,7,12,17,⋯}
- 余数为3时,Z3={⋯,−2,3,8,13,18,⋯}
- 余数为4时,Z4={⋯,−1,4,9,14,19,⋯}
同理可得,对于任意模数n,我们都可以把整数集合Z做如此划分,这些子集就称为模n的同余类。
设a∈Z,n∈N+,如果集合X满足
X={x∈Z∣x≡a(modn)}
则称集合X为模n下的同余类,意为在模n下同余的所有整数组成的集合。
代表元
同余类中每个整数都称作这个同余类的代表元(representative),例如在上面的例子中,−5、0、5、10、15等都是同余类[0]的代表元。
有了代表元以后,我们可以用代表元来表示一个同余类。模n下的同余类,通常取各同余类0到n−1之间最小的代表元a来作为相应同余类的记号,记作[a]n,在不引起歧义时简记为[a]。
由此,前面列举的模5下的5个同余类就可以记为:
[0]5={⋯,−5,0,5,10,15,⋯}[1]5={⋯,−4,1,6,11,16,⋯}[2]5={⋯,−3,2,7,12,17,⋯}[3]5={⋯,−2,3,8,13,18,⋯}[4]5={⋯,−1,4,9,14,19,⋯}
其实在同余类的定义中,在不引起歧义的情况下,[a]形式的简写手法还能再简写为a。
例如[0]、[1]、[2]可简写为0、1、2,[a]∈Zn可简写成a∈Zn。
同时由于同余类的运算法则和模运算完全一致,所以下面的三种写法都是完全等价的:
- [a]n∈Zn,([a]n+[1]n)×([a]n−[1]n)=[a]n2−[1]n
- [a]∈Zn,([a]+[1])×([a]−[1])=[a]2−[1]
- a∈Zn,(a+1)×(a−1)=a2−1
为了表达的直观与方便,网络上的资料大多数都采用了最后一种写法。我们在看到这这种写法时头脑一定要清楚,这里的a和1本质上都是同余类,而不是单纯的整数。
不过在本篇博客中,博主还是尽量选择标准写法,简写有时候自己都能看晕,实在是不利于梳理。
同余类运算
刚刚博主提到了同余类的运算法则。没错,同余类之间是可以进行运算的,虽然每个同余类都是一个集合,但是同余类之间的运算却有一套简单又独特的定义,并不用集合运算“交并差补”那一套。
同余类之间的加法和乘法运算定义如下:
- [a]+[b]:=[a+b]
- [a]×[b]:=[a×b]
其中a和b必定为整数。
注意博主这里的符号使用的是”:=“而不是”=“,因为根据博主查阅到的资料,一般来说同余类之间的运算都是被定义出来的,这可能是因为并不能简单的使用”二元运算“的概念来给两个集合之间的四则运算强加运算法则,也可能有一些博主所不知道的其他的定义或者证明,也请有所了解的大佬在评论区指点一下。
总之,对于同余类运算的具体描述应为:
- 模n下的同余类加法:把[a]+[b]定义为整数a+b所代表的模n下的同余类。
- 模n下的同余类乘法:把[a]×[b]定义为整数a×b所代表的模n下的同余类。
在实际运算时,可以先忽略“[]”,先计算内部整数之间的运算,最后再取模并添加上同余类符号。
举个例子,在模6下,([3]+[4])×[5]=[5],计算过程如下:
([3]6+[4]6)×[5]6=[(3+4)×5]6=[7×5]6=[35]6=[35mod6]6=[5]6
同余类集合
如果我们把每个同余类看作一个元素,那么组成的集合就叫做同余类集合。
模n下的同余类集合一般用Zn表示,那么就有
Zn={[0],[1],[2],⋯,[n−1]}
根据博主的理解,虽然集合Zn和集合Z看似好像内容都是所有整数,但是两个集合是完全不同的两个东西。对于Z来说,集合的构成元素为单个的数,而Zn中构成集合的基本元素为同余类,理解的时候不能再把同余类中的元素拆开讨论,同余类中所有元素既是一个整体。
这个涉及到后面的运算性质,所以需要注意一下把概念区分开。
如果我们这时候在Zn中选择两个元素[a]和[b],并设:
uv=[a]=[b]
根据模运算中乘法逆元的定义我们可以得知,当a×b≡1(modn)时,a和b即在模n下互为乘法逆元。
而根据同余类的运算定理我们知道:
a×b=[a]×[b]=u×v
由此我们可以得出同余类集合中乘法逆元的定义:
对于同余类集合Zn={[0],[1],[2],⋯,[n−1]},设u,v∈Zn,若uv=[1],则称u和v互为乘法逆元。
由此我们可以得出结论:
- 模n下的u和v互为乘法逆元⟺a×b≡1(modn)
翻译过来就是:
- 模n下的u(和v)有乘法逆元⟺a(和b)与n互素
也就是说,并不是所有的同余类都有乘法逆元的。只有那些代表元与模n互素的同余类在Zn中才有乘法逆元。
这个结论非常重要,一定要理解并牢牢记下,马上就会用到。
数论的基石
如果我们去查阅密码学的相关论文,或是网络上的相关资料,经常会看到一个符号"Zn∗"。它就是密码学中大名鼎鼎的”整数模n乘法群“(又称模n既约同余类),它不仅是数论的基石,同时也是公钥密码学的核心概念之一。
现在我们终于具备了能看懂它的基础知识,可以去尝试理解它的性质与神奇之处了。
模n既约同余类
如果我们在同余类中定义符号Zn∗,它并不是一个群,而是一个集合。
模n既约同余类是同余类集合的一种,包含集合Zn中所有具有乘法逆元的同余类,记为:
Zn∗={[a]∣a∈Z,1⩽a⩽n−1,gcd(a,n)=1}
很明显,由之前同余类乘法逆元的定义我们可以知道,Zn∗中的每个同余类,它们的所有代表元都与模n互素。
例如,在模6下我们可以得到:
Z6Z6∗={[0],[1],[2],[3],[4],[5]}={[1],[5]}
其中Z6∗={[1],[5]}的含义是:在模6下,有且只有[1]和[5]这两个同余类中所有的元素与6互素。
Zn和Zn∗之间的关系如下,分为两种情况:
- n为素数时,Zn∗=Zn∖{[0]}。
- n为合数时,Zn∗⊊Zn∖{[0]}。
因为一旦模n为素数,那么对于任意非零整数a必然满足gcd(a,n),此时
Zn∗={[1],[2],[3],⋯,[n−1]}
此时在Zn∗定义里,[a]的取值为1到n−1之间的所有整数。
关于模n为素数的情况,后面会单独介绍。
再回头看欧拉函数,因为欧拉函数φ(n)表示的是小于等于n的正整数中与n互素的数的数目,结合Zn∗={[a]∣a∈Z,1⩽a⩽n−1,gcd(a,n)=1}我们就可以惊讶地发现:欧拉函数定义中“小于等于n的正整数中与n互素的数”其实指的就是Zn∗中的[a]n。
换句话说就是:Zn∗的阶为φ(n)。
我们如果用Zn∗来表示欧拉函数,φ(n)则可定义为:
对于∀n∈N+,φ(n):=∣Zn∗∣,且令φ(1)=1。
在这种情况下,我们就能理解为什么当n取值为素数p时,φ(p)=p−1了。因为当模n为素数时,Zn∗定义中[a]的取值为1到n−1之间的所有整数,这个整数个数即为n−1个。
整数模n乘法群
接下来我们再来看看,Zn∗在数论中的定义——整数模n乘法群。其实这个定义才是用的更为广泛,更加标准的定义。
模n的互素同余类组成一个乘法群,称为整数模n乘法群,记为Zn∗。
其实数论中的这个定义与同余类中的定义并无多少差别,但是唯一的不同是,一个是“同余类”(也就是集合),一个是“群”。也就是说根据群的定义,此处的Zn∗其实是(Zn∗,×)的简写,也可以直接写成Zn×。
既然把Zn∗定义为群,我们可以顺便讨论下它的一些性质:
- Zn∗是一个有限群
- Zn∗中的元素都不是单一整数,而是一个个模n下的同余类(即[a]n)
- Zn∗的单位元是同余类[1]n
- Zn∗的阶是φ(n)
需要注意的是,Zn∗不一定为循环群,所以不一定有生成元。
Zn∗是循环群的条件为:n=1,2,4,pk,2pk(其中p为奇素数,k为正整数)。
这个条件非常重要,后面会用到。
最小简约余数系
如果a≡b(modn),那么gcd(a,n)=gcd(b,n)。也就是说一个数a如果与n互质,那么[a]n里面所有的数都与n互质。因此我们可以从Zn∗中的每个同余类里面抽出一个数来代表对应的同余类。
例如n=8,我们可以将Zn∗写成下面任意一种形式:
- Z8∗={1,3,5,7}
- Z8∗={9,11,13,15}
- Z8∗={1,3,29,87}
通常我们用每个同余类中最小的正整数来表示那个类,这样形成的集合也叫做最小简约余数系。上面提到的Z8∗={1,3,5,7}就是这样一个例子。
一般我们都用模n的最小简约余数系来代表群Zn∗的集合。
群与模运算
在模运算中,原根就是生成元,乘法阶就是元素的阶,原根和乘法阶的性质既可以用模运算的知识来理解,也可以用群论的知识来理解。
乘法阶
乘法阶是模运算中一个很重要的概念。
在模运算中,乘法阶的定义如下:
设a∈Z,gcd(a,n)=1,如果k是满足ak≡1(modn)的最小正整数,则称k是a在模n下的乘法阶,记为ordn(a)。
博主之所以在这里才提出“乘法阶”这个重要概念,因为用Zn∗来定义乘法阶会更容易理解:
设a∈Zn∗,a的乘法阶ordn(a)是满足aordn(a)≡1(modn)的最小正整数。
在这个定义中,元素a不再是一个整数,而是一个同余类。由此我们可以得出这样的结论:
aordn(a)≡1(modn)⟺gcd(aordn(a),n)=1⟺aordn(a)=[1]n
因为[1]n是Zn∗的单位元,结合上文中“元素的阶”的定义我们就会得到一个重要的结论:
- 在Zn∗中,元素的阶就是这个元素的乘法阶。
原根与生成元
既然乘法阶、Zn∗等模运算概念都可以用群论的知识去理解,那么原根也不例外。
相比于前文中原根那晦涩难懂的标准定义,如果我们用乘法阶来定义原根就会通俗很多:
设g∈Z,gcd(g,n)=1,如果
ordn(g)=φ(n)
则称g是模n下的原根。
对于定义中的式子ordn(g)=φ(n),等式左边的ordn(g)指的是g在模n下的乘法阶(也就是满足gk与n互素的情况下,正整数k的最小取值),等式右边的欧拉函数φ(n)则指的是小于等于n的数中与n互素的数目。
根据欧拉定理我们知道,当gcd(g,n)=1时,gφ(n)≡1(modn)。所以若g为模n下的原根,则有:
gordn(g)≡gφ(n)≡1(modn)
并不是所有的整数都存在原根,当且仅当n=1,2,4,pk,2pk(其中p为奇素数,k为正整数)时,模n下才存在原根,这与Zn∗是循环群的条件完全一致!
换一个说法就是,当整数n=1,2,4,pk,2pk(其中p为奇素数,k为正整数)时,n存在原根,Zn∗是循环群。
又因为Zn∗的阶是φ(n),根据原根的定义,原根g的乘法阶也等于φ(n),这就意味着满足gk≡1(modn)的最小正整数k的值与Zn∗的阶相等(都为φ(n)),此时的g通过g1,g2,g3,⋯,gk这样的运算恰好可以生成Zn∗中的所有元素(即此时的Zn∗={[1]n,[2]n,[3]n,⋯,[k]n}),完美符合群论中循环群生成元的定义,于是g就是循环群Zn∗的生成元,总结下来就是:
- 当n=1,2,4,pk,2pk(其中p为奇素数,k为正整数)时,模n下存在原根,原根是Zn∗的生成元,此时的Zn∗是个循环群。
或者换个说法,以下四句话相互等价:
- n=1,2,4,pk,2pk(其中p为奇素数,k为正整数)
- 模n下存在原根
- Zn∗是循环群
- Zn∗的生成元是模n下的原根
至此,博主前面讲到的所有知识几乎都串起来了,就是为了得出上面这个结论。
整数模p乘法循环群
如果说整数模n乘法群(Zn∗)是数论的基石,那么整数模p乘法循环群(Zp∗)就是密码学的基石,因为有大量的公钥算法和安全协议都是基于Zp∗构造的。
Zp∗的定义非常简单,其实就是n为素数时的Zn∗(素数一般都用p表示)。而因为p为素数,由上面的结论可知Zp∗必定是个循环群。
其实研究Zp∗的意义就在于,Zp∗可以完美满足费马小定理的条件,即此时的φ(p)=p−1,根据上面得出的结论,这就意味着:
- Zp∗的阶φ(p)=p−1
- 原根g的乘法阶ordp(g)=φ(p)=p−1
这将又会引申出许许多多的性质,本篇博客就不再往下延申了。
其实到这里,我们终于能想通最开始的那个问题了:
为什么在前面数论中原根的例子中,对于任意素数p,模p下的原根g可以使得gk在1⩽k⩽p−1的情况下,模p的结果各不相等?
在前面,我们举出的例子是对于模p=7下的原根2,有如下关系:
21mod7=222mod7=423mod7=124mod7=225mod7=426mod7=1
我们可以发现,2kmod7的结果在1⩽k⩽6下恰好为1至6间各不相等的整数。
这是因为根据前面的出的重要结论,当模n为素数p时(包含于n=1,2,4,pk,2pk),由p原根g可构成一个整数模p乘法循环群Zp∗。
此时的Zp∗如果用同余类集合来表示的话就很好理解了:
Zp∗={g1,g2,g3,⋯,gp−1}={[g1modp]p,[g2modp]p,[g3modp]p,⋯,[gn−1modp]p}={[1]p,[2]p,[3]p,⋯,[p−1]p}
既然Zp∗是个同余类集合,作为群的时候Zp∗的阶为p−1,集合中不存在两个相等的元素,所以各同余类必然各不相等。
所以gkmodp的结果在1⩽k⩽p−1的时候,恰好可以等于1至p−1间的所有整数。
离散对数问题
至此,本篇博客的内容已经接近尾声,最后博主再补充一下离散对数问题的相关概念以及个人理解作为文章的收尾。
我们再次回顾一下前文中DH密钥交换的流程:
- 爱丽丝和鲍伯相互协商两个数:素数p和它的原根g。
- 爱丽丝选择一个秘密的整数a,计算A=gamodp并发送给鲍伯。
- 鲍伯选择一个秘密的整数b,计算B=gbmodp并发送给爱丽丝。
- 爱丽丝根据自己的a和鲍伯的B,计算出密钥s1=Bamodp=(gbmodp)amodp。
- 鲍伯根据自己的b和爱丽丝的A,计算出密钥s2=Abmodp=(gamodp)bmodp。
其实在DH算法的正式定义中,通讯双方在第一步协商的不是两个数(素数p和它的原根g),这其实只是方便大家理解所用的表述。在最简单、最早提出的DH密钥交换协议中,双方第一步协商的是一个素数p的Zp∗和它的一个生成元g。
在上述流程中,对于攻击者来说,不知道的也就是a、b、s这三个值,其余的p、g、A、B的值都是可以通过手段获取的。
也就是说,只要能获取到a和b中的任意一个数,就能通过
s=Bamodp=Abmodp
得到s的值,进而完成密钥的破解。
如此来说,问题就在于:
对于式子A=gamodp,如何在已知A、g、p的情况下反推出a的值。
b的值亦然。
离散对数
在整数中,离散对数是一种基于同余运算和原根的一种对数运算。
设gcd(g,n)=1,对于模n下的原根g,必存在唯一整数x(0⩽x<φ(n))使得
a≡gx(modn)
此时称x是以g为底的a模n的指标(index)或离散对数(discrete logarithm),简记为x=logg(a)。
需要注意的是,只要是出现“离散对数”这个概念,那么涉及到的底就必须是原根。
有了离散对数的概念,我们可以把上文中a和b的值表示为:
- 对于A=gamodp⟺A≡ga(modp),以g为底的A模p的离散对数a=logg(A)。
- 对于B=gbmodp⟺B≡gb(modp),以g为底的B模p的离散对数b=logg(B)。
问题本质的个人理解
最后来说说博主对离散对数问题本质的个人理解,仅为大家提供一种理解思路,希望能起到抛砖引玉的作用。
我们现在应该可以完全看懂密码学中离散对数问题的正式定义了:
设G是循环群,g∈G是生成元,对于∀y∈G存在正整数x,使得
y=gx
此时称问题“给定y和g,求x”为离散对数问题。
很明显,离散对数问题定义中的x=logg(y),其实对于有限循环群来说,此处需要求的x值即为群G中的元素y的阶,即前面理解的:群G中,元素y到生成元g的"距离",或者说运算次数。
目前来说,计算x的值并没有有效的通用算法。目前公认比较通用的算法就是Trial multiplication算法、Baby-step Giant-step算法、Index Calculus Method算法这三种。拿Trial multiplication算法举例,此算法是最为朴素的算法,核心理念就是暴力破解(brute-force),把所有的可能值都算出来比对。
对于在DH算法中使用的原根g生成的模p下的Zp∗来说,我们知道原根g的乘法阶满足
ordp(g)=φ(p)=p−1
也就是说Zp∗的阶也是p−1。
那么问题来了,在DH密钥交换算法中,p的数值动辄几百上千位(并且一般都用十六进制表示),即便不考虑具体的离散对数计算算法的复杂度,光从这个暴力破解遍历量来看,p−1已经是一个天文数字,这可能也是DH密钥交换算法没有选择Zn∗而是选择素数p为底的Zp∗的重要原因之一。
而这些相关通用算法具体的计算复杂度又涉及到计算复杂性理论,又是一个相对庞大的知识框架,博主精力有限,本篇文章便不再赘述了。
计算复杂性理论
计算复杂性理论(Computational complexity theory)是理论计算机科学和数学的一个分支,它致力于将可计算问题根据它们本身的复杂性分类,以及将这些类别联系起来。一个可计算问题被认为是一个原则上可以用计算机解决的问题,亦即这个问题可以用一系列机械的数学步骤解决,例如算法。
计算复杂性理论所研究的资源中最常见的是时间(要通过多少步才能解决问题)和空间(在解决问题时需要多少内存)。其他资源亦可考虑,例如在并行计算中,需要多少并行处理器才能解决问题。
- 时间复杂度:指在计算机科学与工程领域完成一个算法所需要的时间,是衡量一个算法优劣的重要参数。时间复杂度越小,说明该算法效率越高,则该算法越有价值。
- 空间复杂度:指计算机科学领域完成一个算法所需要占用的存储空间,一般是输入参数的函数。它是算法优劣的重要度量指标,一般来说,空间复杂度越小,算法越好。我们假设有一个图灵机来解决某一类语言的某一问题,设有X个字(word)属于这个问题,把X放入这个图灵机的输入端,这个图灵机为解决此问题所需要的工作带格子数总和称为空间。
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 忘忧草の小破站! 赞助
支付宝
微信