Exemplo n.º 1
0
def index_calculus(g, h, p, b=0):
    if not b:
        b = ceil(exp(sqrt(log(p)*(log(log(p)))))**(1/sqrt(2)))
    primes = nt.eratosthenes(b)
    crt_factors = nt.prime_factorise(p-1, counted=True)
    relations = []

    # we need to find a number of linearly dependent relations
    # first we'll just find 4 times as many as we need
    while len(relations) < 4*len(primes):
        x = randint(1, p-1)
        y = pow(g, x, p)

        if nt.is_b_smooth(y, b):
            factorisation = nt.prime_factorise(y, counted=True)
            relation = [factorisation.get(q, 0) for q in primes] + [x]
            relations.append(relation)

    # perform Gaussian elimination on relations modulo each factor
    sols = []

    for base in sorted(crt_factors.keys()):
        m = base**crt_factors[base]
        sol = nt.reduced_row_echelon(relations, m)
        sols.append([sol[i][-1] for i in range(len(sol[0])-1)])

    small_prime_logs = []

    # use the CRT to stitch together the solutions
    for i in range(len(primes)):
        congruences = []
        for j, base in enumerate(sorted(crt_factors.keys())):
            m = base**crt_factors[base]
            congruences.append((sols[j][i], m))

        small_prime_logs.append(nt.chinese_remainder_theorem(congruences)[0])

    # have the logs of the small primes
    g_inv = nt.mod_mult_inv(g, p)
    g_k = g_inv

    for k in range(1, p):
        v = (h * g_k) % p
        if nt.is_b_smooth(v, b):
            out = k
            factors = nt.prime_factorise(v, counted=True)
            for i, q in enumerate(primes):
                out += small_prime_logs[i] * factors[q]

            return out % (p-1)

        g_k *= g_inv
Exemplo n.º 2
0
Arquivo: intmodp.py Projeto: bward/ecc
 def mult_inverse(self):
     return IntModP(nt.mod_mult_inv(self.value, self.p), self.p)