Example #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
Example #2
0
def pohlig_hellman(g, h, mov_point=False):
    factorisation = nt.prime_factorise(g.order(), counted=True)
    ys = []

    for q in factorisation.keys():

        order = q**factorisation[q]
        g_i = pow(g, g.order()//order)
        h_i = pow(h, g.order()//order)

        ys.append((discrete_log_pp(g_i, h_i, q, factorisation[q], mov_point), order))

    return nt.chinese_remainder_theorem(ys)[0]
Example #3
0
 def order(self):
     field_order = self.field.order()
     fac = prime_factorise(field_order, counted=True)
     powers = [range(e+1) for e in [fac[p] for p in sorted(fac.keys())]]
     candidates = []
     for p in product(*powers):
         value = [f**p for f, p in zip(sorted(fac.keys()), p)]
         out = 1
         for v in value:
             out *= v
         candidates.append(out)
     for c in sorted(candidates):
         if self**c == 1:
             return c
Example #4
0
 def bad_reduction_primes(self):
     a, b = self.curve[0].value[0].value, self.curve[1].value[0].value
     d = 4*a**3+27*b**2
     if d == 0:
         return [self.field.p]
     return set(nt.prime_factorise(abs(d)))