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")
示例#2
0
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
示例#3
0
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)])
示例#4
0
    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
示例#5
0
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
示例#6
0
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:]
示例#7
0
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
示例#8
0
 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
示例#9
0
 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]
示例#10
0
 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
示例#11
0
    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;
示例#12
0
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)
示例#13
0
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
示例#14
0
 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())
示例#15
0
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
示例#16
0
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
示例#17
0
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
示例#18
0
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
示例#19
0
 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()
示例#20
0
    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))
示例#21
0
    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)))
示例#22
0
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())
示例#23
0
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)
示例#24
0
 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
示例#25
0
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
示例#26
0
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
示例#27
0
    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)
示例#28
0
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]
示例#29
0
    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))
示例#30
0
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