Skip to content

Baby-step Giant-step 算法

参考: Baby-step Giant-step 方法

为了找到 \(x\) 满足 \(a^x = b \pmod p\),设 \(m = \lceil \sqrt{p-1} \rceil\),那么一定可以找到 \(i, j \in [0, m)\) 使得 \(x = i + mj\)

那就枚举所有的 \(i \in [0, m)\),计算出 \(a^i \bmod p\) 并保存下来,放到一个集合当中,然后枚举 \(j\),计算 \(b(a^{-m})^j \bmod p\) 是否出现在前述集合中,如果有,那么就有 \(i, j\) 使得 \(a^i = b(a^{-m})^j \pmod p\)\(a^{i+mj}=a^x=b \pmod p\)

代码样例:

def bsgs(unit, base, target, order):
    """Find x < order satisfying power(base, x) = target"""
    m = int(math.sqrt(order)) + 1

    baby = {}
    current = unit
    for j in range(m):
        baby[current] = j
        current = mul(current, base)

    base_m = pow(base, m)
    giant = inv(base_m)
    current = target
    for i in range(m):
        if current in baby:
            return i * m + baby[current]
        current = mul(current, giant)
    return None

Comments