弱い生成元

DLP

from Crypto.Util.number import *
from sage.all import *

def gen_weak_prime(size, smooth):
    """
    generate approximately size-bit prime p
    which p-1 factorized to p_1 * p_2 * ... * p_n and p_n is up to smooth-bit
    (it means that p-1 is <smooth>-smooth number)
    """
    p = 2
    while True:
        if p.bit_length() + smooth >= size:
            p *= getPrime(size - p.bit_length())
            if isPrime(p + 1):
                return p +1
            p = 2
        else:
            p *= getPrime(smooth + 1)

# generate params
p = gen_weak_prime(512, 512-32)
print("[+] p: {}".format(p))
factors = [f[0]**f[1] for f in factor(p-1)]
assert len(factors) == 3
g = getRandomRange(2, p)
g = Mod(g, p) ** (2*factors[2])
x = getRandomRange(2, p) # this is secret
h = g ** x

print("[+] secret: {}".format(x))
dlog = discrete_log(h, g)
print("[+] discrete-log: {}".format(dlog))
print("[+] check1: {}".format(g ** dlog))
print("[+] check2: {}".format(h))