DLP离散对数
基础知识
简单了解几个数论的概念会更好的理解离散对数问题。
欧拉定理:对于任意的只要,那么就有
模指数的阶:与m互质的整数a,我们记满足的最小正整数n为a模m的阶
推论:对于任意的只要,为a模m的阶,那么就有
原根:若存在与m互质的整数,并且模的阶为,那么我们称模m有原根,并称为模的一个原根。实际上就是阶等于的时候原根存在
离散对数
- 了解了指数、原根和阶的概念,其实还可以发现一个规律:设a模m的阶为,那么根据同余的指数运算性质可以发现,,这个指数运算得到的模结果其实发生循环,b的取值范围其实就为,模的指数运算的结果存在周期性,其周期为。
- 这里的,在抽象代数的群论中有一个称呼即,也称为本原元。设G是一个群(可以理解为一个集合,该集合里面的元素可以满足特定的运算,例如集合:),如果集合中存在一个元素,通过对g进行重复的群运算,可以得到G中的每个元素,那么g就被称为G的生成元。
- 由上面的指数、原根和阶的定义,就可以引入一个离散对数的问题,已知模的幂
y
、底数g
、模数p
,要我们求出指数x
使得下面式子成立:- 求解这个问题通用解法只能是从
0~n-1
(n为g模p下的阶)遍历,判断是否 - 当模数
p
比较小的时候,并且n
也较小的时候,求得x
算是比较容易的 - 但是当模数
p
很大、下式的阶n
也很大或者下式存在原根,那要遍历的范围就相当的大(这就导致了在有限的时间无法求得x
,这就是著名的离散对数问题)
- 求解这个问题通用解法只能是从
- 离散对数和大整数分解问题类似,都是不能够在有限的时间内得到答案。基于大整数分解问题得到了著名的
RSA
加密算法,而基于离散对数问题密码学家也提出了对应的加密算法如Diffie-Hellman密钥交换协议
(简称DH密钥交换协议)、ElGamal
加密算法、DSA
数字签名算法、ECDLP
椭圆曲线上的离散对数问题。
求解离散对数的方法
暴力破解法
暴力破解法是最一般的求解离散对数的算法,就是1遍历到n-1
,计算每个模指数的值,直到找到一个指数使其满足才退出循环(由于计算阶还需要时间,这里一般n都是直接用模数的欧拉函数)
1 | def discrete_log(y,g,p): |
BSGS算法
-
BSGS算法本质上也是暴力破解,但是BSGS是经过算法优化后再进行遍历操作,时间复杂度会低一些,但是该算法的思想有用上
meet-in-the-middle
即中间相遇攻击的思想。其推导过程如下:-
对于下面的式子,我们可以得到,其中,,这样,同样可以达到从
0~p-1
的遍历效果。 -
接下来先选取一个
K
(K
取时间复杂度达到最小),遍历计算的结果,并且存储计算结果及其对应的b
。 -
存储得到
b
后,再遍历a
的取值计算,并判断计算结果与前面计算的的其中一个相等(这里就会出现查找的步骤,使用哈希表查找应该是最快的),如果找到相等的数,那么也就找到了这个式子的指数x
-
最后计算,即可得到结果。
-
注意:BSGS有俩中构造方式一种就是
Ka-b
还有一种是Ka+b
这俩中形式,但是貌似Ka+b
是论文原始的构造方法
-
- 下面是
BSGS
的伪代码:
1 | Input: g,y,p |
- Python代码如下:
1 | def bsgs(p,g,y): |
Pohlig-Hellman算法
Pohlig-Hellman
算法是经典用于加速离散对数求解的算法,只适用于一种模数比较特殊的情况即模数p
要满足b-光滑数,该算法的本质其实就是将大整数下的离散对数问题,转换为若干个小模数下的离散对数问题,并且使用中国剩余定理求解
B-Smooth number
(B光滑数):一个正整数它的所有质因数都不大于B,则该正整数就被称为B光滑数,而这个数B
并不确定,但是它通常取决于算法的需要和计算资源。
Pollard λ算法
sagemath相关函数
sage
中discrete_log
就是利用Pohlig-Hellman
算法和BSGS
算法实现的。如果使用sage,只需要调用discrete_log
这个函数即可。- 详细说明一下
discrete_log
的参数,记要求的相关高次同余式如下:- 参数
a
:就是模幂的结果 - 参数
base
:作为底数 - 参数
ord
:群的阶,如果知道群的阶就可以填入,可以加快计算 - 参数
bounds
:指数的搜索范围,即在给定区间内寻找离散对数,可以加快搜索,格式(lower_bound,upper_bound)
例如:(100,1000)
- 参数
operation
:群操作类型,默认为乘法 - 参数
identity
:单位元,通常是函数内部自动处理,若自定义群结构就像ECC
那样,可以手动设置 - 参数
inverse
:取逆函数,默认为None
,也可以传一个函数用于计算逆元 - 参数
op
:自定义操作函数可选 - 参数
algorithm
:默认是bsgs
也就是默认使用bsgs
算法求离散对数,还可以有rho
选项(使用pollard_rho算法求离散对数),lambda
选项(λ 算法Pollard lambda,又叫“kangaroo”方法),automatic
选项Sage自动判断哪种算法更优
- 参数
1 | discrete_log( |
discrete_log
的使用:
1 | b = Mod(2,37) # 先使用Mod(n,m)创建一个底数为n,模数为m的对象,返回的是整数n,n作为Z/mZ中的元素 |
discrete_log
源码如下:
1 | def discrete_log(a, base, ord=None, bounds=None, operation='*', identity=None, inverse=None, op=None, algorithm='bsgs'): |
离散对数加密
ElGamal加密算法
ElGamal
加密算法是一种基于离散对数难题的公钥加密算法,由Taher ElGamal
于1985
年提出。是非对称加密算法。
ElGamal
提出了一个基于(即模数p为素数)上离散对数问题的公钥密码体制.设p是一个素数,使得上的离散对数问题是最难处理的
-
ElGamal
加密算法如下:-
首先选取一个大素数
p
,令生成元为g
-
选取明文空间范围中的整数
-
而密文也是范围内的整数。
-
选取密钥
K
有四个元素,其中三个元素作为公钥,一个元素作为私钥,密钥满足关系,其中是公钥,是私钥 -
加密函数如下:
-
解密函数:
-
-
解密推导过程:
注:ElGamal密码体制中,加密运算是随机的,因为密文既依赖于明文m,也依赖于加密者所选择的随机数k,所以对于同一个明文,会有p-1个可能的密文,这个加密体制其实是概率加密
DH密钥交换协议
-
DH密钥交换也是基于离散对数问题的。设是一个素数,使得上的离散对数问题是难处理的,另g为生成元
-
密钥交换者A:
- 随机选择一个整数
- 计算,并且将发送给B
-
密钥交换者B:
- 随机选择一个整数
- 计算,并且将发送给A
-
双方得到对方发送的值后进行计算,交换者A计算:;交换者B计算
-
这样就可以得到:
- 由于离散对数的困难性问题,这就导致了攻击者知道或者的其中一个得到是非常困难的。
- 并且这里又引出一个新的困难性问题CDH问题:给定,,计算也是很困难的。