数论基础
数论是研究整数性质的学科,在密码学中广泛应用了数论中一些重要结论,比如素数、离散对数问题等。数论的概念和结论都比较抽象,而且涉及大量的证明,初学时忽略这些细节,而涉及到具体密码算法时掌握更多的细节或许是合理的学习方法。下面将介绍数论中的主要内容,包括整除的整除和同余、素数的基本性质和应用等。
更新历史:
- 2021年07月18日完成初稿
数论的知识是比较抽象的,对于只需要简单的数论背景知识的初学者而言,显然长篇大论般的理论和证明是不利于学习的,因此在这里将数论基础分为了「基础篇」和「扩展篇」,基础篇省去了定理的扩展描述和证明,而扩展篇则增加了数论知识的广度和深度,对于初学者而言可以自学习基础篇了解数论中的几个基本概念即可,等到后面涉及数论知识点后重新翻看基础篇和扩展篇即可。
基础篇
在密码学中,最重要的两大块数论基础知识为整除和同余、素数及其定理,下面将简单介绍关于数论基础知识。
1. 整除和同余
整除是小学阶段的概念,对此不多介绍,只介绍数论中整除的定义与使用的符号。
- 整除:设 a , b , m ∈ Z a, b, m\in Z a,b,m∈Z, ∃ m \exists m ∃m使得 a = m b a = mb a=mb成立,则称非零整数 b b b整除 a a a,记作 b ∣ a b|a b∣a,此时称 b b b是 a a a的因子, a a a是 b b b的倍数。举一些例子,比如 2 ∣ 6 , 3 ∣ 6 2|6, 3|6 2∣6,3∣6等。
除数与被除数
需要熟知一个容易混淆的概念,被除数 ÷ \;\div\; ÷除数 = \;=\; =商…余数,因此整除描述了「除数」整除「被除数」的情况,比如 6 ÷ 3 = 2......0 6\;\div\;3=2......0 6÷3=2......0,描述了 3 3 3整除 6 6 6的情况,在中文中除和除以是不同的概念,一定要区分好。
在上面,假设有 m ∣ a , m ∣ b m|a\;,m|b m∣a,m∣b说明 m m m是 a a a的因子,也是 b b b的因子,因此称 m m m是 a a a和 b b b的公因子,由于 1 1 1是任何整数的因子,故公因子一定存在(至少为 1 1 1),而令人感兴趣的是两个整数的最大公因子(Greatest Common Divisor)是多少。
- 最大公因子:设 a , b , m ∈ Z a, b, m \in Z a,b,m∈Z,而且 m ∣ a , m ∣ b m|a, m|b m∣a,m∣b,若 m m m是整除 a a a和 b b b的最大整数,那么 m m m称为 a a a和 b b b的最大公因子,记作 m = g c d ( a , b ) m = gcd(a, b) m=gcd(a,b)。
互素
利用最大公因子,可以定义一个常用的概念,即互素:称整数 a , b a,b a,b是互素的,当且仅当 g c d ( a , b ) = 1 gcd(a,b)=1 gcd(a,b)=1。
求解最大公因子有非常有效的算法——欧几里得算法(Euclidean Algorithm),不过欧几里得算法利用了余数的概念,因此下面先介绍余数的概念。整除理解起来还比较简单,在带余除法中定义了余数的概念:
- 带余除法: ∀ n ∈ Z + \forall n \in Z^+ ∀n∈Z+和 ∀ a ∈ Z \forall a \in Z ∀a∈Z, ∃ q , r ∈ Z \exists q,r \in Z ∃q,r∈Z且 0 ≤ r < n 0\leq r <n 0≤r<n使得 a = q n + r a=qn+r a=qn+r,其中 q = ⌊ a / n ⌋ q=\lfloor a/n \rfloor q=⌊a/n⌋, ⌊ ⌋ \lfloor \rfloor ⌊⌋为向下取整。
可以看到,其中的 q q q即为商,而 r r r即为余数,按照上面的公式有 r = a − ⌊ a / n ⌋ × n r=a-\lfloor a/n \rfloor \times n r=a−⌊a/n⌋×n,在这里用一个更加简洁的符号表达 r r r,那就是模运算符号 m o d mod mod,记作 r = a m o d n r=a\;mod\;n r=amodn,这里称 n n n是模数,该运算称为模 n n n运算。
回到求解最大公因子,对于任意整数 a a a和 b b b可以通过下面的方式计算 g c d ( a , b ) gcd(a,b) gcd(a,b),不断使用带余除法,直至余数为 0 0 0,此时的除数即为最大公因子,即有下面的过程
a = q 1 b + r 1 ( 0 < r 1 < b ) b = q 2 r 1 + r 2 ( 0 < r 2 < r 1 ) r 1 = q 3 r 2 + r 3 ( 0 < r 3 < r 2 ) . . . r n − 2 = q n r n − 1 + r n ( 0 < r n < r n − 1 ) r n − 1 = q n + 1 r n + 0 ⇒ g c d ( a , b ) = r n a = q_1b + r_1\qquad\;\;(0<r_1<b)\\ b = q_2r_1 + r_2\qquad(0<r_2<r_1)\\ r_1 = q_3r_2 + r_3\qquad(0<r_3<r_2)\\ ...\\ r_{n-2} = q_nr_{n-1} + r_n\quad(0<r_n<r_{n-1})\\ r_{n-1}=q_{n+1}r_n+0\quad \Rightarrow gcd(a,b)=r_n\\ a=q1b+r1(0<r1<b)b=q2r1+r2(0<r2<r1)r1=q3r2+r3(0<r3<r2)...rn−2=qnrn−1+rn(0<rn<rn−1)rn−1=qn+1rn+0⇒gcd(a,b)=rn
欧几里得算法证明并利用了等式: g c d ( a , b ) = g c d ( b , r 1 ) = . . . = g c d ( r n − 1 , r n ) = g c d ( r n , 0 ) = r n gcd(a,b) = gcd(b,r_1)=...=gcd(r_{n-1},r_n)=gcd(r_n,0)=r_n gcd(a,b)=gcd(b,r1)=...=gcd(rn−1,rn)=gcd(rn,0)=rn。下面是欧几里得算法的实现:
# 利用Euclid算法计算最小公因数gcd(a, b)
def Euclid_gcd(a, b):
r1 = max(abs(a), abs(b)) # 令r1等于绝对值大的数
r2 = min(abs(a), abs(b)) # 令r2等于绝对值小的数
if r2 == 0:
return r1
else:
return Euclid_gcd(r2, r1%r2)
尽管整除是一种很好的性质,但不是所有整数都具备,大部分情况而言,对于两个整数相除还是会存在余数。注意到一种情况,两个不同的数 a , b a,b a,b都是除以另一个数 n n n可能获得相同的余数,这种情况称为关于模 n n n是同余的:
- 同余:若 a m o d n = b m o d n a\;mod\;n=b\;mod\;n amodn=bmodn,那么称整数 a a a和 b b b是模 n n n同余的,记作 a ≡ b ( m o d n ) a\equiv b(mod\;n) a≡b(modn)。
同余运算中,最重要的是模数 n n n,比如 6 6 6和 11 11 11模 5 5 5同余,而模 3 3 3就不同余了。因此考虑一般情况,对于模 n n n运算,考察所有整数 Z = { 0 , ± 1 , ± 2 , ± 3 , . . . } Z=\{0, \pm 1, \pm 2, \pm 3, ...\} Z={0,±1,±2,±3,...}, ∀ a ∈ Z \forall a\in Z ∀a∈Z,根据定义 a m o d n ∈ { 0 , 1 , 2 , . . . , n − 1 } a\;mod\;n\in \{0, 1, 2,..., n-1\} amodn∈{0,1,2,...,n−1},因此对于任何整数只要进行模 n n n运算之后,所有整数都被限制到有限的集合中,那么必然会出现同余的情况,依据此可以定义下面两个概念:
- 剩余类集:模 n n n运算的所有余数的集合,记作 Z n = { 0 , 1 , 2 , . . . , n − 1 } Z_n=\{0, 1, 2,..., n-1\} Zn={0,1,2,...,n−1}
- 剩余类:所有模 n n n同余的整数的集合,一般用最小的非负整数作为代表,记作 [ 0 ] , [ 1 ] , [ 2 ] , . . , [ n − 1 ] [0],[1],[2],..,[n-1] [0],[1],[2],..,[n−1]
下面举一个例子:计算
∀
a
∈
Z
,
a
m
o
d
3
\forall a\in Z,\;a\;mod\;3
∀a∈Z,amod3有
.
.
.
,
−
9
,
−
6
,
−
3
,
0
,
3
,
6
,
9
,
.
.
.
m
o
d
3
=
0
.
.
.
,
−
8
,
−
5
,
−
2
,
1
,
4
,
7
,
10
,
.
.
.
m
o
d
3
=
1
.
.
.
,
−
7
,
−
4
,
−
1
,
2
,
5
,
8
,
11
,
.
.
.
m
o
d
3
=
2
..., -9, -6, -3, 0, 3, 6, 9, ...\;mod\;3=0\\ ..., -8, -5, -2, 1, 4, 7, 10, ...\;mod\;3=1\\ ..., -7, -4, -1, 2, 5, 8, 11, ...\;mod\;3=2\\
...,−9,−6,−3,0,3,6,9,...mod3=0...,−8,−5,−2,1,4,7,10,...mod3=1...,−7,−4,−1,2,5,8,11,...mod3=2
则
Z
3
=
{
0
,
1
,
2
}
Z_3=\{0, 1, 2\}
Z3={0,1,2},而剩余类有
3
3
3个,分别是:
[
0
]
=
{
.
.
.
,
−
9
,
−
6
,
−
3
,
0
,
3
,
6
,
9
,
.
.
.
}
[
1
]
=
{
.
.
.
,
−
8
,
−
5
,
−
2
,
1
,
4
,
7
,
10
,
.
.
.
}
[
2
]
=
{
.
.
.
,
−
7
,
−
4
,
−
1
,
2
,
5
,
8
,
11
,
.
.
.
}
[0]=\{..., -9, -6, -3, 0, 3, 6, 9, ...\}\\ [1]=\{..., -8, -5, -2, 1, 4, 7, 10, ...\}\\ [2]=\{..., -7, -4, -1, 2, 5, 8, 11, ...\}\\
[0]={...,−9,−6,−3,0,3,6,9,...}[1]={...,−8,−5,−2,1,4,7,10,...}[2]={...,−7,−4,−1,2,5,8,11,...}
上面讲述了很多同余的概念,之所以关注这些是为了进行剩余类上的模运算:
- 模运算:称二元运算 a m o d n = r a\;mod\;n=r amodn=r是模 n n n运算, r r r为 a a a模 n n n的值,且 0 ≤ r < n 0\leq r <n 0≤r<n
可以证明对于任意两个整数 a a a和 b b b有下面的结论,即:
- [ ( a m o d n ) + ( b m o d n ) ] m o d n = ( a + b ) m o d n [(a\;mod\;n)+(b\;mod\;n)]\;mod\;n=(a+b)\;mod\;n [(amodn)+(bmodn)]modn=(a+b)modn
- [ ( a m o d n ) − ( b m o d n ) ] m o d n = ( a − b ) m o d n [(a\;mod\;n)-(b\;mod\;n)]\;mod\;n=(a-b)\;mod\;n [(amodn)−(bmodn)]modn=(a−b)modn
- [ ( a m o d n ) × ( b m o d n ) ] m o d n = ( a × b ) m o d n [(a\;mod\;n)\times (b\;mod\;n)]\;mod\;n=(a\times b)\;mod\;n [(amodn)×(bmodn)]modn=(a×b)modn
- 加法交换律: ( a + b ) m o d n = ( b + a ) m o d n (a+b)\;mod\;n=(b+a)\;mod\;n (a+b)modn=(b+a)modn
- 乘法交换律: ( a × b ) m o d n = ( b × a ) m o d n (a\times b)\;mod\;n=(b\times a)\;mod\;n (a×b)modn=(b×a)modn
- 加法消去律: a + b = a + c ⇒ b = c ( m o d n ) a+b=a+c\Rightarrow b=c\;(mod\;n) a+b=a+c⇒b=c(modn)
- 乘法消去律( a a a在模 n n n运算中存在乘法逆元时): ∀ a ≠ 0 , a × b = a × c ⇒ b = c ( m o d n ) \forall a\neq 0, a\times b=a\times c\Rightarrow b=c\;(mod\;n) ∀a=0,a×b=a×c⇒b=c(modn)
消去律的成立与否与逆元的存在与否有很大关系,下面是加法逆元和乘法逆元的定义:
- 加法逆元: a , b ∈ Z n a,b\in Z_n a,b∈Zn,若 ( a + b ) m o d n = 0 (a+b)\;mod\;n=0 (a+b)modn=0,则 a a a和 b b b互为加法逆元,记 a a a的加法逆元为 − a -a −a
- 乘法逆元: a , b ∈ Z n a,b\in Z_n a,b∈Zn,若 ( a × b ) m o d n = 1 (a\times b)\;mod\;n=1 (a×b)modn=1,则 a a a和 b b b互为乘法逆元,记 a a a的乘法逆元为 a − 1 a^{-1} a−1
由于加法逆元一定存在,故加法消去律一定成立,而但当且仅当 g c d ( a , n ) = 1 gcd(a,n)=1 gcd(a,n)=1时, a a a才在模 n n n运算中存在乘法逆元,故乘法消去律在该条件下才成立。
2. 素数及其定理
素数是数论的核心概念,比如著名的哥德巴赫猜想等就与素数有关。素数的定义很简单,与之对应的还有合数的概念:
- 素数:正因子只有 1 1 1和它本身的正整数称为素数,而且规定 1 1 1不是素数,常记作 p p p
- 合数:合数是指正整数中不是素数的数,其除 1 1 1和它本身之外,还有其他因子
因此, 2 2 2是最小的素数,除 2 2 2以外,素数都为奇数,最小的合数为 4 4 4。合数有一个非常重要的性质,称为算术基本定理:
- 算术基本定理:任何合数都可以唯一分解为若干个素数的乘积。
即对于任何整数 a > 1 a>1 a>1可以唯一分解为 a = p 1 a 1 p 2 a 2 . . . p n a n a=p_1^{a_1} p_2^{a_2}... p_n^{a_n} a=p1a1p2a2...pnan, ∀ i ∈ { 1 , 2 , . . . , n } \forall i\in \{1, 2, ..., n\} ∀i∈{1,2,...,n}有 p i p_i pi是素数( p 1 < p 2 < . . . < p n p_1<p_2<...<p_n p1<p2<...<pn), a i a_i ai是正整数。
关于素数,有两个常用的定理——费马小定理和欧拉定理,这两个定理在密码学中应用十分广泛。
- 费马小定理:若 p p p是素数,则对任何与 p p p互素的正整数 a a a有,则有 a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv 1(mod\;p) ap−1≡1(modp)。
该定理还有另外一种形式:若 p p p是素数,且 a ∈ Z + a\in Z^+ a∈Z+,那么 a p ≡ a ( m o d p ) a^p\equiv a(mod\;p) ap≡a(modp)。因此可以总结费马小定理为:若 p p p是素数,则 ∀ a ∈ Z + \forall a\in Z^+ ∀a∈Z+有 a p ≡ a ( m o d p ) a^p\equiv a(mod\;p) ap≡a(modp),进一步地,若 a a a与 p p p互素,则有 a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv 1(mod\;p) ap−1≡1(modp)。
- 欧拉定理:对于任意互素的正整数 a a a和 n n n有: a ϕ ( n ) ≡ 1 ( m o d n ) a^{\phi(n)}\equiv 1(mod\;n) aϕ(n)≡1(modn)
其中 ϕ ( n ) \phi(n) ϕ(n)称为欧拉函数,是指小于等于 n n n的与 n n n互素的正整数个数,常采用下面几个公式计算 ϕ ( n ) \phi(n) ϕ(n):
- 若 n n n是素数,则 ϕ ( n ) = n − 1 \phi(n)=n-1 ϕ(n)=n−1
- 若 n = p q n=pq n=pq,其中 p p p和 q q q均为素数,那么 ϕ ( n ) = ϕ ( p ) ϕ ( q ) \phi(n)=\phi(p)\phi(q) ϕ(n)=ϕ(p)ϕ(q),进一步地若 p p p和 q q q互素( g c d ( p , q ) = 1 gcd(p,q)=1 gcd(p,q)=1),那么 ϕ ( n ) = ϕ ( p ) ϕ ( q ) \phi(n)=\phi(p)\phi(q) ϕ(n)=ϕ(p)ϕ(q)也成立
- 若 n = p t n=p^t n=pt,其中p是素数,那么 ϕ ( n ) = p t − p t − 1 \phi(n)=p^t-p^{t-1} ϕ(n)=pt−pt−1
总结一下,对于费马定理和欧拉定理,如果计算 a x ≡ b ( m o d n ) a^x\equiv b(mod\;n) ax≡b(modn)中的一些参数,那么如果 n n n是素数,那么考虑费马定理,若 n n n不是素数则考虑欧拉定理。
最后,介绍一下离散对数问题(Discrete logarithm),离散对数问题是包括Diffie-Hellman密钥交换算法和数字签名算法(DSA)在内的许多公钥算法的基础。在介绍离散对数问题之前,还需要介绍一下本原根的概念,它是离散对数的基础。
- 本原根:使得 a m ≡ 1 ( m o d n ) a^m\equiv 1(mod\;n) am≡1(modn)的最小正整数 m m m称为 a a a的阶,若 m = ϕ ( n ) m=\phi(n) m=ϕ(n)则 a a a称为 n n n的本原根
本原根的定义是抽象的,实际上,若考虑 X X X为小于等于 n n n且与 n n n互素的正整数集合,即 X = { x 1 , x 2 , . . . , x ϕ ( n ) } X=\{x_1, x_2, ..., x_{\phi(n)}\} X={x1,x2,...,xϕ(n)},其中 ∀ i ∈ { 1 , 2 , . . . , ϕ ( n ) } \forall i\in\{1, 2, ..., \phi(n)\} ∀i∈{1,2,...,ϕ(n)}有 g c d ( x i , n ) = 1 gcd(x_i, n)=1 gcd(xi,n)=1, a a a是 n n n的本原根当且仅当集合 { ( a 1 m o d n ) , ( a 2 m o d n ) , . . . , ( a ϕ ( n ) m o d n ) } = X \{(a^1\;mod\;n), (a^2\;mod\;n),...,(a^{\phi(n)}\;mod\;n)\}=X {(a1modn),(a2modn),...,(aϕ(n)modn)}=X。
根据定义,对于一个素数 p p p(本原根定义中不要求素数)而言,由于 ϕ ( p ) = p − 1 \phi(p)=p-1 ϕ(p)=p−1,且上述定义的集合 X = { 1 , 2 , . . . , p − 1 } X=\{1,2,...,p-1\} X={1,2,...,p−1},故设 a a a为本原根,则 a a a满足:
{ ( a 1 m o d p ) , ( a 2 m o d p ) , . . . , ( a ϕ ( p ) m o d p ) } = { ( a 1 m o d p ) , ( a 2 m o d p ) , . . . , ( a p − 1 m o d p ) } = { 1 , 2 , . . . , p − 1 } \{(a^1\;mod\;p),(a^2\;mod\;p),...,(a^{\phi (p)}\;mod\;p)\} \\ = \{(a^1\;mod\;p),(a^2\;mod\;p),...,(a^{p-1}\;mod\;p)\} \\ = \{1,2,...,p-1\}\qquad\qquad\qquad\qquad\qquad\qquad {(a1modp),(a2modp),...,(aϕ(p)modp)}={(a1modp),(a2modp),...,(ap−1modp)}={1,2,...,p−1}
因此对于任何整数 b b b有 b m o d p ∈ { 1 , 2 , . . . , p − 1 } b\;mod\;p\in \{1,2,...,p-1\} bmodp∈{1,2,...,p−1},故一定存在 i ∈ { 1 , 2 , . . . , p − 1 } i\in \{1,2,...,p-1\} i∈{1,2,...,p−1}使得 a i ≡ b ( m o d p ) a^i\equiv b(mod\;p) ai≡b(modp),此时 i i i就被称为以 a a a为底模 p p p运算的 b b b的离散对数,记作 i = d l o g a , p b i=dlog_{a,p}b i=dloga,pb:
- 离散对数:若 a i ≡ b ( m o d p ) a^i\equiv b(mod\;p) ai≡b(modp),此时 i i i就被称为以 a a a为底模 p p p运算的 b b b的离散对数,记作 i = d l o g a , p b i=dlog_{a,p}b i=dloga,pb
离散对数是基于本原根的概念,只有存在本原根时才存在唯一的以 a a a为底模 m m m的离散对数,而模数 m m m一般选为素数,因为素数存在本原根。最后介绍一下离散对数难题:
- 离散对数难题:对于方程 y = g x m o d p y=g^x\;mod\;p y=gxmodp,已知 g , x , p g,x,p g,x,p可以很容易计算 y y y,而已知 y , g , p y,g,p y,g,p很难计算 x x x,是指数级别复杂度的,因此计算离散对数是计算困难的。
扩展篇
相比于基础篇,扩展篇增加了很多内容,尤其是定理的证明,不过对于初学者而言,不需要对此有很深刻的理解,初学时跳过即可。
1. 整数的整除和同余
数论中主要研究整数的性质,特别是两个整数之间的关系,其中整除和同余是经常被讨论的。
1.1 整除和余数
在小学里,我们学过这样一个公式:被除数 ÷ \;\div\; ÷除数 = \;=\; =商…余数。整除的含义即为余数为0 ,而当余数不为0时,此时就需要用余数表示不能整除的部分,下面就从整除出发,介绍整数的整除和余数的基本概念。
1.1.1 带余除法
尽管整除理解起来很简单,但还是需要给出整除的形式化定义:
- 整除:设 a , b , m ∈ Z a, b, m\in Z a,b,m∈Z, ∃ m \exists m ∃m使得 a = m b a = mb a=mb成立,则称非零整数 b b b整除 a a a,记作 b ∣ a b|a b∣a,此时称 b b b是 a a a的因子, a a a是 b b b的倍数。
特殊地,任何不等于 0 0 0的整数都整除 0 0 0,即 ∀ a ≠ 0 , a ∣ 0 \forall a \neq 0, a|0 ∀a=0,a∣0,而且 1 1 1整除任何整数,即 ∀ a ∈ Z , 1 ∣ a \forall a \in Z, 1|a ∀a∈Z,1∣a。
不过大多数时候都可能除不尽,即余数不为 0 0 0,那么就会有余数(remainder)的概念。在数论中,带余除法描述了这一情形,下面是带余除法的形式化定义:
- 带余除法: ∀ n ∈ Z + \forall n \in Z^+ ∀n∈Z+和 ∀ a ∈ Z \forall a \in Z ∀a∈Z, ∃ q , r ∈ Z \exists q,r \in Z ∃q,r∈Z且 0 ≤ r < n 0\leq r <n 0≤r<n使得 a = q n + r a=qn+r a=qn+r,其中商 q = ⌊ a / n ⌋ q=\lfloor a/n \rfloor q=⌊a/n⌋, ⌊ ⌋ \lfloor \rfloor ⌊⌋为向下取整,而余数 r = a − ⌊ a / n ⌋ × n r=a-\lfloor a/n \rfloor \times n r=a−⌊a/n⌋×n。
下面是带余除法的图示表示,可以看到 a a a和 q q q是同号的,因为需要保证余数是非负整数。
1.1.2 最大公因子
在整除定义中提到了因子的概念, m ∣ a m|a m∣a说明 m m m是 a a a的因子,若 m ∣ a m|a m∣a且 m ∣ b m|b m∣b说明 m m m是 a , b a,b a,b的因子,称为 a a a和 b b b的公因子,由于 1 1 1是任何整数的因子,故公因子一定存在(至少为 1 1 1),而关注最多的的是最大的公因子:
- 最大公因子(Greatest Common Divisor):设 a , b , m ∈ Z a, b, m \in Z a,b,m∈Z,而且 m ∣ a , m ∣ b m|a, m|b m∣a,m∣b,若 m m m是整除 a a a和 b b b的最大整数,那么 m m m称为 a a a和 b b b的最大公因子,记作 m = g c d ( a , b ) m = gcd(a, b) m=gcd(a,b)。
一般而言,最大公因子要求是正整数,因为对于 m ∈ Z + m\in Z^+ m∈Z+,如果 m ∣ a m|a m∣a,那么 − m ∣ a -m|a −m∣a,显然 − m < m -m<m −m<m。同时可以得到对于 a , b ∈ Z + , g c d ( a , b ) = g c d ( a , − b ) = g c d ( − a , b ) = g c d ( − a , − b ) a, b\in Z^+, gcd(a, b) = gcd(a, -b) = gcd(-a, b) = gcd(-a, -b) a,b∈Z+,gcd(a,b)=gcd(a,−b)=gcd(−a,b)=gcd(−a,−b),因此求解最大公因子时 ∀ a , b ∈ Z , g c d ( a , b ) = g c d ( ∣ a ∣ , ∣ b ∣ ) \forall a, b\in Z, gcd(a, b) = gcd(|a|, |b|) ∀a,b∈Z,gcd(a,b)=gcd(∣a∣,∣b∣),特殊地有: g c d ( a , 0 ) = ∣ a ∣ gcd(a, 0) = |a| gcd(a,0)=∣a∣且 ∀ a ∈ Z \forall a\in Z ∀a∈Z有 g c d ( a , 1 ) = 1 gcd(a, 1) = 1 gcd(a,1)=1 。
其中特别要注意 0 0 0的情况,因子是指非零整数,故 0 0 0不是任何整数的因子,但任何非零整数都是 0 0 0的因子,不过为了使得定义有效,规定 g c d ( 0 , 0 ) = 0 gcd(0, 0) = 0 gcd(0,0)=0。
互素
利用最大公因子,可以定义一个常用的概念,即互素:称整数 a , b a,b a,b是互素的,当且仅当 g c d ( a , b ) = 1 gcd(a,b)=1 gcd(a,b)=1。
1.1.3 欧几里得算法
最大公因子是联系两个整数的桥梁之一,因此求解两个整数的最大公因子的算法也尤为重要,下面描述的算法是经典的欧几里得算法(Euclidean Algorithm),直至今日,欧几里得算法仍是计算最大公因子的有效算法,下面是欧几里得算法的基本思想:
对于任何整数 a a a和 b b b(由于 g c d ( a , b ) = g c d ( ∣ a ∣ , ∣ b ∣ ) gcd(a, b) = gcd(|a|, |b|) gcd(a,b)=gcd(∣a∣,∣b∣),这里假定 a > b ≥ 0 a>b\ge 0 a>b≥0),利用带余除法有 a = q 1 b + r 1 ( 0 < r 1 < b ) a = q_1b + r_1(0<r_1<b) a=q1b+r1(0<r1<b),其中 r 1 ≠ 0 r_1\ne 0 r1=0,否则 g c d ( a , b ) = b gcd(a,b)=b gcd(a,b)=b,下面证明 g c d ( a , b ) = g c d ( b , r 1 ) gcd(a, b) = gcd(b, r_1) gcd(a,b)=gcd(b,r1):
【证】 g c d ( a , b ) = g c d ( b , r 1 ) gcd(a, b) = gcd(b, r_1) gcd(a,b)=gcd(b,r1)
因为最大公因子一定存在,因此设 d = g c d ( a , b ) , g = g c d ( b , r 1 ) d=gcd(a, b), g = gcd(b, r1) d=gcd(a,b),g=gcd(b,r1),则 d ∣ a , d ∣ b , g ∣ b , g ∣ r 1 d|a, \;d|b, \;g|b, \;g|r_1 d∣a,d∣b,g∣b,g∣r1,根据带余除法有 a = q 1 b + r 1 a = q_1b + r_1 a=q1b+r1,那么就有下面的证明:
对 a = q 1 b + r 1 a = q_1b + r_1 a=q1b+r1两边同除以 d d d有: a / d = q 1 b / d + r 1 / d a/d = q_1b/d + r_1/d a/d=q1b/d+r1/d,则 r 1 / d r_1/d r1/d必须是整数,故 d d d也是 b b b和 r 1 r_1 r1的因子,则 d d d也是 b b b和 r 1 r_1 r1的公因子,根据定义 g g g是最大的公因子,因此有 d ≤ g d \le g d≤g。
同理对 a = q 1 b + r 1 a = q_1b + r_1 a=q1b+r1两边同除以 g g g有: a / g = q 1 b / g + r 1 / g a/g = q_1b/g + r_1/g a/g=q1b/g+r1/g,故 g g g是 a a a和 b b b的因子,根据定义 g ≤ d g \le d g≤d。
综上 d = g d=g d=g。
因此多次使用带余除法有:
a
=
q
1
b
+
r
1
(
0
<
r
1
<
b
)
b
=
q
2
r
1
+
r
2
(
0
<
r
2
<
r
1
)
r
1
=
q
3
r
2
+
r
3
(
0
<
r
3
<
r
2
)
.
.
.
r
n
−
2
=
q
n
r
n
−
1
+
r
n
(
0
<
r
n
<
r
n
−
1
)
r
n
−
1
=
q
n
+
1
r
n
+
0
⇒
g
c
d
(
a
,
b
)
=
r
n
a = q_1b + r_1\qquad\;\;(0<r_1<b)\\ b = q_2r_1 + r_2\qquad(0<r_2<r_1)\\ r_1 = q_3r_2 + r_3\qquad(0<r_3<r_2)\\ ...\\ r_{n-2} = q_nr_{n-1} + r_n\quad(0<r_n<r_{n-1})\\ r_{n-1}=q_{n+1}r_n+0\quad \Rightarrow gcd(a,b)=r_n\\
a=q1b+r1(0<r1<b)b=q2r1+r2(0<r2<r1)r1=q3r2+r3(0<r3<r2)...rn−2=qnrn−1+rn(0<rn<rn−1)rn−1=qn+1rn+0⇒gcd(a,b)=rn
根据 0 ≤ r n < r n − 1 < . . . < r 3 < r 2 < r 1 < b 0\le r_n<r_{n-1}<...<r_3<r_2<r_1<b 0≤rn<rn−1<...<r3<r2<r1<b,且 b b b是有界,故 ∃ n \exists n ∃n,使得 r n − 1 = q n + 1 r n + 0 r_{n-1}=q_{n+1}r_n+0 rn−1=qn+1rn+0(即余数一定会减小至 0 0 0),此时根据上述有 g c d ( a , b ) = g c d ( b , r 1 ) = g c d ( r n − 1 , r n ) = g c d ( r n , 0 ) = r n gcd(a,b) = gcd(b,r_1)=gcd(r_{n-1},r_n)=gcd(r_n,0)=r_n gcd(a,b)=gcd(b,r1)=gcd(rn−1,rn)=gcd(rn,0)=rn。下面是欧几里得算法的实现:
# 利用Euclid算法计算最小公因数gcd(a, b)
def Euclid_gcd(a, b):
r1 = max(abs(a), abs(b)) # 令r1等于绝对值大的数
r2 = min(abs(a), abs(b)) # 令r2等于绝对值小的数
if r2 == 0:
return r1
else:
return Euclid_gcd(r2, r1%r2) # %是模运算符号,下面会讲到
欧几里得算法即使对于很大的整数都十分有效,可以证明对于 1 ≤ m , n ≤ 2 N 1\le m, n\le 2^N 1≤m,n≤2N,计算 g c d ( m , n ) gcd(m,n) gcd(m,n)至多需要 2 N 2N 2N次迭代的计算,看看下面的例子:
gcd(1160718174, 316258250)
= gcd(316258250, 211943424)
= gcd(211943424, 104314826)
= ...
= gcd(1078, 0)
= 1078
1.1.4 扩展的欧几里得算法
为了方便之后的讲述,下面还需要介绍一个定理:
- 定理: ∀ a , b ∈ Z , ∃ x , y ∈ Z \forall a,b\in Z,\;\exist x,y\in Z ∀a,b∈Z,∃x,y∈Z使得 x a + y b = g c d ( a , b ) xa + yb = gcd(a,b) xa+yb=gcd(a,b)。
定理的证明不是重点,求解 u u u和 v v v才是重要的,下面就对 u u u和 v v v的值进行推导:假设在下面的每一个步骤可以找到 x i x_i xi和 y i y_i yi使得 r i = a x i + b y i r_i=ax_i+by_i ri=axi+byi
带余除法 | 假设 |
---|---|
a = q 1 b + r 1 a = q_1b + r_1 a=q1b+r1 | r 1 = a x 1 + b y 1 r_1=ax_1+by_1 r1=ax1+by1 |
b = q 2 r 1 + r 2 b = q_2r_1 + r_2 b=q2r1+r2 | r 2 = a x 2 + b y 2 r_2=ax_2+by_2 r2=ax2+by2 |
r 1 = q 3 r 2 + r 3 r_1 = q_3r_2 + r_3 r1=q3r2+r3 | r 3 = a x 3 + b y 3 r_3=ax_3+by_3 r3=ax3+by3 |
. . . ... ... | |
r n − 2 = q n r n − 1 + r n r_{n-2} = q_nr_{n-1} + r_n rn−2=qnrn−1+rn | r n = a x n + b y n r_n=ax_n+by_n rn=axn+byn |
r n − 1 = q n + 1 r n + 0 r_{n-1}=q_{n+1}r_n+0 rn−1=qn+1rn+0 |
因此有 r i = r i − 2 − q i r i − 1 r_i = r_{i-2} - q_ir_{i-1} ri=ri−2−qiri−1,而 r i − 1 = a x i − 1 + b y i − 1 r_{i-1}=ax_{i-1}+by_{i-1} ri−1=axi−1+byi−1和 r i − 2 = a x i − 2 + b y i − 2 r_{i-2}=ax_{i-2}+by_{i-2} ri−2=axi−2+byi−2
故 r i = ( a x i − 2 + b y i − 2 ) − q i ( a x i − 1 + b y i − 1 ) = a ( x i − 2 − q i x i − 1 ) + b ( y i − 2 − q i y i − 1 ) r_i = (ax_{i-2}+by_{i-2}) - q_i(ax_{i-1}+by_{i-1}) = a(x_{i-2}-q_ix_{i-1})+b(y_{i-2}-q_iy_{i-1}) ri=(axi−2+byi−2)−qi(axi−1+byi−1)=a(xi−2−qixi−1)+b(yi−2−qiyi−1)
再根据 r i = a x i + b y i r_i=ax_i+by_i ri=axi+byi有: x i = x i − 2 − q i x i − 1 , y i = y i − 2 − q i y i − 1 x_i=x_{i-2}-q_ix_{i-1},\quad y_i=y_{i-2}-q_iy_{i-1} xi=xi−2−qixi−1,yi=yi−2−qiyi−1
而我们知道 r n = g c d ( a , b ) r_n=gcd(a, b) rn=gcd(a,b),因此 x = x n , y = y n x=x_n,\;y=y_n x=xn,y=yn,以上就用扩展欧几里得算法求解 x a + y b = g c d ( a , b ) xa + yb = gcd(a,b) xa+yb=gcd(a,b)的过程,下面就是计算过程:
其中令 r − 1 = a , r 0 = b r_{-1}=a, r_0=b r−1=a,r0=b,而同样有 r i = a x i + b y i r_i=ax_i+by_i ri=axi+byi,不过此时的 x − 1 = 1 , x 0 = 0 x_{-1}=1, x_0=0 x−1=1,x0=0, y − 1 = 0 , y 0 = 0 y_{-1}=0, y_0=0 y−1=0,y0=0
下面就是扩展欧几里得算法实现:
# 用扩展的Eculid算法计算ax+by=gcd(a,b)
def Extend_eculid(a, b):
(r1, r2) = (a, b)
(x1, x2, y1, y2) = (1, 0, 0, 1)
while r2 != 0:
r = r1 % r2
q = r1 // r2
(r1, r2) = (r2, r)
(x1, x2) = (x2, x1 - q*x2)
(y1, y2) = (y2, y1 - q*y2)
return(r1, x1, y1)
# 主函数
(a, b) = eval(input("Enter two numbers:"))
a_temp = a if abs(a) > abs(b) else b # 令a_temp为绝对值较大者
b_temp = b if abs(a) > abs(b) else a # 令b_temp为绝对值较小者
(g, x, y) = Extend_eculid(a_temp, b_temp)
print("gcd({}, {}) = {} = ({}) * {} + ({}) * {}".format(a_temp, b_temp, g, x, a_temp, y, b_temp))
1.2 同余
1.2.1 同余关系
尽管整除是一种很好的性质,但不是所有整数都具备,大部分情况而言,对于两个整数相除还是会存在余数,回顾带余除法有:
- 带余除法: ∀ n ∈ Z + \forall n \in Z^+ ∀n∈Z+和 ∀ a ∈ Z \forall a \in Z ∀a∈Z, ∃ q , r ∈ Z \exists q,r \in Z ∃q,r∈Z且 0 ≤ r < n 0\leq r <n 0≤r<n使得 a = q n + r a=qn+r a=qn+r,其中 q = ⌊ a / n ⌋ q=\lfloor a/n \rfloor q=⌊a/n⌋, ⌊ ⌋ \lfloor \rfloor ⌊⌋为向下取整。
在这里,我们称 r r r为余数,之前计算r时,有 r = a − ⌊ a / n ⌋ × n r=a-\lfloor a/n \rfloor \times n r=a−⌊a/n⌋×n,在这里用一个更加简洁的符号表达 r r r,那就是模运算符号 m o d mod mod,记作 r = a m o d n r=a\;mod\;n r=amodn,这里称 n n n是模数,该运算称为模 n n n运算。关于模 n n n运算,它是数论中十分重要的一种运算,下面还会详细定义和讨论该运算。
注意到一种情况,两个不同的数 a , b a,b a,b都是除以另一个数 n n n可能获得相同的余数,这种情况称为关于模 n n n是同余的:
- 模 n n n同余:若 a m o d n = b m o d n a\;mod\;n=b\;mod\;n amodn=bmodn,那么称整数 a a a和 b b b是模 n n n同余的,记作 a ≡ b ( m o d n ) a\equiv b(mod\;n) a≡b(modn).
同余有一个等价的定义(即充要条件):若 a a a和 b b b是关于模 n n n同余的,那么 n ∣ ( a − b ) n|(a-b) n∣(a−b),可见同余和整除联系密切。不过同余相比于整除是一个更好的性质,下面比较两种情况:
性质 | 整除 | 同余 |
---|---|---|
自反性 | ∀ a ≠ 0 , a ∥ a \forall a\ne 0,\;a\|a ∀a=0,a∥a | a ≡ a ( m o d n ) a\equiv a(mod\;n) a≡a(modn) |
对称性 | 不具备 | a ≡ b ( m o d n ) a\equiv b(mod\;n) a≡b(modn),则 b ≡ a ( m o d n ) b\equiv a(mod\;n) b≡a(modn) |
传递性 | a ∥ b , b ∥ c ⇒ a ∥ c a\|b, b\|c \Rightarrow a\|c a∥b,b∥c⇒a∥c | a ≡ b ( m o d n ) , b ≡ c ( m o d n ) a\equiv b(mod\;n), b\equiv c(mod\;n) a≡b(modn),b≡c(modn) ⇒ a ≡ c ( m o d n ) \Rightarrow a\equiv c(mod\;n) ⇒a≡c(modn) |
由于同余运算具有自反性、对称性和传递性,因此同余关系是等价关系,所以可以通过同余关系对于集合进行划分,数论主要研究整数集合,因此通过同余关系可以将无穷的整数集合划分为有限的集合,而划分后得到的即为剩余类集。
等价关系
若定义在集合X上的一种关系(这里可以理解为一种运算,不妨用 R R R表示)具有以下性质:
- 自反性: ∀ x ∈ X , x R x \forall x\in X, xRx ∀x∈X,xRx
- 对称性:若 x R y xRy xRy,则 y R x yRx yRx
- 传递性:若 x R y , y R z xRy,yRz xRy,yRz,则 x R z xRz xRz
比如全等三角形中的全等关系就是一种等价关系,不过在这里,不必对于等价关系进行很深的理解,只需明白由全等关系就可以将集合进行划分成若干个部分即可。
1.2.2 剩余类集
对于任一整数(用 a a a表示),那么利用模运算有 0 ≤ a m o d n < n 0\leq a\;mod\;n<n 0≤amodn<n,因此 a m o d n ∈ { 0 , 1 , 2 , . . , n − 1 } a\;mod\;n \in \{0, 1, 2,.., n-1\} amodn∈{0,1,2,..,n−1},可以证明 { a m o d n ∣ ∀ a ∈ Z } = { 0 , 1 , 2 , . . , n − 1 } \{a\;mod\;n|\forall a\in Z\}=\{0, 1, 2,.., n-1\} {amodn∣∀a∈Z}={0,1,2,..,n−1},即通过模 n n n运算可以得到 0 ∼ n − 1 0\sim n-1 0∼n−1内的任何一个数,且只能得到其中的一个数。因此我们把余数的集合称为剩余类集,而剩余类集中的数作为剩余类的代表,即有:
- 剩余类集:模 n n n运算的所有余数的集合,记作 Z n = { 0 , 1 , 2 , . . . , n − 1 } Z_n=\{0, 1, 2,..., n-1\} Zn={0,1,2,...,n−1}
- 剩余类:所有模 n n n同余的整数的集合,一般用最小的非负整数作为代表,记作 [ 0 ] , [ 1 ] , [ 2 ] , . . , [ n − 1 ] [0],[1],[2],..,[n-1] [0],[1],[2],..,[n−1],对于 [ r ] [r] [r]而言有: [ r ] = { a ∣ a ∈ Z , a ≡ r ( m o d n ) } [r]=\{a|a \in Z, a\equiv r(mod\;n)\} [r]={a∣a∈Z,a≡r(modn)},
下面举一个例子来说明:计算
a
m
o
d
3
a\;mod\;3
amod3有
.
.
.
,
−
9
,
−
6
,
−
3
,
0
,
3
,
6
,
9
,
.
.
.
m
o
d
3
=
0
.
.
.
,
−
8
,
−
5
,
−
2
,
1
,
4
,
7
,
10
,
.
.
.
m
o
d
3
=
1
.
.
.
,
−
7
,
−
4
,
−
1
,
2
,
5
,
8
,
11
,
.
.
.
m
o
d
3
=
2
..., -9, -6, -3, 0, 3, 6, 9, ...\;mod\;3=0\\ ..., -8, -5, -2, 1, 4, 7, 10, ...\;mod\;3=1\\ ..., -7, -4, -1, 2, 5, 8, 11, ...\;mod\;3=2\\
...,−9,−6,−3,0,3,6,9,...mod3=0...,−8,−5,−2,1,4,7,10,...mod3=1...,−7,−4,−1,2,5,8,11,...mod3=2
则 Z 3 = { 0 , 1 , 2 } Z_3=\{0, 1, 2\} Z3={0,1,2},而剩余类有 3 3 3个,分别是:
[ 0 ] = { . . . , − 9 , − 6 , − 3 , 0 , 3 , 6 , 9 , . . . } [ 1 ] = { . . . , − 8 , − 5 , − 2 , 1 , 4 , 7 , 10 , . . . } [ 2 ] = { . . . , − 7 , − 4 , − 1 , 2 , 5 , 8 , 11 , . . . } [0]=\{..., -9, -6, -3, 0, 3, 6, 9, ...\}\\ [1]=\{..., -8, -5, -2, 1, 4, 7, 10, ...\}\\ [2]=\{..., -7, -4, -1, 2, 5, 8, 11, ...\}\\ [0]={...,−9,−6,−3,0,3,6,9,...}[1]={...,−8,−5,−2,1,4,7,10,...}[2]={...,−7,−4,−1,2,5,8,11,...}
在剩余类 [ r ] [r] [r]中有这样的一个性质,他们模 n n n是同余的,在这一点上,剩余类 [ r ] [r] [r]中任何一个元素就可以代表其他元素了,因此就只需要研究这一个元素的性质,就可以大致了解所有元素的共性了,这也是剩余类的本质特性。
1.2.3 模运算
之所以大费周章地定义剩余类集,是因为可以通过模运算来将所有整数的运算限制在剩余类集中,首先需要正式地定义模运算(Modular arithmetic):
- 模 n n n运算:称二元运算 a m o d n = r a\;mod\;n=r amodn=r是模 n n n运算, r r r为 a a a模 n n n的值,且 0 ≤ r < n 0\leq r <n 0≤r<n。
对于一种运算而言,其最重要的就是运算律,下面就阐述一下模 n n n运算的运算律,并着重讨论其交换律和消去律。
我们知道对于任意两个整数 a a a和 b b b, a a a和 b b b的加、减、乘运算之后的结果还是整数(显然除法不是如此),那么 a m o d n a\;mod\;n amodn和 b m o d n b\;mod\;n bmodn在剩余类集 Z n Z_n Zn中,而 a ⋅ b m o d n a\cdot b\;mod\;n a⋅bmodn( ⋅ \cdot ⋅ 代表加、减乘、运算)显然也在剩余类集 Z n Z_n Zn中(只要是整数,模 n n n运算之后就会在剩余类集 Z n Z_n Zn中),那么两者的关系是关注的重点。通过上面的叙述,显然有下面的结论,其证明都可以用带余除法来证明:
- [ ( a m o d n ) + ( b m o d n ) ] m o d n = ( a + b ) m o d n [(a\;mod\;n)+(b\;mod\;n)]\;mod\;n=(a+b)\;mod\;n [(amodn)+(bmodn)]modn=(a+b)modn
- [ ( a m o d n ) − ( b m o d n ) ] m o d n = ( a − b ) m o d n [(a\;mod\;n)-(b\;mod\;n)]\;mod\;n=(a-b)\;mod\;n [(amodn)−(bmodn)]modn=(a−b)modn
- [ ( a m o d n ) × ( b m o d n ) ] m o d n = ( a × b ) m o d n [(a\;mod\;n)\times (b\;mod\;n)]\;mod\;n=(a\times b)\;mod\;n [(amodn)×(bmodn)]modn=(a×b)modn
除了加、减、乘运算,模运算是否具有普通运算的运算律呢?这里讨论简单的交换律和消去律,这两种规律是之后计算的基础。先考虑下面的例子,我们进行模 8 8 8的运算有:
第一栏和第二栏是加法和乘法(减法和加法类似),最右一栏是加法逆元和乘法逆元,它们是消去律的基础,其定义如下:
- 加法逆元: a , b ∈ Z n a,b\in Z_n a,b∈Zn,若 ( a + b ) m o d n = 0 (a+b)\;mod\;n=0 (a+b)modn=0,则 a a a和 b b b互为加法逆元,记 a a a的加法逆元为 − a -a −a
- 乘法逆元: a , b ∈ Z n a,b\in Z_n a,b∈Zn,若 ( a × b ) m o d n = 1 (a\times b)\;mod\;n=1 (a×b)modn=1,则 a a a和 b b b互为乘法逆元,记 a a a的乘法逆元为 a − 1 a^{-1} a−1
观察上面的表格,可以得出以下的结论:
- 关于加法:表格是关于对角线对称的,因此模 n n n加法具有交换律,即 ( a + b ) m o d n = ( b + a ) m o d n (a+b)\;mod\;n=(b+a)\;mod\;n (a+b)modn=(b+a)modn
- 关于乘法:表格是关于对角线对称的,因此模 n n n乘法具有交换律,即 ( a × b ) m o d n = ( b × a ) m o d n (a\times b)\;mod\;n=(b\times a)\;mod\;n (a×b)modn=(b×a)modn
- 关于逆元:加法逆元一定存在,但乘法逆元不一定存在
关注一下减法,对于减法运算 ( a − b ) m o d n (a-b)\;mod\;n (a−b)modn而言,可以看成是 ( a + ( − b ) ) m o d n (a+(-b))\;mod\;n (a+(−b))modn,其中 − b -b −b是 b b b的加法逆元。不过像普通算术的减法一样,减法不具有交换律。关于运算的其他运算律,如结合律、分配律等同样可以进行分析。
讨论完交换律和逆元,下面基于逆元来讨论加法和乘法的消去律:在普通的算术运算中有消去律: a + b = a + c ⇒ b = c a+b=a+c\Rightarrow b=c a+b=a+c⇒b=c,和 ∀ a ≠ 0 , a × b = a × c ⇒ b = c \forall a\neq 0, a\times b=a\times c\Rightarrow b=c ∀a=0,a×b=a×c⇒b=c,即在等式两边可以同时消去相同的数,那么在模运算上有下面的证明:
由于加法逆元存在,则有
( a + b ) m o d n = ( a + c ) m o d n ⇒ ( a + b ) ≡ ( a + c ) ( m o d n ) ⇒ ( ( − a ) + a + b ) ≡ ( ( − a ) + a + c ) ( m o d n ) ⇒ b ≡ c ( m o d n ) (a+b)\;mod\;n=(a+c)\;mod\;n\Rightarrow (a+b)\equiv (a+c)(mod\;n)\Rightarrow ((-a)+a+b)\equiv ((-a)+a+c)(mod\;n)\Rightarrow b\equiv c(mod\;n) (a+b)modn=(a+c)modn⇒(a+b)≡(a+c)(modn)⇒((−a)+a+b)≡((−a)+a+c)(modn)⇒b≡c(modn)
而乘法逆元不一定存在,因此下式只对于乘法逆元存在的情况:
( a × b ) m o d n = ( a × c ) m o d n ⇒ ( a × b ) ≡ ( a × c ) ( m o d n ) ⇒ ( ( a − 1 ) × a × b ) ≡ ( ( a − 1 ) × a × c ) ( m o d n ) ⇒ b ≡ c ( m o d n ) (a\times b)\;mod\;n=(a\times c)\;mod\;n\Rightarrow (a\times b)\equiv (a\times c)(mod\;n)\Rightarrow ((a^{-1})\times a\times b)\equiv ((a^{-1})\times a\times c)(mod\;n)\Rightarrow b\equiv c(mod\;n) (a×b)modn=(a×c)modn⇒(a×b)≡(a×c)(modn)⇒((a−1)×a×b)≡((a−1)×a×c)(modn)⇒b≡c(modn)
模运算与普通运算
模运算是一种新定义的运算,我们所熟知的规律不一定在该运算下成立,因此对于任何证明也都应保持这种敏锐感,对于上面的证明,利用了一个假设:在模运算的等式两边同乘任何数,等式仍然成立。这个假设在普通运算下是毫无疑问的,但在模运算下仍然需要引起怀疑,不过这个假设是正确的。如证明 a ≡ b ( m o d n ) ⇒ a c ≡ b c ( m o d n ) a\equiv b(mod\;n)\Rightarrow ac\equiv bc(mod \;n) a≡b(modn)⇒ac≡bc(modn),利用带余除法 a = q 1 n + r , b = q 2 n + r a=q_1n+r,b=q_2n+r a=q1n+r,b=q2n+r展开等式便可证明。
因此判断乘法逆元是否存在也变得十分关键,对于模 n n n运算而言, a a a的乘法逆元存在的充要条件为 a a a与 n n n互素,即 g c d ( a , n ) = 1 gcd(a,n)=1 gcd(a,n)=1,下面用一个例子来说明原因:
Z 8 Z_8 Z8 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
用 a = 6 a=6 a=6乘以 Z 8 Z_8 Z8中各元素行模 8 8 8运算 | ||||||||
∀ b ∈ Z 8 ( b × 6 ) ( m o d 8 ) \forall b\in Z_8\quad(b \times 6)(mod\;8) ∀b∈Z8(b×6)(mod8) | 0 | 6 | 4 | 2 | 0 | 6 | 4 | 2 |
用 a = 5 a=5 a=5乘以 Z 8 Z_8 Z8中各元素进行模 8 8 8运算 | ||||||||
∀ b ∈ Z 8 ( b × 5 ) ( m o d 8 ) \forall b\in Z_8\quad(b \times 5)(mod\;8) ∀b∈Z8(b×5)(mod8) | 0 | 5 | 2 | 7 | 4 | 1 | 6 | 3 |
记 { ( b × a ) ( m o d n ) ∣ ∀ b ∈ Z n } \{(b \times a)(mod\;n)|\forall b\in Z_n\} {(b×a)(modn)∣∀b∈Zn}为用 a a a乘以 Z n Z_n Zn中所有元素所产生的集合,我们看到当 a a a与 n n n不互素时,集合 { ( b × a ) ( m o d n ) ∣ ∀ b ∈ Z n } ⊂ Z 8 \{(b \times a)(mod\;n)|\forall b\in Z_n\}\sub Z_8 {(b×a)(modn)∣∀b∈Zn}⊂Z8,而当 a a a与 n n n互素时 { ( b × a ) ( m o d n ) ∣ ∀ b ∈ Z n } = Z 8 \{(b \times a)(mod\;n)|\forall b\in Z_n\}=Z_8 {(b×a)(modn)∣∀b∈Zn}=Z8。因此当 a a a与 n n n不互素时,集合 Z 8 Z_8 Z8到集合 { ( b × a ) ( m o d n ) ∣ ∀ b ∈ Z n } \{(b \times a)(mod\;n)|\forall b\in Z_n\} {(b×a)(modn)∣∀b∈Zn}的映射是多对一的映射,而当 a a a与 n n n互素是一对一的映射,求逆元的元素相当于逆映射,只有一对一的映射(一一映射)才有逆映射,此时才有逆元。
因此总结一下关于模运算的规律:
- [ ( a m o d n ) + ( b m o d n ) ] m o d n = ( a + b ) m o d n [(a\;mod\;n)+(b\;mod\;n)]\;mod\;n=(a+b)\;mod\;n [(amodn)+(bmodn)]modn=(a+b)modn
- [ ( a m o d n ) − ( b m o d n ) ] m o d n = ( a − b ) m o d n [(a\;mod\;n)-(b\;mod\;n)]\;mod\;n=(a-b)\;mod\;n [(amodn)−(bmodn)]modn=(a−b)modn
- [ ( a m o d n ) × ( b m o d n ) ] m o d n = ( a × b ) m o d n [(a\;mod\;n)\times (b\;mod\;n)]\;mod\;n=(a\times b)\;mod\;n [(amodn)×(bmodn)]modn=(a×b)modn
- 加法交换律: ( a + b ) m o d n = ( b + a ) m o d n (a+b)\;mod\;n=(b+a)\;mod\;n (a+b)modn=(b+a)modn
- 乘法交换律: ( a × b ) m o d n = ( b × a ) m o d n (a\times b)\;mod\;n=(b\times a)\;mod\;n (a×b)modn=(b×a)modn
- 加法消去律: a + b = a + c ⇒ b = c ( m o d n ) a+b=a+c\Rightarrow b=c\;(mod\;n) a+b=a+c⇒b=c(modn)
- 乘法消去律( g c d ( a , n ) = 1 gcd(a,n)=1 gcd(a,n)=1): ∀ a ≠ 0 , a × b = a × c ⇒ b = c ( m o d n ) \forall a\neq 0, a\times b=a\times c\Rightarrow b=c\;(mod\;n) ∀a=0,a×b=a×c⇒b=c(modn)
2. 素数
下面开始数论的核心——素数,比如著名的哥德巴赫猜想等就与素数有关,下面将介绍素数的基本概念,讨论与素数的定理和应用。
2.1 素数及其定理
素数的定义十分简单,与素数相对的即为合数,两者的定义如下:
- 素数:整数 p > 1 p>1 p>1是素数,当且仅当 p p p的正因子只有 1 1 1和 p p p。
- 合数:合数是指正整数中不是素数的数,其除 1 1 1和它本身之外,还有其他因子
合数有一个十分重要的性质,也称为算术基本定理:
- 算术基本定理:任何合数都可以唯一分解为若干个素数的乘积。
因此,对于任何整数 a > 1 a>1 a>1可以唯一分解为 a = p 1 a 1 p 2 a 2 . . . p n a n a=p_1^{a_1} p_2^{a_2}... p_n^{a_n} a=p1a1p2a2...pnan, ∀ i ∈ { 1 , 2 , . . . , n } \forall i\in \{1, 2, ..., n\} ∀i∈{1,2,...,n}有 p i p_i pi是素数( p 1 < p 2 < . . . < p n p_1<p_2<...<p_n p1<p2<...<pn), a i a_i ai是正整数。
例如 30 = 2 × 3 × 5 30 = 2\times 3\times 5 30=2×3×5,不过对一个数进行素因子分解是困难的,特别是对大整数。基于素数,有下面两个定理——费马小定理和欧拉定理,它们在公钥密码学上有非常重要的应用。
2.1.1 费马小定理
- 费马小定理(Fermat’s little theorem):若 p p p是素数,则对任何与 p p p互素的正整数 a a a有,则有 a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv 1(mod\;p) ap−1≡1(modp)。
正如前述, a a a与 p p p互素说明 g c d ( a , p ) = 1 gcd(a,p)=1 gcd(a,p)=1,不过由于 p p p是素数,因此其还有以下两层含义:
- a a a不是 p p p的倍数,即 a ≠ p , 2 p , . . . a\ne p, 2p, ... a=p,2p,...,即只有素数的倍数才不与素数互素
- a a a在 Z p Z_p Zp中有乘法逆元
【证】 a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv 1(mod\;p) ap−1≡1(modp)
令 Z p + = { 1 , 2 , . . . , p − 1 } , X = { ( a m o d p ) , ( 2 a m o d p ) , ( 3 a m o d p ) , . . . , ( ( p − 1 ) a m o d p ) } Z_p^+=\{1,2,...,p-1\},\;X=\{(a\;mod\;p),(2a\;mod\;p),(3a\;mod\;p),...,((p-1)a\;mod\;p)\} Zp+={1,2,...,p−1},X={(amodp),(2amodp),(3amodp),...,((p−1)amodp)}
显然 ∀ i ≠ j ∈ { 1 , 2 , 3 , . . . p − 1 } \forall i\ne j\in \{1,2,3,...p-1\} ∀i=j∈{1,2,3,...p−1}有 ( i a m o d p ) ≠ ( j a m o d p ) (ia\;mod\;p)\ne (ja\;mod\;p) (iamodp)=(jamodp),否则两边同乘 a − 1 a^{-1} a−1( a a a与 p p p互素)便可得到 ( i m o d p ) = ( j m o d p ) (i\;mod\;p)= (j\;mod\;p) (imodp)=(jmodp),从而得到 i = j i=j i=j,故 X X X中没有重复元素。
因此 X X X中有 p − 1 p-1 p−1个元素,且每个元素都在 { 1 , 2 , 3 , . . . , p − 1 } \{1,2,3,...,p-1\} {1,2,3,...,p−1}中,故 Z p + = X Z_p^+=X Zp+=X,故有下面的等式:
1 × 2 × 3 × . . . × ( p − 1 ) = ( a m o d p ) × ( 2 a m o d p ) × ( 3 a m o d p ) × . . . × ( ( p − 1 ) a m o d p 1\times 2\times 3\times ...\times (p-1)=(a\;mod\;p)\times (2a\;mod\;p)\times (3a\;mod\;p)\times ...\times ((p-1)a\;mod\;p 1×2×3×...×(p−1)=(amodp)×(2amodp)×(3amodp)×...×((p−1)amodp
整理得 ( p − 1 ) ! = ( p − 1 ) ! × a p ( m o d p ) ⇒ a p − 1 ≡ 1 ( m o d p ) (p-1)!=(p-1)!\times a^p (mod\;p)\Rightarrow a^{p-1}\equiv 1(mod\;p) (p−1)!=(p−1)!×ap(modp)⇒ap−1≡1(modp)(注意 ( p − 1 ) ! (p-1)! (p−1)!与 p p p互素)
事实上,费马小定理还有另一种形式:
- 费马小定理另一形式:若 p p p是素数,且 a ∈ Z + a\in Z^+ a∈Z+,那么 a p ≡ a ( m o d p ) a^p\equiv a(mod\;p) ap≡a(modp)。
该形式可用数学归纳法证明,或者基于上述 a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv 1(mod\;p) ap−1≡1(modp)进行证明,下面是证明要点:
【证】 a p ≡ a ( m o d p ) a^p\equiv a(mod\;p) ap≡a(modp)
若 a a a与 p p p互素,那么有 a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv 1(mod\;p) ap−1≡1(modp),两边同乘a可得 a p ≡ a ( m o d p ) a^p\equiv a(mod\;p) ap≡a(modp),若 a a a与 p p p不互素,那么有 a = n p ( n = 1 , 2 , 3 , . . . . ) a=np(n=1, 2, 3,....) a=np(n=1,2,3,....),则 a p ( m o d p ) = ( n p ) p ( m o d p ) = 0 = n p ( m o d p ) = a ( m o d p ) a^p(mod\;p)=(np)^p(mod\;p)=0=np(mod\;p)=a(mod\;p) ap(modp)=(np)p(modp)=0=np(modp)=a(modp)
事实上,第一种形式是第二种形式的特殊情况,在第二种形式 a p ≡ a ( m o d p ) a^p\equiv a(mod\;p) ap≡a(modp)中,由于 a a a与 p p p互素,则可以在两边乘以 a − 1 a^{-1} a−1,便可得到 a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv 1(mod\;p) ap−1≡1(modp)。因此可以总结费马小定理为:
- 费马小定理:若 p p p是素数,则 ∀ a ∈ Z + \forall a\in Z^+ ∀a∈Z+有 a p ≡ a ( m o d p ) a^p\equiv a(mod\;p) ap≡a(modp),进一步地,若 a a a与 p p p互素,则有 a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv 1(mod\;p) ap−1≡1(modp)。
2.1.2 欧拉定理
在讲述欧拉定理(Euler’s theorem)之前要先介绍欧拉函数(Euler’s totient function),其定义如下:
- 欧拉函数:正整数 n n n的欧拉函数是指小于等于 n n n的与 n n n互素的正整数个数,记作 ϕ ( n ) \phi(n) ϕ(n)。
计算 ϕ ( n ) \phi(n) ϕ(n)是十分重要的,在之后的练习中常常用到,下面介绍几个公式:
- 若 n n n是素数,则 ϕ ( n ) = n − 1 \phi(n)=n-1 ϕ(n)=n−1
- 若 n = p q n=pq n=pq,其中 p p p和 q q q均为素数,那么 ϕ ( n ) = ϕ ( p ) ϕ ( q ) \phi(n)=\phi(p)\phi(q) ϕ(n)=ϕ(p)ϕ(q),进一步地若 p p p和 q q q互素,那么 ϕ ( n ) = ϕ ( p ) ϕ ( q ) \phi(n)=\phi(p)\phi(q) ϕ(n)=ϕ(p)ϕ(q)也成立
- 若 n = p t n=p^t n=pt,其中p是素数,那么 ϕ ( n ) = p t − p t − 1 \phi(n)=p^t-p^{t-1} ϕ(n)=pt−pt−1
上面第一点和第三点按照定义即可证明,对其因子计数即可。而对于第二点,对于前半部分 p p p和 q q q是素数的情况,可以列举 p p p和 q q q的因子并按照定义加以证明,而 p p p与 q q q互素的情况则需要利用中国剩余定理(之后会讲述)证明,这里忽略公式的证明,能够熟练地记住和利用公式便可。
下面介绍计算 ϕ ( n ) \phi(n) ϕ(n)的步骤:
- ϕ ( 1 ) = 1 \phi(1)=1 ϕ(1)=1
- 若 n n n是素数,则 ϕ ( n ) = n − 1 \phi(n)=n-1 ϕ(n)=n−1。
- 若 n n n不是素数,则由算术基本定理可知: n n n可表示为 n = p 1 n 1 p 2 n 2 p 3 n 3 . . . p t n t n=p_1^{n_1} p_2^{n_2} p_3^{n_3}... p_t^{n_t} n=p1n1p2n2p3n3...ptnt,其中 ∀ i ∈ { 1 , 2 , 3 , . . . , n } \forall i\in \{1, 2, 3, ..., n\} ∀i∈{1,2,3,...,n}, p i p_i pi是素数( p 1 < p 2 < p 3 < . . . < p t p_1<p_2<p_3<...<p_t p1<p2<p3<...<pt), n i n_i ni是正整数,则利用上面的三个欧拉函数的计算公式可以推出: ϕ ( n ) = ∏ i = 1 t p i n i − 1 ( p i − 1 ) \phi(n)=\prod_{i=1}^t{p_{i}^{n_i-1}( p_i-1 )} ϕ(n)=∏i=1tpini−1(pi−1)
下面是计算欧拉函数的算法实现
import math
# 判断素数函数
def isprime(n):
if n < 2:
return False
for i in range(2, int(math.sqrt(n))+1):
if n % i == 0:
return False
return True
# 求欧拉函数phi(n)
def phi(n):
assert n > 0
if n == 1: # n = 1
return 1
elif isprime(n): # n是素数
return n-1
else: # n不是素数
factor_dict = {} # 对n进行素因子分解
while n != 1:
for i in range(2, n+1):
if n%i==0 and isprime(i): # i是n的素因子
factor_dict[i] = factor_dict.get(i, 0) + 1
n = n // i
break
phi = 1 # 计算欧拉函数的值
for key in factor_dict.keys():
value = factor_dict[key]
phi *= pow(key, value) - pow(key, value-1)
return phi
计算欧拉函数不是很困难,而在欧拉定理中,利用了欧拉函数的值。下面正式地介绍一下欧拉定理:
- 欧拉定理:对于任意互素的正整数 a a a和 n n n有: a ϕ ( n ) ≡ 1 ( m o d n ) a^{\phi(n)}\equiv 1(mod\;n) aϕ(n)≡1(modn),下面是定理的证明:
【证明】 a ϕ ( n ) ≡ 1 ( m o d n ) a^{\phi(n)}\equiv 1(mod\;n) aϕ(n)≡1(modn)
当 n = 1 n=1 n=1时明显成立,考虑 n > 2 n>2 n>2时,有 ϕ ( n ) \phi(n) ϕ(n)是指小于等于 n n n的与 n n n互素的正整数个数,那么考虑这些整数构成的集合 R = { x 1 , x 2 , x 3 , . . . , x ϕ ( n ) } R=\{x_1,x_2,x_3,..., x_{\phi(n)}\} R={x1,x2,x3,...,xϕ(n)},而且 ∀ i ∈ { 1 , 2 , 3 , . . . , ϕ ( n ) } \forall i\in \{1, 2, 3,..., \phi(n)\} ∀i∈{1,2,3,...,ϕ(n)}有 g c d ( x i , n ) = 1 gcd(x_i, n)=1 gcd(xi,n)=1,且不妨设 0 < x 1 < x 2 < x 3 < . . . < x ϕ ( n ) < n 0<x_1<x_2<x_3<...<x_{\phi(n)}<n 0<x1<x2<x3<...<xϕ(n)<n
考虑 S = { ( a x 1 m o d n ) , ( a x 2 m o d n ) , ( a x 3 m o d n ) , . . . , ( a x ϕ ( n ) m o d n ) } S=\{(ax_1\;mod\;n),(ax_2\;mod\;n),(ax_3\;mod\;n),...,(ax_{\phi(n)}\;mod\;n)\} S={(ax1modn),(ax2modn),(ax3modn),...,(axϕ(n)modn)},可知 ∀ i ∈ { 1 , 2 , 3 , . . . , ϕ ( n ) } \forall i\in \{1, 2, 3,..., \phi(n)\} ∀i∈{1,2,3,...,ϕ(n)}有 a , x i a,x_i a,xi和 n n n互素,故 a x i ax_i axi和 n n n互素,根据欧几里得算法 g c d ( a x i , n ) = g c d ( n , a x i ( m o d n ) ) = 1 gcd(ax_i, n)=gcd(n, ax_i(mod\;n))=1 gcd(axi,n)=gcd(n,axi(modn))=1,因此 S S S中的每一个元素都大于 0 0 0,小于 n n n,且与 n n n互素。
同时 ∀ i , j ∈ { 1 , 2 , 3 , . . . , ϕ ( n ) } \forall i,j\in \{1, 2, 3,..., \phi(n)\} ∀i,j∈{1,2,3,...,ϕ(n)},若 i ≠ j i\ne j i=j,那么 ( a x i m o d n ) ≠ ( a x j m o d n ) (ax_i\;mod\;n)\ne (ax_j\;mod\;n) (aximodn)=(axjmodn),否则 ( a x i m o d n ) = ( a x j m o d n ) ⇒ ( ( a − 1 ) × a x i m o d n ) = ( ( a − 1 ) × a x j m o d n ) ⇒ ( x i m o d n ) = ( x j m o d n ) ⇒ x i = x j (ax_i\;mod\;n)=(ax_j\;mod\;n)\Rightarrow ((a^{-1})\times ax_i\;mod\;n)=((a^{-1})\times ax_j\;mod\;n)\Rightarrow (x_i\;mod\;n)=(x_j\;mod\;n)\Rightarrow x_i=x_j (aximodn)=(axjmodn)⇒((a−1)×aximodn)=((a−1)×axjmodn)⇒(ximodn)=(xjmodn)⇒xi=xj
与 0 < x 1 < x 2 < x 3 < . . . < x ϕ ( n ) < n 0<x_1<x_2<x_3<...<x_{\phi(n)}<n 0<x1<x2<x3<...<xϕ(n)<n不合
综上所述, S S S中有 ϕ ( n ) \phi(n) ϕ(n)个元素,每个元素都大于 0 0 0,小于 n n n,且与 n n n互素,则 R = S R=S R=S,那么有:
x 1 × x 2 × . . . × x ϕ ( n ) = ( a x 1 m o d n ) × ( a x 2 m o d n ) × . . . × ( a x ϕ ( n ) m o d n ) ⇒ a ϕ ( n ) ≡ 1 ( m o d n ) x_1\times x_2\times...\times x_{\phi(n)}=(ax_1\;mod\;n)\times (ax_2\;mod\;n)\times ...\times (ax_{\phi(n)}\;mod\;n)\Rightarrow a^{\phi(n)}\equiv 1(mod\;n) x1×x2×...×xϕ(n)=(ax1modn)×(ax2modn)×...×(axϕ(n)modn)⇒aϕ(n)≡1(modn)
与费马小定理一样,欧拉定理也有另一种形式:
- 欧拉定理另一形式:对于任意正整数 a a a和 n n n,若 n n n的素数分解不包括重复因子(即 n = p 1 n 1 p 2 n 2 p 3 n 3 . . . p t n t n=p_1^{n_1} p_2^{n_2} p_3^{n_3}... p_t^{n_t} n=p1n1p2n2p3n3...ptnt中素数的指数均为 1 1 1),则有 a ϕ ( n ) + 1 ≡ a ( m o d n ) a^{\phi(n)+1}\equiv a(mod\;n) aϕ(n)+1≡a(modn),
这一公式也十分有用,不过该公式的证明超出了本文讨论的范围。总结一下关于费马定理和欧拉定理的使用:
对于费马定理和欧拉定理,如果计算 a x ≡ b ( m o d n ) a^x\equiv b(mod\;n) ax≡b(modn)中的一些参数,那么如果n是素数,那么考虑费马定理,若n不是素数则考虑欧拉定理,下面举两个例子介绍一下:
- 求 0 ≤ x ≤ 28 0\le x \le28 0≤x≤28,使得 x 85 ≡ 6 ( m o d 29 ) ? x^{85}\equiv 6(mod\;29)? x85≡6(mod29)?
29 29 29是素数,那么可以利用费马定理: x 29 ≡ x ( m o d 29 ) x^{29}\equiv x(mod\;29) x29≡x(mod29),由于 0 ≤ x ≤ 28 0\le x \le28 0≤x≤28,则 x x x与 29 29 29互素,那么 x 29 − 1 ≡ 1 ( m o d 29 ) x^{29-1}\equiv 1(mod\;29) x29−1≡1(mod29),则 x 85 ≡ ( x 28 ) 3 × x ≡ x ≡ 6 ( m o d 29 ) x^{85}\equiv (x^{28})^3\times x\equiv x\equiv 6(mod\; 29) x85≡(x28)3×x≡x≡6(mod29),则 x = 6 x=6 x=6。
- 求 0 ≤ a ≤ 9 0\le a \le9 0≤a≤9,使得 7 1000 ≡ a ( m o d 10 ) ? 7^{1000}\equiv a(mod\;10)? 71000≡a(mod10)?
10 = 2 × 5 10=2\times 5 10=2×5,故 10 10 10不是素数,但 7 7 7与 10 10 10互素,且 ϕ ( 10 ) = ϕ ( 2 ) × ϕ ( 5 ) = 4 \phi(10)=\phi(2)\times \phi(5)=4 ϕ(10)=ϕ(2)×ϕ(5)=4,那么由欧拉定理有 7 1000 ≡ ( 7 4 ) 250 ≡ 1 ≡ a ( m o d 10 ) 7^{1000}\equiv (7^4)^{250}\equiv 1\equiv a(mod\;10) 71000≡(74)250≡1≡a(mod10),则a = 1 =1 =1。
2.1.3 素性检测
从上面可以看到,素数具有很多良好的性质,而且在密码学中经常要找到一个足够大的素数(例如300位以上)。不过到目前为止还没有一个很好的素数检测算法,大多算法都是基于一定数学问题来筛选素数,这些算法大多不是一个确定性算法,即通过测试的整数不一定是素数,但大概率是一个素数,多次对一个素数进行检测可以以很高的概率认为这就是一个素数。下面给出一个检测素数的算法——MIller-Rabin算法,下面是算法的伪代码
Primetest(n):
输入:一个整数 n n n。
输出:返回对该整数的素数判断,若 n n n可能是素数,则返回不确定,否则返回合数。
k ← 0 , q ← n − 1 k \leftarrow 0, q \leftarrow n-1 k←0,q←n−1
w h i l e q m o d 2 = = 0 d o while\;q\;mod\;2 == 0\quad do whileqmod2==0do
k ← k + 1 \qquad k \leftarrow k+1 k←k+1
q ← q / 2 \qquad q \leftarrow q /2 q←q/2
a ← { 2 , 3 , . . . n − 1 } a \leftarrow \{2, 3, ...n-1\}\qquad \qquad a←{2,3,...n−1} // 从 2 ∼ n − 1 2\sim n-1 2∼n−1中随机选择一个数
i f a q m o d n = = 1 t h e n r e t u r n “ 不 确 定 ” if\;a^q\;mod\;n == 1\quad then\;return\;“不确定” ifaqmodn==1thenreturn“不确定”
e l s e else else
f o r j ← 0 t o k − 1 d o \qquad for\;j \leftarrow 0\;to\;k-1\quad do forj←0tok−1do
i f 2 2 j q m o d n = = n − 1 t h e n r e t u r n “ 不 确 定 ” \qquad \qquad if\;2^{2^jq}\;mod\;n == n-1\quad then\;return\;“不确定” if22jqmodn==n−1thenreturn“不确定”
r e t u r n “ 合 数 ” \qquad return\;“合数” return“合数”
该算法是一个不确定算法,通过测试(返回不确定)的数不是素数的概率小于 1 / 4 1/4 1/4,因此多次对该数进行Miller-Rabin算法测试可以以很大的概率判断该数是素数。
2.2 中国剩余定理
下面讨论一下中国古代数学家为数论作出的一些贡献:中国剩余定理(The Chinese Remainder Theorem,CRT)。中国剩余定理是由公元100年前的孙子发现的,其给出了大数运算的简便计算方法,中国剩余定理有两种形式,其常用的形式如下:
令
m
1
,
m
2
,
m
3
,
.
.
.
,
m
k
m_1, m_2, m_3,...,m_k
m1,m2,m3,...,mk是两两互素的整数,
M
=
∏
i
=
1
k
m
i
M=\prod_{i=1}^{k}m_i
M=∏i=1kmi,设
a
1
,
a
2
,
a
3
,
.
.
.
,
a
k
a_1, a_2, a_3,...,a_k
a1,a2,a3,...,ak是整数,则同余方程组在模M下有唯一解。
x
≡
a
1
(
m
o
d
m
1
)
x
≡
a
2
(
m
o
d
m
2
)
x
≡
a
3
(
m
o
d
m
3
)
.
.
.
x
≡
a
k
(
m
o
d
m
k
)
x\equiv a_1(mod\; m_1)\\ x\equiv a_2(mod\; m_2)\\ x\equiv a_3(mod\; m_3)\\ ...\\ x\equiv a_k(mod\; m_k)\\
x≡a1(modm1)x≡a2(modm2)x≡a3(modm3)...x≡ak(modmk)
这种定义方式比较直观,但不能表现中国剩余定理的用途。下面给出一种有用的表达形式:
令 M = ∏ i = 1 k m i M=\prod _{i=1}^km_i M=∏i=1kmi,其中 m i m_i mi是两两互素的, ∀ A ∈ Z M \forall A\in Z_M ∀A∈ZM,可将 A A A对应于一个 k k k元组 ( a 1 , a 2 , a 3 , . . . , a k ) (a_1, a_2, a_3,..., a_k) (a1,a2,a3,...,ak),即 A ⟷ ( a 1 , a 2 , a 3 , . . . , a k ) A\longleftrightarrow (a_1, a_2, a_3,..., a_k) A⟷(a1,a2,a3,...,ak),其中 a i a_i ai有: a i ∈ Z m i a_i\in Z_{m_i} ai∈Zmi且 a i = A m o d m i a_i=A\;mod\;m_i ai=Amodmi
中国剩余定理第二种形式说明以下两种情况是成立的:
- A ⟷ ( a 1 , a 2 , a 3 , . . . , a k ) A\longleftrightarrow (a_1, a_2, a_3,..., a_k) A⟷(a1,a2,a3,...,ak)的映射是从 Z M Z_M ZM到 Z m 1 × Z m 1 × Z m 1 × . . . × Z m 1 Z_{m_1}\times Z_{m_1}\times Z_{m_1}\times ...\times Z_{m_1} Zm1×Zm1×Zm1×...×Zm1的一一对应(即双射)
- Z M Z_M ZM中元素上的运算等价于对应于 k k k元组上的运算
第一点中 A A A对应于 ( a 1 , a 2 , a 3 , . . . , a k ) (a_1, a_2, a_3,..., a_k) (a1,a2,a3,...,ak)是容易理解的,而 ( a 1 , a 2 , a 3 , . . . , a k ) (a_1, a_2, a_3,..., a_k) (a1,a2,a3,...,ak)如何对应 A A A呢,也就是如何计算 A A A的问题:
对 1 ≤ i ≤ k 1\le i\le k 1≤i≤k,令 M i = M / m i M_i=M/m_i Mi=M/mi,故 M i M_i Mi与 m i m_i mi互素,而 ∀ j ≠ i , M i ≡ 0 ( m o d m j ) \forall j\ne i,M_i\equiv 0(mod\;m_j) ∀j=i,Mi≡0(modmj)。根据 M i M_i Mi与 m i m_i mi互素可知, M i M_i Mi在模 m i m_i mi运算下有乘法逆元 M i − 1 M_i^{-1} Mi−1,故令 c i = M i × ( M i − 1 m o d m i ) c_i=M_i\times (M_i^{-1}\;mod\;m_i) ci=Mi×(Mi−1modmi),其中 1 ≤ i ≤ k 1\le i\le k 1≤i≤k,则有下面计算 A A A的公式: A ≡ ( ∑ i = 1 k a i c i ) ( m o d M ) A\equiv (\sum_{i=1}^k{a_ic_i})(mod\;M) A≡(∑i=1kaici)(modM)
不过得证明上式公式是正确的,也即证明 ∀ 1 ≤ i ≤ k , a i = A m o d m i \forall 1\le i\le k,\;a_i=A\;mod\;m_i ∀1≤i≤k,ai=Amodmi,将 A A A的公式代入计算则有:
A m o d m i = ( ∑ i = 1 k a i c i ) ( m o d m i ) = a i c i ( m o d m i ) = a i × ( M i × ( M i − 1 m o d m i ) ) ( m o d m i ) = a i A\;mod\;m_i = (\sum_{i=1}^k{a_ic_i})(mod\;m_i)=a_ic_i(mod\;m_i)=a_i\times(M_i\times (M_i^{-1}\;mod\;m_i))(mod\;m_i)=a_i Amodmi=(∑i=1kaici)(modmi)=aici(modmi)=ai×(Mi×(Mi−1modmi))(modmi)=ai
其中利用了 ∀ j ≠ i , c j m o d m i = ( M j × ( M j − 1 m o d m j ) ) ( m o d m i ) = 0 \forall j\ne i,c_j\;mod\;m_i=(M_j\times (M_j^{-1}\;mod\;m_j))(mod\;m_i)=0 ∀j=i,cjmodmi=(Mj×(Mj−1modmj))(modmi)=0
第二点的含义是:设有 A ⟷ ( a 1 , a 2 , a 3 , . . . , a k ) , B ⟷ ( b 1 , b 2 , b 3 , . . . , b k ) A\longleftrightarrow (a_1, a_2, a_3,..., a_k),\;B\longleftrightarrow (b_1, b_2, b_3,..., b_k) A⟷(a1,a2,a3,...,ak),B⟷(b1,b2,b3,...,bk),则有
- ( A + B ) m o d M ⟷ ( ( a 1 + b 1 ) m o d m 1 , . . . , ( a k + b k ) m o d m k ) (A+B)\;mod\;M\longleftrightarrow ((a_1+b_1)\;mod\;m_1,...,(a_k+b_k)\;mod\;m_k) (A+B)modM⟷((a1+b1)modm1,...,(ak+bk)modmk)
- ( A − B ) m o d M ⟷ ( ( a 1 − b 1 ) m o d m 1 , . . . , ( a k − b k ) m o d m k ) (A-B)\;mod\;M\longleftrightarrow ((a_1-b_1)\;mod\;m_1,...,(a_k-b_k)\;mod\;m_k) (A−B)modM⟷((a1−b1)modm1,...,(ak−bk)modmk)
- ( A × B ) m o d M ⟷ ( ( a 1 × b 1 ) m o d m 1 , . . . , ( a k × b k ) m o d m k ) (A\times B)\;mod\;M\longleftrightarrow ((a_1\times b_1)\;mod\;m_1,...,(a_k\times b_k)\;mod\;m_k) (A×B)modM⟷((a1×b1)modm1,...,(ak×bk)modmk)
下面用一个例子来解释一下:假设计算 ( 973 + 678 ) m o d 1813 (973+678)\;mod\;1813 (973+678)mod1813(这个数目不够大,仅仅作为演示),可知 M = 1813 = 37 × 49 M=1813=37\times 49 M=1813=37×49,令 m 1 = 37 , m 2 = 49 m_1=37, m_2=49 m1=37,m2=49,而且 37 37 37和 49 49 49互素。
首先计算 973 973 973和 678 678 678对应的 k k k元组(这里是 2 2 2元组):
973 ⟷ ( 973 m o d 37 , 973 m o d 49 ) = ( 11 , 42 ) 678 ⟷ ( 678 m o d 37 , 678 m o d 49 ) = ( 12 , 41 ) 973 \longleftrightarrow (973\;mod\;37, 973\;mod\;49)=(11, 42)\\ 678 \longleftrightarrow (678\;mod\;37, 678\;mod\;49)=(12, 41) 973⟷(973mod37,973mod49)=(11,42)678⟷(678mod37,678mod49)=(12,41)
因此 ( 973 + 678 ) m o d 1813 ⟷ ( ( 11 + 12 ) m o d 37 , ( 42 + 41 ) m o d 49 ) = ( 23 , 34 ) (973+678)\;mod\;1813\longleftrightarrow ((11+12)\;mod\;37, (42+41)\;mod\;49)=(23,34) (973+678)mod1813⟷((11+12)mod37,(42+41)mod49)=(23,34)。那么还需要知道 ( 23 , 34 ) (23,34) (23,34)对应与 Z M Z_M ZM中的哪一个数,根据上面的推导 A = ( a 1 c 1 + a 2 c 2 ) ( m o d M ) A=(a_1c_1+a_2c_2)(mod\;M) A=(a1c1+a2c2)(modM),下面计算有
a 1 = 23 , c 1 = M 1 × ( M 1 − 1 m o d m 1 ) = 49 × ( − 3 m o d 37 ) = 1666 a 2 = 34 , c 2 = M 2 × ( M 2 − 1 m o d m 2 ) = 37 × ( 4 m o d 49 ) = 148 a_1=23,\;c_1=M_1\times (M_1^{-1}\;mod\;m_1)=49\times (-3\;mod\;37)=1666\\ a_2=34,\;c_2=M_2\times (M_2^{-1}\;mod\;m_2)=37\times (4\;mod\;49)=148\quad\; a1=23,c1=M1×(M1−1modm1)=49×(−3mod37)=1666a2=34,c2=M2×(M2−1modm2)=37×(4mod49)=148
其中 m 1 = 37 , m 2 = 49 m_1=37,m_2=49 m1=37,m2=49, M 1 = M / m 1 = 49 , M 2 = M / m 2 = 37 M_1=M/m_1=49,M_2=M/m_2=37 M1=M/m1=49,M2=M/m2=37,而 M 1 − 1 M_1^{-1} M1−1和 M 2 − 1 M_2^{-1} M2−1需要利用前述的扩展的欧几里得算法(1.1.3节)进行计算:
# 输入M1和m1得到M1的乘法逆元
Enter two numbers:49, 37 # M1 = 49,m1 = 37
gcd(49, 37) = 1 = (-3) * 49 + (4) * 37 # M1前面的系数即为乘法逆元,此处49前面的系数为-3
# 输入M2和m2得到M2的乘法逆元
Enter two numbers:37, 49 # M2 = 37,m2 = 49
gcd(49, 37) = 1 = (-3) * 49 + (4) * 37 # M2前面的系数即为乘法逆元,此处37前面的系数为4
则 49 49 49模 37 37 37运算的乘法逆元为 − 3 -3 −3, 37 37 37模 49 49 49运算的乘法逆元为 4 4 4,即为上面的值。因此 A A A的值为: A = ( 23 × 1666 + 34 × 148 ) ( m o d 1813 ) = 1651 A=(23\times 1666+34\times 148)(mod\;1813)=1651 A=(23×1666+34×148)(mod1813)=1651
可能你会觉得直接计算 ( 973 + 678 ) m o d 1813 (973+678)\;mod\;1813 (973+678)mod1813会更加简单,但是如果当 M M M很大时利用中国剩余定理将十分有用。
2.3 离散对数
下面讲述离散对数问题(Discrete logarithms),离散对数问题是包括Diffie-Hellman密钥交换算法和数字签名算法(DSA)在内的许多公钥算法的基础,下面就来简单介绍一下离散对数问题。
2.3.1 本原根
根据欧拉定理,对于任意互素的正整数a和n有: a ϕ ( n ) ≡ 1 ( m o d n ) a^{\phi(n)}\equiv 1(mod\;n) aϕ(n)≡1(modn),考虑更一般的表达形式:对于任意 a a a和 n n n,有 m m m使得 a m ≡ 1 ( m o d n ) a^m\equiv 1(mod\;n) am≡1(modn)。
当 a a a和 n n n互素时, m m m一定存在,至少 m = ϕ ( n ) m=\phi(n) m=ϕ(n)是成立的,因此有下面关于阶的概念:
- a ( m o d n ) a(mod\;n) a(modn)的阶:使得 a m ≡ 1 ( m o d n ) a^m\equiv 1(mod\;n) am≡1(modn)成立的最小正幂 m m m是 a a a模 n n n的阶
作为示例,下面给出模 19 19 19的正整数幂,需要注意表中行列的取值是十分讲究的,由于当 a a a模 n n n的阶 m m m存在时, a m ≡ 1 ( m o d n ) a^m\equiv 1(mod\;n) am≡1(modn),因此计算正整数幂的时候,只需要计算 { 1 , 2 , 3 , . . . , m } \{1, 2, 3,...,m\} {1,2,3,...,m},因为再往后一定与前面的值重复,即对于 t ∈ N t\in N t∈N和 i ∈ { 1 , 2 , . . . , ϕ ( n ) } i\in \{1,2,...,\phi(n)\} i∈{1,2,...,ϕ(n)}, a t m + i a^{tm+i} atm+i可以表示所有正整数幂,且有 a t m + i ≡ a i ( m o d n ) a^{tm+i}\equiv a^i(mod\;n) atm+i≡ai(modn)。
下表由于事先不知道 m m m的值,故取 m = ϕ ( 19 ) = 18 m=\phi(19)=18 m=ϕ(19)=18,因为 19 19 19是素数,故对于 { 1 , 2 , 3 , . . . , 18 } \{1, 2, 3,...,18\} {1,2,3,...,18}内的整数全与 19 19 19互素,因此这些整数模 19 19 19的阶 m ≤ ϕ ( 19 ) = 18 m\le\phi(19)=18 m≤ϕ(19)=18,故下表的第一行只计算了 a 1 , a 2 , . . . , a 18 a^1, a^2,...,a^{18} a1,a2,...,a18
而第一列中可以看到 a a a依次取值 { 1 , 2 , 3 , . . . , 18 } \{1, 2, 3,...,18\} {1,2,3,...,18},大于 18 18 18的值之所以不考虑是因为以下两点:
- 当 m = 19 n ( n ∈ Z + ) m=19n(n\in Z^+) m=19n(n∈Z+)时, ∀ i ∈ { 1 , 2 , 3 , . . . , 18 } , m i m o d 19 = 0 \forall i\in \{1, 2, 3,...,18\},m^i\;mod\;19=0 ∀i∈{1,2,3,...,18},mimod19=0
- 当 m = 19 n + a ( n ∈ N , a ∈ { 1 , 2 , 3 , . . . , 18 } ) m=19n+a(n\in N, a\in \{1, 2, 3,...,18\}) m=19n+a(n∈N,a∈{1,2,3,...,18})时 m i ≡ ( 19 n + a ) i ( m o d 19 ) ≡ a i ( m o d 19 ) m^i\equiv (19n+a)^i(mod\;19)\equiv a^i(mod\;19) mi≡(19n+a)i(mod19)≡ai(mod19)
因此只计算下表即可知道所有的情况
观察上表,我们发现所有序列都是以 1 1 1为结尾,此时对应的 m m m即为 a a a模 n n n的阶,在 1 1 1之前的数都各不相同,在 1 1 1之后的数则出现了周期性的重复。另外对于一些整数来说,比如 2 , 3 , 10 , 13 , 14 , 15 2,3,10,13,14,15 2,3,10,13,14,15而言,它们的正整数幂的值互不相同,包含了 { 1 , 2 , 3 , . . . , 18 } \{1, 2, 3,...,18\} {1,2,3,...,18},称这样的整数为模数 19 19 19的本原根,下面就是本原根的形式化定义:
- 本原根: a a a称为模数 n n n的本原根,当且仅当 a a a模 n n n的阶为 ϕ ( n ) \phi(n) ϕ(n)。
下面证明一下本原根的一个性质:若 a a a是模数 n n n的本原根,那么 { a 1 , a 2 , . . . , a ϕ ( n ) } m o d n \{a^1, a^2,...,a^{\phi(n)}\}\;mod\;n {a1,a2,...,aϕ(n)}modn各不相同,且均与 n n n互素。
【证明】若 a a a是模数 n n n的本原根,那么 { a 1 , a 2 , . . . , a ϕ ( n ) } m o d n \{a^1, a^2,...,a^{\phi(n)}\}\;mod\;n {a1,a2,...,aϕ(n)}modn各不相同,且均与 n n n互素。
a a a的正整数幂各不相同是容易理解的,因为若当 1 ≤ i < j ≤ ϕ ( n ) 1\le i<j\le\phi(n) 1≤i<j≤ϕ(n)时 a i ≡ a j ( m o d n ) a^i\equiv a^j(mod\;n) ai≡aj(modn),根据 a i a^i ai与n互素知 a j − i ≡ 1 ( m o d n ) a^{j-i}\equiv 1(mod\;n) aj−i≡1(modn),则a模n的阶为 j − i ≤ ϕ ( n ) j-i\le \phi(n) j−i≤ϕ(n)与a模n的阶是 ϕ ( n ) \phi(n) ϕ(n)矛盾,这个推理用到了 a i a^i ai与n互素的假设。
下面来证明 { a 1 , a 2 , . . . , a ϕ ( n ) } m o d n \{a^1, a^2,...,a^{\phi(n)}\}\;mod\;n {a1,a2,...,aϕ(n)}modn均与 n n n互素,假设 ∃ i ∈ { 1 , 2 , . . . , ϕ ( n ) } \exist i\in \{1,2,...,\phi(n)\} ∃i∈{1,2,...,ϕ(n)}使得 a i m o d n a^imod\;n aimodn与 n n n不互素,那么 g c d ( ( a i m o d n ) , n ) = r > 1 gcd((a^i\;mod\;n), n)=r>1 gcd((aimodn),n)=r>1,而根据欧几里得算法有 g c d ( a i , n ) = g c d ( n , ( a i m o d n ) ) gcd(a^i, n)=gcd(n,(a^i\;mod\;n)) gcd(ai,n)=gcd(n,(aimodn)),故 a i m o d n a^imod\;n aimodn与n不互素等价于 a i a^i ai与n不互素,但是 a i a^i ai与n不互素说明 a i , a i + 1 , . . . , a ϕ ( n ) a^i, a^{i+1},...,a^{\phi(n)} ai,ai+1,...,aϕ(n)均与n不互素,而 a ϕ ( n ) ≡ 1 ( m o d n ) a^{\phi(n)}\equiv 1(mod\;n) aϕ(n)≡1(modn),故 a ϕ ( n ) m o d n a^{\phi(n)}\;mod\;n aϕ(n)modn与n互素,也即 a ϕ ( n ) a^{\phi(n)} aϕ(n)与 n n n互素,故假设不成立,则 a i a^i ai与 n n n互素。
既然如此,那么考察两个集合 R = { ( a 1 m o d n ) , ( a 2 m o d n ) , . . . , ( a ϕ ( n ) m o d n ) } R=\{(a^1\;mod\;n), (a^2\;mod\;n),...,(a^{\phi(n)}\;mod\;n)\} R={(a1modn),(a2modn),...,(aϕ(n)modn)}和集合 X X X,集合 X X X是与小于等于 n n n,且与 n n n互素的正整数的集合,设 X = { x 1 , x 2 , x 3 , . . . , x ϕ ( n ) } X=\{x_1,x_2,x_3,..., x_{\phi(n)}\} X={x1,x2,x3,...,xϕ(n)}
当 n = 1 n=1 n=1时,显然有 R = X R=X R=X,考虑 n > 2 n>2 n>2,由上面的推理可知, R R R有 ϕ ( n ) \phi(n) ϕ(n)个元素,且所有元素小于 n n n与 n n n互素,恰好满足集合 X X X的定义( n > 2 n>2 n>2时 X X X内的元素只能小于 n n n),那么 R = X R=X R=X,综上 R = X R=X R=X。
不过上面本原根的定义十分抽象,根据上面的证明可以发现本原根更直观的定义就是:
- 本原根:设 X X X为小于等于 n n n且与 n n n互素的正整数集合,即 X = { x 1 , x 2 , x 3 , . . . , x ϕ ( n ) } X=\{x_1, x_2, x_3, ..., x_{\phi(n)}\} X={x1,x2,x3,...,xϕ(n)},其中 ∀ i ∈ { 1 , 2 , 3 , . . . , ϕ ( n ) } \forall i\in\{1, 2, 3, ..., \phi(n)\} ∀i∈{1,2,3,...,ϕ(n)}有 g c d ( x i , n ) = 1 gcd(x_i, n)=1 gcd(xi,n)=1, a a a是 n n n的本原根当且仅当集合 { ( a 1 m o d n ) , ( a 2 m o d n ) , . . . , ( a ϕ ( n ) m o d n ) } = X \{(a^1\;mod\;n), (a^2\;mod\;n),...,(a^{\phi(n)}\;mod\;n)\}=X {(a1modn),(a2modn),...,(aϕ(n)modn)}=X。
从两个定义看,求解本原根的过程是复杂的,而且不是所有整数都有本原根,可以证明(这里不证),只有形式 2 , 4 , p α , 2 p α 2,4,p^{\alpha },2p^{\alpha } 2,4,pα,2pα的整数才有本原根,其中 p p p是任意奇素数,$\alpha $为正整数。
2.3.2 离散对数难题
引入本原根的概念,其实是为了介绍离散对数问题,对于对数大家是不陌生的,对数函数
y
=
l
o
g
a
x
(
a
>
0
,
a
≠
1
)
y=log_ax(a>0,a\ne 1)
y=logax(a>0,a=1)和指数函数
y
=
a
x
(
a
>
0
,
a
≠
1
)
y=a^x(a>0,a\ne 1)
y=ax(a>0,a=1)是一对反函数,那么从这个定义出发,根据本原根的定义,对于一个素数
p
p
p(本原根定义中不要求素数)而言,可以发现,小于等于素数p且与之互素的正整数集合为
{
1
,
2
,
.
.
.
,
p
−
1
}
\{1,2,...,p-1\}
{1,2,...,p−1},故设
a
a
a为本原根,则
a
a
a满足:
{
(
a
1
m
o
d
p
)
,
(
a
2
m
o
d
p
)
,
.
.
.
,
(
a
ϕ
(
p
)
m
o
d
p
)
}
=
{
(
a
1
m
o
d
p
)
,
(
a
2
m
o
d
p
)
,
.
.
.
,
(
a
p
−
1
m
o
d
p
)
}
=
{
1
,
2
,
.
.
.
,
p
−
1
}
\{(a^1\;mod\;p),(a^2\;mod\;p),...,(a^{\phi (p)}\;mod\;p)\} \\ = \{(a^1\;mod\;p),(a^2\;mod\;p),...,(a^{p-1}\;mod\;p)\} \\ = \{1,2,...,p-1\}\qquad\qquad\qquad\qquad\qquad\qquad
{(a1modp),(a2modp),...,(aϕ(p)modp)}={(a1modp),(a2modp),...,(ap−1modp)}={1,2,...,p−1}
而对于任何整数 b b b有 b m o d p ∈ { 1 , 2 , . . . , p − 1 } b\;mod\;p\in \{1,2,...,p-1\} bmodp∈{1,2,...,p−1},故 ∃ i ∈ { 1 , 2 , . . . , p − 1 } \exist i\in \{1,2,...,p-1\} ∃i∈{1,2,...,p−1}使得 a i ≡ b ( m o d p ) a^i\equiv b(mod\;p) ai≡b(modp),此时 i i i就被称为以 a a a为底模 p p p运算的 b b b的离散对数,记作 i = d l o g a , p b i=dlog_{a,p}b i=dloga,pb:
- 离散对数:若 a i ≡ b ( m o d p ) a^i\equiv b(mod\;p) ai≡b(modp),此时 i i i就被称为以 a a a为底模 p p p运算的 b b b的离散对数,记作 i = d l o g a , p b i=dlog_{a,p}b i=dloga,pb
不过离散对数是基于本原根的概念,只有存在本原根时才存在唯一的以 a a a为底模 m m m的离散对数,而模数 m m m一般选为素数,因为素数存在本原根,下面给出以 2 2 2为底( 2 2 2是 29 29 29的本原根)模 29 29 29的离散对数 d l o g 2 , 29 a dlog_{2,29}a dlog2,29a:
a a a | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
d l o g 2 , 29 a dlog_{2,29}a dlog2,29a | 28 | 1 | 5 | 2 | 22 | 6 | 12 | 3 | 10 | 23 | 25 | 7 | 18 | 13 |
a a a | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
d l o g 2 , 29 a dlog_{2,29}a dlog2,29a | 27 | 25 | 21 | 11 | 9 | 24 | 17 | 26 | 20 | 8 | 16 | 19 | 15 | 14 |
基于上面的讨论,给出求解正整数 n n n的本原根的算法实现:
# 利用Euclid算法计算最小公因数gcd(a, b)
def Euclid_gcd(a, b):
r1 = max(abs(a), abs(b))
r2 = min(abs(a), abs(b))
if r2 == 0:
return r1
else:
return Euclid_gcd(r2, r1%r2)
# 求与小于等于n且与n互素的正整数集合
n = eval(input("Please enter a number: "))
X = set()
for i in range(1, n, 1):
if Euclid_gcd(i, n) == 1:
X.add(i)
# 求解n的本原根
for i in range(1, n, 1):
A = set()
for j in range(1, len(X)+1):
A.add(pow(i, j, n)) # pow(i, j, n)计算了i^j mod n
if A == X:
print(i, end = " ")
下面阐述一下基于离散对数的困难问题,对于方程 y = g x m o d p y=g^x\;mod\;p y=gxmodp,已知 g , x , p g,x,p g,x,p可以很容易计算 y y y,而已知 y , g , p y,g,p y,g,p很难计算 x x x,是指数级别复杂度的,比如你在上面的程序中想要计算 2 127 − 1 2^{127}-1 2127−1( 39 39 39位的素数)的本原根,程序可能会运行很久,问题就在于计算一次 g x m o d p g^x\;mod\;p gxmodp最坏要 g g g次乘法,最好也要 l o g ( g ) log(g) log(g)次乘法,下面给出计算 g x m o d p g^x\;mod\;p gxmodp比较有效的算法:
def square(n):
return n*n
# 计算g^x mod p
def exp_mod(g, x, p):
if x == 0:
return 1
if x % 2 == 0:
return square(exp_mod(g, x//2, p)) % p # x是偶数,g^x mod p = (g^(x/2) mod p)^2 mod p
else:
return (g * exp_mod(g, x-1, p)) % p # x是奇数,g^x mod p = ((g^(x-1) mod p)*g) mod p
g, x, p = eval(input("Please Enter three number:"))
print(exp_mod(g, x, p))