密码学笔记:离散对数求解相关算法实现

博客:https://blog.slight-wind.com/

密码学笔记:离散对数求解相关算法实现

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G2ZOYqwR-1584639702715)(01.png)]

在整数中,离散对数(英语:Discrete logarithm)是一种基于同余运算和原根的一种对数运算。而在实数中对数的定义 log ⁡ b a \log_ba logba 是指对于给定的 a 和 b,有一个数 x,使得 b x b^{x} bx = a。相同地在任何群 G 中可为所有整数 k 定义一个幂数为 b k b^{k} bk,而离散对数 log ⁡ b a \log_ba logba 是指使得 b k b^{k} bk = a 的整数 k。 离散对数在一些特殊情况下可以快速计算。然而,通常没有具非常效率的方法来计算它们。公钥密码学中几个重要算法的基础,是假设寻找离散对数的问题解,在仔细选择过的群中,并不存在有效率的求解算法。Wikipedia

索引

  • Shank’s Babystep-Giantstep Algorithm (BSGS离散对数算法)

  • 中国剩余定理(Chinese remainder theorem)

  • Pollard’s rho (分解质因数算法)

  • Pohlig-Hellman Algorithm (Pohlig-Hellman 离散对数算法)

Shanks’s Babystep-Giantstep Algorithm

对于同余式 g x ≡ h g^x ≡ h gxh (mod p) ,g 为质数 p 的一个原根,这种情况便可以使用 Shanks 算法。令 N = p-1,相比于暴力枚举法 O ( N ) O(N) O(N) 的时间复杂度,Shanks 算法可以将时间复杂度降到 O ( N ) O(\sqrt{N}) O(N ) .

求解过程

  1. 计算 n = ⌊ N ⌋ \lfloor {\sqrt{N}} \rfloor N + 1 .
  2. 构造出两个列表:
    1. List1 = [ 1 1 1 , g g g , g 2 g^2 g2 , g 2 g^2 g2 , . . . ... ... , g n g^n gn ]
    2. List2 = [ h h h , h h h ⋅ \cdot g − n g^{-n} gn , h h h ⋅ \cdot g − 2 n g^{-2n} g2n , h h h ⋅ \cdot g − 3 n g^{-3n} g3n , . . . ... ... , h h h ⋅ \cdot g − n 2 g^{-n^2} gn2 ]
  3. 在 List1 和 List2 中找到两个相同的元素,即 List1[ i ] == List2[ j ] ,那么就会有 g i = h g − j n g^i = hg^{-jn} gi=hgjn.
  4. 那么 x = i + jn 便是 g x = h g^x = h gx=h 的一个解.

Python 3 实现

#python3.7.6
#Author:Am473ur
#调用函数 sDLP(g,h,p) 返回 g^x≡h (mod p) 的一个解
#Shanks's Babystep-Giantstep Algorithm
from gmpy2 import invert,iroot
from Crypto.Util.number import getPrime

class node:
    def _init_(self):
        self.vue=0
        self.num=0
def cmp(a):
      return a.vue
def init_list(first,g,n,p):
      List=[]
      temp=node()
      temp.vue,temp.num=first,0
      List.append(temp)
      for i in range(1,n+1):
            temp=node()
            temp.num = i
            temp.vue = List[i-1].vue * g % p
            List.append(temp)
      List.sort(key=cmp)
      return List
def sDLP(a,b,p):
    ans=p
    n=iroot(p,2)[0]+1
    L1=init_list(1,a,n,p)
    aa=pow(invert(a,p),n,p)
    L2=init_list(b,aa,n,p)
    i = 0
    j = 0
    while True :
        if (i>=n or j>=n): break
        while (L1[i].vue < L2[j].vue and i<n): i += 1
        while (L1[i].vue > L2[j].vue and j<n): j += 1
        if L1[i].vue == L2[j].vue :
            x=L1[i].num+L2[j].num*n
            return int(x)
p = 552022109
g = 520158203
h = 525148510
print(sDLP(g,h,p))

中国剩余定理(Chinese remainder theorem)

其实这里应该介绍 Pohlig–Hellman 离散对数算法了,但是其主要过程利用了中国剩余定理(CRT),所以也在这里提一下,相关计算和证明过程在百度百科就很容易找到,在此不做赘述。

这里引用 A n I n t r o d u c t i o n t o M a t h e m a t i c a l C r y p t o g r a p h y AnIntroductiontoMathematicalCryptography AnIntroductiontoMathematicalCryptography 书中的一段话:

In addition to being a theorem and an algorithm, we would suggest to the
reader that the Chinese remainder theorem is also a state of mind.

