Example #1
0
    def __init__(self, ec, P = None, dmap = None, order = None, pairing="weil", k = None, seed=None):
        self.ec = ec
        self.P = P

        self.distortion = self._deco(dmap)
        if dmap == None:
            self.distortion = self._ext

        if order == None:
            self.order = P.order()
        else:
            self.order = order

        self.pairing = pairing

        ord = self.ec.base_ring().cardinality()
        if k == None:
            k = Zmod(self.order)(ord).multiplicative_order()
        self.k = k

        random.seed(seed)
        self.t = random.randint(2, self.order-1)

        base = FiniteField(ord**self.k, 'b')
        self.hom = Hom(self.ec.base_ring(), base)(base.gen()**((ord**self.k-1)/(ord-1)))
        self.ec2 = EllipticCurve(map(int,self.ec.a_invariants())).change_ring(base)
    def __init__(self,
                 ec,
                 P=None,
                 dmap=None,
                 order=None,
                 pairing="weil",
                 k=None,
                 seed=None):
        self.ec = ec
        self.P = P

        self.distortion = self._deco(dmap)
        if dmap == None:
            self.distortion = self._ext

        if order == None:
            self.order = P.order()
        else:
            self.order = order

        self.pairing = pairing

        ord = self.ec.base_ring().cardinality()
        if k == None:
            k = Zmod(self.order)(ord).multiplicative_order()
        self.k = k

        random.seed(seed)
        self.t = random.randint(2, self.order - 1)

        base = FiniteField(ord**self.k, 'b')
        self.hom = Hom(self.ec.base_ring(),
                       base)(base.gen()**((ord**self.k - 1) / (ord - 1)))
        self.ec2 = EllipticCurve(map(int,
                                     self.ec.a_invariants())).change_ring(base)
Example #3
0
    def __init__(self, curve=None, nbits=256):
        curves = self.supported_curves()

        if curve is None:
            if nbits == 160:
                curve = "brainpoolp160r1"
            elif nbits == 192:
                curve = "nist192p"
            elif nbits == 224:
                curve = "nist224p"
            elif nbits == 256:
                curve = "secp256k1"
            elif nbits == 320:
                curve = "brainpoolp320r1"
            elif nbits == 384:
                curve = "nist384p"
            elif nbits == 521:
                curve = "nist521p"
            else:
                raise NotImplementedError("nlen={nlen} is not implemented".format(nlen=nbits))

        if str.lower(curve) in curves.keys():
            self.curve = curves[curve]
            self.baselen = self.curve.baselen
            self.nbits = self.curve.order.bit_length()
            self.G = self.curve.generator
            self.n = Integer(self.G.order())
            self.F = FiniteField(self.curve.curve.p())
            self.C = EllipticCurve([self.F(self.curve.curve.a()), self.F(self.curve.curve.b())])
            self.GG = self.C([self.G.x(), self.G.y()])
        else:
            raise NotImplementedError("curve={curve} is not implemented".format(curve=curve))
Example #4
0
 def roots_finite_field(p):
     Fq = FiniteField(p**d, "a")
     Fq_X = PolynomialRing(Fq, "x")
     pol = Fq_X(defining_polynomial)
     # print "Got cycle_type", cycle_type
     # print "I compute the polynomial to be ", pol
     # print "I am looking for solution over ", Fq_X
     roots = pol.roots(multiplicities=False)
     assert len(roots) == len(defining_polynomial) - 1
     return roots
def random_split_primes(field, primes = 1, bits = 62, seed = None, relative_ext = None):
    # input:
    # * Number Field
    # * number of split primes in the field
    # * number of bits desired in each prime
    # * random "seed"
    # * optionally we might also require that a certain polynomial splits completely over the split primes
    # Output a list [(p, root)] where:
    # * p is a partially split prime in the number field (and fully split in the relative extension)
    # * a root of the defining polynomial mod p
    lower_bound = 2 ** (bits - 1);
    if seed is None:
        k = randint(1,2 ** (bits - 2) )
    else:
        k = 0;
    p = lower_bound + 1 + 2*k;
    if field is QQ:
        f = [0, 1]
    else:
        f = field.defining_polynomial().list()

    output = [];
    ps = [];

    if relative_ext is not None:
        f_relative = relative_ext.list();


    while len(output) < primes:
        while not is_pseudoprime(p):
            p += 2;
        FF = FiniteField(p);
        FFz = PolynomialRing(FF, "z");
        roots = FFz(f).roots()
        if len(roots) > 0: #== f.degree():
            root = roots[0][0].lift();
            if relative_ext is not None:
                if len(FFz( reduce_list_split(f_relative, (p, root)) ).roots()) == len(f_relative) - 1:
                    output.append((p, root));
                    ps.append(p);
            else:
                output.append((p, root));
                ps.append(p);
        p += 2;
    return output;
