根据SCNU斌头老师的课件整理
整理者:0.H.P
可除性与带余除法
- 定理:设a,b ,,那么,使得其中,且这对整数q,r为上述a,b所唯一确定。
- 证明:
(1).证r的范围:
将实数轴分为左闭右开的长度均为b的无穷个小区间,即
可得a必定落在某一区间内,故,使得.令,则,又因为,故得.
(2).证q与r的唯一性:
首先证a所在区间的唯一性:运用反证法。
假设且,其中,那么假设.得
那么假设,那么有:
故得:a所在区间唯一。又由于,得q唯一。又a=qb+r,得r唯一。
证毕。
欧几里得算法(gcd)
目的:
求两个数的最大公约数
公式:
直到
时间复杂度:
递归算法:
def gcd(a,b):
if b==0:
return a
else:
return gcd(b,a%b)
迭代算法:
def gcd(a,b):
while b!=0:
y=b
b=a%b
a=y
return a
拓展欧几里得算法(egcd)
目的:
求线性方程组的一组解
方法:
以此循环
def egcd(a,b):
r0,r1,s0,s1=1,0,0,1
while b:
q,a,b=a//b,b,a%b
r0,r1=r1,r0-q*r1
s0,s1=s1,s0-q*s1
print(a,r0,s0)
费马小定理
公式:
p是素数时,
有
证明:
取
由消去律得
故得
所以
即
例题:
解:
得
所以
故
欧拉公式
公式:
证明:
设集合
与条件矛盾,故得
所以
由消去律得
米勒拉宾素数测试
米勒拉宾算法:
一种检测一个整数是否为素数的算法,准确率约大于3/4,即伪素数通过检验的概率约小于1/4。
介绍该算法前,先了解素数的两个性质。
- 若是素数,那么存在,当且仅当或时,有
- 若是素数,且那么有:,有,满足一下条件之一:
(1).
(2). 在中,必然存在一个数模p与-1同余
理解这两个性质:
首先,从费马小定理出发,有,那么,由于p是素数,所以,那么可表示为
那么得,那么必然有或(由此理解性质1)
然后,将按以上思路进行分治,直到,分治过程中,要么所有值都为1,那么必然;或者中间某个值为-1.(由此理解性质2)
算法步骤:
- 将分解至,得到q
- 选取随机数
- 若,通过检验;否则循环一下操作
- 计算,其中若出现有结果为-1,那么通过检验,否则不通过
应用:
一般用作检验时,循环10次以上米勒拉宾操作,以保证正确概率。
可用该算法,随机生成一个大整数,然后检验该数是否为素数的方法,生成随机素数。
代码:
#A quickly multiply algorithm with modding n
def Qmul(a,b,n):
r=0
while b:
if b&1:
r=(r+a)%n
b=b>>1
a=(a<<1)%n
return r
#A quidckly exponential algorithm with modding n
def QPow(a,x,n):
result=1
while x:
if x&1:
result=(result*a)%n
x=x>>1
a=(a*a)%n
return result
#Find the number = (n-1)/2^k
def Find_q(n):
while not n&1:
n=n>>1
return n
#Miller Rabin algorithm
def Miller_Rabin(a,n):
q=Find_q(n-1)
aq=QPow(a,q,n)
#final condition,q=n-1
while q<n:
if aq==1 or aq==-1:
return True
#make aq = aq(q*2^j)
aq=QPow(aq,2,n)
q=q<<1
return False
群
性质:
0.满足封闭性;
1.满足结合律;
2.存在单位元;
3.存在逆元。
单位元唯一性:
设亦为G的单位元
那么有:
所以
逆元唯一性:
设
存在性:在群操作中,运算满足封闭性,h恒存在
唯一性:设有另一个逆元h,使得
那么:,由消去律得
子群(subgroup):
循环群(cyclic group):
阶:
满足
例子:
群,阶为,生成元个数,生成元,有
群,阶为,生成元个数,生成元:
定理1:
若存在正整数k,使得 ,当且仅当k整除n.
证:
充分性:令
必要性:令
由消去律得:
定理2:
证:
设有正整数m,使得
故
故
所以
陪集(coset)
定义:
H是G的子群,对于
左陪集:
右陪集:
例子:
设
遍历:
得①③,②④分别相等,所以左陪集有俩:与
同理可求右陪集
性质1:
H是G的subgroup,则有
性质2:划分
所有左陪集构成一个划分,所有右陪集构成一个划分
拉格朗日定理
定义:
证:
由
由于每个陪集不同,得:
推论一:
群G的阶为n,所有
推论二:
G是素数阶群,则存在
同构(Isomorphisms)
定义:
群
满足one-to-one(单射) and onto(满射)映射
称φ为一个同构(isomorphic)
证明方法:
1.构造映射;
2.证明阶相同;
3.满足群操作;
4.双射
5.群操作保持:
即先映射后计算等于先计算后映射(证同态)
同态(Homomorphisms)
定义:
群,φ是两者间的一个映射,对于所有
正规子群(normal subgroup)
定义:
(即左右陪集相等)
性质:
若同态,则
1.
2.
3.
4.
商群(quotient group)
定义:
则
性质:
商群的阶等于陪集元素的个数
即
例子:
得
满足
中国剩余定理
概念:
一种求一次同余式组的算法
算法:
有一次同余式组:
解:
令:
(乘法逆元)
#algorithm of egcd
def egcd(a,b):
r0,r1,s0,s1=1,0,0,1
while b:
q,a,b=a//b,b,a%b
r0,r1=r1,r0-q*r1
s0,s1=s1,s0-q*s1
return r0
#algorithm of CRT
def CRT(a,m):
M,x=1,0
b=list()
b_=list()
for n in range(len(m)):
M=M*m[n];
for i in range(len(m)):
b.append(M//m[i])
'''
compute b_
because b_[i]*b[i]=1(mod m[i])
so b[i]*b_[i]-1=c1*m[i]
than b[i]*b_[i]+c2*m[i]=1
use egcd to compute the result
'''
b_.append(egcd(b[i],m[i]))
'''
when the result is a negative number
let it become a positive number which is a Equivalence class about b_[i]
'''
if b_[i]<0:
b_[i]=b_[i]%m[i]
x=(a[i]*b[i]*b_[i]+x)%M
return x
证明:
思路:构造法证存在;反证法证唯一。
例题:
Using CRT to solve the system of congruence:
x ≡ 1 (mod 5)
x ≡ 2 (mod 7)
x ≡ 3 (mod 9)
x ≡ 4 (mod 11)
解:由题得:
令:
所以
因为
得
由拓展欧几里得算法解得
解得
大整数分解
pollard's p-1算法
目的:
求合数N的数因子
思路及算法:
1.设数字m,且,p是素数且为N的因子
那么,由费马小定理得:
故有;
2.令;
3.计算;
4.若结果为1或者N,n自增1,重复步骤2-3,否则,,即为答案;
def gcd(a,b):
if b==0:
return a
else:
return gcd(b,a%b)
def Pollard_PM1(N):
a=2
for i in range(2,N):
a=(a^i)%N
divisor=gcd(a-1,N)
if divisor!=1 and divisor!=N:
return divisor
return 1
pollard's rho算法
目的:
求合数N的数因子
思路及算法
1.假设N有两个数因子x和y
令
2.设有函数
令
,,d即为答案
#伪代码
def PollardRho(N):
x1 = x2 = Random_ZN_Star(N)
for i in range(1, 2^(N.nbits()//2)):
x1 = F(x1, N)
x2 = F(F(x2, N), N)
p = gcd(x1 − x2, N)
if p != 1 and p != N:
return p
设
import random
import cmath
def F(x):
return x^2-1
def gcd(a,b):
if b==0:
return a
else:
return gcd(b,a%b)
def PollardRho(N):
i,k=1,2
x=random.randint(0,N-1)
y=x
while True:
i=i+1
x=F(x)%N
divisor=gcd(y-x,N)
if divisor!=1 and divisor !=N:
return divisor
if i==k:
y,k=x,2*k
离散对数
g是群G的生成元,|G|=p-1,,求
Pohlig-Hellman 算法
1.令
2.
得
那么:有
由于
故得
思路:
为求x,构造一组一次同余式组,以CRT求解。
那么,每个可以用p-1的各个因子去构造。
#Problem: Given base g, y \in <g>, y = g^x mod p, to find x.
def Pohlig_Hellman(y, g, p):
prime_list = factor(p − 1)
n = len(prime_list)
q_list = [prime_list[i][0]^prime_list[i][1] for i in range(n)]
G = [ g^((p − 1) // q_list[i]) for i in range(n) ]
Y = [ y^((p − 1) // q_list[i]) for i in range(n) ]
val_list = [discrete_log(Y[i], G[i]) for i in range(n)]
modulus_list = [q_list[i] for i in range(n)]
x = crt(val_list, modulus_list) # solve the CRT problem.
return x
大步小步算法
1.大步
令
那么有
2.小步
令
有
3.算x
得
故
# Input: g,y,n where g is the base, y = g^x mod p,
def BGS(g, y, p):
s = floor(sqrt(p))
A = [(y*(g^r) % p) for r in range(0, s)] #Baby Step.
B = [(g^(t*s) % p) for t in range(1, s+1)] #Giant Step.
r,t = 0,0
for u in A:
for v in B:
if u == v: #Collision.
r, t = A.index(u), B.index(v)
return ((t+1)*s − r) % p # Return x
pollard's rho算法
算法
1.设置变量:
2.设置随机函数F()
令
直到出现
3.那么
#Input: y = g^x mod p; Output: x
def PollardRhoDLOG(y):
lefta, lg, ly = 1, 0, 0 # lefta = g^lg * y^ly
righta, rg, ry = y, 0, 1 # righta = g^rg * y^ry
while lefta != righta:
lefta, lg, ly = F(lefta, lg, ly)
righta, rg, ry = F(righta, rg, ry)
righta, rg, ry = F(righta, rg, ry)
s, t = lg − rg, ry − ly
if s == 0:
return ’fail’
return s * (t^(−1))
关于随机函数
Pollard suggests:
时间开销
Θ()