【深入浅出密码学】离散对数

群相关知识点

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

离散对数相关

在这里插入图片描述## 蛮力搜索

对于解决 α x = β \alpha^{x} =\beta αx=β,我们不断地选取合适地 x x x,计算 a x a^x ax,直到找到满足这个等式的 x x x,时间复杂度 O ( ∣ G ∣ ) O(|G|) O(G).

Baby-Step Giant-Step

对于解决 α x = β   m o d   ( p ) \alpha^x=\beta\ mod\ (p) αx=β mod (p),我们将 x x x表示为 x = x g ∗ p + x b x=x_g*\sqrt{p}+x_b x=xgp +xb.这里的 x b , x g ∈ [ 0 , p ] x_b,x_g \in[0,\sqrt{p}] xb,xg[0,p ]

现将问题转化为,求解 a x g ∗ p + x b = β   m o d ( p ) a^{x_g*\sqrt{p}+x_b}=\beta \ mod(p) axgp +xb=β mod(p),此时我们只需要寻找满足等式的 ( x g , x b ) (x_g,x_b) (xg,xb),

将等式等价变换成 a x g ∗ p = β ∗ a − x b   m o d ( p ) a^{x_g*\sqrt{p}}=\beta*a^{-x_b}\ mod(p) axgp =βaxb mod(p).

在Baby-Step阶段,我们枚举 x b x_b xb的取值,并采用哈希表或者字典等数据结构记录 ( x b , β ∗ a − x b ) (x_b,\beta*a^{-x_b}) (xb,βaxb).

在Giant-Step阶段,我们枚举 x g x_g xg,计算 a x g ∗ p a^{x_g*\sqrt{p}} axgp ,并且在哈希表当中查找,直到出现相等的值。

这个算法的时间和空间复杂度都是 O ( P ) O(\sqrt{P}) O(P )

Pollards’s Rho

在整数分解当中的应用:

问题描述:

设大整数为 n n n,我们需要找到 n n n的一个因子 p p p

我们设想存在两个整数 x , x ′ ∈ Z n x,x^{'}\in Z_n x,xZn,满足 x = x ′   m o d   ( p ) x=x^{'}\ mod\ (p) x=x mod (p),这样的话就有 p ∣ ( x − x ′ ) p|(x-x^{'}) p(xx),又因为 p ∣ n p|n pn,那么 g c d ( x − x ′ , n ) gcd(x-x',n) gcd(xx,n)一定是 n n n的非平凡因子。问题归结为:如何找到满足条件的 x , x ′ x,x' x,x

解释: x − x ′ = k ∗ p , n = k ∗ p , 那么 g c d ( x − x ′ , n ) = p x-x'=k*p,n=k*p,那么gcd(x-x',n)=p xx=kp,n=kp,那么gcd(xx,n)=p

我们选定一个随机的序列 X ⊂ Z n X \subset Z_n XZn, x = { x 1 , x 2 , . . , x l } x=\{x_1,x_2,..,x_l\} x={x1,x2,..,xl},这里的 l = n 1 / 4 l=n^{1/4} l=n1/4,我们从中随机选择两个数计算 g c d ( x − x ′ , n ) gcd(x-x',n) gcd(xx,n),我们需要进行 C l 2 C_l^2 Cl2 g c d gcd gcd运算,这时的计算效率并不高,需要后续的优化。

这里我们选定一个伪随机数生成器,让我们每次的选择看上去好像是随机的。

f ( x ) = x 2 + 1   m o d   n f(x)=x^2+1\ mod \ n f(x)=x2+1 mod n,随机选择一个 x 0 ∈ Z n x_0\in Z_n x0Zn,然后计算 x 1 = f ( x 0 ) , x 2 = f ( x 1 ) , . . x i = f ( x i − 1 ) x_1=f(x_0),x_2=f(x_1),..x_i=f(x_{i-1}) x1=f(x0),x2=f(x1),..xi=f(xi1).

我们画出 Z p Z_p Zp的图像

在这里插入图片描述但是 p p p是未知的,我们无法直接画出这个图像。

1. L e t   y 0 = x 0 1.Let\ y_0=x_0 1.Let y0=x0

2. F o r   i = 1 , 2 , . . . 2.For\ i=1,2,... 2.For i=1,2,...

( a )   x i = f ( x i − 1 ) (a)\ x_i=f(x_{i-1}) (a) xi=f(xi1)

( b )   y i = f ( f ( y i − 1 ) ) (b)\ y_i=f(f(y_{i-1})) (b) yi=f(f(yi1))

( c )   I F   g c d ( x i − y i , n ) ≠   1   r e t u r n   t h i s   d i s c o v e r e d   f a c t o r (c)\ IF\ gcd(x_i-y_i,n)\neq\ 1\ return\ this\ discovered\ factor (c) IF gcd(xiyi,n)= 1 return this discovered factor

在离散对数当中的应用:

在这里插入图片描述在这里插入图片描述在ECC当中的应用:

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

def pollard_rho(g, y, p):
    q = (p-1) // 2
    def new_xab(x, a, b,  g, y, p, q):
        subset = x % 3
        if subset == 0:
            return ((x*x) % p, (a*2) % q, (b*2) % q)
        if subset == 1:
            return ((x*g) % p, (a+1) % q, b        )
        if subset == 2:
            return ((x*y) % p, a        , (b+1) % q)
    x, a, b = 1, 0, 0
    X, A, B = x, a, b
    for i in range(1, p):
        x, a, b = new_xab(x, a, b,  g, y, p, q)
        X, A, B = new_xab(X, A, B,  g, y, p, q)
        X, A, B = new_xab(X, A, B,  g, y, p, q)
        if x == X:
            break
    res = ((a - A) * pow(B - b, -1, q)) % q
    if pow(g, res, p) == y:
        return res
    if pow(g, res + q, p) == y:
        return res + q
    return None

g = 
y = 
p = 
x = pollard_rho(g, y, p)
print(x)
print(pow(g, x, p) == y)

Pollards’s Hellman

适用条件:p是一个素数,p-1包含的质因子较小并且比较少

对于 a x = b   m o d   ( p ) a^x=b\ mod\ (p) ax=b mod (p),记其原根为 g g g,记 a = g a i , b = g b i a=g^{a_i},b=g^{b_i} a=gai,b=gbi,此时得到 g a i x = g b i   m o d   ( p ) g^{a_ix}=g^{b_i}\ mod\ (p) gaix=gbi mod (p),所以 a i x = b i   m o d   ( p − 1 ) a_ix=b_i\ mod\ (p-1) aix=bi mod (p1),如果我们得到 a i , b i a_i,b_i ai,bi那么 x x x易得。

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
在ECC当中的应用

在这里插入图片描述

#Sage Code 1
p = 
a = 
b = 
gx = 
gy = 
px = 
py = 

E = EllipticCurve(GF(p), [a, b])
G = E(gx, gy)
n = E.order()
QA = E(px, py)

factors = list(factor(n))
m = 1
moduli = []
remainders = []

print(f"[+] Running Pohlig Hellman")
print(factors)

for i, j in factors:
    if i > 10**9:
        print(i)
        break
    mod = i**j
    g2 = G*(n//mod)
    q2 = QA*(n//mod)
    r = discrete_log(q2, g2, operation='+')
    remainders.append(r)
    moduli.append(mod)
    m *= mod

r = crt(remainders, moduli)
print(r)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值