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)
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))
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;
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
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)))