def polish_approx_hyperbolic_structure(approx_hyperbolic_structure, bits_prec=53, verbose=False): RF = RealField(bits_prec + 20) twoPi = 2 * RF.pi() edge_parameters = vector(RF, approx_hyperbolic_structure.edge_lengths) epsilon = RF(0.5)**bits_prec if not (approx_hyperbolic_structure.exact_edges and approx_hyperbolic_structure.var_edges): raise Exception("Did not pick exact/var edges") for i in range(100): try: result = HyperbolicStructure( approx_hyperbolic_structure.mcomplex, edge_parameters, approx_hyperbolic_structure.exact_edges, approx_hyperbolic_structure.var_edges) except BadDihedralAngleError as e: raise PolishingFailedWithBadDihedralAngleError("When polishing", e) errs = vector( [result.angle_sums[e] - twoPi for e in result.exact_edges]) max_err = max([abs(err) for err in errs]) if verbose: print("Iteration %d: error = %s" % (i, RealField(53)(max_err))) if max_err < epsilon: return result j = result.full_rank_jacobian_submatrix() try: jinv = j.inverse() except ZeroDivisionError: raise PolishingError("Singular matrix") delta = jinv * errs for e, d in zip(result.var_edges, delta): edge_parameters[e] -= d print("Max error", max_err) print(approx_hyperbolic_structure.full_rank_jacobian_submatrix().SVD() [1].diagonal()) raise PolishingError("Newton method did not produce a result")
def display_float(x, digits, method="truncate", extra_truncation_digits=3, try_halfinteger=True, no_sci=None, latex=False): if abs(x) < 10.**(-digits - extra_truncation_digits): return "0" # if small, try to display it as an exact or half integer if try_halfinteger and abs(x) < 10.**digits: if is_exact(x): s = str(x) if len(s) < digits + 2: # 2 = '/' + '-' return str(x) k = round_to_half_int(x) if k == x: k2 = None try: k2 = ZZ(2 * x) except TypeError: pass # the second statement checks for overflow if k2 == 2 * x and (2 * x + 1) - k2 == 1: if k2 % 2 == 0: s = '%s' % (k2 / 2) else: s = '%s' % (float(k2) / 2) return s if method == 'truncate': rnd = 'RNDZ' else: rnd = 'RNDN' if no_sci is None: no_sci = 'e' not in "%.{}g".format(digits) % float(x) try: s = RealField(max(53, 4 * digits), rnd=rnd)(x).str(digits=digits, no_sci=no_sci) except TypeError: # older versions of Sage don't support the digits keyword s = RealField(max(53, 4 * digits), rnd=rnd)(x).str(no_sci=no_sci) point = s.find('.') if point != -1: if point < digits: s = s[:digits + 1] else: s = s[:point] if latex and "e" in s: s = s.replace("e", r"\times 10^{") + "}" return s
def EC_nf_plot(E, base_field_gen_name): K = E.base_field() n1 = K.signature()[0] if n1 == 0: return plot([]) prec = 53 maxprec = 10 ** 6 while prec < maxprec: # Try to base change to R. May fail if resulting curve is almost singular, so increase precision. try: SR = K.embeddings(RealField(prec)) X = [E.base_extend(s) for s in SR] break except ArithmeticError: prec *= 2 if prec >= maxprec: return text("Unable to plot", (1, 1), fontsize="xx-large") X = [e.plot() for e in X] xmin = min([x.xmin() for x in X]) xmax = max([x.xmax() for x in X]) ymin = min([x.ymin() for x in X]) ymax = max([x.ymax() for x in X]) cols = ["blue", "red", "green", "orange", "brown"] # Preset colours, because rainbow tends to return too pale ones if n1 > len(cols): cols = rainbow(n1) return sum([EC_R_plot([SR[i](a) for a in E.ainvs()], xmin, xmax, ymin, ymax, cols[i], "$" + base_field_gen_name + " \mapsto$ " + str(SR[i].im_gens()[0].n(20))) for i in range(n1)])
def TwoPointsMinusInfinity(self, P, Q): # Creates a divisor class of P + Q - g*\infty maxlower = self.lower xP, yP = self.Rextraprec(P[0]), self.Rextraprec(P[1]) xQ, yQ = self.Rextraprec(Q[0]), self.Rextraprec(Q[1]) assert (self.f(xP) - yP**2).abs() <= (yP**2).abs() * self.almostzero assert (self.f(xQ) - yQ**2).abs() <= (yQ**2).abs() * self.almostzero WPQ = Matrix(self.Rextraprec, self.nZ, 3 * self.g + 7) # H0(3D0 - g*\infty) Ev = Matrix(self.Rextraprec, 2, 3 * self.g + 7) # basis of H0(3D0 - g*\infty) evaluated at P and Q Exps=[] for n in range( 2 * self.g + 4): Exps.append((n,0)) if n > self.g: Exps.append(( n - self.g - 1, 1)) for j in range( 3 * self.g + 7): u, v = Exps[j] for i in range( self.nZ ): x, y = self.Z[i] WPQ[ i, j ] = x**u * y**v Ev[0,j] = xP**u * yP**v Ev[1,j] = xQ**u * yQ**v K, upper, lower = Kernel(Ev, 2) assert self.threshold_check(upper, lower), "upper = %s lower = %s" % (RealField(35)(upper), RealField(35)(lower)) maxlower = max(maxlower, lower); #Returns H0(3*D0 - P - Q - g infty) # note that [P + Q + g infty - D0] ~ P + Q - infty return (WPQ * K).change_ring(self.R), maxlower
def real_parabolic_reps_from_ptolemy(M, pari_prec=15): R = PolynomialRing(QQ, 'x') RR = RealField(1000) ans = [] obs_classes = M.ptolemy_obstruction_classes() for obs in obs_classes: V = M.ptolemy_variety(N=2, obstruction_class=obs) #for sol in V.retrieve_solutions(): for sol in V.compute_solutions(engine='magma'): if sol.dimension > 0: print("Positive dimensional component!") continue prec = snappy.pari.set_real_precision(pari_prec) is_geometric = sol.is_geometric() snappy.pari.set_real_precision(prec) cross_ratios = sol.cross_ratios() shapes = [ R(cross_ratios['z_0000_%d' % i].lift()) for i in range(M.num_tetrahedra()) ] s = shapes[0] p = R(sol.number_field()) if p == 0: # Field is Q assert False # print p, '\n' for r in p.roots(RR, False): rho = pe.real_reps.PSL2RRepOf3ManifoldGroup( M, target_meridian_holonomy=RR(1), rough_shapes=[cr(r) for cr in shapes]) rho.is_galois_conj_of_geom = is_geometric ans.append(rho) return ans
def fixed_prec(r, digs=3): n = RealField(200)(r) * (10**digs) n = str(n.round()) head = int(n[:-digs]) if head >= 10**4: head = comma(head) return str(head) + '.' + n[-digs:]
def signature_function_of_integral_matrix(V, prec=53): """ Computes the signature function sigma of V via numerical methods. Returns two lists, the first representing a partition of [0, 1]: x_0 = 0 < x_1 < x_2 < ... < x_n = 1 and the second list consisting of the values [v_0, ... , v_(n-1)] of sigma on the interval (x_i, x_(i+1)). Currently, the value of sigma *at* x_i is not computed. """ poly = alexander_poly_from_seifert(V) RR = RealField(prec) CC = ComplexField(prec) pi = RR.pi() I = CC.gen() partition = [RR(0)] + [a for a, e in roots_on_unit_circle(poly, prec) ] + [RR(1)] n = len(partition) - 1 values = [] for i in range(n): omega = exp((2 * pi * I) * (partition[i] + partition[i + 1]) / 2) A = (1 - omega) * V + (1 - omega.conjugate()) * V.transpose() values.append(signature_via_numpy(A)) assert list(reversed(values)) == values return partition, values
def central_char_function(self): dim = self.dimension() dfactor = (-1)**dim # doubling insures integers below # we could test for when we need it, but then we carry the "if" # throughout charf = 2*self.character_field() localfactors = self.local_factors_table() bad = [0 if dim+1>len(z) else 1 for z in localfactors] localfactors = [self.from_conjugacy_class_index_to_polynomial(j+1) for j in range(len(localfactors))] localfactors = [z.leading_coefficient()*dfactor for z in localfactors] # Now take logs to figure out what power these are mypi = RealField(100)(pi) localfactors = [charf*log(z)/(2*I*mypi) for z in localfactors] localfactorsa = [z.real().round() % charf for z in localfactors] # Test to see if we are ok? localfactorsa = [localfactorsa[j] if bad[j]>0 else -1 for j in range(len(localfactorsa))] def myfunc(inp, n): fn = list(factor(inp)) pvals = [[localfactorsa[self.any_prime_to_cc_index(z[0])-1], z[1]] for z in fn] # -1 is the marker that the prime divides the conductor for j in range(len(pvals)): if pvals[j][0] < 0: return -1 pvals = sum([z[0]*z[1] for z in pvals]) return (pvals % n) return myfunc
def coefficient_at_coset(self, n): r""" Compute Fourier coefficients of f|A_n """ if hasattr(n, "matrix"): n = self._get_coset_n(n) if not self._base_coeffs: self.coefficients_f() CF = ComplexField(self._prec) if not self._coefficients_at_coset.has_key(n): M = self.truncation_M(n) h, w = self.get_shift_and_width_for_coset(n) zN = CyclotomicField(w).gens()[0] prec1 = self._prec + ceil(log_b(M, 2)) RF = RealField(prec1) coeffs = [] fak = RF(w)**-(RF(self._k) / RF(2)) #print "f=",f,n for i in range(M): al = CF(self.atkin_lehner(n)) c0 = self._base_coeffs_embedding[i] #if hasattr(c0,"complex_embeddings"): # c0 = c0.complex_embedding(prec1) #else: # c0 = CF(c0) qN = zN**((i + 1) * h) #print "qN=",qN,type(qN) an = fak * al * c0 * qN.complex_embedding(prec1) #an = self.atkin_lehner(n)*self._base_coeffs[i]*zN**((i+1)*h) #an = f*an.complex_embedding(prec1) coeffs.append(an) self._coefficients_at_coset[n] = coeffs return self._coefficients_at_coset[n]
def coefficients_f(self): r""" Compute the maximum number of coefficients we need to use (with current precision). """ if not self._base_coeffs: kf = 0.5 * (self._k - 1.0) M0 = self.maxM() prec1 = self._prec + ceil(log_b(M0 * 6, 2)) if hasattr(self._f, "O"): self._base_coeffs = self._f.coefficients() if len(self._base_coeffs) < M0: raise ValueError, "Too few coefficients available!" else: self._base_coeffs = self._f.coefficients(ZZ(M0)) self._base_coeffs_embedding = [] #precn = prec1 if hasattr(self._base_coeffs[0], "complex_embedding"): n = 1 #print "kf=",kf #print "kfprec1=",prec1 for a in self._base_coeffs: ## Use precision high enough that c(n)/n^((k-1)/2) have self._prec correct bits precn = prec1 + kf * ceil(log_b(n, 2)) self._base_coeffs_embedding.append( a.complex_embedding(precn)) n += 1 else: ## Here we have a rational number so we can ue the default number of bits n = 1 for a in self._base_coeffs: precn = prec1 + kf * ceil(log_b(n, 2)) aa = RealField(precn)(a) self._base_coeffs_embedding.append(a) #self._RF(a)) n += 1 return self._base_coeffs
def PointMinusInfinity(self, P, sign = 0): # Creates a divisor class of P- \inty_{(-1)**sign} maxlower = self.lower assert self.f.degree() == 2*self.g + 2; sqrtan = (-1)**sign * self.Rextraprec( sqrt( self.Rdoubleextraprec(self.an)) ); xP, yP = self.Rextraprec(P[0]),self.Rextraprec(P[1]) assert (self.f(xP) - yP**2).abs() <= (yP**2).abs() * self.almostzero if xP != 0 and self.a0 != 0: x0 = self.Rextraprec(0); else: x0 = xP while x0 == xP: x0 = self.Rextraprec(ZZ.random_element()) y0 = self.Rextraprec( sqrt( self.Rdoubleextraprec( self.f( x0 )))) # P0 = (x0, y0) WP1 = Matrix(self.Rextraprec, self.nZ, 3 * self.g + 6) # H0(3D0 - P0 - g \infty) = H0(3D0 - P0 - g(\infty_{+} + \infty_{-})) EvP = Matrix(self.Rextraprec, 1, 3 * self.g + 6) # the functions of H0(3D0-P0-g \infty) at P B = Matrix(self.Rextraprec, self.nZ, 3 * self.g + 5) # H0(3D0 - \infty_{sign} - P0 - g\infty) # adds the functions x - x0, (x - x0)**1, ..., (x - x0)**(2g+2) to it for j in xrange(2 * self.g + 2 ): for i, (x, y) in enumerate( self.Z ): WP1[ i, j] = B[ i, j] = (x - x0) ** (j + 1) EvP[ 0, j] = (xP - x0) ** (j + 1) # adds y - y0 for i, (x, y) in enumerate( self.Z ): WP1[ i, 2 * self.g + 2 ] = B[ i, 2 * self.g + 2] = y - y0 EvP[ 0, 2 * self.g + 2] = yP - y0 # adds (x - x0) * y ... (x-x0)**(g+1)*y for j in range(1, self.g + 2): for i, (x,y) in enumerate( self.Z ): WP1[ i, 2 * self.g + 2 + j ] = B[ i, 2 * self.g + 2 + j] = (x-x0)**j * y EvP[ 0, 2 * self.g + 2 + j] = (xP - x0)**j * yP # adds (x - x0)**(2g + 3) and y * (x - x0)**(g + 2) for i,(x,y) in enumerate(self.Z): WP1[ i, 3 * self.g + 4 ] = (x - x0)**( 2 * self.g + 3) WP1[ i, 3 * self.g + 5 ] = y * (x - x0)**(self.g + 2) B[ i, 3 * self.g + 4 ] = (x - x0)**( self.g + 2) * ( y - sqrtan * x**(self.g + 1) ) EvP[ 0, 3 * self.g + 4] = (xP - x0) ** ( 2 * self.g + 3) EvP[ 0, 3 * self.g + 5] = yP * (xP - x0)**(self.g + 2) # A = functions in H0(3D0-P0-g \infty) that vanish at P # = H**0(3D0 - P0 - P -g \infty) K, upper, lower = Kernel(EvP, EvP.ncols() - (3 * self.g + 5)) assert self.threshold_check(upper, lower), "upper = %s lower = %s" % (RealField(35)(upper), RealField(35)(lower)) maxlower = max(maxlower, lower); A = WP1 * K # A - B = P0 + P + g \infty - (\infty_{+} + P0 + g\infty) = P - \inty_{+} res, lower = self.Sub(A,B) maxlower = max(maxlower, lower); return res.change_ring(self.R), maxlower;
def mpmath_matrix_to_sage(A): entries = list(A) if all(isinstance(e, mp.mpf) for e in entries): F = RealField(mp.prec) entries = [F(e) for e in entries] else: F = ComplexField(mp.prec) entries = [F(e.real, e.imag) for e in entries] return matrix(F, A.rows, A.cols, entries)
def real_root_arguments(p, prec=212): """ Note: if p(x) = g(x + 1/x) then p'(1) = p'(-1) = 0 by the chain rule; in particular, 1 and -1 are *never* simple roots of p(x). """ assert p(1) != 0 and p(-1) != 0 g = compact_form(p) RR = RealField(prec) roots = sorted([(arccos(x/2), e) for x, e in g.roots(RR) if abs(x) <= 2]) return roots
def __init__(self, real, imag=None): def find_prec(s): if isinstance(s, string_types): # strip negatives and exponent s = s.replace("-","") if "e" in s: s = s[:s.find("e")] return ceil(len(s) * 3.322) else: try: return s.parent().precision() except Exception: return 53 if imag is None: # Process strings if isinstance(real, string_types): M = CC_RE.match(real) if M is None: raise ValueError("'%s' not a valid complex number" % real) a, b = M.groups() # handle missing coefficient of i if b == '-': b = '-1' elif b in ['+', '']: b = '1' # The following is a good guess for the bit-precision, # but we use LmfdbRealLiterals to ensure that our number # prints the same as we got it. prec = max(find_prec(a), find_prec(b), 53) parent = ComplexField(prec) R = parent._real_field() self._real_literal = LmfdbRealLiteral(R, a) self._imag_literal = LmfdbRealLiteral(R, b) elif isinstance(real, LmfdbRealLiteral): parent = ComplexField(real.parent().precision()) self._real_literal = real self._imag_literal = parent._real_field()(0) elif isintance(real, ComplexLiteral): parent = real.parent() self._real_literal = real._real_literal self._imag_literal = real._imag_literal else: raise TypeError("Object '%s' of type %s not valid input" % (real, type(real))) else: prec = max(find_prec(real), find_prec(imag), 53) R = RealField(prec) parent = ComplexField(prec) for x, xname in [(real, '_real_literal'), (imag, '_imag_literal')]: if isinstance(x, string_types): x = LmfdbRealLiteral(R, x) if not isinstance(x, LmfdbRealLiteral): raise TypeError("Object '%s' of type %s not valid input" % (x, type(x))) setattr(self, xname, x) ComplexNumber.__init__(self, self.real(), self.imag())
def preserves_hermitian_form(SL2C_matrices): """ >>> CC = ComplexField(100) >>> A = matrix(CC, [[1, 1], [1, 2]]); >>> B = matrix(CC, [[0, 1], [-1, 0]]) >>> C = matrix(CC, [[CC('I'),0], [0, -CC('I')]]) >>> ans, sig, form = preserves_hermitian_form([A, B]) >>> ans True >>> sig 'indefinite' >>> form.change_ring(ComplexField(10)) [ 0.00 -1.0*I] [ 1.0*I 0.00] >>> preserves_hermitian_form([A, B, C]) (False, None, None) >>> ans, sig, form = preserves_hermitian_form([B, C]) >>> sig 'definite' """ M = block_matrix(len(SL2C_matrices), 1, [ left_mult_by_adjoint(A) - right_mult_by_inverse(A) for A in SL2C_matrices ]) CC = M.base_ring() mp.prec = CC.prec() RR = RealField(CC.prec()) epsilon = RR(2)**(-int(0.8 * mp.prec)) U, S, V = mp.svd(sage_matrix_to_mpmath(M)) S = list(mp.chop(S, epsilon)) if mp.zero not in S: return False, None, None elif S.count(mp.zero) > 1: for i, A in enumerate(SL2C_matrices): for B in SL2C_matrices[i + 1:]: assert (A * B - B * A).norm() < epsilon sig = 'indefinite' if any(abs(A.trace()) > 2 for A in SL2C_matrices) else 'both' return True, sig, None else: in_kernel = list(mp.chop(V.H.column(S.index(mp.zero)))) J = mp.matrix([in_kernel[:2], in_kernel[2:]]) iJ = mp.mpc(imag=1) * J J1, J2 = J + J.H, iJ + iJ.H J = J1 if mp.norm(J1) >= mp.norm(J2) else J2 J = (1 / mp.sqrt(abs(mp.det(J)))) * J J = mpmath_matrix_to_sage(J) assert all((A.conjugate_transpose() * J * A - J).norm() < epsilon for A in SL2C_matrices) sig = 'definite' if J.det() > 0 else 'indefinite' return True, sig, J
def compute_p_from_w_and_parity(w, parity): """ Compute p such that w - p * pi * i should have imaginary part between -pi and pi and p has the same parity as the given value for parity (the given value is supposed to be 0 or 1). Note that this computation is not verified. """ RF = RealField(w.parent().precision()) real_part = (w.imag().center() / RF(pi) - parity) / 2 return 2 * Integer(real_part.round()) + parity
def tensor_get_an_no_deg1(L1, L2, d1, d2, BadPrimeInfo): """ Same as the above in the case no dimension is 1 """ if d1 == 1 or d2 == 1: raise ValueError('min(d1,d2) should not be 1, use direct method then') s1 = len(L1) s2 = len(L2) if s1 < s2: S = s1 if s2 <= s1: S = s2 BadPrimes = [] for bpi in BadPrimeInfo: BadPrimes.append(bpi[0]) P = prime_range(S + 1) Z = S * [1] S = RealField()(S) for p in P: f = S.log(base=p).floor() q = 1 E1 = [] E2 = [] if not p in BadPrimes: for i in range(f): q = q * p E1.append(L1[q - 1]) E2.append(L2[q - 1]) e1 = list_to_euler_factor(E1, f + 1) e2 = list_to_euler_factor(E2, f + 1) # ld1 = d1 # not used # ld2 = d2 # not used else: # either convolve, or have one input be the answer and other 1-t i = BadPrimes.index(p) e1 = BadPrimeInfo[i][1] e2 = BadPrimeInfo[i][2] # ld1 = e1.degree() # not used # ld2 = e2.degree() # not used F = e1.list()[0].parent().fraction_field() R = PowerSeriesRing(F, "T", default_prec=f + 1) e1 = R(e1) e2 = R(e2) E = tensor_local_factors(e1, e2, f) A = euler_factor_to_list(E, f) while len(A) < f: A.append(0) q = 1 for i in range(f): q = q * p Z[q - 1] = A[i] all_an_from_prime_powers(Z) return Z
def lifted_slope(M, target_meridian_holonomy_arg, shapes): RR = RealField() target = RR(target_meridian_holonomy_arg) rho = PSL2CRepOf3ManifoldGroup(M, target, rough_shapes=shapes, precision=1000) assert rho.polished_holonomy().check_representation() < 1.0e-100 rho_real = PSL2RRepOf3ManifoldGroup(rho) meridian, longitude = rho.polished_holonomy().peripheral_curves()[0] rho_tilde = rho_real.lift_on_cusped_manifold() M, L = rho_tilde.peripheral_translations() return -L / M
def sage(self): """ Return as an element of the approriate RealField or ComplexField """ if not _within_sage: raise ImportError("Not within SAGE.") if self.gen.type() == 't_REAL': return RealField(self._precision)(self.gen) elif self.gen.type() == 't_COMPLEX': return ComplexField(self._precision)(self.gen) else: return self.gen.sage()
def evf(cls, m, max_klen, prec=53): """ Estimate norm of target vector. :param m: number of samples :param klen: length of key to recover :param prec: precision to use """ w = 2 ** (max_klen - 1) RR = RealField(prec) w = RR(w) return RR(sqrt(m * (w ** 2 / 3 + 1 / RR(6)) + w ** 2))
def volf(cls, m, p, klen_list, prec=53): """ Lattice volume. :param m: number of samples :param p: ECDSA modulus :param klen_list: list of lengths of key to recover :param prec: precision to use """ w = 2 ** (max(klen_list) - 1) RR = RealField(prec) f_list = [Integer(w / (2 ** (klen - 1))) for klen in klen_list] return RR(exp(log(p) * (m - 1) + sum(map(log, f_list)) + log(w)))
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 get_euler_factor(L, p): """ takes L list of all ans and p is a prime it returns the euler factor at p # utility function to get an Euler factor, unused """ S = RealField()(len(L)) f = S.log(base=p).floor() E = [] q = 1 for i in range(f): q = q * p E.append(L[q - 1]) return list_to_euler_factor(E, f)
def special_value(self, n): r""" Compute L(f,n) Recall that L(f,n+1)=(2pii)^(n+1)*(-1)^(n+1)/Gamma(n+1) * r_n(f) """ RF = RealField(self._prec) CF = ComplexField(self._prec) if n < 0 or n > self._w + 1: print "{0} is not a special point for this f!".format(n) return if not self._polynomials: self._get_polynomials() rk = self.get_rk(0, n - 1) return CF(0, 2 * RF.pi())**(n) * (-1)**(n) / RF(n).gamma() * rk
def display_float(x, digits, method="truncate", extra_truncation_digits=3): if is_exact(x): return '%s' % x if abs(x) < 10.**(-digits - extra_truncation_digits): return "0" k = round_to_half_int(x) if k == x: k2 = None try: k2 = ZZ(2 * x) except TypeError: pass # the second statment checks for overflow if k2 == 2 * x and (2 * x + 1) - k2 == 1: if k2 % 2 == 0: s = '%s' % (k2 / 2) else: s = '%s' % (float(k2) / 2) return s if method == 'truncate': rnd = 'RNDZ' else: rnd = 'RNDN' no_sci = 'e' not in "%.{}g".format(digits) % float(x) try: s = RealField(max(53, 4 * digits), rnd=rnd)(x).str(digits=digits, no_sci=no_sci) except TypeError: # older versions of Sage don't support the digits keyword s = RealField(max(53, 4 * digits), rnd=rnd)(x).str(no_sci=no_sci) point = s.find('.') if point != -1: if point < digits: s = s[:digits + 1] else: s = s[:point] return s
def parse_file(filename, prec=53): from sage.all import RealField, ComplexField RR = RealField(prec) CC = ComplexField(prec) data = open(filename).read() open('polys.txt', 'w').write(data) data = data.split('THE SOLUTIONS')[-1] data = re.subn('[*]{3,}', '', data)[0] ans = [] solutions = re.findall('(solution \d+ : \s* start residual .*?) ==', data, re.DOTALL) for sol in solutions: kind = sol.split('=')[-1].strip() if kind == 'no solution': continue mult = int(re.search('^m : (\d+)', sol, re.MULTILINE).group(1)) err = float(re.search('== err :\s+(.*?)\s+= ', sol).group(1)) coors = re.findall('^ (.*) :\s+(\S*)\s+(\S*)', sol, re.MULTILINE) if kind.startswith('real'): coors = { restore_forbidden(var): RR(real) for var, real, imag in coors } ans.append({ 'kind': 'real', 'mult': mult, 'err': err, 'coors': coors }) elif kind.startswith('complex'): coors = { restore_forbidden(var): CC(RR(real), RR(imag)) for var, real, imag in coors } ans.append({ 'kind': 'complex', 'mult': mult, 'err': err, 'coors': coors }) num_real = int( re.search('Number of real solutions\s+:\s(.*).', data).group(1)) num_complex = int( re.search('Number of complex solutions\s+:\s(.*).', data).group(1)) kinds = [sol['kind'] for sol in ans] assert kinds.count('real') == num_real assert kinds.count('complex') == num_complex return ans
def mvf(cls, m, max_klen, prec=53): """ Maximal norm of target vector. :param m: number of samples :param max_klen: length of key to recover :param prec: precision to use """ w = 2 ** (max_klen - 1) RR = RealField(prec) w = RR(w) d = m + 1 return RR(sqrt(d) * w)
def all_an_from_prime_powers(L): """ L is a list of an such that the terms are correct for all n which are prime powers and all others are equal to 1; this function changes the list in place to make the correct ans for all n """ S = ZZ(len(L)) for p in prime_range(S + 1): q = 1 Sr = RealField()(len(L)) f = Sr.log(base=p).floor() for k in range(f): q = q * p for m in range(2, 1 + (S // q)): if (m % p) != 0: L[m * q - 1] = L[m * q - 1] * L[q - 1]
def ghf(cls, m, p, klen_list, prec=53): """ Estimate norm of shortest vector according to Gaussian Heuristic. :param m: number of samples :param p: ECDSA modulus :param klen_list: list of lengths of key to recover :param prec: precision to use """ # NOTE: The Gaussian Heuristic does not hold in small dimensions w = 2 ** (max(klen_list) - 1) RR = RealField(prec) w = RR(w) f_list = [Integer(w / (2 ** (klen - 1))) for klen in klen_list] d = m + 1 log_vol = log(p) * (m - 1) + sum(map(log, f_list)) + log(w) lgh = log_gamma(1 + d / 2.0) * (1.0 / d) - log(sqrt(pi)) + log_vol * (1.0 / d) return RR(exp(lgh))
def tensor_get_an_deg1(L, D, BadPrimeInfo): """ Same as above, except that the BadPrimeInfo is now a list of lists of the form [p,f] where f is a polynomial. """ s1 = len(L) s2 = len(D) if s1 < s2: S = s1 if s2 <= s1: S = s2 BadPrimes = [] for bpi in BadPrimeInfo: BadPrimes.append(bpi[0]) P = prime_range(S + 1) Z = S * [1] S = RealField()(S) # fix bug for p in P: f = S.log(base=p).floor() q = 1 u = 1 e = D[p - 1] if not p in BadPrimes: for i in range(f): q = q * p u = u * e Z[q - 1] = u * L[q - 1] else: i = BadPrimes.index(p) e = BadPrimeInfo[i][1] F = e.list()[0].parent().fraction_field() R = PowerSeriesRing(F, "T", default_prec=f + 1) e = R(e) A = euler_factor_to_list(e, f) for i in range(f): q = q * p Z[q - 1] = A[i] all_an_from_prime_powers(Z) return Z