Example #6
0
def trace_and_norm_ladic(L,
                         M,
                         P0,
                         P1,
                         P2,
                         f,
                         alpha,
                         degree_bound,
                         primes=120,
                         bits=62,
                         verbose=True):
    if verbose:
        print "trace_and_norm_ladic()"
        print "primes = %d, bits = %d" % (primes, bits)
    # Input:
    # * L the number field where P0, alpha, norm and trace are defined over
    # * M a relative extension of L where P1 and P2 are defined over
    # * P0 initial point already embedded in M
    # * P1, P2 image points alpha(2 * P0 - \infty) = P1 + P2 - \infty
    # * alpha the matrix represing the endomorphism on the tangent space in M
    # * f the defining polynomial of the curve such that y^2 = f(x)
    # * degree bound for the trace and norm as rational maps
    # Note: Due to inconsistencies of the complex embeddings of L and M we require P0 and alpha to be given in M
    # Output:
    # * [trace_numberator, trace_denominator, norm_numberator, norm_denominator]
    # represented as lists of elements in L

    for arg in [P0, P1, P2, alpha]:
        assert arg.base_ring() is M

    hard_bound = 2 * degree_bound + 1
    soft_bound = hard_bound + 10
    if verbose:
        print "hard_bound = %d\nsoft_bound = %d" % (hard_bound, soft_bound)
        print "Generating split primes..."
        c, w = cputime(), walltime()
        ps_roots = random_split_primes(field=L,
                                       bits=bits,
                                       primes=primes,
                                       relative_ext=M.relative_polynomial())
        print "Time: CPU %.2f s, Wall: %.2f s" % (
            cputime(c),
            walltime(w),
        )
    else:
        ps_roots = random_split_primes(field=L,
                                       bits=bits,
                                       primes=primes,
                                       relative_ext=M.relative_polynomial())

    to_lift_raw = []
    if verbose:
        print "Applying newton lift at each prime"
    for p_root in ps_roots:
        ell, root = p_root

        FF = FiniteField(ell)
        FF_xell = PolynomialRing(FF, "xell")

        Lpoly = FF_xell(
            reduce_list_split(M.relative_polynomial().list(), p_root))
        assert Lpoly.degree() == len(Lpoly.roots())
        Lroot = Lpoly.roots()[0][0].lift()

        PSring_ell = PowerSeriesRing(FF, "Tell", default_prec=soft_bound)

        P0_ell = vector(FF, reduce_list_split_relative(P0, p_root, Lroot))
        P1_ell = vector(FF, reduce_list_split_relative(P1, p_root, Lroot))
        P2_ell = vector(FF, reduce_list_split_relative(P2, p_root, Lroot))

        f_ell = FF_xell(reduce_list_split(f.list(), p_root))
        alpha_ell = reduce_matrix_split_relative(alpha, p_root, Lroot)

        x1_ell, x2_ell = newton_linear(P0_ell, P1_ell, P2_ell, f_ell,
                                       alpha_ell, PSring_ell, soft_bound)

        trace_series_ell = x1_ell + x2_ell

        norm_series_ell = x1_ell * x2_ell

        trace_numerator_ell, trace_denominator_ell = rational_reconstruct_poly(
            FF_xell(trace_series_ell.list()),
            FF_xell.gen()**trace_series_ell.prec())
        norm_numerator_ell, norm_denominator_ell = rational_reconstruct_poly(
            FF_xell(norm_series_ell.list()),
            FF_xell.gen()**norm_series_ell.prec())

        # shift the series back to zero
        shift = FF_xell.gen() - P0_ell[0]

        factors_ell = [
            trace_numerator_ell(shift).list(),
            trace_denominator_ell(shift).list(),
            norm_numerator_ell(shift).list(),
            norm_denominator_ell(shift).list()
        ]
        degrees_ell = tuple([len(elt) for elt in factors_ell])
        to_lift_raw.append((p_root, degrees_ell, factors_ell))
    if verbose:
        print "Getting rid of bad primes..."
    # get rid of badprimes
    degrees_count = {}
    for _, degrees_ell, _ in to_lift_raw:
        if degrees_ell in degrees_count:
            degrees_count[degrees_ell] += 1
        else:
            degrees_count[degrees_ell] = 1
    max_value = 0
    max_arg = None

    for degrees_ell, count in degrees_count.items():
        if count > max_value:
            max_arg = degrees_ell
            max_value = count

    output = [None] * 4
    for i, elt in enumerate(max_arg):
        output[i] = [0] * elt

    to_lift = []
    ps_roots = []

    for p_root, degrees_ell, factors_ell in to_lift_raw:
        if degrees_ell == max_arg:
            ps_roots.append(p_root)
            to_lift.append(factors_ell)

    extra_factor = to_lift[-1]
    extra_p_root = ps_roots[-1]

    to_lift = to_lift[:-1]
    ps_roots = ps_roots[:-1]

    OL = L.ring_of_integers()
    p_ideals = [OL.ideal(p,
                         L.gen() - r) for p, r in ps_roots]
    I = prod(p_ideals)
    if L is QQ:
        BI_coordinates = None
    else:
        BI = I.basis()
        # basis as a ZZ-module
        BI_coordinates = [OL.coordinates(b) for b in BI]

    if verbose:
        print "Lifting everything"
    for i, lift in enumerate(output):
        for j, elt in enumerate(lift):
            residues = [residue[i][j] for residue in to_lift]
            output[i][j] = fractional_CRT_split(residues=residues,
                                                ps_roots=ps_roots,
                                                K=L,
                                                BI_coordinates=BI_coordinates)
            assert reduce_constant_split(output[i][j],
                                         extra_p_root) == extra_factor[i][j]
    if verbose:
        print "trace_and_norm_ladic() Done"

    return output
Example #7
0
def is_totally_split(L, p):
    if L.discriminant() % p == 0:
        return False;
    return len(PolynomialRing(FiniteField(p),'z')(L.absolute_polynomial().list()).factor()) == L.absolute_polynomial().degree()
def reduce_constant_split_relative(x, p_root, relative_root):
    x_list = list(x);
    p , _ = p_root;
    return  FiniteField(p)(sum(reduce_constant_split(xi, p_root) * relative_root**i for i, xi in enumerate(x_list)))
def reduce_constant_split(x, p_root):
    x_list = list(x);
    p , root = p_root;
    return  FiniteField(p)(sum(xi * root**i for i, xi in enumerate(x_list)))