算法数论-素性检验算法
一些算法概念
判定问题
:只回答是
或者否
的问题,也就是算法的返回值只有True
或者False
随机算法
:使用了随机数的算法
判定问题偏是(Yes-biased)Monte-Carlo算法
:算法给出是
的回答总是正确的,给出否
的回答也许不正确。如果对应该为是
的输入至多以的概率给出否
的答案则说该算法具有错误概率
判定问题偏否(No-biased)Monte-Carlo算法
:算法给出否
的回答总是正确的,给出是
的回答也许不正确。如果对应该为否
的输入至多以的概率给出是
的答案则说该算法具有错误概率
素性检验介绍
-
在公钥密码学中经常都是要生成一个大素数,而大素数是没办法直接生成的,需要随机生成一个大数,在判断该数是否为素数。
-
由于生成的是一个大数,程序没办法遍历2到该数的平方根发现该数是否有因子,这种方法对大数并不高效,所以就需要设计一个算法判断一个大数是否为素数。判断一个数是否为素数这个行为就是素性检验
-
具体介绍一下生成随机素数的一般方法:
- 生成随机整数
n
- 判断
n
是否为素数,有两种判断方法,即确定性算法
、随机算法
:- 确定性算法:以概率1确定n是否为素数,2002年三位印度计算机科学家发现了第一个多项式时间的算法,称为AKS素性检测,计算复杂度为
- 随机算法:如果n通过某些素数判定准则,则n可能为素数,如果不通过则n肯定为合数。如:
Fermat素性检测
、Miller-Rabin素性检测
、Solovay-Strassen素性检测
、Lucas素性检测
- 生成随机整数
-
这里先对成功概率进行分析:在
1~N
之间随机选取一个数,其为素数的概率约为,这个其实就是素数的密度。 -
在RSA加密算法中,大素数
p、q
选取为512bit
的素数,其成功概率为,即可以在随机选取的355
个数中以高概率找到一个素数的。
Fermat素性检验
-
Fermat
素性检验是一个判定问题偏否(No-biased)Monte-Carlo算法
,该检验算法是随机算法,目前该素性检验方法已经过时了。 -
应用:PGP(邮件加密软件)使用
Fermat
素性检测算法,在PGP中,通过测试的数为Carmichael
数的概率小于 -
Fermat
素性检验算法原理其实就是费马小定理:若p是素数,则,或者。 -
算法的具体过程:
-
该算法的代码实现:
1 | def Fermat_test(): |
Fermat
素性检验存在的缺陷:存在这样的合数n
,使得,这样的合数称为Carmichael
数,如561
是一个Carmichael
数。
Miller-Rabin素性检验
-
Miller-Rabin
算法对于合数问题是一个偏是的Monte Carlo
算法。 -
Miller-Rabin
素性检验,也被称为强伪素数检验,是对Fermat
检测的改进。该算法目前为止很常用。 -
Miller-Rabin
素性检验的原理:- 当n为素数的时候,对于二次同余方程
- 设,其中m是奇数,若,则可以由费马小定理得到:
- 如果
- 如果
- …
- 如果
- 这样对于序列就会得到这样的一个序列:或者。
- 对于一个随机数,按照上述方法计算,如果
p
是素数,就会得到序列或者,如果p
不是素数,就不会得到该序列
-
算法具体过程:
-
第一步:先把写成的形式,其中m是一个奇数
-
第二步:使用随机数生成器,生成一个整数
-
第三步:
- 。这里直接先从开始检查
- ,
return "n is prime"
。先检查形式是否为(1,1,...,1)
。
-
第四步:
-
for i<- 0 to k-1
-
do
:,
return "n is prime"
此时判断形式是否为(*,...,*,-1,1,...)
) -
return "n is composite"
-
-
-
代码实现如下:
1 | def Miller_Rabin_test(): |
- 错误概率分析:
- 如果黎曼猜想为真,
Miller-Rabin
素性检验可以转为确定性算法。当目前算法的确定性与否还不知道。 - 如果
n
是奇合数,则在范围内至多有个a能让n
通过Miller-Rabin
检测 - 这说明奇合数只有至多的概率通过一次
Miller-Rabin
检测,则奇合数通过k
次的Miller-Rabin
检测的概率至多为(但是这并不是错误概率) - 错误概率:
n
通过了素性检测,但n
是合数的概率。(该问题是一个条件概率的问题)。先定义两个随机变量也就是,定义a: 一个特定长度的随机奇整数n是合数
,定义b: 算法连续回答了m次"n是一个素数"
,则求错误概率其实就是求条件概率,也就是当事件b
发生时,事件a
发生的概率。- 可以很容易知道
奇整数n为素数的概率
:,因为素数在整数的分布为,而在奇整数的概率就翻倍了。这样就可以得到 - 还可以知道
在已知n为奇素数条件下,事件b是必然发生
即:,由条件概率 - 由上面可以知道
在已知n为奇合数条件下,算法m次回答"n是一个素数"的概率
:由条件概率可以知道, - 那么由条件概率和全概率的公式就可以得到:
- 可以很容易知道
- 从错误概率的推导可以看出,随着检测次数的增加,错误概率是逐渐降低的。
- 如果黎曼猜想为真,
- 下图给出错误概率的一张表:
Solovay-Strassen素性检验
Lucas素性检验
Python-Crypto.Util.number源码
- 对于Python中的
Crypto.Util.number
应该都不陌生,经常都在用,这里主要分析三个函数的源码,即getPrime
、isPrime
、_rabinMillerTest
这三个函数,其中getPrime
中有使用isPrime
函数,而isPrime
中有使用的就是_rabinMillerTest
函数作为素性检测算法 - 一般来说都是使用
pycharm
作为python
的开发环境,所以这里就说明一下pycharm
中如何找到该源码(没下载的要先下载),首先打开venv->Lib->
这个目录
- 然后找到
Crypto
这个包,再找到Crypto
中Util
这个子包
- 最后找到
number.py
这个文件即可
getPrime
1 | def getPrime(N, randfunc=None): |
isPrime
1 | def isPrime(N, false_positive_prob=1e-6, randfunc=None): |
_rabinMillerTest
1 | def _rabinMillerTest(n, rounds, randfunc=None): |