def fc_of_pullback_of_diff_eisen(l, k, m, A, D, u3, u4, verbose=False): '''Return the Fourier coefficient of exp(2pi A Z1 + 2pi D Z2) of pullback of vector valued Eisenstein series F_{l, (k, m)} in [DIK], pp 1313. ''' dct = {"A": A, "D": D} res = _U_ring(0) es = sess(weight=l, degree=4) us = list(_U_ring.gens()) + [u3, u4] # D_up is multiplication by d_up_mlt on p(z2)e(A Z1 + R^t Z12 + D Z2) v_up = vector(_U_ring, us[:2]) d_up_mlt = v_up * A * v_up v_down = vector(us[2:]) d_down_mlt = v_down * D * v_down d_up_down_mlt = d_up_mlt * d_down_mlt _u1, _u2 = (_Z_U_ring(a) for a in ["u1", "u2"]) for R, mat in r_n_m_iter(A, D): r_ls = R.list() pol = D_tilde_nu(l, k - l, QQ(1), r_ls, **dct) # L_operator is a differential operator whose order <= m, # we truncate it. pol = _Z_ring( {t: v for t, v in pol.dict().iteritems() if sum(list(t)) <= m}) _l_op_tmp = L_operator(k, m, A, D, r_ls, pol * es.fourier_coefficient(mat), us, d_up_down_mlt) _l_op_tmp = _U_ring({(m - a, a): _l_op_tmp[_u1 ** (m - a) * _u2 ** a] for a in range(m + 1)}) res += _l_op_tmp res = res * QQ(mul(k + i for i in range(m))) ** (-1) res = res * _zeta(1 - l) * _zeta(1 - 2 * l + 2) * _zeta(1 - 2 * l + 4) if verbose: print "Done computation of Fourier coefficient of pullback." return res
def split_into_diamond_orbits(cuspsums,level): """ Input a list of cuspsums w.r.t. to the standard basis. Output a list of orbits of these cuspsums. """ csp_grp = conjectural_cuspidal_classgroup(level) diamonds = counts([tuple(sorted(set(csp_grp(vector(i)) for i in diamond_orbits_cuspsum(c,level)))) for c in cuspsums]) cusp_grp_to_cusp_sum = dict((csp_grp(vector(c)),c) for c in cuspsums) return [[cusp_grp_to_cusp_sum[k] for k in d[0]] for d in diamonds]
def upsert_embedding(id_number, skip = False): rowcc = db.mf_hecke_cc.lucky({'id':id_number}, projection=['an', 'hecke_orbit_code','id','lfunction_label', 'embedding_root_imag','embedding_root_real']) if rowcc is None: return if skip: if rowcc.get("embedding_root_imag", None) is not None: if rowcc.get("embedding_root_real", None) is not None: return row_embeddings = {} hecke_orbit_code = rowcc['hecke_orbit_code'] newform = db.mf_newforms.lucky({'hecke_orbit_code':hecke_orbit_code}) if newform is None: # No newform in db return if newform['dim'] == 1: row_embeddings['embedding_root_imag'] = 0 row_embeddings['embedding_root_real'] = 0 elif newform['weight'] == 1: return elif newform.get('field_poly', None) is None: return else: # print rowcc['lfunction_label'] HF = NumberField(ZZx(newform['field_poly']), "v") numerators = newform['hecke_ring_numerators'] denominators = newform['hecke_ring_denominators'] betas = [HF(elt)/denominators[i] for i, elt in enumerate(numerators)] embeddings = HF.complex_embeddings(prec=2000) an_nf = list(db.mf_hecke_nf.search({'hecke_orbit_code':hecke_orbit_code}, ['n','an'], sort=['n'])) betas_embedded = [map(elt, betas) for elt in embeddings] CCC = betas_embedded[0][0].parent() qexp = [convert_eigenvals_to_qexp(elt, an_nf) for elt in betas_embedded] min_len = min(len(rowcc['an']), len(qexp[0])) an_cc = vector(CCC, map(lambda x: CCC(x[0], x[1]), rowcc['an'][:min_len])) #qexp_diff = [ (vector(CCC, elt[:min_len]) - an_cc).norm() for elt in qexp ] # normalized, to avoid the unstability comming from large weight qexp_diff = [ vector([(elt- an_cc[i])/elt.abs() for i, elt in enumerate(q) if elt != 0]).norm() for j,q in enumerate(qexp)] qexp_diff_sorted = sorted(qexp_diff) min_diff = qexp_diff_sorted[0] #print "min_diff = %.2e \t min_diff/2nd = %.2e" % (min_diff, min_diff/qexp_diff_sorted[1]) #assuring that is something close to zero, and that no other value is close to it assert min_diff < 1e-6 assert min_diff/qexp_diff_sorted[1] < 1e-15 for i, elt in enumerate(qexp_diff): if elt == min_diff: row_embeddings['embedding_root_real'] = float(embeddings[i](HF.gen()).real()) row_embeddings['embedding_root_imag'] = float(embeddings[i](HF.gen()).imag()) break assert len(row_embeddings) == 2 db.mf_hecke_cc.upsert({'id': rowcc['id']}, row_embeddings)
def optimal_remove_points(Delta, Fundam): l = ZZ(5) candidates = [(vector(pt),) for pt in Delta.integral_points()] V = Delta.vertices() if len(V) == 3: candidates.append(tuple(vector(pt) for pt in V)) elif len(V) == 4: VV = list(V) WW = [] V0 = VV[0] for edge in Delta.faces(1): edge = edge.vertices() if edge[0] == V0: e = edge[1] VV.remove(e); WW.append(e) elif edge[1] == V0: e = edge[0] VV.remove(e); WW.append(e) # We should be left with 2 pairs assert len(VV) == 2 assert len(WW) == 2 candidates.append(tuple(vector(pt) for pt in VV)) candidates.append(tuple(vector(pt) for pt in WW)) Delta_pts = Delta.integral_points() Delta_int_pts = interior_points(Delta) Delta2_int_pts = interior_points(ZZ(2) * Delta) # Check monomials in the fundamental domain X, Y = ZZ_X_Y.gens() AUT = polygon_symmetries(l * Delta) lFundam = fundamental_points(l * Fundam, AUT) monomials = [X**pt[0] * Y**pt[1] for pt in lFundam] def difficulty(remove_points): all_pts = list(Delta_pts) int_pts = list(Delta_int_pts) int_pts2 = list(Delta2_int_pts) for pt in remove_points: all_pts.remove(pt) for z in int_pts: int_pts2.remove(pt + z) fd_coeff = genf_koszul_points(all_pts, int_pts, l-1).monomial_coefficient fc_coeff = genf_koszul_points(all_pts, int_pts2, l-2).monomial_coefficient return max(fd_coeff(monom) * fc_coeff(monom) for monom in monomials) return min(candidates, key=difficulty)
def find_linearly_indep_indices(vectors, r): ''' Let vectors be a list of vectors or a list of list. Assume r be the rank of vectors. This function returns a list of indices I of length r such that the rank of [vectors[i] for i in I] is equal to r. ''' acc = [] if isinstance(vectors[0], list): vectors = [vector(a) for a in vectors] while True: if r == 0: return acc nrws = len(vectors) first, first_r_idx = next((a, i) for i, a in enumerate(vectors) if a != 0) nonzero_col_index, a = next((j, a) for j, a in enumerate(first) if a != 0) v = a ** (-1) * first vectors1 = [] for j in range(first_r_idx + 1, nrws): w = vectors[j] vectors1.append(w - w[nonzero_col_index] * v) vectors = vectors1 r -= 1 if acc == []: acc.append(first_r_idx) else: acc.append(first_r_idx + acc[-1] + 1)
def in_kernel(self): """ Determine whether this :class:`StrataAlgebraElement` is in the span of the FZ relations, and hence in the kernel of the map to the tautological ring. :: sage: from strataalgebra import * sage: s = StrataAlgebra(QQ,0,(1,2,3,4,5)) sage: b = s.boundary(0,(1,2,5)) + s.boundary(0,(1,2)) - s.boundary(0,(1,3,5)) - s.boundary(0,(1,3)) sage: b Dg0m1_2_5 + Dg0m1_2 - Dg0m1_3_5 - Dg0m1_3 sage: b.in_kernel() True sage: (s.psi(1) - s.psi(2)).in_kernel() False It should work fine for non-homogeneous things as well. :: sage: (b + s.psi(1)).in_kernel() False sage: (b + s.psi(1)**2 - s.psi(2)**2).in_kernel() True """ for codim in range(self.codim()+1): v = vector([0]*self.parent().hilbert(codim)) for (cd, index), coef in self.coef_dict.items(): if cd == codim: v[index] = coef if v not in self.parent().FZ_matrix(codim).row_space(): return False return True
def NonCubicSet(K,S, verbose=False): u = -1 if K==QQ else K(K.unit_group().torsion_generator()) from KSp import IdealGenerator Sx = [u] + [IdealGenerator(P) for P in S] r = len(Sx) d123 = r + binomial(r,2) + binomial(r,3) vecP = vec123(K,Sx) A = Matrix(GF(2),0,d123) N = prod(S,1) primes = primes_iter(K,None) T = [] while A.rank() < d123: p = primes.next() while p.divides(N): p = primes.next() v = vecP(p) if verbose: print("v={}".format(v)) A1 = A.stack(vector(v)) if A1.rank() > A.rank(): A = A1 T.append(p) if verbose: print("new A={} with {} rows and {} cols".format(A,A.nrows(),A.ncols())) print("T increases to {}".format(T)) return T
def small_lgs2(A, c, mod, sol=None): ''' Find short x with Ax = c (mod m). This is more generic because it also works for composite m, but it does not work for c = 0. The difference is that we don't have to compute the orthogonal lattice of A. TODO: For c = 0, we can brute force a k with small ||k|| and solve for c = k*mod instead. See [2] (p. 264-268) and https://crypto.stackexchange.com/questions/37836/ ''' m, n = A.dimensions() A = list(A) for i in range(n): A.append([0]*i + [mod] + [0]*(n-i-1)) A = matrix(ZZ, A) L = A.LLL() for i in range(m): assert L[i] == 0 L = L[m:] if c == 0 or c == None: # Brutal heuristic here, see TODO above. We are only trying one single k # here, namely (0, ..., 0, 1) x = normalize(integer_lgs(L, vector([0]*(n-1) + [mod]))) for t in x: assert 0 <= x < mod return x # compute Y such that Y*A == L Y = [] smith = A.transpose().smith_form() for i in range(L.nrows()): y = integer_lgs(None, L[i], smith) # assert At*y == L[i] Y.append(y) Y = matrix(ZZ, Y) # assert Y*A == L c = Y*vector(list(c)+[0]*n)%mod for i in range(len(c)): if c[i] * 2 >= mod: c[i] -= mod assert abs(c[i]) * 2 < mod return integer_lgs(Y*A, c)
def normal_vertices(Delta): vertices = [] for ineq in Delta.inequalities_list(): c = ineq[0] ineq = ineq[1:] assert gcd(ineq) == 1 vertices.append(vector(ZZ, ineq)) return vertices
def class_mats_m1(lst): d = {0:[],1:[],2:[]} for M in lst: x = sum(min(1, M.columns().count(vector(c))) for c in SYS_COL) d[x].append(M) return d
def __getitem__(self, t): if (isinstance(t, tuple) and isinstance(t[0], tuple) and is_number(t[1])): tpl, i = t return self.forms[i][tpl] else: vec = vector([f[t] for f in self.forms]) return vec
def kernel_lattice(A, mod=None): ''' Lattice of vectors x with Ax = 0 (potentially mod m) ''' A = matrix(ZZ if mod is None else Integers(mod), A) L = [vector(ZZ, row) for row in A.right_kernel().basis()] if mod is not None: cols = len(L[0]) for i in range(cols): L.append([0]*i + [mod] + [0]*(cols-i-1)) return matrix(L)
def as_polynomial_in_E4_and_E6(self,insert_in_db=True): r""" If self is on the full modular group writes self as a polynomial in E_4 and E_6. OUTPUT: -''X'' -- vector (x_1,...,x_n) with f = Sum_{i=0}^{k/6} x_(n-i) E_6^i * E_4^{k/4-i} i.e. x_i is the coefficient of E_6^(k/6-i)* """ if(self.level() != 1): raise NotImplementedError("Only implemented for SL(2,Z). Need more generators in general.") if(self._as_polynomial_in_E4_and_E6 is not None and self._as_polynomial_in_E4_and_E6 != ''): return self._as_polynomial_in_E4_and_E6 d = self._parent.dimension_modular_forms() # dimension of space of modular forms k = self.weight() K = self.base_ring() l = list() # for n in range(d+1): # l.append(self._f.q_expansion(d+2)[n]) # v=vector(l) # (self._f.coefficients(d+1)) v = vector(self.coefficients(range(d),insert_in_db=insert_in_db)) d = dimension_modular_forms(1, k) lv = len(v) if(lv < d): raise ArithmeticError("not enough Fourier coeffs") e4 = EisensteinForms(1, 4).basis()[0].q_expansion(lv + 2) e6 = EisensteinForms(1, 6).basis()[0].q_expansion(lv + 2) m = Matrix(K, lv, d) lima = floor(k / 6) # lima=k\6; if((lima - (k / 2)) % 2 == 1): lima = lima - 1 poldeg = lima col = 0 monomials = dict() while(lima >= 0): deg6 = ZZ(lima) deg4 = (ZZ((ZZ(k / 2) - 3 * lima) / 2)) e6p = (e6 ** deg6) e4p = (e4 ** deg4) monomials[col] = [deg4, deg6] eis = e6p * e4p for i in range(1, lv + 1): m[i - 1, col] = eis.coefficients()[i - 1] lima = lima - 2 col = col + 1 if (col != d): raise ArithmeticError("bug dimension") # return [m,v] if self._verbose > 0: wmf_logger.debug("m={0}".format(m, type(m))) wmf_logger.debug("v={0}".format(v, type(v))) try: X = m.solve_right(v) except: return "" self._as_polynomial_in_E4_and_E6 = [poldeg, monomials, X] return [poldeg, monomials, X]
def apply(self, c, G, h, evaluation): "LinearProgramming[c_, G_, h_]" (c, G, h), subs = to_sage((c, G, h), evaluation) n = len(c) c = vector(c) G = matrix([[-item for item in row] for row in G] + [unit_vector(k, n, -1) for k in range(n)]) h = vector([-item for item in h] + [0] * n) result = linear_program(c, G, h) status = result["status"] if status == "dual infeasible": evaluation.message("LinearProgramming", "lpsub") return Expression("List", *([Symbol("Indeterminate")] * n)) elif status == "primal infeasible": return evaluation.message("LinearProgramming", "lpsnf") # print result x = result["x"] x = [round(value, mpf("0.000001")) for value in x] # round result to 6 digits after comma return from_sage(x, subs)
def _to_vector(self, fm, tpls=None): ''' Returns a vector corresponding to fm. By this method, self.basis() becomes the standard basis. ''' if tpls is None: tpls = self.linearly_indep_tuples() m1 = matrix([[f[t] for t in tpls] for f in self.basis()]) v = vector([fm[t] for t in tpls]) return v * m1 ** (-1)
def multiply_mat_vec(E,v): KE = E.base_ring() if isinstance(v,list): v = vector(v) Kv = v.base_ring() if KE != QQ and KE != Kv: EE = convert_matrix_to_extension_fld(E,Kv) return EE*v else: return E*v
def _assert(d): alphas = [] while len(set(alphas)) < d and all(a != 0 for a in alphas): alphas.append(random_prime(100000)) alphas = list(set(alphas)) A = matrix([[alpha ** i for alpha in alphas] for i in range(d)]) v = [random_prime(100000) for _ in range(d)] x = PolynomialRing(QQ, names="x").gens()[0] chpy = mul(x - alpha for alpha in alphas) self.assertEqual(first_elt_of_kern_of_vandermonde(chpy, alphas[0], v), (A ** (-1) * vector(v))[0])
def test_permutation(g,R): Rp = permute_matrix(g,R) pat = map(ray_sign_pattern, [R,Rp]) vec = np.array(permutation_action(g, ray_sign_vector(R))) if vec[0]==-1: vec *= -1 pred = vector(list(vec)) d = {-1:"-", 1:"+"} pred = "".join(map(d.get, pred)) #print R,"\n\n",Rp #print "p0: %s\tp': %s\tp_pred: %s" % (pat[0], pat[1], pred) assert pred==pat[1]
def root(self): if self.mode == 'K': ell = self.ell self.RS = RationalSet([PositiveOrthant(ell)], ambient_dim=ell) actual_ring = self.ring F = FractionField(actual_ring) r = matrix(F, self.R).rank() self.r = r if not self.d: return F = [ LaurentIdeal( gens=[LaurentPolynomial(f) for f in self.R.minors(j)], RS=self.RS, normalise=True) for j in range(r + 1) ] elif self.mode == 'O': self.RS = RationalSet([PositiveOrthant(self.d)], ambient_dim=self.d) actual_ring = PolynomialRing(QQ, 'x', self.d) xx = vector(actual_ring, actual_ring.gens()) self.C = matrix(actual_ring, [xx * matrix(actual_ring, A) for A in self.basis]) r = matrix(FractionField(actual_ring), self.C).rank() self.r = r if not self.d: return F = [ LaurentIdeal( gens=[LaurentPolynomial(f) for f in self.C.minors(j)], RS=self.RS, normalise=True) for j in range(r + 1) ] else: raise ValueError('invalid mode') oo = r + 1 # On pairs: # The first component is used as is, the second is multiplied by the extra # variable. Note that index 0 corresponds to {1} and index oo to {0}. self.pairs = ([(oo, 0)] + [(i, oo) for i in range(1, r)] + [(i, i - 1) for i in range(1, r + 1)]) # Total number of pairs: 2 * r self.integrand = ((1, ) + (2 * r - 1) * (0, ), (self.d - r + 1, ) + (r - 1) * (-1, ) + r * (+1, )) self.datum = IgusaDatum(F + [ LaurentIdeal(gens=[], RS=self.RS, ring=FractionField(actual_ring)) ]).simplify() return self.datum
def dirichlet_coefficients(euler_factors): R = vector(sum(euler_factors), []).base_ring() PS = PowerSeriesRing(R) pef = list(zip(primes_first_n(len(euler_factors)), euler_factors)) an_list_bound = next_prime(pef[-1][0]) res = [1]*an_list_bound for p, ef in pef: k = RR(an_list_bound).log(p).floor()+1 foo = (1/PS(ef)).padded_list(k) for i in range(1, k): res[p**i] = foo[i] extend_multiplicatively(res) return res
def padically_evaluate_regular(self, datum): A = self.A n = self.nvertices m = self.nedges RS = RationalSet(PositiveOrthant(n + 1)) polytopes = [Polyhedron(vertices=[vector(ZZ, n * [0] + [1])])] I = list(identity_matrix(ZZ, n + 1)) for j in range(m): vertices = [vector(ZZ, n * [0] + [1])] for i, a in enumerate(A.column(j)): if a == 1: vertices.append(I[i]) polytopes.append(Polyhedron(vertices=vertices)) for z in padically_evaluate_monomial_integral(RS, polytopes, [(1, ) + m * (0, ), (m + 1) * (1, )]): yield z
def truncated_lgs(A, y, mod): ''' Find short x with A(y + x) = 0 (mod m). This is essentially a special case of small_lgs2, might be faster? See [2] (p. 264-268) and https://crypto.stackexchange.com/questions/37836/ ''' ## This will also work usually, but might be slower # c = -A*y%mod # return y + small_lgs2(A, c, mod) n = A.ncols() A = list(matrix(ZZ, A)) for i in range(n): A.append([0]*i + [mod] + [0]*(n-i-1)) L = matrix(ZZ, A).LLL() W1 = L*vector(ZZ, y) W2 = vector([int(round(RR(w)/mod))*mod - w for w in W1]) return L.solve_right(W2) + y
def orbits(L, G): """ Given a collection `L` of points, group them in orbits under the action of `G` (a collection of matrices representing elements of AGL.). """ from collections import defaultdict orbits = defaultdict(list) for pt in L: v = vector(ZZ, tuple(pt) + (1,)) orbit = frozenset(tuple(g*v)[:-1] for g in G) orbits[orbit] = orbits[orbit] + [pt] return orbits.values()
def key_words(polyList): """ Returns chunks of 4 polynomials in a dictionary with integer keys starting from 0 :param polyList: list of polynomials :return: dictionary of vectors of 4 polynomials for each key """ result = {} assert mod(len(polyList), 4) == 0 index = 0 for i in xrange(0, len(polyList), 4): result[index] = vector(polyList[i:i + 4]) index += 1 return result
def solveNash(payoffMatrix): mb = [0 for i in range(len(payoffMatrix))] mb.append(1) mc = [0 for i in range(len(payoffMatrix[0]))] mc.append(1) vt = ['>=' for i in range(len(payoffMatrix))] vt.append('') ct = ['>=' for i in range(len(payoffMatrix[0]))] ct.append('==') ag = [1 for i in range(len(payoffMatrix))] ag.append(0) A = matrix(QQ, payoffMatrix).transpose().augment(vector(QQ, [-1 for i in range(len(payoffMatrix[0]))])).stack(vector(QQ, ag)) b = vector(QQ, mb) c = vector(QQ, mc) P = InteractiveLPProblem(A, b, c, variable_type=vt, constraint_type=ct) P = P.standard_form() P.run_simplex_method() return [P.objective_value(P.optimal_solution()), P.optimal_solution()[:-2]]
def MatrixToPermutation(P): n = P.dimensions()[1] ei = lambda i: vector([int(i == j) for j in range(n)]) def ie(v): for _ in range(n): if v[_] == 1: return _ for i in range(n): assert (ie(ei(i)) == i) # check p = [ie(P * ei(i)) + 1 for i in range(n)] # need to shift up by one return Permutation(p)
def run_instance(L, block_size, tours, evec): from fpylll import BKZ, LLL, GSO, IntegerMatrix from fpylll.algorithms.bkz2 import BKZReduction as BKZ2 from sage.all import e A = IntegerMatrix.from_matrix(L) block_size = ZZ(block_size) par = BKZ.Param(block_size=block_size, strategies=BKZ.DEFAULT_STRATEGY, flags=BKZ.VERBOSE) block_size = ZZ(block_size) delta_0 = (block_size / (2 * pi * e) * (pi * block_size)**(1 / block_size))**(1 / (2 * block_size - 1)) n = ZZ(L.nrows()) alpha = delta_0**(-2 * n / (n - 1)) if len(evec) == n - 1: evec = vector(list(evec) + [1]) LLL.reduction(A) M = GSO.Mat(A) M.update_gso() vol = sqrt(prod([RR(M.get_r(i, i)) for i in range(n)])) norms = [ map(lambda x: RR(log(x, 2)), [(alpha**i * delta_0**n * vol**(1 / n))**2 for i in range(n)]) ] def proj(v, i): return v - vector(RR, M.to_canonical(list(M.from_canonical(v, 0, i)))) # norms += [map(lambda x: RR(log(x,2)), # [(stddev*sqrt(n-i))**2 for i in range(n)])] norms += [ map(lambda x: RR(log(x, 2)), [proj(evec, i).norm()**2 for i in range(1, n - 1)]) ] norms += [[log(RR(M.get_r(i, i)), 2) for i in range(n)]] bkz = BKZ2(M) for i in range(tours): bkz.tour(par) norms += [[log(M.get_r(i, i), 2) for i in range(n)]] return A.to_matrix(matrix(ZZ, n, n)), norms
def data_gen(A, ell): # Generate a set S = {As : Hw(s) <= ell} k = A.ncols() m = A.nrows() A = transpose(A) S_ = set() S = set() Count = vector(ZZ, [0] * k) A = A.augment(Count) S_.add(tuple([0] * (m + 1))) S.add(tuple([0] * m)) #print 'Making a dataset S = { YA_2 * s : HW(s) < ell }...' for _ in range(ell): #print ' - Processing with hamming weight ', _, '... ' TMP = set() TMP2 = set() for v in S_: for i in range(v[-1], k): for j in [0, 1]: tmp = vector(ZZ, v) + (-1)**j * A[i] tmp[-1] = i + 1 TMP.add(tuple(tmp)) tmp = tmp[:m] TMP2.add(tuple(tmp)) S_ = S_.union(TMP) S = S.union(TMP2) #sys.stdout.write("\033[F") #sys.stdout.write("\033[K") #print ' - Done' #print return S
def expand_until_certified(self, verbose=False): try: h = HyperbolicStructure(self.mcomplex, self.initial_edge_lengths, self.exact_edges, self.var_edges) except BadDihedralAngleError as e: raise KrawczykFailedWithBadDihedralAngleError( "When preparing for certification", e) error_at_initial_edge_lengths = vector( self.RIF, [h.angle_sums[e] - self.twoPi for e in self.var_edges]) self.first_term = (vector( self.RIF, [self.initial_edge_lengths[c] for c in self.var_edges]) - self.approx_inverse * error_at_initial_edge_lengths) edge_lengths = self.initial_edge_lengths num_iterations = (25 if self.bits_prec > 53 else 11) for i in range(num_iterations + 1): old_edge_lengths = edge_lengths edge_lengths = self.krawczyk_iteration(edge_lengths) if KrawczykCertifiedEdgeLengthsEngine.interval_vector_is_contained_in( edge_lengths, old_edge_lengths): self.certified_edge_lengths = edge_lengths if verbose: print("Certified in iteration", i) return True edge_lengths = KrawczykCertifiedEdgeLengthsEngine.interval_vector_union( edge_lengths, old_edge_lengths) raise KrawczykFailedToFinishError("Failed after iterations", num_iterations)
def __init__(self, parent, matrix, is_zero=lambda p: False, relations=[]): ## Checking the parent parameter if (parent.is_field()): parent = parent.base() if (not (isUniPolynomial(parent) or isMPolynomial(parent))): raise TypeError( "The parent for this algorithm must be a polynomial ring.\n\t Got: %s" % parent) ## Checking the matrix input matrix = Matrix(parent, matrix) super().__init__(parent, matrix, vector(parent, matrix.ncols() * [0]), is_zero, relations)
def apply_short1(y, A, c, scale=1): """ Compute `y*A`, `y*c` where y is a vector in the integer row span of ``dual_instance(A)`` :param y: (short) vector in scaled dual lattice :param A: LWE matrix :param c: LWE vector """ m = A.nrows() y = vector(ZZ, 1/ZZ(scale) * y[-m:]) a = balanced_lift(y*A) e = balanced_lift(y*c) return a, e
def cvp_embed(L, v, b=None): if not b: b = max(max(row) for row in L.rows()) L2 = matrix([list(row) + [0] for row in L] + [list(v) + [b]]) res = None for x in lll(matrix(L2)): if x[-1] > 0: x = -x if x[-1] == -b: u = vector(x[:-1]) + v assert in_lattice(L, u) if res is None or (v - u).norm() < (v - res).norm(): res = u return res
def _get_matrix_composition(self, other): from ajpastor.misc.matrix import matrix_of_dMovement as move g = other Mf = self.companion() full_companion, parent = self._compose_companion(Mf, g) init_vector = vector(parent, [1] + [0 for i in range(1, self.order())]) return self._post_proc( move(self._pre_proc(full_companion), self._pre_proc(init_vector), self.derivate(), full_companion.ncols() + 1))
def compute_kernel(args): if args.seed is not None: set_random_seed(args.seed) FPLLL.set_random_seed(args.seed) ecdsa = ECDSA(nbits=args.nlen) lines, k_list, _ = ecdsa.sample(m=args.m, klen_list=args.klen_list, seed=args.seed, errors=args.e) w_list = [2 ** (klen - 1) for klen in args.klen_list] f_list = [Integer(max(w_list) / wi) for wi in w_list] targetvector = vector([(k - w) * f for k, w, f in zip(k_list, w_list, f_list)] + [max(w_list)]) try: solver = ECDSASolver(ecdsa, lines, m=args.m, d=args.d, threads=args.threads) except KeyError: raise ValueError("Algorithm {alg} unknown".format(alg=args.alg)) expected_length = solver.evf(args.m, max(args.klen_list), prec=args.nlen // 2) gh = solver.ghf(args.m, ecdsa.n, args.klen_list, prec=args.nlen // 2) params = args.params if args.params else {} key, res = solver(solver=args.algorithm, flavor=args.flavor, **params) RR = RealField(args.nlen // 2) logging.info( ( "try: {i:3d}, tag: 0x{tag:016x}, success: {success:1d}, " "|v|: 2^{v:.2f}, |b[0]|: 2^{b0:.2f}, " "|v|/|b[0]|: {b0r:.3f}, " "E|v|/|b[0]|: {eb0r:.3f}, " "|v|/E|b[0]|: {b0er:.3f}, " "cpu: {cpu:10.1f}s, " "wall: {wall:10.1f}s, " "work: {total:d}" ).format( i=args.i, tag=args.tag, success=int(res.success), v=float(log(RR(targetvector.norm()), 2)), b0=float(log(RR(res.b0), 2)), b0r=float(RR(targetvector.norm()) / RR(res.b0)), eb0r=float(RR(expected_length) / RR(res.b0)), b0er=float(RR(targetvector.norm()) / gh), cpu=float(res.cputime), wall=float(res.walltime), total=res.ntests, ) ) return key, res, float(targetvector.norm())
def __init__(self, val, degree, variable=False, field=RIF): if isinstance(val, Taylor): self.val = val.val self.degree = val.degree elif isinstance(val, list): self.val = vector(field, val) self.degree = degree else: self.degree = degree self.val = zero_vector(field, degree + 1) self.val[0] = field(val) if variable: self.val[1] = field(1.0)
def apply_short1(y, A, c, scale=1): """ Compute `y*A`, `y*c` where y is a vector in the integer row span of ``dual_instance(A)`` :param y: (short) vector in scaled dual lattice :param A: LWE matrix :param c: LWE vector """ m = A.nrows() y = vector(ZZ, 1 / ZZ(scale) * y[-m:]) a = balanced_lift(y * A) e = balanced_lift(y * c) return a, e
def group_action(self, mt): ''' mt is an element of GL2. Returns a vector corresponding to mt . self, where . means the group action. ''' (a, b), (c, d) = mt vec_pl = self._to_pol() u1, u2 = vec_pl.parent().gens() vec_pl = vec_pl.subs({u1: u1 * a + u2 * c, u2: u1 * b + u2 * d}) dt = (a * d - b * c) ** self.wt vec = vector([dt * vec_pl[(self.sym_wt - i, i)] for i in range(self.sym_wt + 1)]) return SymTensorRepElt(vec, self.wt)
def attack(p, x1, y1, x2, y2): """ Recovers the a and b parameters from an elliptic curve when two points are known. :param p: the prime of the curve base ring :param x1: the x coordinate of the first point :param y1: the y coordinate of the first point :param x2: the x coordinate of the second point :param y2: the y coordinate of the second point :return: a tuple containing the a and b parameters of the elliptic curve """ m = Matrix(GF(p), [[x1, 1], [x2, 1]]) v = vector(GF(p), [y1**2 - x1**3, y2**2 - x2**3]) a, b = m.solve_right(v) return int(a), int(b)
def evaluate_monomial_integral(mode, RS, polytopes, substitution, dims=None): # NOTE: # The name is slightly misleading since the factor (1-1/q)**RS.ambient_dim # is missing in the p-adic case. # In other words, we're really computing (1-1/q)**(-RS.ambient_dim) * integral. for P in polytopes: if P.ambient_dim() != RS.ambient_dim: raise RuntimeError('dimension mismatch') if not polytopes or any(P.is_empty() for P in polytopes): raise ValueError('need a non-empty collection of non-empty polytopes') for polyhedron in inner_open_normal_fan(sum(polytopes)): y = vector(polyhedron.vertices()[0]) alphas = [vertex_by_direction(Q, y) for Q in polytopes] local_RS = RS & RationalSet(polyhedron) if local_RS.is_empty(): continue A = matrix(ZZ, alphas) Phi = matrix(ZZ, [vector(ZZ, substitution[0]) * A, vector(ZZ, substitution[1]) * A - vector(ZZ, A.ncols() * [1])]).transpose() if mode == 'topological': if local_RS.dim() < RS.dim(): continue for surf in local_RS.topologise(Phi, dims=dims): yield surf elif mode == 'p-adic': with TemporaryList() as tmp_list: sm = local_RS.generating_function(base_list=tmp_list) for z in sm.monomial_substitution(QQ['t', 'q'], Phi): yield z else: raise ValueError('unknown mode')
def _get_system_derivative(self, ncols, inhom=False): r''' Method to compute an ansatz system for the derivative of a fixed size. This method computes an ansatz system for the derivative of solutions to ``self``. Namely, if `f(x)` is a solution to ``self``, we can consider the module: .. MATH:: M = \langle f, \partial(f),\ldots\rangle which (since `f(x)` is annihilated by ``self``) is a finitely generated module. Hence, the module generated by `f'(x)` is also finitely generated. This method creates an ansatz system in the module `M` for computing the linear relation between `h(x) = f'(x)` and its derivatives. INPUT: * ``other``: the operator for the second operand. * ``ncols``: size of the desired system (in number of columns) * ``inhom``: if ``True``, the method return the ansazt matrix system together with a vector representing the inhomogeneous term of the system. OUTPUT: The ansazt system for compute a linear relation with `\partial^{ncols}(f'(x))` and its previous derivatives within the module `M`. ''' from ajpastor.misc.matrix import vector_derivative as der ## Controlling the input ncols if (ncols < 0): raise ValueError("The number of columns must be a natural number") d_matrix = self._get_derivation_matrix_self() ## Base case: 0 column, only inhomogeneous term if (ncols == 0): v = d_matrix * self._pre_proc( vector([1] + (self.order() - 1) * [0])) system = Matrix(d_matrix.parent().base(), [[]]) else: # General case, we build the next column aux_s, new_v = self._get_system_derivative(ncols - 1, True) system = Matrix(aux_s.columns() + [new_v]).transpose() v = der(d_matrix, new_v, self.derivate()) if (inhom): return self._post_proc(system), v else: return self._post_proc(system)
def __contains__(self, x): """ Test whether ``x`` is an element of this subgroup. EXAMPLES:: sage: G.<a,b> = AbelianGroup(2) sage: A = G.subgroup([a]) sage: a in G True sage: a in A True TESTS: Check that :trac:`32910` is fixed:: sage: G.<a,b> = AbelianGroup(2, [4, 576]) sage: Hgens = [a^2, a*b^2] sage: H = G.subgroup(Hgens) sage: [g in H for g in (a^3, b^2, b^3, a^3*b^2, "junk")] [False, False, False, True, False] Check that :trac:`31507` is fixed:: sage: G = AbelianGroup(2, gens_orders=[16, 16]) sage: f0, f1 = G.gens() sage: H = G.subgroup([f0*f1^3]) sage: [g in H for g in (f0, f0*f1^2, f0*f1^3, f0*f1^4)] [False, False, True, False] sage: G.<a,b> = AbelianGroup(2) sage: Hgens = [a*b, a*b^-1] sage: H = G.subgroup(Hgens) sage: b^2 in H True """ if not isinstance(x, AbelianGroupElement): return False if x.parent() is self: return True elif x in self.ambient_group(): amb_inv = self.ambient_group().gens_orders() inv_basis = diagonal_matrix(ZZ, amb_inv) gens_basis = matrix(ZZ, len(self._gens), len(amb_inv), [g.list() for g in self._gens]) return vector(ZZ, x.list()) in inv_basis.stack(gens_basis).row_module() return False
def key_gen(cls, seed=None): """Generate a new public/secret key pair :param cls: Kyber class, inherit and change constants to change defaults :param seed: seed used for random sampling if provided .. note :: Resembles Algorithm 1 of the Kyber paper. """ n, q, eta, k, D = cls.n, cls.q, cls.eta, cls.k, cls.D if seed is not None: set_random_seed(seed) R, x = PolynomialRing(ZZ, "x").objgen() Rq = PolynomialRing(GF(q), "x") f = R(cls.f) A = matrix(Rq, k, k, [Rq.random_element(degree=n-1) for _ in range(k*k)]) s = vector(R, k, [R([(D(eta)) for _ in range(n)]) for _ in range(k)]) e = vector(R, k, [R([(D(eta)) for _ in range(n)]) for _ in range(k)]) t = (A*s + e) % f # NOTE ignoring compression return (A, t), s
def test_skipper_prec(skipper=Skipper4, kyber=Kyber, l=None): """Test precision prediction by construction worst case instance (?) :param skipper: Skipper instance :param kyber: Kyber instance for parameters such as `n` and `q` :param l: bits of precision to use TESTS:: sage: test_skipper_prec(Skipper4, Kyber) sage: l = ceil(Skipper4.prec(Kyber)) - 1 sage: test_skipper_prec(Skipper4, Kyber, l=l) Traceback (most recent call last): ... AssertionError sage: test_skipper_prec(Skipper2Negated, Kyber) sage: l = ceil(Skipper2Negated.prec(Kyber)) - 1 sage: test_skipper_prec(Skipper2Negated, Kyber, l=l) Traceback (most recent call last): ... AssertionError """ n, q, k, eta = kyber.n, kyber.q, kyber.k, kyber.eta R, x = PolynomialRing(ZZ, "x").objgen() f = R(kyber.f) # attempt to construct a worst-case instance a = vector(R, k, [R([q // 2 for _ in range(n)]) for _ in range(k)]) b = vector(R, k, [R([eta for _ in range(n)]) for _ in range(k)]) c = R([eta for _ in range(n)]) d0 = (a * b + c) % f d1 = skipper.muladd(kyber, a, b, c, l=l) assert (d0 == d1)
def test_back_and_forth_nf(): p = iet.Permutation("a b c", "c b a") x = polygen(QQ) K = NumberField(x**2 - 2, 'sqrt2', embedding=AA(2).sqrt()) sqrt2 = K.gen() T = iet.IntervalExchangeTransformation(p, [1, sqrt2, sqrt2 - 1]) T2 = iet_to_pyintervalxt(T) T3 = iet_from_pyintervalxt(T2) assert T == T3 r1 = vector(ZZ, (0, 0, 0, 1, 1, 0)) r2 = vector(ZZ, (3, 1, 0, 1, 0, 2)) r3 = vector(ZZ, (5, 0, 1, 2, 0, 3)) K = NumberField(x**3 - 3, 'cbrt3', embedding=AA(3)**QQ((1, 3))) cbrt3 = K.gen() p = iet.Permutation(["a", "b", "c", "d", "e", "f"], ["f", "d", "c", "b", "a", "e"]) l = r1 + (cbrt3 - 1) * r2 + cbrt3**2 * r3 T = iet.IntervalExchangeTransformation(p, l) assert T.sah_arnoux_fathi_invariant().is_zero() T2 = iet_to_pyintervalxt(T) assert list(T2.safInvariant()) == [0, 0, 0] T3 = iet_from_pyintervalxt(T2) assert T == T3
def CnSymmetricGridConstruction(cls, G, delta): def Cn_symmetric_k_points(n,k, alpha=Integer(1) ): n = Integer(n) k = Integer(k) if not mod(k,n) in [Integer(0) ,Integer(1) ]: raise ValueError('Only possible if k mod n in {{0,1}}, here {} mod {} = {}.'.format(k,n,mod(k,n))) res = { i : vector([RR(cos(RR(Integer(2) *pi*i)/n)),RR(sin(RR(Integer(2) *pi*i)/n))]) for i in range(Integer(0) ,n) } N = k if mod(k,n)==Integer(1) : res[N-Integer(1) ] = vector([Integer(0) ,Integer(0) ]) N = N-Integer(1) for i in range(n,N): r = (i-i%n)/n +Integer(1) res[i] = r*res[i%n] for i in res: res[i] = alpha*vector([res[i][Integer(0) ], res[i][Integer(1) ]]) return [res[i] for i in sorted(res.keys())] n = delta.n a = Cn_symmetric_k_points(n, len(delta._noninvariant_components['red'])) a += [vector([Integer(0) ,Integer(0) ]) for _ in range(len(delta._partially_invariant_components['red']))] b = Cn_symmetric_k_points(n, len(delta._noninvariant_components['blue'])) b += [vector([Integer(0) ,Integer(0) ]) for _ in range(len(delta._partially_invariant_components['blue']))] ab = [b, a] M = GraphMotion.GridConstruction(G, delta, check=False, zigzag=ab, red_components_ordered=delta._noninvariant_components['red']+delta._partially_invariant_components['red'], blue_components_ordered=delta._noninvariant_components['blue']+delta._partially_invariant_components['blue']) for comp in delta._partially_invariant_components['red']+delta._partially_invariant_components['blue']: if len(comp)>Integer(1) : M.fix_edge(Graph(G).subgraph(comp).edges(labels=False)[Integer(0) ]) break return M
def check_collision(query, sgn_, T, index, index_num, bound): ''' :param sgn_: A ternary (-1,0,1) vector / See 'sgnvar' function :param index: The index set where sgn_(i) = -1 :param index_num: A flag for recursive call which lies in (0, len(index)) ''' if index_num == len(index): if power(sgn_) in T: for vec in T[power(sgn_)]: vec = vector(ZZ, vec) query = vector(ZZ, query) if max_norm(query - vec) <= bound: return vec else: for i in [0, 1]: sgn_[index[index_num]] = i res = check_collision(query, sgn_, T, index, index_num + 1, bound) if res is not None: return res
def AJ1_digits(f, P, desired_digits, mesh=4): for k in range(1, f.degree() + 1): assert mesh >= 2 # the guess should take less than 2s working_digits = 300 SetPariPrec(working_digits) CF = ComplexField(ceil(RR(log(10) / log(2)) * working_digits)) aj = {} correct_digits = {} sum = 0 total = 0 guess = 10000 CF = ComplexField(log(10) / log(2) * working_digits) for i in range(mesh, max(0, mesh - 3), -1): PariIntNumInit(i) aj[i] = AJ1(CF, f, P, k) if i < mesh: correct_digits[i] = RR((-log( max([ abs(CF((aj[mesh][j] - x) / aj[mesh][j])) for j, x in enumerate(aj[i]) ])) / log(10.)) / working_digits) if i + 1 < mesh: sum += correct_digits[i + 1] / correct_digits[i] total += 1 for i in sorted(correct_digits.keys()): if correct_digits[i] > 1: guess = i break avg = sum / total if guess == 0 and avg > 1.1: guess = mesh - 1 + ceil( log((1.1 / correct_digits[mesh - 1])) / log(avg)) if guess != 0 and 2**guess * desired_digits**2 * log( RR(desired_digits))**3 < (300**2 * 2**11 * log(RR(300))**3): SetPariPrec(ceil(desired_digits) + 10 * guess) PariIntNumInit(guess) CF = ComplexField(log(10) / log(2) * desired_digits) result = vector(CF, AJ1(CF, f, P, k)) # avoiding memory leaks gp._reset_expect() load_gp() return result else: gp._reset_expect() load_gp() raise OverflowError
def __reduce_solution(self, solution, syzygy): r''' Method to compute the "smallest" solution of the system. ''' from sage.rings.polynomial.polynomial_ring import is_PolynomialRing if(is_PolynomialRing(self.parent()) and syzygy.ncols() == 1): d = max(el.degree() for el in syzygy.column(0)) p = max(el.degree() for el in solution) while(p >= d): i = 0 while(solution[i].degree() < p): i += 1 q,_ = self.__euclidean(solution[i], syzygy[0][i]) solution -= syzygy*vector([q]) p = max(el.degree() for el in solution) return (solution, syzygy)
def run(self, typ, logdir, label=None): self._cur_label = label tname = "%s.%s" % (self.__class__.__name__, typ.shortname) files = [ os.path.join(logdir, tname + suffix) for suffix in ['.log', '.errors', '.progress', '.started', '.done'] ] logfile, errfile, progfile, startfile, donefile = files checks = self.get_checks(typ) # status = failures, errors, timeouts, aborts status = vector(ZZ, 4) # excludes disabled disabled = 0 with open(startfile, 'w') as startf: startf.write("%s.%s started (pid %s)\n" % (self.__class__.__name__, typ.__name__, os.getpid())) with open(logfile, 'a') as log: with open(progfile, 'a') as prog: with open(errfile, 'a') as err: start = time.time() for check_num, check in enumerate(checks, 1): name = "%s.%s" % (self.__class__.__name__, check.__name__) if check.disabled: prog.write('%s (check %s/%s) disabled\n' % (name, check_num, len(checks))) disabled += 1 continue prog.write( '%s (check %s/%s) started at %s\n' % (name, check_num, len(checks), datetime.now())) prog.flush() status += self._run_check(check, typ, label, (prog, log, err)) with open(donefile, 'a') as done: reports = [] for scount, sname in zip(status, ["failure", "error", "timeout", "abort"]): if scount: reports.append(pluralize(scount, sname)) if disabled: reports.append("%s disabled" % disabled) status = "FAILED with " + ", ".join( reports) if reports else "PASSED" done.write("%s.%s %s in %.2fs\n" % (self.__class__.__name__, typ.__name__, status, time.time() - start)) os.remove(startfile)
def convert_hecke_eigenvalues(K_old, eigenvals, K_new, int_basis): """Re-express the Hecke eigenvalues in terms of the integral basis given in the LMFDB INPUT: K_old -- the field containing the Hecke eigenvalues eigenvals -- the Hecke eigenvalues, in terms of a field generator (usually the eigenvalue for T_2) for the field K_old K_new -- a "nicer" field isomorphic to K_old (often one whose polynomial has been polredabs'd) int_basis -- an integral basis for the ring of integers of K_new OUTPUT: eigenvals_new -- list, a list of strings of the coefficients of the Hecke eigenvalues with respect to the integral basis recorded in the LMFDB K_new -- number field, the (normalized) number field containing the Hecke eigenvalues, as given in the LMFDB a -- number field element, the generator for the field K_new int_basis -- list, a list containing the integral basis for K_new """ if not K_old.is_isomorphic(K_new): return "Error! Fields not isomorphic!" iota = K_old.embeddings(K_new)[0] (a, ) = K_new._first_ngens(1) # make change of basis matrix chg_basis_entries = [] for el in int_basis: chg_basis_entries.append(el.list()) chg_basis_mat = matrix( chg_basis_entries) # changes from int_basis to 1, a, a^2, ..., a^(n-1) chg_basis_mat = chg_basis_mat.inverse( ) # changes from 1, a, a^2, ..., a^(n-1) to int_basis # convert entries eigenvals_new = [] for el in eigenvals: v = vector(iota(el).list()) eigenvals_new.append(v * chg_basis_mat) # verify correctness of new expression for eigenvalues eigenvals_old = [iota(el) for el in eigenvals] for j in range(0, len(eigenvals)): new_val = 0 for i in range(0, len(int_basis)): new_val += eigenvals_new[j][i] * int_basis[i] assert new_val == eigenvals_old[j] eigen_strings = [] for c in eigenvals_new: eigen_strings.append(vector_to_string(c)) return eigen_strings, K_new, a, int_basis
def balanced_lift(e): """ Lift e mod q to integer such that result is between -q/2 and q/2 :param e: a value or vector mod q """ from sage.rings.finite_rings.integer_mod import is_IntegerMod q = e.base_ring().order() if is_IntegerMod(e): e = ZZ(e) if e > q//2: e -= q return e else: return vector(balanced_lift(ee) for ee in e)
def balanced_lift(e): """ Lift e mod q to integer such that result is between -q/2 and q/2 :param e: a value or vector mod q """ from sage.rings.finite_rings.integer_mod import is_IntegerMod q = e.base_ring().order() if is_IntegerMod(e): e = ZZ(e) if e > q // 2: e -= q return e else: return vector(balanced_lift(ee) for ee in e)
def herm_signature(self): from sage.all import exp, vector, matrix from sage.misc.functional import numerical_approx n = self._dimension alpha_exp = [numerical_approx(exp(2*1j*pi*self._alpha[i]),30) for i in xrange(self._dimension)] beta_exp = [numerical_approx(exp(2*1j*pi*self._beta[i]),30) for i in xrange(self._dimension)] v = vector([1]*n)*matrix(n,n, lambda i, j: 1/(alpha_exp[j] + beta_exp[i])).inverse() d_val = [1/(-beta_exp[i]/v[i]).real_part() for i in xrange(self._dimension)] d_val.sort() k = 0 while (k < n) and (d_val[k] < 0): k += 1 return(k, n-k)
def get_T1(K, S, unit_first=True, verbose=False): # Sx is a list of generators of K(S,2) with the unit first or last, assuming h(K)=1 u = -1 if K==QQ else K(K.unit_group().torsion_generator()) from KSp import IdealGenerator Sx = [IdealGenerator(P) for P in S] if unit_first: Sx = [u] + Sx else: Sx = Sx + [u] r = len(Sx) N = prod(S,1) # Initialize T1 to be empty and A to be a matric with 0 rows and r=#Sx columns T1 = [] A = Matrix(GF(2),0,len(Sx)) primes = primes_iter(K,1) p = primes.next() # Repeat the following until A has full rank: take the next prime p # from the iterator, skip if it divides N (=product over S), form the # vector v, and keep p and append v to the bottom of A if it increases # the rank: while A.rank() < r: p = primes.next() while p.divides(N): p = primes.next() if verbose: print("A={} with {} rows and {} cols".format(A,A.nrows(),A.ncols())) v = vector(alphalist(p, Sx)) if verbose: print("v={}".format(v)) A1 = A.stack(v) if A1.rank() > A.rank(): A = A1 T1 = T1 + [p] if verbose: print("new A={} with {} rows and {} cols".format(A,A.nrows(),A.ncols())) print("T1 increases to {}".format(T1)) # the last thing returned is a "decoder" which returns the # discriminant Delta given the splitting beavious at the primes in # T1: B = A.inverse() def decoder(alphalist): e = list(B*vector(alphalist)) return prod([D**ZZ(ei) for D,ei in zip(Sx,e)], 1) return T1, A, decoder
def convert_hecke_eigenvalues(K_old, eigenvals, K_new, int_basis): """Re-express the Hecke eigenvalues in terms of the integral basis given in the LMFDB INPUT: K_old -- the field containing the Hecke eigenvalues eigenvals -- the Hecke eigenvalues, in terms of a field generator (usually the eigenvalue for T_2) for the field K_old K_new -- a "nicer" field isomorphic to K_old (often one whose polynomial has been polredabs'd) int_basis -- an integral basis for the ring of integers of K_new OUTPUT: eigenvals_new -- list, a list of strings of the coefficients of the Hecke eigenvalues with respect to the integral basis recorded in the LMFDB K_new -- number field, the (normalized) number field containing the Hecke eigenvalues, as given in the LMFDB a -- number field element, the generator for the field K_new int_basis -- list, a list containing the integral basis for K_new """ if not K_old.is_isomorphic(K_new): return "Error! Fields not isomorphic!" iota = K_old.embeddings(K_new)[0] (a,) = K_new._first_ngens(1) # make change of basis matrix chg_basis_entries = [] for el in int_basis: chg_basis_entries.append(el.list()) chg_basis_mat = matrix(chg_basis_entries) # changes from int_basis to 1, a, a^2, ..., a^(n-1) chg_basis_mat = chg_basis_mat.inverse() # changes from 1, a, a^2, ..., a^(n-1) to int_basis # convert entries eigenvals_new = [] for el in eigenvals: v = vector(iota(el).list()) eigenvals_new.append(v*chg_basis_mat) # verify correctness of new expression for eigenvalues eigenvals_old = [iota(el) for el in eigenvals] for j in range(0,len(eigenvals)): new_val = 0 for i in range(0,len(int_basis)): new_val += eigenvals_new[j][i]*int_basis[i] assert new_val == eigenvals_old[j] eigen_strings = [] for c in eigenvals_new: eigen_strings.append(vector_to_string(c)) return eigen_strings, K_new, a, int_basis
def gen_fhe_instance(n, q, alpha=None, h=None, m=None, seed=None): """ Generate FHE-style LWE instance :param n: dimension :param q: modulus :param alpha: noise rate (default: 8/q) :param h: hamming weight of the secret (default: 2/3n) :param m: number of samples (default: n) """ if seed is not None: set_random_seed(seed) q = next_prime(ceil(q)-1, proof=False) if alpha is None: alpha = ZZ(8)/q n, alpha, q = preprocess_params(n, alpha, q) stddev = stddevf(alpha*q) if m is None: m = n K = GF(q, proof=False) A = random_matrix(K, m, n) if h is None: s = random_vector(ZZ, n, x=-1, y=1) else: S = [-1, 1] s = [S[randint(0, 1)] for i in range(h)] s += [0 for _ in range(n-h)] shuffle(s) s = vector(ZZ, s) c = A*s D = DiscreteGaussian(stddev) for i in range(m): c[i] += D() return A, c
def modular_units_of_degree(G,deg,rational = True, verbose = False,qfminim_bound = 10**5): """ Returns an iterator over all modular units on the curve X(G). INPUT: - ``G`` - a congruence subgroup - ``deg`` - int, the degree of modular unit to search for - ``rational`` - bool, true means modular unit should be defined over QQ - ``verbose`` - bool (default = false), wether or not to print progress - ``qfminim_bound`` - int (default - 10^5), given to pari's qfminim command, and is an upper bound on how many vectors of short l2 norm are returned by pari this function will raise an error if pari finds more short vectors then it returns """ if rational: L,D=rational_modular_unit_lattice(G) else: L,D=modular_unit_lattice(G) M = L.basis_matrix().change_ring(ZZ).LLL() GS_matrix=M*M.transpose() pari_gs=pari(GS_matrix) short_vectors=pari_gs.qfminim(deg**2*2,qfminim_bound) if verbose: print short_vectors[:2] count = 0 for i in short_vectors[2]: count+=1 if verbose and count%10000==0: print count v=vector(QQ,i.list())*M if v.norm(1)/2 == deg: yield L(v) assert short_vectors[0].sage() < 2*qfminim_bound
def order_gen(self): if self.field_poly_root_of_unity == 4: return r'\(i = \sqrt{-1}\)' elif self.hecke_ring_power_basis and self.field_poly_is_cyclotomic: return r'a primitive root of unity \(\zeta_{%s}\)' % self.field_poly_root_of_unity elif self.dim == 2: c, b, a = map(ZZ, self.field_poly) D = b**2 - 4*a*c d = D.squarefree_part() s = (D//d).isqrt() if self.hecke_ring_power_basis: k, l = ZZ(0), ZZ(1) else: k, l = map(ZZ, self.hecke_ring_numerators[1]) k = k / self.hecke_ring_denominators[1] l = l / self.hecke_ring_denominators[1] beta = vector((k - (b*l)/(2*a), ((s*l)/(2*a)).abs())) den = lcm(beta[0].denom(), beta[1].denom()) beta *= den if d == -1: Sqrt = 'i' else: Sqrt = r'\sqrt{%s}' % d if beta[1] != 1: Sqrt = r'%s%s' % (beta[1], Sqrt) if beta[0] == 0: Num = Sqrt else: Num = r'%s + %s' % (beta[0], Sqrt) if den == 1: Frac = Num else: Frac = r'\frac{1}{%s}(%s)' % (den, Num) return r'\(\beta = %s\)' % Frac elif self.hecke_ring_power_basis: return r'a root \(\beta\) of the polynomial %s' % (self.defining_polynomial()) else: if self.dim <= 5: betas = ",".join(r"\beta_%s" % (i) for i in range(1, self.dim)) else: betas = r"\beta_1,\ldots,\beta_{%s}" % (self.dim - 1) return r'a basis \(1,%s\) for the coefficient ring described below' % (betas)