CRT更是一种解决问题的思想,把一个大的问题分解为若干个小的问题分别求解,CRT使得若干个子问题的解可以再组合成原问题的解(同余方程组)。这种算法应用到解决离散对数问题显得非常巧妙。这就是 Pohlig-Hellman 离散对数算法。

Python 3 实现 CRT

#python3.7.6
#Author:Am473ur
# m 和 a 为两个列表,表示同余方程组 x mod m = a (m1,a1;m2,a2;...)
from functools import reduce
from gmpy2 import invert

def CRT(m,a):
      Num=len(m)
      M=reduce(lambda x,y: x*y, m)
      Mi=[M//i for i in m]
      t=[invert(Mi[i], m[i]) for i in range(Num)]
      x=0
      for i in range(Num):
            x+=a[i]*t[i]*Mi[i]
      return x%M

Pollard’s rho (分解质因数算法)

同样是为了实现 Pohlig-Hellman 离散对数算法,我们还需要了解一种分解质因数算法——Pollard’s rho Algorithm 。

Python 3 实现 Pollard’s rho

#python3.7.6
#Author:Am473ur
#通过调用 Factor(n) 进行质因数分解,返回值是因数列表。
from Crypto.Util.number import isPrime
from math import gcd

def f(x):
    return x**2 + 1

def pollard_rho(N):
    xn = 2
    x2n = 2
    d = 1
    while d == 1:
        xn = f(xn) % N
        x2n = f(f(x2n)) % N
        abs_val = abs(xn - x2n)
        d = gcd(abs_val, N)
    return d

def Factor(n):
    ans=[]
    while True:
        temp=pollard_rho(n)
        ans.append(temp)
        n=n//temp
        if n==1:return ans
        if isPrime(n):
            ans.append(n)
            return ans
'''
n=12345678754345678765456789876587654567899876
print(Factor(n))
output:[4, 3109, 3553454208763, 279372423577347576184497407]
'''

Pohlig-Hellman Algorithm (Pohlig-Hellman 离散对数算法)

若 p-1 是一个 B-smooth number ,Pohlig-Hellman 离散对数算法只有在 B 较小的时候表现良好,所以对于解决离散对数问题(DLP)来说,其仍是微不足道的。同时也说明了如果在加密过程中选择了 p-1 的最大质因子较小的质数 p,那么此时的 DLP 可能容易受到Pohlig-Hellman 算法的攻击。

In number theory, a n-smooth (or n-friable) number is an integer whose prime factors are all less or equal to n.–Wikipedia

Pohlig-Hellman 离散对数算法

对于离散对数问题 g x g^x gx ≡ ≡ h h h (mod p) , N = p-1 为 G 的秩,根据 唯一分解定理 : N N N = = = q 1 e 1 q_1^{e_1} q1e1 ⋅ \cdot q 2 e 2 q_2^{e_2} q2e2 ⋅ ⋅ ⋅ \cdot\cdot\cdot q t e t q_t^{e_t} qtet

  1. 对 N 进行分解,得到因数列表 List q e q^e qe . 即 qe = [ q 1 e 1 q_1^{e_1} q1e1, q 2 e 2 q_2^{e_2} q2e2 , ⋅ ⋅ ⋅ \cdot\cdot\cdot , q t e t q_t^{e_t} qtet]
  2. 用已知的每一项 q i e i q_i^{e_i} qiei 计算 List g ( p − 1 ) / q e g^{(p-1)/q^e} g(p1)/qe 和 List h ( p − 1 ) / q e h^{(p-1)/q^e} h(p1)/qe .
  3. 对于每一组 g ( p − 1 ) / q e g^{(p-1)/q^e} g(p1)/qe h ( p − 1 ) / q e h^{(p-1)/q^e} h(p1)/qe ,计算出 ( g ( p − 1 ) / q e g^{(p-1)/q^e} g(p1)/qe) x ^x x = h ( p − 1 ) / q e h^{(p-1)/q^e} h(p1)/qe 中的 x x x ,并存入 List x x x .
  4. 最后一步利用CRT算法,对于 List 中对应的各 i 项, x x x = = = List x x x[i] (mod List q e q^e qe[i]) 构成同余方程组 .

Python 3 实现 Pohlig-Hellman Algorithm

有了前面的 CRT 算法和 Pollard’s rho 质因数分解算法的铺垫,实现 Pohlig-Hellman 离散对数算法就会容易很多。

#python3.7.6
#Author:Am473ur
from Crypto.Util.number import long_to_bytes
from functools import reduce
from gmpy2 import gcd,invert
from ShanksDLP import sDLP
from PollardRhoFactor import Factor
import time
#g^x = h (mod p)

def CRT(m,a):
      Num=len(m)
      M=reduce(lambda x,y: x*y, m)
      Mi=[M//i for i in m]
      t=[invert(Mi[i], m[i]) for i in range(Num)]
      x=0
      for i in range(Num):
            x+=a[i]*t[i]*Mi[i]
      return x%M
def BruteForceDLP(A,B,P):
      for i in range(P):
            if pow(A,i,P)==B:
                  return int(i)
def PohligHellman(g,h,p):
      qe=Factor(p-1)
      assert reduce(lambda x,y: x*y, qe) == p-1
      print(qe)
      Lg=[pow(g,(p-1)//i,p) for i in qe]
      Lh=[pow(h,(p-1)//i,p) for i in qe]
      length=len(qe)
      La=[]
      for i in range(length):
            if p<1000000000000:#p较小Shanks's算法可以接受就使用Shanks's解决
                  La.append(sDLP(Lg[i],Lh[i],p))
            else:#p-1的最大质因子较小的话暴力枚举法也有很好的表现
                  La.append(BruteForceDLP(Lg[i],Lh[i],p))
            #print(Lg[i],Lh[i],La[i])
      X=CRT(qe,La)
      if pow(g,X,p)==h:
            print("x is Right ! x = ",X)
      else:print("Wrang Answer")

print("g^x = h (mod p)")
p=int(input("p= "))
g=int(input("g= "))
h=int(input("h= "))
start_time=time.time()
PohligHellman(g,h,p)
print("it takes ",time.time()-start_time," seconds",)

参考

  • 19
    点赞
  • 101
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
### 回答1: 《应用密码学:协议、算法与C源程序》是一本关于密码学的重要著作。该书主要介绍了密码学的基本概念、协议和算法以及相关的C语言源代码。 在协议方面,该书详细介绍了一些常见的密码学协议,如RSA、Diffie-Hellman、AES等。这些协议是实现安全通信和数据保护的基础,读者可以通过学习这些协议了解到密码学在实际应用中的工作原理。 在算法方面,该书涵盖了密码学中一些经典的算法,如对称加密算法、非对称加密算法和哈希算法等。对称加密算法包括DES、AES等,非对称加密算法包括RSA等,而哈希算法包括MD5、SHA-1等。这些算法的原理和实现细节都在书中有详细的介绍,读者可以通过学习这些算法了解到密码学在保护数据传输和存储安全方面的作用。 同时,该书还提供了一些相关的C语言源代码示例,以便读者更好地理解协议和算法实现过程。这些源代码可以帮助读者理解密码学在实际编程中的应用方式,有助于读者在自己的项目中使用密码学技术实现安全保护。 总之,《应用密码学:协议、算法与C源程序》是一本涵盖了密码学基本概念、协议、算法和源代码的综合性教材,对于想要深入了解密码学并应用到实际项目中的读者来说是一本不可多得的书籍。 ### 回答2: 《应用密码学:协议、算法与C源程序》是一本关于密码学领域的书籍,主要介绍密码学在通信安全和数据保护方面的应用。通过该书,读者可以深入了解密码学的理论基础、常用协议、算法和C语言实现。下面我将简要介绍一些书籍内容。 首先,该书详细介绍了密码学的基本概念和原理。读者可以了解加密算法、解密算法、对称加密和非对称加密等密码学基础知识,理解信息的加密和解密过程。 其次,该书介绍了一些常用的密码协议,如SSL/TLS协议、IPSec协议等。读者可以了解这些协议的原理、安全性和应用场景,深入了解网络通信安全中密码学的应用。 此外,该书还详细介绍了一些常见的密码算法,如DES、AES、RSA等。读者可以学习这些算法的原理、加密过程和解密过程,并且提供了相应的C语言源代码供读者进行实践。这有助于读者进一步理解密码算法的具体实现和应用。 最后,该书还介绍了一些密码学中的实际应用,如数字签名、数字证书、身份认证等。读者可以了解这些应用的原理和实现方式,进一步了解密码学在实际场景中的应用价值。 总之,《应用密码学:协议、算法与C源程序》是一本很好的密码学领域的入门书籍,通过学习该书可以深入了解密码学的基本原理、常用协议和算法,并且提供了相关的C语言源代码供读者实践。无论是对于密码学专业人士还是对于对密码学有兴趣的读者,这本书都是一本值得推荐的参考书。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风好衣轻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值