def gonality_lower_bound(G,lambda1 = 0.238): """ Return the gonality bound of the modular curve X(G) as given by Dan Abramovich in "A linear lower bound on the gonality of modular curves" lambda1 is conjectured to 1/4th, but has only been proven to be > 0.238 [1, p. 3], bigger lambda1 means a better lowerbound. EXAMPLES:: sage: from mdsage import * sage: gonality_lower_bound(Gamma1(171)) 129 [1] On the torsion of elliptic curves over quartic number fields - Daeyol Jeon, Chang Heon Kim and Euising Park """ return ceil(G.projective_index()*lambda1/24)
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 x5_jacobi_pwsr(prec): mx = int(ceil(sqrt(8 * prec) / QQ(2)) + 1) mn = int(floor(-(sqrt(8 * prec) - 1) / QQ(2))) mx1 = int(ceil((sqrt(8 * prec + 1) - 1) / QQ(2)) + 1) mn1 = int(floor((-sqrt(8 * prec + 1) - 1) / QQ(2))) R = LaurentPolynomialRing(QQ, names="t") t = R.gens()[0] S = PowerSeriesRing(R, names="q1") q1 = S.gens()[0] eta_3 = sum([QQ(-1) ** n * (2 * n + 1) * q1 ** (n * (n + 1) // 2) for n in range(mn1, mx1)]) + bigO(q1 ** (prec + 1)) theta = sum([QQ(-1) ** n * q1 ** (((2 * n + 1) ** 2 - 1) // 8) * t ** (n + 1) for n in range(mn, mx)]) # ct = qexp_eta(ZZ[['q1']], prec + 1) return theta * eta_3 ** 3 * QQ(8) ** (-1)
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 __init__(self,G,k=QQ(1)/QQ(2),number=0,ch=None,dual=False,version=1,dimension=1,**kwargs): r""" Initialize the Eta multiplier system: $\nu_{\eta}^{2(k+r)}$. INPUT: - G -- Group - ch -- character - dual -- if we have the dual (in this case conjugate) - weight -- Weight (recall that eta has weight 1/2 and eta**2k has weight k. If weight<>k we adjust the power accordingly. - number -- we consider eta^power (here power should be an integer so as not to change the weight...) """ self._weight=QQ(k) if floor(self._weight-QQ(1)/QQ(2))==ceil(self._weight-QQ(1)/QQ(2)): self._half_integral_weight=1 else: self._half_integral_weight=0 MultiplierSystem.__init__(self,G,character=ch,dual=dual,dimension=dimension) number = number % 12 if not is_even(number): raise ValueError,"Need to have v_eta^(2(k+r)) with r even!" self._pow=QQ((self._weight+number)) ## k+r self._k_den=self._pow.denominator() self._k_num=self._pow.numerator() self._K = CyclotomicField(12*self._k_den) self._z = self._K.gen()**self._k_num self._i = CyclotomicField(4).gen() self._fak = CyclotomicField(2*self._k_den).gen()**-self._k_num self._version = version self.is_consistent(k) # test consistency
def saw_tooth_fn(x): if floor(x) == ceil(x): return 0 elif x in QQ: return QQ(x)-QQ(floor(x))-QQ(1)/QQ(2) else: return x-floor(x)-0.5
def crack_when_pq_close(n): t = Integer(ceil(sqrt(n))) while True: k = t**2 - n if k > 0: s = Integer(int(round(sqrt(t**2 - n)))) if s**2 + n == t**2: return t + s, t - s t += 1
def degree_cusp(i,N): """ Function DegreeCusp in Mark his code returns the degree over Q of the cusp $q^(i/n)\zeta_n^j$ on X_1(N) """ i = ZZ(i); N = ZZ(N) d = euler_phi(gcd(i,N)) if i == 0 or 2*i == N: return ceil(d/2) return d
def babystepgiantstep(g, h): n = g.multiplicative_order() m = ceil(sqrt(n)) babysteps = {} for j in range(m): babysteps[g ** j] = j X = g ** -m a = h for i in range(m - 1): if a in babysteps: return i*m + babysteps[a] else: a = a * X
def is_CM(k, N=1, chi=0, fi=0, prec=10): r""" Checks if f has complex multiplication and if it has then it returns the character. INPUT: - ''k'' -- positive integer : the weight - ''N'' -- positive integer (default 1) : level - ''chi'' -- non-neg. integer (default 0) use character nr. chi - ''fi'' -- non-neg. integer (default 0) We want to use the element nr. fi f=Newforms(N,k)[fi] OUTPUT: -''[t,x]'' -- string saying whether f is CM or not and if it is, the corresponding character EXAMPLES:: """ (t, f) = _get_newform(k, N, chi, fi) if(not t): return f max_nump = number_of_hecke_to_check(f) coeffs = f.coefficients(max_nump + 1) nz = coeffs.count(0) # number of zero coefficients nnz = len(coeffs) - nz # number of non-zero coefficients if(nz == 0): return [False, 0] # probaly checking too many for D in range(3, ceil(QQ(max_nump) / QQ(2))): try: for x in DirichletGroup(D): if(x.order() != 2): continue # we know that for CM we need x(p) = -1 => c(p)=0 # (for p not dividing N) if(x.values().count(-1) > nz): raise StopIteration() # do not have CM with this char for p in prime_range(max_nump + 1): if(x(p) == -1 and coeffs[p] != 0): raise StopIteration() # do not have CM with this char # if we are here we have CM with x. return [True, x] except StopIteration: pass return [False, 0]
def lyap_isotopic_decomposed(ie, it) : t = 0 isotopic_dimension = [ceil(ie.character_degree()[k]*ie.number_of_character_appeareance(k)/2) for k in range(ie.n_characters())] v_iter = [ (k, l) for k in range(ie.n_characters()) for l in range(isotopic_dimension[k])] v = [[ie.canonical_VectPaths().random() for l in range(isotopic_dimension[k])] for k in range(ie.n_characters())] theta = [[0 for l in range(isotopic_dimension[k])] for k in range(ie.n_characters())] def project(): for k, l in v_iter: v[k][l] = ie.vector_isotopic_projection(k, v[k][l]) for i in range(it) : project() (c,A,B, name_A, name_B, name_A_twin, Ap_give_name, ident_B) = ie.rauzy_rev() for k, l in v_iter: #first apply the change of B w = v[k][l] image = VectPaths(w._labels, w._degrees) for n, a in w._iter: if a == B: #return inversed and transposed matrix, thus add (-1) image._vect[n][a] = CC(w.val(n,B) + c*w.val(name_A(name_B.inverse()(n)),A)) else: image._vect[n][a] = CC(w.val(n,a)) v[k][l] = image for k, l in v_iter: #then apply the permutation w = v[k][l] image = VectPaths(w._labels, w._degrees) for n, a in w._iter: if a == A: if Ap_give_name: image._vect[n][a] = CC(w.val(name_A(ident_B.inverse()(n)),A)) #inverse and transpose of a permutation matrix are the same else: image._vect[n][a] = CC(w.val(name_A_twin(n),A)) else: image._vect[n][a] = CC(w.val(n,a)) v[k][l] = image if ie.diff_sum() > diff_sum_seuil: t += -log(ie.normalise()) if ie.min_length() < 2**(-10): t += -log(ie.normalise()) for k in range(ie.n_characters()): nm = vect_paths_ortho_householder(v[k]) for l in range(isotopic_dimension[k]): theta[k][l] += log(nm[l]) if t == 0: return [[0 for l in range(isotopic_dimension[k])] for k in range(ie.n_characters())] else: return [[theta[k][l]/t for l in range(isotopic_dimension[k])] for k in range(ie.n_characters())]
def __init__(self,group,dchar=(0,0),dual=False,is_trivial=False,dimension=1,**kwargs): if not ZZ(4).divides(group.level()): raise ValueError," Need level divisible by 4. Got:%s " % self._group.level() MultiplierSystem.__init__(self,group,dchar=dchar,dual=dual,is_trivial=is_trivial,dimension=dimension,**kwargs) self._i = CyclotomicField(4).gen() self._one = self._i**4 self._weight= QQ(kwargs.get("weight",QQ(1)/QQ(2))) ## We have to make sure that we have the correct multiplier & character ## for the desired weight if self._weight<>None: if floor(2*self._weight)<>ceil(2*self._weight): raise ValueError," Use ThetaMultiplier for half integral or integral weight only!" t = self.is_consistent(self._weight) if not t: self.set_dual() t1 = self.is_consistent(self._weight) if not t1: raise ArithmeticError,"Could not find consistent theta multiplier! Try to add a character."
def _pell_solve_2(D,m): # m^2 >= D prim_sols = [] t,u = _pell_solve_1(D,1)[0] if m > 0: L = Integer(0) U = Integer(floor(sqrt(m*(t-1)/(2*D)))) else: L = Integer(ceil(sqrt(-m/D))) U = Integer(floor(sqrt(-m*(t+1)/(2*D)))) for y in range(L,U+1): y = Integer(y) x = (m + D*(y**2)) if is_square(x): x = Integer(sqrt(x)) prim_sols.append((x,y)) if not ((-x*x - y*y*D) % m == 0 and (2*y*x) % m == 0): # (x,y) and (-x,y) are in different solution classes, so add both prim_sols.append((-x,y)) return (t,u),prim_sols
def set_is_CM(self,insert_in_db=True): r""" Checks if f has complex multiplication and if it has then it returns the character. OUTPUT: -''[t,x]'' -- string saying whether f is CM or not and if it is, the corresponding character EXAMPLES:: """ if(len(self._is_CM) > 0): return self._is_CM max_nump = self._number_of_hecke_eigenvalues_to_check() # E,v = self._f.compact_system_of_eigenvalues(max_nump+1) try: coeffs = self.coefficients(range(max_nump + 1),insert_in_db=insert_in_db) except IndexError: return None,None nz = coeffs.count(0) # number of zero coefficients nnz = len(coeffs) - nz # number of non-zero coefficients if(nz == 0): self._is_CM = [False, 0] return self._is_CM # probaly checking too many for D in range(3, ceil(QQ(max_nump) / QQ(2))): try: for x in DirichletGroup(D): if(x.order() != 2): continue # we know that for CM we need x(p) = -1 => c(p)=0 # (for p not dividing N) if(x.values().count(-1) > nz): raise StopIteration() # do not have CM with this char for p in prime_range(max_nump + 1): if(x(p) == -1 and coeffs[p] != 0): raise StopIteration() # do not have CM with this char # if we are here we have CM with x. self._is_CM = [True, x] return self._is_CM except StopIteration: pass self._is_CM = [False, 0] return self._is_CM
def get_coefficients(self, data={}, verbose=0, **kwds): if verbose > 0: print("data=", data) maass_id = data.get('maass_id') if maass_id is None: raise ValueError if verbose > 0: print("id=", maass_id) f = db.mwf_forms.lucky({'maass_id': maass_id}) if f is None: return None #nc = f.get('Numc', 0) if verbose > 0: print("f=", f) #if nc == 0: # return None cid = f.get('coeff_label', None) if cid is None: R = f.get('Eigenvalue', None) if R is None: return f.get('Coefficients', None) R = [floor(R * 1E9) * 1E-9, ceil(R * 1E9) * 1E-9] for r in R: searchcoeffs = db.mwf_coeffs.search( {'label': { '$regex': str(r) }}) for res in searchcoeffs: c = res['coefficients'] d = loads(str(c)) if type(d) == type([]): d = {i: d[i] for i in range(0, len(d))} e = self.find_coeffs_from_dict(d, type(d)) if (e is not None): return e return f.get('Coefficients', None) ff = db.mwf_coeffs.lucky({'label': cid}, 'coefficients') if ff is None: return None elif PY3: return loads(bytes(ff)) else: return loads(str(ff))
def findrotationmulticiphertexts(lwe_n, q, sd, B, m, name): n = 2 * RR(lwe_n) q = RR(q) B = RR(B) vars = RR(sd**2) varc = vars ##################### # precalculations # ##################### # qt qt = q / 2**(B + 1) # |s| and |c*| norms = ZZ(ceil(sqrt(n * vars))) # This is an approximation of the mean value normc = norms ################## # calculations # ################## numsucces = 0 for CIPHERTEXTS in [3, 4, 5]: results = [] import pathos pool = pathos.pools._ProcessPool(4, maxtasksperchild=1) results = pool.map( lambda x: findonemulticiphertextrotation(n, varc, CIPHERTEXTS, qt, norms), range(0, TESTS)) pool.terminate() pool.join() numsucces = np.sum(results) print( 'experimental probability of combining %d ciphertexts in %d rounds, succesprob %f' % (CIPHERTEXTS, REP, numsucces / TESTS)) with open(name + '/findingfailurelocation.txt', 'a') as f: print( 'experimental probability of combining %d ciphertexts in %d rounds, succesprob %f' % (CIPHERTEXTS, REP, numsucces / TESTS), file=f)
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 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 __init__(self,group,dchar=(0,0),dual=False,is_trivial=False,dimension=1,**kwargs): if not ZZ(4).divides(group.level()): raise ValueError," Need level divisible by 4. Got:%s " % self._group.level() MultiplierSystem.__init__(self,group,dchar=dchar,dual=dual,is_trivial=is_trivial,dimension=dimension,**kwargs) self._i = CyclotomicField(4).gen() self._one = self._i**4 #print "weight=",weight self._weight= QQ(kwargs.get("weight",QQ(1)/QQ(2))) ## We have to make sure that we have the correct multiplier & character ## for the desired weight if self._weight<>None: if floor(2*self._weight)<>ceil(2*self._weight): raise ValueError," Use ThetaMultiplier for half integral or integral weight only!" t = self.is_consistent(self._weight) if not t: self.set_dual() t1 = self.is_consistent(self._weight) if not t1: raise ArithmeticError,"Could not find consistent theta multiplier! Try to add a character."
def __init__(self,A,B,r,s,k=None,number=0,ch=None,dual=False,version=1,**kwargs): r""" Initialize the Eta multiplier system: $\nu_{\eta}^{2(k+r)}$. INPUT: - G -- Group - ch -- character - dual -- if we have the dual (in this case conjugate) - weight -- Weight (recall that eta has weight 1/2 and eta**2k has weight k. If weight<>k we adjust the power accordingly. - number -- we consider eta^power (here power should be an integer so as not to change the weight...) EXAMPLE: """ self._level=lcm(A,B) G = Gamma0(self._level) if k==None: k = (QQ(r)-QQ(s))/QQ(2) self._weight=QQ(k) if floor(self._weight-QQ(1)/QQ(2))==ceil(self._weight-QQ(1)/QQ(2)): self._half_integral_weight=1 else: self._half_integral_weight=0 MultiplierSystem.__init__(self,G,dimension=1,character=ch,dual=dual) number = number % 12 if not is_even(number): raise ValueError,"Need to have v_eta^(2(k+r)) with r even!" self._arg_num = A self._arg_den = B self._exp_num = r self._exp_den = s self._pow=QQ((self._weight+number)) ## k+r self._k_den=self._pow.denominator() self._k_num=self._pow.numerator() self._K = CyclotomicField(12*self._k_den) self._z = self._K.gen()**self._k_num self._i = CyclotomicField(4).gen() self._fak = CyclotomicField(2*self._k_den).gen()**-self._k_num self._version = version self.is_consistent(k) # test consistency
def BHESoofmkTbbZR(): pspict, fig = SinglePicture("BHESoofmkTbbZR") pspict.dilatation_X(15) pspict.dilatation_Y(4) x = var('x') eps = 0.02 / pspict.xunit # We start drawing at visual 0.02 f = phyFunction(sin(1 / x)).graph(eps, 1) f.linear_plotpoints = 500 # 500 points linearly spaced on the domain # We ask to compute some more points, but chosen ones. # These are the values of 'x' for which f(x)=1,-1,0. k_max = ceil(2 / (eps * pi)) f.added_plotpoints = [2 / (k * pi) for k in range(1, k_max)] pspict.DrawGraphs(f) pspict.DrawDefaultAxes() fig.no_figure() fig.conclude() fig.write_the_file()
def findrotation2ciphertexts(lwe_n, q, sd, B, m, name): n = 2 * lwe_n q = q B = B vars = sd**2 varc = vars ##################### # precalculations # ##################### # qt qt = q / 2**(B + 1) # print('qt: ', qt) # |s| and |c*| norms = ZZ(ceil(sqrt(n * vars))) # This is an approximation of the mean value normc = norms ################## # calculations # ################## import pathos pool = pathos.pools._ProcessPool(4, maxtasksperchild=1) results = pool.map(lambda x: findrotation(n, varc, m, qt), range(0, TESTS)) pool.terminate() pool.join() numsucces = np.sum(results) print( 'experimental probability of combining 2 ciphertexts, succesprob %f' % (float(numsucces) / TESTS, )) with open(name + '/findingfailurelocation.txt', 'a') as f: print( 'experimental probability of combining 2 ciphertexts, succesprob %f' % (float(numsucces) / TESTS, ), file=f)
def get_type_2_uniform_bound(ecdb_type): if ecdb_type == "LSS": BOUND_TERM = (log(x) + 9 + 2.5 * (log(log(x)))**2)**2 elif ecdb_type == "BS": # BOUND_TERM = (4*log(x) + 10)**2 # BOUND_TERM = (3.29*log(x) + 2.96 + 4.9)**2 BOUND_TERM = (1.881 * log(x) + 2 * 0.34 + 5.5)**2 else: raise ValueError("argument must be LSS or BS") f = BOUND_TERM**6 + BOUND_TERM**3 + 1 - x try: bound = find_root(f, 1000, GENERIC_UPPER_BOUND) return ceil(bound) except RuntimeError: warning_msg = ( "Warning: Type 2 bound for quadratic field with " "discriminant {} failed. Returning generic upper bound").format(5) print(warning_msg) return GENERIC_UPPER_BOUND
def numeric_converter(value, cur=None): """ Used for converting numeric values from Postgres to Python. INPUT: - ``value`` -- a string representing a decimal number. - ``cur`` -- a cursor, unused OUTPUT: - either a sage integer (if there is no decimal point) or a real number whose precision depends on the number of digits in value. """ if value is None: return None if "." in value: # 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 = ceil(len(value) * 3.322) return LmfdbRealLiteral(RealField(prec), value) else: return Integer(value)
def __init__(self,args=[1],exponents=[1],ch=None,dual=False,version=1,**kwargs): r""" Initialize the Eta multiplier system: $\nu_{\eta}^{2(k+r)}$. INPUT: - G -- Group - ch -- character - dual -- if we have the dual (in this case conjugate) - weight -- Weight (recall that eta has weight 1/2 and eta**2k has weight k. If weight<>k we adjust the power accordingly. - number -- we consider eta^power (here power should be an integer so as not to change the weight...) EXAMPLE: """ assert len(args) == len(exponents) self._level=lcm(args) G = Gamma0(self._level) k = sum([QQ(x)*QQ(1)/QQ(2) for x in exponents]) self._weight=QQ(k) if floor(self._weight-QQ(1)/QQ(2))==ceil(self._weight-QQ(1)/QQ(2)): self._half_integral_weight=1 else: self._half_integral_weight=0 MultiplierSystem.__init__(self,G,dimension=1,character=ch,dual=dual) self._arguments = args self._exponents =exponents self._pow=QQ((self._weight)) ## k+r self._k_den = self._weight.denominator() self._k_num = self._weight.numerator() self._K = CyclotomicField(12*self._k_den) self._z = self._K.gen()**self._k_num self._i = CyclotomicField(4).gen() self._fak = CyclotomicField(2*self._k_den).gen()**-self._k_num self._version = version self.is_consistent(k) # test consistency
def test_sage_conversions(): x, y = sage.SR.var('x y') x1, y1 = symbols('x, y') # Symbol assert x1._sage_() == x assert x1 == sympify(x) # Integer assert Integer(12)._sage_() == sage.Integer(12) assert Integer(12) == sympify(sage.Integer(12)) # Rational assert (Integer(1) / 2)._sage_() == sage.Integer(1) / 2 assert Integer(1) / 2 == sympify(sage.Integer(1) / 2) # Operators assert x1 + y == x1 + y1 assert x1 * y == x1 * y1 assert x1**y == x1**y1 assert x1 - y == x1 - y1 assert x1 / y == x1 / y1 assert x + y1 == x + y assert x * y1 == x * y # Doesn't work in Sage 6.1.1ubuntu2 # assert x ** y1 == x ** y assert x - y1 == x - y assert x / y1 == x / y # Conversions assert (x1 + y1)._sage_() == x + y assert (x1 * y1)._sage_() == x * y assert (x1**y1)._sage_() == x**y assert (x1 - y1)._sage_() == x - y assert (x1 / y1)._sage_() == x / y assert x1 + y1 == sympify(x + y) assert x1 * y1 == sympify(x * y) assert x1**y1 == sympify(x**y) assert x1 - y1 == sympify(x - y) assert x1 / y1 == sympify(x / y) # Functions assert sin(x1) == sin(x) assert sin(x1)._sage_() == sage.sin(x) assert sin(x1) == sympify(sage.sin(x)) assert cos(x1) == cos(x) assert cos(x1)._sage_() == sage.cos(x) assert cos(x1) == sympify(sage.cos(x)) assert function_symbol('f', x1, y1)._sage_() == sage.function('f')(x, y) assert (function_symbol('f', 2 * x1, x1 + y1).diff(x1)._sage_() == sage.function('f')( 2 * x, x + y).diff(x)) assert LambertW(x1) == LambertW(x) assert LambertW(x1)._sage_() == sage.lambert_w(x) assert KroneckerDelta(x1, y1) == KroneckerDelta(x, y) assert KroneckerDelta(x1, y1)._sage_() == sage.kronecker_delta(x, y) assert erf(x1) == erf(x) assert erf(x1)._sage_() == sage.erf(x) assert lowergamma(x1, y1) == lowergamma(x, y) assert lowergamma(x1, y1)._sage_() == sage.gamma_inc_lower(x, y) assert uppergamma(x1, y1) == uppergamma(x, y) assert uppergamma(x1, y1)._sage_() == sage.gamma_inc(x, y) assert loggamma(x1) == loggamma(x) assert loggamma(x1)._sage_() == sage.log_gamma(x) assert beta(x1, y1) == beta(x, y) assert beta(x1, y1)._sage_() == sage.beta(x, y) assert floor(x1) == floor(x) assert floor(x1)._sage_() == sage.floor(x) assert ceiling(x1) == ceiling(x) assert ceiling(x1)._sage_() == sage.ceil(x) assert conjugate(x1) == conjugate(x) assert conjugate(x1)._sage_() == sage.conjugate(x) # For the following test, sage needs to be modified # assert sage.sin(x) == sage.sin(x1) # Constants and Booleans assert pi._sage_() == sage.pi assert E._sage_() == sage.e assert I._sage_() == sage.I assert GoldenRatio._sage_() == sage.golden_ratio assert Catalan._sage_() == sage.catalan assert EulerGamma._sage_() == sage.euler_gamma assert oo._sage_() == sage.oo assert zoo._sage_() == sage.unsigned_infinity assert nan._sage_() == sage.NaN assert true._sage_() == True assert false._sage_() == False assert pi == sympify(sage.pi) assert E == sympify(sage.e) assert GoldenRatio == sympify(sage.golden_ratio) assert Catalan == sympify(sage.catalan) assert EulerGamma == sympify(sage.euler_gamma) assert oo == sympify(sage.oo) assert zoo == sympify(sage.unsigned_infinity) assert nan == sympify(sage.NaN) # SympyConverter does not support converting the following # assert I == sympify(sage.I) # Matrix assert DenseMatrix(1, 2, [x1, y1])._sage_() == sage.matrix([[x, y]]) # SympyConverter does not support converting the following # assert DenseMatrix(1, 2, [x1, y1]) == sympify(sage.matrix([[x, y]])) # Sage Number a = sage.Mod(2, 7) b = PyNumber(a, sage_module) a = a + 8 b = b + 8 assert isinstance(b, PyNumber) assert b._sage_() == a assert str(a) == str(b) # Sage Function e = x1 + wrap_sage_function(sage.log_gamma(x)) assert str(e) == "x + log_gamma(x)" assert isinstance(e, Add) assert (e + wrap_sage_function(sage.log_gamma(x)) == x1 + 2 * wrap_sage_function(sage.log_gamma(x))) f = e.subs({x1: 10}) assert f == 10 + log(362880) f = e.subs({x1: 2}) assert f == 2 f = e.subs({x1: 100}) v = f.n(53, real=True) assert abs(float(v) - 459.13420537) < 1e-7 f = e.diff(x1)
def muladd(cls, kyber, a, b, c, l=None): """ Compute `a \cdot b + c` using big-integer arithmetic :param cls: Skipper class :param kyber: Kyber class, inherit and change constants to change defaults :param a: vector of polynomials in `ZZ_q[x]/(x^n+1)` :param b: vector of polynomials in `ZZ_q[x]/(x^n+1)` :param c: polynomial in `ZZ_q[x]/(x^n+1)` :param l: bits of precision """ m, k = 4, kyber.k w = kyber.n // m R, x = PolynomialRing(ZZ, "x").objgen() f = R([1] + [0] * (w - 1) + [1]) if l is None: # Could try passing degree w, but would require more careful # sneezing l = ceil(cls.prec(kyber)) R = PolynomialRing(ZZ, "x") x = R.gen() A = vector(R, k, [ sum( cls.snort(cls.ff(a[j], m, i), f, 2**l) * x**i for i in range(m)) for j in range(k) ]) C = sum(cls.snort(cls.ff(c, m, i), f, 2**l) * x**i for i in range(m)) B = vector(R, k, [ sum( cls.snort(cls.ff(b[j], m, i), f, 2**l) * x**i for i in range(m)) for j in range(k) ]) F = f(2**l) # MUL: k * 3^2 (Karatsuba for length 4) # % F here is applied to the 64-coeff-packs. # k comes from len(A) = len(B) = k, each constrains # a deg 4 poly needing (recursive) karatsuba => 9 W = (A * B + C) % F # MUL: 3 # specific trick for how we multiply degree n = 256 polys # the coefficients from above need readjustment # here doing 2**l * is basically doing y * !!! and if this wraps around # it takes care of the - in front W = sum((W[0 + i] + (2**l * W[m + i] % F)) * x**i for i in range(m - 1)) + W[m - 1] * x**(m - 1) D = [cls.sneeze(W[i] % F, f, 2**l) for i in range(m)] d = [] for j in range(w): for i in range(m): d.append(D[i][j]) return R(d)
def compute_cm_values_numeric(self,digits=12,insert_in_db=True): r""" Compute CM-values numerically. """ if isinstance(self._cm_values,dict) and self._cm_values <> {}: return self._cm_values # the points we want are i and rho. More can be added later... bits = ceil(int(digits) * int(4)) CF = ComplexField(bits) RF = ComplexField(bits) eps = RF(10 ** - (digits + 1)) if(self._verbose > 1): wmf_logger.debug("eps={0}".format(eps)) K = self.base_ring() # recall that degree = self.degree() cm_vals = dict() rho = CyclotomicField(3).gen() zi = CyclotomicField(4).gen() points = [rho, zi] maxprec = 1000 # max size of q-expansion minprec = 10 # max size of q-expansion for tau in points: q = CF(exp(2 * pi * I * tau)) fexp = dict() cm_vals[tau] = dict() if(tau == I and self.level() == -1): # cv= #"Exact(soon...)" #_cohen_exact_formula(k) for h in range(degree): cm_vals[tau][h] = cv continue if K.absolute_degree()==1: v1 = CF(0) v2 = CF(1) try: for prec in range(minprec, maxprec, 10): if(self._verbose > 1): wmf_logger.debug("prec={0}".format(prec)) v2 = self.as_factor().q_eigenform(prec).truncate(prec)(q) err = abs(v2 - v1) if(self._verbose > 1): wmf_logger.debug("err={0}".format(err)) if(err < eps): raise StopIteration() v1 = v2 cm_vals[tau][0] = None except StopIteration: cm_vals[tau][0] = v2 else: v1 = dict() v2 = dict() err = dict() for h in range(degree): v1[h] = 1 v2[h] = 0 try: for prec in range(minprec, maxprec, 10): if(self._verbose > 1): wmf_logger.debug("prec={0}".format(prec)) c = self.coefficients(range(prec),insert_in_db=insert_in_db) for h in range(degree): fexp[h] = list() v2[h] = 0 for n in range(prec): cn = c[n] if hasattr(cn, 'complex_embeddings'): cc = cn.complex_embeddings(CF.prec())[h] else: cc = CF(cn) v2[h] = v2[h] + cc * q ** n err[h] = abs(v2[h] - v1[h]) if(self._verbose > 1): wmf_logger.debug("v1[{0}]={1}".format(h,v1[h])) wmf_logger.debug("v2[{0}]={1}".format(h,v2[h])) wmf_logger.debug("err[{0}]={2}".format(h,err[h])) if(max(err.values()) < eps): raise StopIteration() v1[h] = v2[h] except StopIteration: pass for h in range(degree): if(err[h] < eps): cm_vals[tau][h] = v2[h] else: cm_vals[tau][h] = None self._cm_values = cm_vals
def test_all(self): todo = [] from lmfdb import db maxNk2 = db.mf_newforms.max('Nk2') for Nk2 in range(1, maxNk2 + 1): for N in ZZ(Nk2).divisors(): k = sqrt(Nk2/N) if k in ZZ: todo.append((N, int(k))) formerrors = list(self.all_newforms(todo)) spaceserrors = list(self.all_newspaces(todo)) errors = [] res = [] for k, io in enumerate([formerrors, spaceserrors]): for i, o in io: if not isinstance(o, list): if k == 0: command = "all_newforms" else: command = "all_newspaces" errors.append( [command, i] ) else: res.extend(o) if not errors: print("No errors while running the tests!") else: print("Unexpected errors occurring while running:") for e in errors: print(e) broken_urls = [ u for l, u in res if u is None ] working_urls = [ (l, u) for l, u in res if u is not None] working_urls.sort(key= lambda elt: elt[0]) just_times = [ l for l, u in working_urls] total = len(working_urls) if not broken_urls: print("All the pages passed the tests") if total > 0: print("Average loading time: %.2f" % (sum(just_times)/total,)) print("Min: %.2f Max %.2f" % (just_times[0], just_times[-1])) print("Quartiles: %.2f %.2f %.2f" % tuple([just_times[ max(0, int(total*f) - 1)] for f in [0.25, 0.5, 0.75]])) print("Slowest pages:") for t, u in working_urls[-10:]: print("%.2f - %s" % (t,u)) if total > 2: print("Histogram") h = 0.5 nbins = (just_times[-1] - just_times[0])/h while nbins < 50: h *= 0.5 nbins = (just_times[-1] - just_times[0])/h nbins = ceil(nbins) bins = [0]*nbins i = 0 for elt in just_times: while elt > (i + 1)*h + just_times[0]: i += 1 bins[i] += 1 for i, b in enumerate(bins): d = 100*float(b)/total print('%.2f\t|' %((i + 0.5)*h + just_times[0]) + '-'*(int(d)-1) + '| - %.2f%%' % d) else: print("These pages didn't pass the tests:") for u in broken_urls: print(u)
def precalc(lwe_n, q, sd, B, m, name): name2 = name name = name + '/tmp' if not os.path.exists(name): os.mkdir(name) n = 2 * RR(lwe_n) q = RR(q) B = RR(B) vars = RR(sd**2) m = RR(m) ##################### # precalculations # ##################### # qt qt = q / 2**(B + 1) # |s| and |c*| norms = ZZ(ceil(sqrt(n * vars))) # This is an approximation of the mean value normc2 = norms ################################################ # Calculate the grid and failure probability # ################################################ # make a grid of possible ciphertext points points = GRIDPOINTS xrange = np.linspace(0, normc2 * 3, points) yrange = np.linspace(0, float(pi), points) xrange = [RR(i) for i in xrange] yrange = [RR(i) for i in yrange] # calculate the usual failure boosting if not os.path.isfile(name + '/beta0.txt'): alpha, beta = failureboosting(xrange, yrange, n, qt, vars, norms, m) np.savetxt(name + '/alpha0.txt', alpha) np.savetxt(name + '/beta0.txt', beta) del alpha, beta # make a list of theta_SE thetaSE = arccos(qt / norms / normc2) # Considering the worst case scenario for an attacker var('N') meanangle = arccos(cos(thetaSE) / sqrt(cos(thetaSE)**2 + sin(thetaSE)**2 / N)) thetaSE_list = [(meanangle(N=i).n(), i) for i in list(range(1, CIPHERTEXTS))] # calculate alpha beta for each theta_SE def generate_alphabeta(thetaSE, i, name, xrange, yrange, n, qt, vars, norms, m): if not os.path.isfile('%s/beta%d.txt' % (name, i)): alphac, betac = failureboostingWithInfo(xrange, yrange, thetaSE, n, qt, vars, norms, m) np.savetxt('%s/alpha%d.txt' % (name, i), alphac) np.savetxt('%s/beta%d.txt' % (name, i), betac) return i f = lambda i: generate_alphabeta(i[0], i[1], name, xrange, yrange, n, qt, vars, norms, m) # import multiprocessing as mp # import pathos # pool = pathos.pools._ProcessPool(4, maxtasksperchild=1) # pool.map(f, thetaSE_list ) # pool.close() # pool.join() # pool.clear() # TODO: fix memory leak in this map operation map(f, thetaSE_list) alphabetalist = [] for i in range(0, 4): alpha = np.loadtxt('%s/alpha%d.txt' % (name, i)) beta = np.loadtxt('%s/beta%d.txt' % (name, i)) alphabetalist.append((alpha, beta, i)) ################ # Let's plot # ################ alpha, beta, ciphertexts = alphabetalist[0] plt.loglog(alpha, beta, basex=2, basey=2, color='r', label='no extra info') for i in alphabetalist[1:]: alphac, betac, ciphertexts = i plt.loglog(alphac, betac, basex=2, basey=2, color='b', label=str(ciphertexts) + ' ciphertext') plt.xlabel(u'work to generate one weak sample (1/α)') plt.ylabel(u'weak ciphertext failure rate (β)') plt.legend(loc='lower right') plt.gca().set_xlim(left=1) plt.tight_layout() plt.savefig(name2 + '/alphabeta.pdf') # plt.show() plt.clf() plt.rcParams.update({'font.size': 16}) plt.loglog(beta, [np.sqrt(a) * b**-1 for a, b in zip(alpha, beta)], basex=2, basey=2, color='r', label='no extra info') for i in alphabetalist[1:]: alphac, betac, ciphertexts = i plt.loglog(betac, [np.sqrt(a) * b**-1 for a, b in zip(alphac, betac)], basex=2, basey=2, color='b', label=str(ciphertexts) + ' ciphertext') plt.axvline(x=2**-64, color='r', linestyle='--') plt.xlabel(u'weak ciphertext failure rate (β)') plt.ylabel(u'total work to generate a failure (1/β√α)') plt.legend(loc='upper right') plt.tight_layout() plt.savefig(name2 + '/betatot.pdf') # plt.show() plt.clf() plt.rcParams.update({'font.size': 10}) plt.loglog(np.sqrt(alpha), [np.sqrt(a) * b**-1 for a, b in zip(alpha, beta)], basex=2, basey=2, color='r', label='no extra info') # print("normal failprob: %f" % -np.log2(float(np.min(b)))) tmp = min([(np.sqrt(a) * b**-1, b**-1) for a, b in zip(alpha, beta)], key=lambda x: x[0]) # print("min failureboosting: (%f, %f)" % (np.log2(float(tmp[0])), np.log2(float(tmp[1])))) # print("min failureboosting: %f" % np.log2(float(np.min([np.sqrt(a) * b**-1 for a, b in zip(alpha, beta)])))) for i in alphabetalist[1:]: alphac, betac, ciphertexts = i plt.loglog(np.sqrt(alphac), [np.sqrt(a) * b**-1 for a, b in zip(alphac, betac)], basex=2, basey=2, color='b', label=str(ciphertexts) + ' ciphertext') # print out cost of attack tmp = min([(np.sqrt(a) * b**-1, b**-1) for a, b in zip(alphac, betac)], key=lambda x: x[0]) # print("min failureboosting with %d ciphertexts: (%f, %f)" # % (ciphertexts, np.log2(float(tmp[0])), np.log2(float(tmp[1])))) # print("min failureboosting with %d ciphertexts: (%f, %f)" # % (ciphertexts, np.log2(float(np.min([np.sqrt(a) * b**-1 for a, b in zip(alphac, betac)]))), numfailures)) plt.xlabel(u'work to generate one weak sample (1/√α)') plt.ylabel(u'total work to generate a failure (1/β√α)') plt.legend(loc='lower right') plt.gca().set_xlim(left=1) plt.tight_layout() plt.savefig(name2 + '/sqrtalphatot.pdf') # plt.show() plt.clf()
def add_trace_and_norm_ladic(g, D, alpha_geo, verbose=True): if verbose: print "add_trace_and_norm_ladic()" #load Fields L = D['L'] if L is QQ: QQx = PolynomialRing(QQ, "x") L = NumberField(QQx.gen(), "b") prec = D['prec'] CCap = ComplexField(prec) # load endo alpha = D['alpha'] rosati = bound_rosati(alpha_geo) if alpha.base_ring() is not L: alpha_K = copy(alpha) alpha = Matrix(L, 2, 2) #shift alpha field from K to L for i, row in enumerate(alpha_K.rows()): for j, elt in enumerate(row): if elt not in L: assert elt.base_ring().absolute_polynomial( ) == L.absolute_polynomial() alpha[i, j] = L(elt.list()) else: alpha[i, j] = L(elt) # load algx_poly algx_poly_coeff = D['algx_poly'] #sometimes, by mistake the algx_poly is defined over K where K == L, but with a different name for i, elt in enumerate(algx_poly_coeff): if elt not in L: assert elt.base_ring().absolute_polynomial( ) == L.absolute_polynomial() algx_poly_coeff[i] = L(elt.list()) else: algx_poly_coeff[i] = L(elt) x_poly = vector(CCap, D['x_poly']) for i in [0, 1]: assert almost_equal( x_poly[i], algx_poly_coeff[i]), "%s != %s" % (algx_poly_coeff[i], x_poly[i]) # load P P0 = vector(L, [D['P'][0], D['P'][1]]) for i, elt in enumerate(P0): if elt not in L: assert elt.base_ring().absolute_polynomial( ) == L.absolute_polynomial() P0[i] = L(elt.list()) else: P0[i] = L(elt) if verbose: print "P0 = %s" % (P0, ) # load image points, P1 and P2 L_poly = PolynomialRing(L, "xL") xL = L_poly.gen() Xpoly = L_poly(algx_poly_coeff) if Xpoly.is_irreducible(): M = Xpoly.root_field("c") else: # this avoids bifurcation later on in the code, we don't want to be always checking if M is L M = NumberField(xL, "c") # trying to be sure that we keep the same complex_embedding... M_complex_embedding = 0 if L.gen() not in QQ: M_complex_embedding = None Lgen_CC = toCCap(L.gen(), prec=prec) for i, _ in enumerate(M.complex_embeddings()): if norm(Lgen_CC - M(L.gen()).complex_embedding(prec=prec, i=i) ) < CCap(2)**(-0.7 * Lgen_CC.prec()) * Lgen_CC.abs(): M_complex_embedding = i assert M_complex_embedding is not None, "\nL = %s\n%s = %s\n%s" % ( L, L.gen(), Lgen_CC, M.complex_embeddings()) M_poly = PolynomialRing(M, "xM") xM = M_poly.gen() # convert everything to M P0_M = vector(M, [elt for elt in P0]) alpha_M = Matrix(M, [[elt for elt in row] for row in alpha.rows()]) Xpoly_M = M_poly(Xpoly) for i in [0, 1]: assert almost_equal(x_poly[i], Xpoly_M.list()[i], ithcomplex_embedding=M_complex_embedding ), "%s != %s" % (Xpoly_M.list()[i], x_poly[i]) P1 = vector(M, 2) P1_ap = vector(CCap, D['R'][0]) P2 = vector(M, 2) P2_ap = vector(CCap, D['R'][1]) M_Xpoly_roots = Xpoly_M.roots() assert len(M_Xpoly_roots) > 0 Ypoly_M = prod([xM**2 - g(root) for root, _ in M_Xpoly_roots]) # also \in L_poly assert sum(m for _, m in Ypoly_M.roots(M)) == Ypoly_M.degree( ), "%s != %s\n%s\n%s" % (sum(m for _, m in Ypoly_M.roots(M)), Ypoly_M.degree(), Ypoly_M, Ypoly_M.roots(M)) if len(M_Xpoly_roots) == 1: # we have a double root P1[0] = M_Xpoly_roots[0][0] P2[0] = M_Xpoly_roots[0][0] ae_prec = prec * 0.4 else: assert len(M_Xpoly_roots) == 2 ae_prec = prec # we have two distinct roots P1[0] = M_Xpoly_roots[0][0] P2[0] = M_Xpoly_roots[1][0] if not_equal(P1_ap[0], P1[0], ithcomplex_embedding=M_complex_embedding): P1[0] = M_Xpoly_roots[1][0] P2[0] = M_Xpoly_roots[0][0] assert almost_equal( P1_ap[0], P1[0], ithcomplex_embedding=M_complex_embedding, prec=ae_prec), "\n%s = %s \n != %s" % ( P1[0], toCCap( P1[0], ithcomplex_embedding=M_complex_embedding), CC(P1_ap[0])) assert almost_equal( P2_ap[0], P2[0], ithcomplex_embedding=M_complex_embedding, prec=ae_prec), "\n%s = %s \n != %s" % ( P2[0], toCCap( P2[0], ithcomplex_embedding=M_complex_embedding), CC(P2_ap[0])) # figure out the right square root # pick the default branch P1[1] = sqrt(g(P1[0])) P2[1] = sqrt(g(P2[0])) if 0 in [P1[1], P2[1]]: print "one of image points is a Weirstrass point" print P1 print P2 raise ZeroDivisionError #switch if necessary if not_equal(P1_ap[1], P1[1], ithcomplex_embedding=M_complex_embedding, prec=ae_prec): P1[1] *= -1 if not_equal(P2_ap[1], P2[1], ithcomplex_embedding=M_complex_embedding, prec=ae_prec): P2[1] *= -1 # double check for i in [0, 1]: assert almost_equal(P1_ap[i], P1[i], ithcomplex_embedding=M_complex_embedding, prec=ae_prec), "%s != %s" % (P1_ap[i], P1[i]) assert almost_equal(P2_ap[i], P2[i], ithcomplex_embedding=M_complex_embedding, prec=ae_prec), "%s != %s" % (P2_ap[i], P2[i]) # now alpha, P0 \in L # P1, P2 \in L if verbose: print "P1 = %s\nP2 = %s" % (P1, P2) print "Computing the trace and the norm ladically\n" trace_and_norm = trace_and_norm_ladic(L, M, P0_M, P1, P2, g, 2 * alpha_M, 16 * rosati, primes=ceil(prec * L.degree() / 61)) else: trace_and_norm = trace_and_norm_ladic(L, M, P0_M, P1, P2, g, 2 * alpha_M, 16 * rosati, primes=ceil(prec * L.degree() / 61)) # Convert the coefficients to polynomials trace_numerator, trace_denominator, norm_numerator, norm_denominator = [ L_poly(coeff) for coeff in trace_and_norm ] assert trace_numerator(P0[0]) == trace_denominator( P0[0]) * -algx_poly_coeff[1], "%s/%s (%s) != %s" % ( trace_numerator, trace_denominator, P0[0], -algx_poly_coeff[1]) assert norm_numerator(P0[0]) == norm_denominator( P0[0]) * algx_poly_coeff[0], "%s/%s (%s) != %s" % ( norm_numerator, norm_denominator, P0[0], algx_poly_coeff[0]) buffer = "# x1 + x2 = degree %d/ degree %d\n" % ( trace_numerator.degree(), trace_denominator.degree()) buffer += "# = (%s) / (%s) \n" % (trace_numerator, trace_denominator) buffer += "# max(%d, %d) <= %d\n\n" % ( trace_numerator.degree(), trace_denominator.degree(), 16 * rosati) buffer += "# x1 * x2 = degree %d/ degree %d\n" % ( norm_numerator.degree(), norm_denominator.degree()) buffer += "# = (%s) / (%s) \n" % (norm_numerator, norm_denominator) buffer += "# max(%d, %d) <= %d\n" % ( norm_numerator.degree(), norm_denominator.degree(), 16 * rosati) if verbose: print buffer print "\n" assert max(trace_numerator.degree(), trace_denominator.degree()) <= 16 * rosati assert max(norm_numerator.degree(), norm_denominator.degree()) <= 16 * rosati if verbose: print "Veritfying if x1*x2 and x1 + x2 are correct..." verified = verify_algebraically(g, P0, alpha, trace_and_norm, verbose=verbose) if verbose: print "\nDoes it act on the tangent space as expected? %s\n" % verified print "Done add_trace_and_norm_ladic()" return verified, [ trace_numerator.list(), trace_denominator.list(), norm_numerator.list(), norm_denominator.list() ]
def DirichletCoefficients(euler_factors, bound = None): """ INPUT: - ``euler_factors`` -- a dictionary p --> Lp.list() where Lp \in 1 + ZZ[t] OUTPUT: A list of length bound + 1 -- [0, a1, a2, ... , a_bound] EXAMPLES: sage: E17a2_euler_factors = {2: [1, 1, 2], 3: [1, 0, 3], 5: [1, 2, 5], 7: [1, -4, 7], 11: [1, 0, 11], 13: [1, 2, 13], 17: [1, -1], 19: [1, 4, 19], 23: [1, -4, 23], 29: [1, -6, 29], 31: [1, -4, 31], 37: [1, 2, 37], 41: [1, 6, 41], 43: [1, -4, 43], 47: [1, 0, 47], 53: [1, -6, 53], 59: [1, 12, 59], 61: [1, 10, 61], 67: [1, -4, 67], 71: [1, 4, 71], 73: [1, 6, 73], 79: [1, -12, 79], 83: [1, 4, 83], 89: [1, -10, 89], 97: [1, -2, 97]} sage: A = DirichletCoefficients(E17a2_euler_factors, bound = 99) sage: A == [0, 1, -1, 0, -1, -2, 0, 4, 3, -3, 2, 0, 0, -2, -4, 0, -1, 1, 3, -4, 2, 0, 0, 4, 0, -1, 2, 0, -4, 6, 0, 4, -5, 0, -1, -8, 3, -2, 4, 0, -6, -6, 0, 4, 0, 6, -4, 0, 0, 9, 1, 0, 2, 6, 0, 0, 12, 0, -6, -12, 0, -10, -4, -12, 7, 4, 0, 4, -1, 0, 8, -4, -9, -6, 2, 0, 4, 0, 0, 12, 2, 9, 6, -4, 0, -2, -4, 0, 0, 10, -6, -8, -4, 0, 0, 8, 0, 2, -9, 0] True sage: E33a3_euler_factors = {2: [1, -1, 2], 3: [1, 1], 5: [1, 2, 5], 7: [1, -4, 7], 11: [1, -1], 13: [1, 2, 13], 17: [1, 2, 17], 19: [1, 0, 19], 23: [1, -8, 23], 29: [1, 6, 29], 31: [1, 8, 31], 37: [1, -6, 37], 41: [1, 2, 41], 43: [1, 0, 43], 47: [1, -8, 47], 53: [1, -6, 53], 59: [1, 4, 59], 61: [1, -6, 61], 67: [1, 4, 67], 71: [1, 0, 71], 73: [1, 14, 73], 79: [1, 4, 79], 83: [1, -12, 83], 89: [1, 6, 89], 97: [1, -2, 97]} sage: A = DirichletCoefficients(E33a3_euler_factors, bound = 99) sage: A == [0, 1, 1, -1, -1, -2, -1, 4, -3, 1, -2, 1, 1, -2, 4, 2, -1, -2, 1, 0, 2, -4, 1, 8, 3, -1, -2, -1, -4, -6, 2, -8, 5, -1, -2, -8, -1, 6, 0, 2, 6, -2, -4, 0, -1, -2, 8, 8, 1, 9, -1, 2, 2, 6, -1, -2, -12, 0, -6, -4, -2, 6, -8, 4, 7, 4, -1, -4, 2, -8, -8, 0, -3, -14, 6, 1, 0, 4, 2, -4, 2, 1, -2, 12, 4, 4, 0, 6, -3, -6, -2, -8, -8, 8, 8, 0, -5, 2, 9, 1] True """ if bound is None: bound = next_prime( max(euler_factors.keys() ) ) - 1; degree = 0; for p, L in euler_factors.iteritems(): if len(L) > degree + 1: degree = len(L) - 1; R = PolynomialRing(ZZ, degree, "a") S = PowerSeriesRing(R, default_prec = ceil(log(bound)/log(2))); P = [1] + list(R.gens()); recursion = (1/S(P)).list(); A = [None]*(bound + 1); A[0] = 0; A[1] = 1; i = 1; # sieve through [1, bound] while i <= bound: if A[i] is None: #i is a prime if i in euler_factors: euler_i = euler_factors[i][1:]; else: euler_i = []; euler_i += [0] * (degree - len(euler_i)); # fill with zeros if necessary # deal with its powers r = 1; ipower = i # i^r while ipower <= bound: A[ipower] = recursion[r](euler_i) ipower *= i; r += 1; # deal with multiples of its powers by smaller numbers for m in range(2, bound): if A[m] is not None and m%i != 0: ipower = i while m*ipower <= bound: assert A[m*ipower] is None A[m*ipower] = A[m] * A[ipower] ipower *= i i += 1 return A;
def nice_coset_reps(G): r""" Compute a better/nicer list of right coset representatives [V_j] i.e. SL2Z = \cup G V_j Use this routine for known congruence subgroups. EXAMPLES:: sage: G=MySubgroup(Gamma0(5)) sage: G._get_coset_reps_from_G(Gamma0(5)) [[1 0] [0 1], [ 0 -1] [ 1 0], [ 0 -1] [ 1 1], [ 0 -1] [ 1 -1], [ 0 -1] [ 1 2], [ 0 -1] [ 1 -2]] """ cl=list() S,T=SL2Z.gens() lvl=G.generalised_level() # Start with identity rep. cl.append(SL2Z([1 ,0 ,0 ,1 ])) if(not S in G): cl.append(S) # If the original group is given as a Gamma0 then # the reps are not the one we want # I.e. we like to have a fundamental domain in # -1/2 <=x <= 1/2 for Gamma0, Gamma1, Gamma for j in range(1 , ZZ( ceil(RR(lvl/2.0))+2)): for ep in [1 ,-1 ]: if(len(cl)>=G.index()): break # The ones about 0 are all of this form A=SL2Z([0 ,-1 ,1 ,ep*j]) # just make sure they are inequivalent try: for V in cl: if((A<>V and A*V**-1 in G) or cl.count(A)>0 ): raise StopIteration() cl.append(A) except StopIteration: pass # We now addd the rest of the "flips" of these reps. # So that we end up with a connected domain i=1 while(True): lold=len(cl) for V in cl: for A in [S,T,T**-1 ]: B=V*A try: for W in cl: if( (B*W**-1 in G) or cl.count(B)>0 ): raise StopIteration() cl.append(B) except StopIteration: pass if(len(cl)>=G.index() or lold>=len(cl)): # If we either did not addd anything or if we addded enough # we exit break # If we missed something (which is unlikely) if(len(cl)<>G.index()): print "cl=",cl raise ValueError,"Problem getting coset reps! Need %s and got %s" %(G.index(),len(cl)) return cl
def certify_heuristic(g, label=None, digits=600, power=15, verbose=True, internalverbose=False): from heuristic_endomorphisms import EndomorphismData out = "" curve_dict = {} curve_dict['label'] = label curve_dict['digits'] = digits prec = ceil(log(10) / log(2) * digits) curve_dict['prec'] = prec buffer = "curve_dict = {};\n" for key in ['digits', 'prec']: buffer += "curve_dict['%s'] = %s;\n" % (key, curve_dict[key]) buffer += "curve_dict['%s'] = '%s';\n" % ('label', label) if verbose: print buffer out += buffer #Ambient ring buffer = "" buffer += "\n# basic rings\n" buffer += "curve_dict['%s'] = %s;\n" % ('QQx', 'PolynomialRing(QQ, \'x\')') buffer += "# curve_dict, x, and the number field's generator are the only variables are the only global variables\n\n" buffer += "x = curve_dict['QQx'].gen();\n\n" out += buffer Qx = PolynomialRing(QQ, "x") x = Qx.gen() curve_dict['QQx'] = Qx # force g in Qx g = Qx(g.list()) # Compute EndomorphismData # field of definition # and endomorphisms xsubs_list = [x, x + 1, x - 1, 1 - x, -1 - x, x + 2, x - 2, -x - 2, 2 - x] if label == '540800.a.540800.1': xsubs_list = xsubs_list[1:] for xsubs in xsubs_list: try: gtry = g(xsubs) if gtry.degree() == 5: gtry = Qx(gtry(x**(-1)) * x**6) if gtry.degree() == 5: gtry = Qx(gtry((x - 1) / x) * x**6) if verbose: print "Computing the EndomorphismData..." c, w = cputime(), walltime() End = EndomorphismData(gtry, prec=digits) print "Time: CPU %.2f s, Wall: %.2f s" % ( cputime(c), walltime(w), ) else: End = EndomorphismData(gtry, prec=digits) geo = End.geometric_representations() K = End.field_of_definition() g = gtry break except TypeError: pass if label == '810.a.196830.1': power += 2 buffer = "#working with the model y^2 = g(x)\n" buffer += "curve_dict['%s'] = %s;\n" % ('g', g.list()) curve_dict['g'] = g.list() out += buffer if verbose: print buffer # initialize numerical methods iaj = InvertAJglobal(g, prec, internalverbose) #CCap = iaj.C; buffer += "curve_dict['%s'] = %s;\n" % ('CCap', ' ComplexField(%s)' % curve_dict['prec']) #buffer += "CCap = curve_dict['CCap'];\n\n" # generator is r K = End.field_of_definition() if K.degree() == 1: K = QQ buffer = "# Field of definition of alpha\n" buffer += "curve_dict['%s'] = %s;\n" % ('K', sage_str_numberfield(K, 'x', 'r')) buffer += "K = %s\n" % ("curve_dict['K']") if K is not QQ: buffer += "r_approx = %s\n" % (K.gen().complex_embedding(), ) out += buffer out += "r = K.gen();\n" if verbose: print buffer #get the matrices over K geo = End.geometric_representations() #convert to sage # we also must take the transpose alphas = [convert_magma_matrix_to_sage(y, K).transpose() for y in geo[0]] alphas_geo = [y.sage() for y in geo[2]] d = len(alphas) out += "curve_dict['alphas_K'] = [None] * %d\n\n" % d out += "curve_dict['alphas_geo'] = [None] * %d\n\n" % d for i, _ in enumerate(alphas): alpha = alphas[i] alpha_geo = alphas_geo[i] buffer = "curve_dict['alphas_K'][%d] = Matrix(K, %s);\n" % ( i, alpha.rows(), ) buffer += "curve_dict['alphas_geo'][%d] = Matrix(%s);\n\n" % ( i, alpha_geo.rows(), ) out += buffer if verbose: print buffer curve_dict['alphas_K'] = alphas curve_dict['alphas_geo'] = alphas_geo out += "# where we stored all the data, for each alpha\n" out += "curve_dict['data'] = [{} for _ in range(%d) ] ;" % d curve_dict['data'] = [{} for _ in range(d)] for i in range(d): if alphas[i] == Matrix([[1, 0], [0, 1]]): curve_dict['data'][i] = None else: if verbose: print "Computing alpha(P + P)" print "where alpha = Matrix(K, %s)\n" % (alphas[i].rows(), ) # Pick a rational point, or a point over a quadratic extension with small discriminant for j, P0 in enumerate(find_rational_point(g)): if label in [ '540800.a.540800.1', '529.a.529.1', '1521.a.41067.1', '12500.a.12500.1', '18225.c.164025.1' ] and j < 2: pass elif label in ['810.a.196830.1'] and i == 2 and j == 0: pass else: if verbose: print "j = %s" % j sys.stdout.flush() sys.stderr.flush() try: output_alpha = compute_alpha_point(g, iaj, alphas[i], P0, digits, power, verbose=verbose, aggressive=True, append=str(i)) verified, trace_and_norm = add_trace_and_norm_ladic( g, output_alpha, alphas_geo[i], verbose=verbose) break except ZeroDivisionError: pass except OverflowError: if verbose: print "the mesh for numerical integral is too big" pass if verbose: print "trying with a new point\n" if verbose: print "\n\n\n" output_alpha['trace_and_norm'] = trace_and_norm output_alpha['verified'] = verified output_alpha['alphas_geo'] = alphas_geo[i] internal_out = "\n" #local_dict = {}\n\n"; # # the fields internal_out += "# L the field where P and the algx_poly are defined\n" internal_out += "curve_dict['data'][%d]['L'] = %s\n" % ( i, sage_str_numberfield(output_alpha['L'], 'x', 'b' + str(i)), ) if output_alpha['L'] is not QQ: internal_out += "b%d = curve_dict['data'][%d]['L'].gen()\n" % ( i, i) internal_out += "curve_dict['data'][%d]['Lgen_approx'] = %s\n" % ( i, output_alpha['L'].gen().complex_embedding()) internal_out += "\n" internal_out += "curve_dict['data'][%d]['alpha'] = Matrix(curve_dict['data'][%d]['L'], %s) \n\n" % ( i, i, [[elt for elt in row] for row in output_alpha['alpha'].rows()]) internal_out += "curve_dict['data'][%d]['alpha_geo'] = curve_dict['alphas_geo'][%d]\n\n" % ( i, i) internal_out += "curve_dict['data'][%d]['P'] = vector(curve_dict['data'][%d]['L'], %s)\n\n" % ( i, i, output_alpha['P']) internal_out += "# alpha(P + P) - \inf = R0 + R1 - \inf\n" internal_out += "\n\n\n" for key in [ 'algx_poly', 'R', 'x_poly', 'trace_and_norm', 'verified' ]: internal_out += "curve_dict['data'][%d]['%s'] = %s;\n" % ( i, key, output_alpha[key]) # this just clutters the file, # internal_out += "curve_dict['data'][%d]['ajP'] = vector(%s)\n\n" % (i, output_alpha['ajP']); # internal_out += "curve_dict['data'][%d]['alpha2P0'] = alphas_ap[%d] * 2 * local_dict['ajP']\n\n" % (i, i) internal_out += "\n\n\n" curve_dict['data'][i] = output_alpha out += internal_out verified = all( [elt['verified'] for elt in curve_dict['data'] if elt is not None]) out += "curve_dict['verified'] = %s\n\n" % verified return curve_dict, out, verified
def dimension(self, k, ignore=False, debug=0): if k < 2 and not ignore: raise NotImplementedError("k has to >= 2") s = self._signature if not (2 * k in ZZ): raise ValueError("k has to be integral or half-integral") if (2 * k + s) % 2 != 0: return 0 m = self._m n2 = self._n2 if self._v2.has_key(0): v2 = self._v2[0] else: v2 = 1 if self._g != None: if not self._aniso_formula: vals = self._g.values() #else: #print "using aniso_formula" M = self._g else: vals = self._M.values() M = self._M if (2 * k + s) % 4 == 0: d = Integer(1) / Integer(2) * ( m + n2 ) # |dimension of the Weil representation on even functions| self._d = d self._alpha4 = 1 / Integer(2) * (vals[0] + v2 ) # the codimension of SkL in MkL else: d = Integer(1) / Integer(2) * ( m - n2 ) # |dimension of the Weil representation on odd functions| self._d = d self._alpha4 = 1 / Integer(2) * (vals[0] - v2 ) # the codimension of SkL in MkL prec = ceil(max(log(M.order(), 2), 52) + 1) + 17 #print prec RR = RealField(prec) CC = ComplexField(prec) if debug > 0: print "d, m = {0}, {1}".format(d, m) eps = exp(2 * CC.pi() * CC(0, 1) * (s + 2 * k) / Integer(4)) eps = round(real(eps)) if self._alpha3 is None or self._last_eps != eps: self._last_eps = eps if self._aniso_formula: self._alpha4 = 1 self._alpha3 = -sum( [BB(a) * mm for a, mm in self._v2.iteritems() if a != 0]) #print self._alpha3 self._alpha3 += Integer(d) - Integer( 1) - self._g.beta_formula() #print self._alpha3, self._g.a5prime_formula() self._alpha3 = self._alpha3 / RR(2) else: self._alpha3 = eps * sum( [(1 - a) * mm for a, mm in self._v2.iteritems() if a != 0]) if debug > 0: print "alpha3t = ", self._alpha3 self._alpha3 += sum([(1 - a) * mm for a, mm in vals.iteritems() if a != 0]) #print self._alpha3 self._alpha3 = self._alpha3 / Integer(2) alpha3 = self._alpha3 alpha4 = self._alpha4 if debug > 0: print alpha3, alpha4 g1 = M.char_invariant(1) g1 = CC(g1[0] * g1[1]) #print g1 g2 = M.char_invariant(2) g2 = CC(g2[0] * g2[1]) if debug > 0: print g2, g2.parent() g3 = M.char_invariant(-3) g3 = CC(g3[0] * g3[1]) if debug > 0: print "eps = {0}".format(eps) if debug > 0: print "d/4 = {0}, m/4 = {1}, e^(2pi i (2k+s)/8) = {2}".format( RR(d) / RR(4), sqrt(RR(m)) / RR(4), CC(exp(2 * CC.pi() * CC(0, 1) * (2 * k + s) / Integer(8)))) if eps == 1: g2_2 = real(g2) else: g2_2 = imag(g2) * CC(0, 1) alpha1 = RR(d) / RR(4) - sqrt(RR(m)) / RR(4) * CC( exp(2 * CC.pi() * CC(0, 1) * (2 * k + s) / Integer(8)) * g2_2) if debug > 0: print alpha1 alpha2 = RR(d) / RR(3) + sqrt(RR(m)) / (3 * sqrt(RR(3))) * real( exp(CC(2 * CC.pi() * CC(0, 1) * (4 * k + 3 * s - 10) / 24)) * (g1 + eps * g3)) if debug > 0: print "alpha1 = {0}, alpha2 = {1}, alpha3 = {2}, g1 = {3}, g2 = {4}, g3 = {5}, d = {6}, k = {7}, s = {8}".format( alpha1, alpha2, alpha3, g1, g2, g3, d, k, s) dim = real(d + (d * k / Integer(12)) - alpha1 - alpha2 - alpha3) if debug > 0: print "dimension:", dim if abs(dim - round(dim)) > 1e-6: raise RuntimeError( "Error ({0}) too large in dimension formula for {1} and k={2}". format(abs(dim - round(dim)), self._M if self._M is not None else self._g, k)) dimr = dim dim = Integer(round(dim)) if k >= 2 and dim < 0: raise RuntimeError("Negative dimension (= {0}, {1})!".format( dim, dimr)) return dim
def charpoly_frobenius(frob_matrix, charpoly_prec, p, weight, a = 1): """ INPUT: - ``frob_matrix`` -- a matrix representing the p-power Frobenius lift to Z_q up to some precision - ``charpoly_prec`` -- a vector ai, such that, frob_matrix.change_ring(ZZ).charpoly()[i] will be correct mod p^ai, this can be easily deduced from the hodge numbers and knowing the q-adic precision of frob_matrix - ``p`` -- prime p - ``weight`` -- weight of the motive - ``a`` -- q = q^a OUTPUT: a list of integers corresponding to the characteristic polynomial of the Frobenius action Examples: sage: M = Matrix([[O(17), 8 + O(17)], [O(17), 15 + O(17)]]) sage: charpoly_frobenius(M, [2, 1, 1], 17, 1, 1) [17, 2, 1] sage: R = Zq(17 ** 2 , names=('a',)); sage: M = Matrix(R, [[8*17 + 16*17**2 + O(17**3), 8 + 11*17 + O(17**2)], [7*17**2 + O(17**3), 15 + 8*17 + O(17**2)]]) sage: charpoly_frobenius(M, [3, 2, 2], 17, 1, 2) [289, 30, 1] sage: M = Matrix([[8*31 + 8*31**2 + O(31**3), O(31**3), O(31**3), O(31**3)], [O(31**3), 23*31 + 22*31**2 + O(31**3), O(31**3), O(31**3)], [O(31**3), O(31**3), 27 + 7*31 + O(31**3), O(31**3)], [O(31**3), O(31**3), O(31**3), 4 + 23*31 + O(31**3)]]) sage: charpoly_frobenius(M, [4, 3, 2, 2, 2], 31, 1, 1) [961, 0, 46, 0, 1] sage: M = Matrix([[4*43**2 + O(43**3), 17*43 + 11*43**2 + O(43**3), O(43**3), O(43**3), 17 + 37*43 + O(43**3), O(43**3)], [30*43 + 23*43**2 + O(43**3), 5*43 + O(43**3), O(43**3), O(43**3), 3 + 38*43 + O(43**3), O(43**3)], [O(43**3), O(43**3), 9*43 + 32*43**2 + O(43**3), 13 + 25*43 + O(43**3), O(43**3), 17 + 18*43 + O(43**3)], [O(43**3), O(43**3), 22*43 + 25*43**2 + O(43**3), 11 + 24*43 + O(43**3), O(43**3), 36 + 5*43 + O(43**3)], [42*43 + 15*43**2 + O(43**3), 22*43 + 8*43**2 + O(43**3), O(43**3), O(43**3), 29 + 4*43 + O(43**3), O(43**3)], [O(43**3), O(43**3), 6*43 + 19*43**2 + O(43**3), 8 + 24*43 + O(43**3), O(43**3), 31 + 42*43 + O(43**3)]]) sage: charpoly_frobenius(M, [5, 4, 3, 2, 2, 2, 2], 43, 1, 1) [79507, 27735, 6579, 1258, 153, 15, 1] """ if a > 1: F = frob_matrix sigmaF = F; for _ in range(a - 1): sigmaF = Matrix(F.base_ring(), [[elt.frobenius() for elt in row] for row in sigmaF.rows()]) F = F * sigmaF F = F.change_ring(ZZ) else: F = frob_matrix.change_ring(ZZ) cp = F.charpoly().list(); assert len(charpoly_prec) == len(cp) assert cp[-1] == 1; # reduce cp mod prec degree = F.nrows() mod = [0] * (degree + 1) for i in range(degree): mod[i] = p**charpoly_prec[i] cp[i] = cp[i] % mod[i] # figure out the sign if weight % 2 == 1: # for odd weight the sign is always 1 # it's the charpoly of a USp matrix # and charpoly of a symplectic matrix is reciprocal sign = 1 else: for i in range(degree/2): p_power = p ** min( charpoly_prec[i], charpoly_prec[degree - i] + (a*(degree - 2*i)*weight/2)); # Note: degree*weight = 0 mod 2 if cp[i] % p_power != 0 and cp[degree-i] % p_power != 0: if 0 == (cp[i] + cp[degree - i] * p**(a*(degree-2*i)*weight/2)) % p_power: sign = -1; else: sign = 1; assert 0 == (-sign*cp[i] + cp[degree - i] * p**(a*(degree-2*i)*weight/2)) % p_power; break; cp[0] = sign * p**(a*degree*weight/2) #calculate the i-th power sum of the roots and correct cp allong the way halfdegree = ceil(degree/2) + 1; e = [None]*(halfdegree) for k in range(halfdegree): e[k] = cp[degree - k] if (k%2 ==0) else -cp[degree - k] if k > 0: # verify if p^charpoly_prec[degree - k] > 2*degree/k * q^(w*k/2) assert log(k)/log(p) + charpoly_prec[degree - k] > log(2*degree)/log(p) + a*0.5*weight*k, "log(k)/log(p) + charpoly_prec[degree - k] <= log(2*degree)/log(p) + a*0.5*weight*k, k = %d" % k #e[k] = \sum x_{i_1} x_{i_2} ... x_{i_k} # where x_* are eigenvalues # and i_1 < i_2 ... < i_k #s[k] = \sum x_i ^k for i>0 s = [None]*(halfdegree) for k in range(1, halfdegree): # assume that s[i] and e[i] are correct for i < k # e[k] correct modulo mod[degree - k] # S = sum (-1)^i e[k-i] * s[i] # s[k] = (-1)^(k-1) (k*e[k] + S) ==> (-1)^(k-1) s[k] - S = k*e[k] S = sum( (-1)**i * e[k-i] * s[i] for i in range(1,k)) s[k] = (-1)**(k - 1) * (S + k*e[k]) #hence s[k] is correct modulo k*mod[degree - k] localmod = k*mod[degree - k] s[k] = s[k] % localmod # |x_i| = p^(w*0.5) # => s[k] <= degree*p^(a*w*k*0.5) # recall, 2*degree*p^(a*w*k*0.5) /k < mod[degree - k] if s[k] > degree*p**(a*weight*k*0.5) : s[k] = -(-s[k] % localmod); #now correct e[k] with: # (-1)^(k-1) s[k] - S = k*e[k] e[k] = (-S + (-1)**(k - 1) * s[k])//k; assert (-S + (-1)**(k - 1) * s[k])%k == 0 cp[degree - k] = e[k] if k % 2 == 0 else -e[k] cp[k] = sign*cp[degree - k]*p**(a*(degree-2*k)*weight/2) return cp
def plotAngleDifference(lwe_n, q, sd, B, m, name): points = 10000 n = 2 * RR(lwe_n) q = RR(q) B = RR(B) vars = RR(sd**2) m = RR(m) ##################### # precalculations # ##################### # qt qt = q / 2**(B + 1) # |s| and |c*| norms = ZZ(ceil(sqrt(n * vars))) # This is an approximation of the mean value normc = norms K = qt / norms / normc ##################### # distributions # ##################### angle = np.linspace(0, float(pi), points) uniformdist = np.vectorize(Ptheta)(angle, n) uniformdist = np.nan_to_num(np.vectorize(float)(uniformdist)) uniformdist = uniformdist / (sum(uniformdist) * float(pi) / points) if m > 1.5: Pthetamax2 = PthetaMax(n, 2 * (m - 1)) maxdist = np.vectorize(Pthetamax2)(angle) maxdist = maxdist / (sum(maxdist) * float(pi) / points) else: maxdist = uniformdist posdist = np.vectorize(Ptheta)(arccos((cos(angle) - K**2) / (1 - K**2)), n - 1) posdist = np.nan_to_num(np.vectorize(float)(posdist)) posdist = posdist / (sum(posdist) * float(pi) / points) negdist = np.vectorize(Ptheta)(arccos((cos(angle) + K**2) / (1 - K**2)), n - 1) negdist = np.nan_to_num(np.vectorize(float)(negdist)) negdist = negdist / (sum(negdist) * float(pi) / points) prob = 0 for y in trange(0, len(angle)): for x in range(0, y): prob += posdist[x] * maxdist[y] with open(name + '/findingfailurelocation.txt', 'a') as f: print("theoretical probability of good estimate: %f" % (prob, ), file=f) ############ # plot # ############ angledivpi = angle / float(pi) import matplotlib.ticker as tck plt.rcParams.update({'font.size': 10}) plt.plot(angledivpi, uniformdist, label=u'Θₙ') plt.xlim(left=0, right=1) ax = plt.gca() ax.xaxis.set_major_formatter(tck.FormatStrFormatter('%g $\pi$')) ax.xaxis.set_major_locator(tck.MultipleLocator(base=0.25)) # plt.legend(loc='upper left') plt.xlabel(u'θ') plt.ylabel(u'pdf') plt.tight_layout() plt.savefig(name + '/randomangle.pdf') # plt.show() plt.clf() # angle = angle/float(pi) cosangle = np.cos(angle) plt.rcParams.update({'font.size': 16}) plt.plot(cosangle, posdist, label=u'C(δ₁,₀)') plt.plot(cosangle, negdist, label=u'C(δ₁,₀ + N)') plt.plot(cosangle, uniformdist, label=u'C(r); r ≠ (δ₁,₀ mod N)') if m > 1: plt.plot(cosangle, maxdist, label=u'maxᵣ C(r); r ≠ (δ₁,₀ mod N)') plt.xlim(left=-0.25, right=0.25) plt.legend(loc='upper left') plt.xlabel(u'C(r)') plt.ylabel(u'pdf') plt.tight_layout() plt.savefig(name + '/findingfailurelocation.pdf')
def nice_coset_reps(G): r""" Compute a better/nicer list of right coset representatives [V_j] i.e. SL2Z = \cup G V_j Use this routine for known congruence subgroups. EXAMPLES:: sage: G=MySubgroup(Gamma0(5)) sage: G._get_coset_reps_from_G(Gamma0(5)) [[1 0] [0 1], [ 0 -1] [ 1 0], [ 0 -1] [ 1 1], [ 0 -1] [ 1 -1], [ 0 -1] [ 1 2], [ 0 -1] [ 1 -2]] """ cl = list() S, T = SL2Z.gens() lvl = G.generalised_level() # Start with identity rep. cl.append(SL2Z([1, 0, 0, 1])) if (not S in G): cl.append(S) # If the original group is given as a Gamma0 then # the reps are not the one we want # I.e. we like to have a fundamental domain in # -1/2 <=x <= 1/2 for Gamma0, Gamma1, Gamma for j in range(1, ZZ(ceil(RR(lvl / 2.0)) + 2)): for ep in [1, -1]: if (len(cl) >= G.index()): break # The ones about 0 are all of this form A = SL2Z([0, -1, 1, ep * j]) # just make sure they are inequivalent try: for V in cl: if ((A <> V and A * V**-1 in G) or cl.count(A) > 0): raise StopIteration() cl.append(A) except StopIteration: pass # We now addd the rest of the "flips" of these reps. # So that we end up with a connected domain i = 1 while (True): lold = len(cl) for V in cl: for A in [S, T, T**-1]: B = V * A try: for W in cl: if ((B * W**-1 in G) or cl.count(B) > 0): raise StopIteration() cl.append(B) except StopIteration: pass if (len(cl) >= G.index() or lold >= len(cl)): # If we either did not addd anything or if we addded enough # we exit break # If we missed something (which is unlikely) if (len(cl) <> G.index()): print "cl=", cl raise ValueError, "Problem getting coset reps! Need %s and got %s" % ( G.index(), len(cl)) return cl
def fn(i): return max(ceil(RR(wts[i]) / RR(av_wt)), 1)
def edge_clique_cover_minimum(self, bound=None): """ Returns an minimum edge clique cover for the graph if the number of covering cliques is at most ``bound``; otherwise, returns ``None``. An edge clique cover is a set of cliques which contain all of the edges of the graph. .. note:: This function assumes self is connected. :param bound: the maximum number of cliques to consider in an edge clique cover :return: If a minimum edge clique cover is found that has at most ``bound`` cliques, the edge clique cover is returned as a list of lists, each sublist being the vertices of a clique. If a clique cover from this function requires more than ``bound`` cliques, ``None`` is returned. EXAMPLES:: sage: graphs.PathGraph(3).edge_clique_cover_minimum() [[0, 1], [1, 2]] sage: graphs.CompleteGraph(5).edge_clique_cover_minimum() [[0, 1, 2, 3, 4]] sage: graphs.HouseGraph().edge_clique_cover_minimum() [[2, 3, 4], [0, 1], [0, 2], [1, 3]] sage: graphs.PetersenGraph().edge_clique_cover_minimum(bound=4) """ from sage.all import ceil, Combinations # Take care of trivial case if self.size() == 0: return [] max_cliques=self.cliques_maximal() max_cliques.sort(key=len) largest_clique_vertices = len(max_cliques[-1]) max_cliques = [sorted(clique) for clique in max_cliques] largest_clique_edges = largest_clique_vertices \ *(largest_clique_vertices-1)/2 edges_of_graph=self.edges(labels=False) num_edges = self.size() mandatory_cliques=[] for v in self.vertices(): # If v is contained in only one clique, then that clique must # be in the clique cover cliques_containing_v = [c for c in max_cliques if v in c] if len(cliques_containing_v)==1 \ and (cliques_containing_v[0] not in mandatory_cliques): mandatory_cliques.append(cliques_containing_v[0]) for e in self.edges(): # If e is contained in only one clique, then that clique must # be in the clique cover cliques_containing_e = [c for c in max_cliques if e[0] in c and e[1] in c] if len(cliques_containing_e)==1 \ and (cliques_containing_e[0] not in mandatory_cliques): mandatory_cliques.append(cliques_containing_e[0]) # Check to see if mandatory_cliques contains a clique cover edges_in_set_of_cliques = set([]) for clique in mandatory_cliques: edges_in_clique = [(clique[i], clique[j]) for i in xrange(len(clique)) for j in xrange(i+1,len(clique))] edges_in_set_of_cliques.update(set(edges_in_clique)) if len(edges_in_set_of_cliques) == num_edges: if bound is None or len(mandatory_cliques) <= bound: return mandatory_cliques else: # There are too many cliques. Return None to be # consistent with the documentation, even though we # actually know the clique cover number (and it is greater # than bound). return None max_cliques = [c for c in max_cliques if c not in mandatory_cliques] if bound==None: stopping_point=len(max_cliques) else: stopping_point=min(len(max_cliques),bound-len(mandatory_cliques)) starting_point = max(1,ceil(float(num_edges) / largest_clique_edges) \ - len(mandatory_cliques)) for i in range(starting_point,stopping_point+1): for set_of_cliques in Combinations(max_cliques,i): edges_in_set_of_cliques = set([]) for clique in set_of_cliques+mandatory_cliques: edges_in_clique = [(clique[i], clique[j]) for i in xrange(len(clique)) for j in xrange(i+1,len(clique))] edges_in_set_of_cliques.update(set(edges_in_clique)) if len(edges_in_set_of_cliques) == num_edges: return set_of_cliques+mandatory_cliques return None
def dimension(self, k, ignore=False, debug=0): if k < 2 and not ignore: raise NotImplementedError("k has to >= 2") s = self._signature if not (2 * k in ZZ): raise ValueError("k has to be integral or half-integral") if (2 * k + s) % 4 != 0 and not ignore: raise NotImplementedError( "2k has to be congruent to -signature mod 4") if self._v2.has_key(0): v2 = self._v2[0] else: v2 = 1 if self._g != None: if not self._aniso_formula: vals = self._g.values() #else: #print "using aniso_formula" M = self._g else: vals = self._M.values() M = self._M prec = ceil(max(log(M.order(), 2), 52) + 1) + 17 #print prec RR = RealField(prec) CC = ComplexField(prec) d = self._d m = self._m if debug > 0: print d, m if self._alpha3 == None: if self._aniso_formula: self._alpha4 = 1 self._alpha3 = -sum( [BB(a) * mm for a, mm in self._v2.iteritems() if a != 0]) #print self._alpha3 self._alpha3 += Integer(d) - Integer( 1) - self._g.beta_formula() #print self._alpha3, self._g.a5prime_formula() self._alpha3 = self._alpha3 / RR(2) else: self._alpha3 = sum([(1 - a) * mm for a, mm in self._v2.iteritems() if a != 0]) #print self._alpha3 self._alpha3 += sum([(1 - a) * mm for a, mm in vals.iteritems() if a != 0]) #print self._alpha3 self._alpha3 = self._alpha3 / Integer(2) self._alpha4 = 1 / Integer(2) * ( vals[0] + v2) # the codimension of SkL in MkL alpha3 = self._alpha3 alpha4 = self._alpha4 if debug > 0: print alpha3, alpha4 g1 = M.char_invariant(1) g1 = CC(g1[0] * g1[1]) #print g1 g2 = M.char_invariant(2) g2 = RR(real(g2[0] * g2[1])) if debug > 0: print g2, g2.parent() g3 = M.char_invariant(-3) g3 = CC(g3[0] * g3[1]) if debug > 0: print RR(d) / RR(4), sqrt(RR(m)) / RR(4), CC( exp(2 * CC.pi() * CC(0, 1) * (2 * k + s) / Integer(8))) alpha1 = RR(d) / RR(4) - (sqrt(RR(m)) / RR(4) * CC( exp(2 * CC.pi() * CC(0, 1) * (2 * k + s) / Integer(8))) * g2) if debug > 0: print alpha1 alpha2 = RR(d) / RR(3) + sqrt(RR(m)) / (3 * sqrt(RR(3))) * real( exp(CC(2 * CC.pi() * CC(0, 1) * (4 * k + 3 * s - 10) / 24)) * (g1 + g3)) if debug > 0: print alpha1, alpha2, g1, g2, g3, d, k, s dim = real(d + (d * k / Integer(12)) - alpha1 - alpha2 - alpha3) if debug > 0: print "dimension:", dim if abs(dim - round(dim)) > 1e-6: raise RuntimeError( "Error ({0}) too large in dimension formula for {1} and k={2}". format(abs(dim - round(dim)), self._M if self._M is not None else self._g, k)) dimr = dim dim = Integer(round(dim)) if k >= 2 and dim < 0: raise RuntimeError("Negative dimension (= {0}, {1})!".format( dim, dimr)) return dim
def edge_clique_cover_minimum(self, bound=None): """ Returns an minimum edge clique cover for the graph if the number of covering cliques is at most ``bound``; otherwise, returns ``None``. An edge clique cover is a set of cliques which contain all of the edges of the graph. .. note:: This function assumes self is connected. :param bound: the maximum number of cliques to consider in an edge clique cover :return: If a minimum edge clique cover is found that has at most ``bound`` cliques, the edge clique cover is returned as a list of lists, each sublist being the vertices of a clique. If a clique cover from this function requires more than ``bound`` cliques, ``None`` is returned. EXAMPLES:: sage: graphs.PathGraph(3).edge_clique_cover_minimum() [[0, 1], [1, 2]] sage: graphs.CompleteGraph(5).edge_clique_cover_minimum() [[0, 1, 2, 3, 4]] sage: graphs.HouseGraph().edge_clique_cover_minimum() [[2, 3, 4], [0, 1], [0, 2], [1, 3]] sage: graphs.PetersenGraph().edge_clique_cover_minimum(bound=4) """ from sage.all import ceil, Combinations # Take care of trivial case if self.size() == 0: return [] max_cliques = self.cliques_maximal() max_cliques.sort(key=len) largest_clique_vertices = len(max_cliques[-1]) max_cliques = [sorted(clique) for clique in max_cliques] largest_clique_edges = largest_clique_vertices \ *(largest_clique_vertices-1)/2 edges_of_graph = self.edges(labels=False) num_edges = self.size() mandatory_cliques = [] for v in self.vertices(): # If v is contained in only one clique, then that clique must # be in the clique cover cliques_containing_v = [c for c in max_cliques if v in c] if len(cliques_containing_v)==1 \ and (cliques_containing_v[0] not in mandatory_cliques): mandatory_cliques.append(cliques_containing_v[0]) for e in self.edges(): # If e is contained in only one clique, then that clique must # be in the clique cover cliques_containing_e = [ c for c in max_cliques if e[0] in c and e[1] in c ] if len(cliques_containing_e)==1 \ and (cliques_containing_e[0] not in mandatory_cliques): mandatory_cliques.append(cliques_containing_e[0]) # Check to see if mandatory_cliques contains a clique cover edges_in_set_of_cliques = set([]) for clique in mandatory_cliques: edges_in_clique = [(clique[i], clique[j]) for i in xrange(len(clique)) for j in xrange(i + 1, len(clique))] edges_in_set_of_cliques.update(set(edges_in_clique)) if len(edges_in_set_of_cliques) == num_edges: if bound is None or len(mandatory_cliques) <= bound: return mandatory_cliques else: # There are too many cliques. Return None to be # consistent with the documentation, even though we # actually know the clique cover number (and it is greater # than bound). return None max_cliques = [c for c in max_cliques if c not in mandatory_cliques] if bound == None: stopping_point = len(max_cliques) else: stopping_point = min(len(max_cliques), bound - len(mandatory_cliques)) starting_point = max(1,ceil(float(num_edges) / largest_clique_edges) \ - len(mandatory_cliques)) for i in range(starting_point, stopping_point + 1): for set_of_cliques in Combinations(max_cliques, i): edges_in_set_of_cliques = set([]) for clique in set_of_cliques + mandatory_cliques: edges_in_clique = [(clique[i], clique[j]) for i in xrange(len(clique)) for j in xrange(i + 1, len(clique))] edges_in_set_of_cliques.update(set(edges_in_clique)) if len(edges_in_set_of_cliques) == num_edges: return set_of_cliques + mandatory_cliques return None
def dimension(self,k,ignore=False, debug = 0): if k < 2 and not ignore: raise NotImplementedError("k has to >= 2") s = self._signature if not (2*k in ZZ): raise ValueError("k has to be integral or half-integral") if (2*k+s)%2 != 0: return 0 m = self._m n2 = self._n2 if self._v2.has_key(0): v2 = self._v2[0] else: v2 = 1 if self._g != None: if not self._aniso_formula: vals = self._g.values() #else: #print "using aniso_formula" M = self._g else: vals = self._M.values() M = self._M if (2*k+s)%4 == 0: d = Integer(1)/Integer(2)*(m+n2) # |dimension of the Weil representation on even functions| self._d = d self._alpha4 = 1/Integer(2)*(vals[0]+v2) # the codimension of SkL in MkL else: d = Integer(1)/Integer(2)*(m-n2) # |dimension of the Weil representation on odd functions| self._d = d self._alpha4 = 1/Integer(2)*(vals[0]-v2) # the codimension of SkL in MkL prec = ceil(max(log(M.order(),2),52)+1)+17 #print prec RR = RealField(prec) CC = ComplexField(prec) if debug > 0: print "d, m = {0}, {1}".format(d,m) eps = exp( 2 * CC.pi() * CC(0,1) * (s + 2*k) / Integer(4) ) eps = round(real(eps)) if self._alpha3 is None or self._last_eps != eps: self._last_eps = eps if self._aniso_formula: self._alpha4 = 1 self._alpha3 = -sum([BB(a)*mm for a,mm in self._v2.iteritems() if a != 0]) #print self._alpha3 self._alpha3 += Integer(d) - Integer(1) - self._g.beta_formula() #print self._alpha3, self._g.a5prime_formula() self._alpha3 = self._alpha3/RR(2) else: self._alpha3 = eps*sum([(1-a)*mm for a,mm in self._v2.iteritems() if a != 0]) if debug>0: print "alpha3t = ", self._alpha3 self._alpha3 += sum([(1-a)*mm for a,mm in vals.iteritems() if a != 0]) #print self._alpha3 self._alpha3 = self._alpha3 / Integer(2) alpha3 = self._alpha3 alpha4 = self._alpha4 if debug > 0: print alpha3, alpha4 g1=M.char_invariant(1) g1=CC(g1[0]*g1[1]) #print g1 g2=M.char_invariant(2) g2=CC(g2[0]*g2[1]) if debug > 0: print g2, g2.parent() g3=M.char_invariant(-3) g3=CC(g3[0]*g3[1]) if debug > 0: print "eps = {0}".format(eps) if debug > 0: print "d/4 = {0}, m/4 = {1}, e^(2pi i (2k+s)/8) = {2}".format(RR(d) / RR(4), sqrt(RR(m)) / RR(4), CC(exp(2 * CC.pi() * CC(0,1) * (2 * k + s) / Integer(8)))) if eps == 1: g2_2 = real(g2) else: g2_2 = imag(g2)*CC(0,1) alpha1 = RR(d) / RR(4) - sqrt(RR(m)) / RR(4) * CC(exp(2 * CC.pi() * CC(0,1) * (2 * k + s) / Integer(8)) * g2_2) if debug > 0: print alpha1 alpha2 = RR(d) / RR(3) + sqrt(RR(m)) / (3 * sqrt(RR(3))) * real(exp(CC(2 * CC.pi() * CC(0,1) * (4 * k + 3 * s - 10) / 24)) * (g1 + eps*g3)) if debug > 0: print "alpha1 = {0}, alpha2 = {1}, alpha3 = {2}, g1 = {3}, g2 = {4}, g3 = {5}, d = {6}, k = {7}, s = {8}".format(alpha1, alpha2, alpha3, g1, g2, g3, d, k, s) dim = real(d + (d * k / Integer(12)) - alpha1 - alpha2 - alpha3) if debug > 0: print "dimension:", dim if abs(dim-round(dim)) > 1e-6: raise RuntimeError("Error ({0}) too large in dimension formula for {1} and k={2}".format(abs(dim-round(dim)), self._M if self._M is not None else self._g, k)) dimr = dim dim = Integer(round(dim)) if k >=2 and dim < 0: raise RuntimeError("Negative dimension (= {0}, {1})!".format(dim, dimr)) return dim
def plot_profiles(lwe_n, q, sd, B, name): n = 2 * RR(lwe_n) q = RR(q) B = RR(B) vars = RR(sd**2) ##################### # precalculations # ##################### qt = q / 2**(B + 1) # |s| and |c*| norms = ZZ(ceil(sqrt(n * vars))) # This is an approximation of the mean value normc2 = norms # thetaSE thetaSE = arccos(qt / norms / normc2) # Considering the worst case scenario for an attacker ##################################### # calculate probability functions # ##################################### # make a discrete grid xrange = np.linspace(normc2 * 0.5, normc2 / 0.5, GRIDPOINTS) yrange = np.linspace(float(pi / 4), float(3 * pi / 4), GRIDPOINTS) plotNormC, plotTheta = np.meshgrid(xrange, yrange) # calculate failure probability of ciphertext given C* (log2) vcalcFailgivennormct = np.vectorize(lambda theta, normc: calcFailgivennormct(theta, normc, thetaSE, norms, qt, n)) plotFailprob = np.log2(vcalcFailgivennormct(plotTheta, plotNormC)) # calculate ciphertext probability (log2) calcNormC = np.vectorize(lambda x: float(log(Pnormc(x, vars, n), 2))) plotCiphertextprob = calcNormC(plotNormC) calcT = np.vectorize(lambda theta: float(log(Ptheta(theta, n), 2))) plotCiphertextprob += calcT(plotTheta) ###################### # plot the results # ###################### if not os.path.exists(name): os.mkdir(name) # Plot the distribution of failing ciphertexts plt.title('distribution of failing ciphertexts') plt.xlabel('NormC') plt.ylabel('theta (angle C - C*)') plt.pcolormesh(plotNormC, plotTheta, plotFailprob + plotCiphertextprob) plt.savefig(name + '/failingciphertextsdistribution.pdf') # plt.show() plt.clf() # Plot the distribution of successfull ciphertexts plt.title('distribution of ciphertexts') plt.xlabel('NormC') plt.ylabel('theta (angle C - C*)') plt.pcolormesh(plotNormC, plotTheta, plotCiphertextprob) plt.savefig(name + '/succesciphertextsdistribution.pdf') # plt.show() plt.clf() # Plot the failure probability of ciphertexts plt.title('failure probability of ciphertexts') plt.xlabel(u'||C||₂') plt.ylabel('theta (angle C - C*)') plt.pcolormesh(plotNormC, plotTheta, plotFailprob) plt.savefig(name + '/failprobability.pdf') # plt.show() plt.clf() # Plot the failure probability of ciphertexts using contours fig, ax = plt.subplots() # somewhat bigger text to fit paper size plt.rcParams.update({'font.size': 16}) plt.title('failure probability of ciphertexts') plt.xlabel(u'||C||₂') plt.ylabel(u'θ_CE') # select some grid points levels = [-i * 20 for i in list(range(12, 6, -2)) + list(range(6, -1, -1))] CS = ax.contour(plotNormC, plotTheta, plotFailprob, levels=levels) ax.clabel(CS, inline=1, fontsize=10, fmt='2^%d') plt.savefig(name + '/failprobabilitycontour.pdf') # plt.show() plt.clf() plt.rcParams.update({'font.size': 10}) # Plot the failure probability of ciphertexts using contours (cos(theta) on y axis) fig, ax = plt.subplots() plt.rcParams.update({'font.size': 16}) plt.title('failure probability of ciphertexts') plt.xlabel(u'||C||₂') plt.ylabel(u'cos(θ_CE)') levels = [-i * 20 for i in list(range(12, 6, -2)) + list(range(6, -1, -1))] CS = ax.contour(plotNormC, np.cos(plotTheta), plotFailprob, levels=levels) ax.clabel(CS, inline=1, fontsize=10, fmt='2^%d') plt.savefig(name + '/failprobabilitycontourcos.pdf') # plt.show() plt.clf() # Plot the failure probability of ciphertexts using contours (cos(theta) on y axis) fig, ax = plt.subplots() plt.rcParams.update({'font.size': 16}) plt.title('failure probability of ciphertexts') plt.ylim(bottom=-0.15, top=0.15) plt.xlim(left=75, right=87) plt.xlabel(u'||C||₂') plt.ylabel(u'cos(θ_CE)') levels = list(range(-135, -95, 10)) CS = ax.contour(plotNormC, np.cos(plotTheta), plotFailprob, levels=levels) ax.clabel(CS, inline=1, fontsize=10, fmt='2^%d') plt.savefig(name + '/failprobabilitycontourcosmini.pdf') # plt.show() plt.clf()
def dimension(self,k,ignore=False, debug = 0): if k < 2 and not ignore: raise NotImplementedError("k has to >= 2") s = self._signature if not (2*k in ZZ): raise ValueError("k has to be integral or half-integral") if (2*k+s)%4 != 0 and not ignore: raise NotImplementedError("2k has to be congruent to -signature mod 4") if self._v2.has_key(0): v2 = self._v2[0] else: v2 = 1 if self._g != None: if not self._aniso_formula: vals = self._g.values() #else: #print "using aniso_formula" M = self._g else: vals = self._M.values() M = self._M prec = ceil(max(log(M.order(),2),52)+1)+17 #print prec RR = RealField(prec) CC = ComplexField(prec) d = self._d m = self._m if debug > 0: print d,m if self._alpha3 == None: if self._aniso_formula: self._alpha4 = 1 self._alpha3 = -sum([BB(a)*mm for a,mm in self._v2.iteritems() if a != 0]) #print self._alpha3 self._alpha3 += Integer(d) - Integer(1) - self._g.beta_formula() #print self._alpha3, self._g.a5prime_formula() self._alpha3 = self._alpha3/RR(2) else: self._alpha3 = sum([(1-a)*mm for a,mm in self._v2.iteritems() if a != 0]) #print self._alpha3 self._alpha3 += sum([(1-a)*mm for a,mm in vals.iteritems() if a != 0]) #print self._alpha3 self._alpha3 = self._alpha3 / Integer(2) self._alpha4 = 1/Integer(2)*(vals[0]+v2) # the codimension of SkL in MkL alpha3 = self._alpha3 alpha4 = self._alpha4 if debug > 0: print alpha3, alpha4 g1=M.char_invariant(1) g1=CC(g1[0]*g1[1]) #print g1 g2=M.char_invariant(2) g2=RR(real(g2[0]*g2[1])) if debug > 0: print g2, g2.parent() g3=M.char_invariant(-3) g3=CC(g3[0]*g3[1]) if debug > 0: print RR(d) / RR(4), sqrt(RR(m)) / RR(4), CC(exp(2 * CC.pi() * CC(0,1) * (2 * k + s) / Integer(8))) alpha1 = RR(d) / RR(4) - (sqrt(RR(m)) / RR(4) * CC(exp(2 * CC.pi() * CC(0,1) * (2 * k + s) / Integer(8))) * g2) if debug > 0: print alpha1 alpha2 = RR(d) / RR(3) + sqrt(RR(m)) / (3 * sqrt(RR(3))) * real(exp(CC(2 * CC.pi() * CC(0,1) * (4 * k + 3 * s - 10) / 24)) * (g1+g3)) if debug > 0: print alpha1, alpha2, g1, g2, g3, d, k, s dim = real(d + (d * k / Integer(12)) - alpha1 - alpha2 - alpha3) if debug > 0: print "dimension:", dim if abs(dim-round(dim)) > 1e-6: raise RuntimeError("Error ({0}) too large in dimension formula for {1} and k={2}".format(abs(dim-round(dim)), self._M if self._M is not None else self._g, k)) dimr = dim dim = Integer(round(dim)) if k >=2 and dim < 0: raise RuntimeError("Negative dimension (= {0}, {1})!".format(dim, dimr)) return dim
def muladd(cls, kyber, a, b, c, l=None): """ Compute `a \cdot b + c` using big-integer arithmetic :param cls: Skipper class :param kyber: Kyber class, inherit and change constants to change defaults :param a: vector of polynomials in `ZZ_q[x]/(x^n+1)` :param b: vector of polynomials in `ZZ_q[x]/(x^n+1)` :param c: polynomial in `ZZ_q[x]/(x^n+1)` :param l: bits of precision """ m, k = 2, kyber.k w = kyber.n//m R, x = PolynomialRing(ZZ, "x").objgen() f = R([1]+[0]*(w-1)+[1]) g = R([1]+[0]*(w//2-1)+[1]) if l is None: l = ceil(cls.prec(kyber)) R = PolynomialRing(ZZ, "x") x = R.gen() Ap = vector(R, k, [sum(cls.snort(cls.ff(a[j], m, i), f, 2**l) * x**i for i in range(m)) for j in range(k)]) An = vector(R, k, [sum(cls.snort(cls.ff(a[j], m, i), f, -2**l) * x**i for i in range(m)) for j in range(k)]) Cp = sum(cls.snort(cls.ff(c, m, i), f, 2**l) * x**i for i in range(m)) Cn = sum(cls.snort(cls.ff(c, m, i), f, -2**l) * x**i for i in range(m)) Bp = vector(R, k, [sum(cls.snort(cls.ff(b[j], m, i), f, 2**l) * x**i for i in range(m)) for j in range(k)]) Bn = vector(R, k, [sum(cls.snort(cls.ff(b[j], m, i), f, -2**l) * x**i for i in range(m)) for j in range(k)]) F = 2**(w * l) + 1 # MUL: 2 * k * 3 Wp = (Ap*Bp + Cp) % F Wn = (An*Bn + Cn) % F We = (Wp+Wn) % F Wo = (Wp-Wn) % F Wo, We = (sum((Wo[0+i] + (2**l * We[m+i] % F))*x**i for i in range(m-1)) + Wo[m-1]*x**(m-1)) % F, \ (sum((We[0+i] + (2**l * Wo[m+i] % F))*x**i for i in range(m-1)) + We[m-1]*x**(m-1)) % F _inverse_of_2_mod_F = F - 2**(w*l-1) _inverse_of_2_to_the_l_plus_1_mod_F = F - 2**(w*l-1-l) We = (We * _inverse_of_2_mod_F) % F Wo = (Wo * _inverse_of_2_to_the_l_plus_1_mod_F) % F D = [cls.sneeze(We[i] % F, g, 2**(2*l)) for i in range(m)] D += [cls.sneeze(Wo[i] % F, g, 2**(2*l)) for i in range(m)] d = [] for j in range(w//2): for i in range(2*m): d.append(D[i][j]) return R(d)
def get_values_at_CM_points(k, N=1, chi=0, fi=0, digits=12, verbose=0): r""" Computes and returns a list of values of f at a collection of CM points as complex floating point numbers. INPUT: - ''k'' -- positive integer : the weight - ''N'' -- positive integer (default 1) : level - ''chi'' -- non-neg. integer (default 0) use character nr. chi - ''fi'' -- non-neg. integer (default 0) We want to use the element nr. fi f=Newforms(N,k)[fi] -''digits'' -- we want this number of corrrect digits in the value OUTPUT: -''s'' string representation of a dictionary {I:f(I):rho:f(rho)}. TODO: Get explicit, algebraic values if possible! """ (t, f) = _get_newform(k, N, chi, fi) if(not t): return f bits = max(53, ceil(digits * 4)) CF = ComplexField(bits) RF = ComplexField(bits) eps = RF(10 ** -(digits + 1)) logger.debug("eps=" % eps) K = f.base_ring() cm_vals = dict() # the points we want are i and rho. More can be added later... rho = CyclotomicField(3).gen() zi = CyclotomicField(4).gen() points = [rho, zi] maxprec = 1000 # max size of q-expansion minprec = 10 # max size of q-expansion for tau in points: q = CF(exp(2 * pi * I * tau)) fexp = dict() if(K == QQ): v1 = CF(0) v2 = CF(1) try: for prec in range(minprec, maxprec, 10): logger.debug("prec=%s" % prec) v2 = f.q_expansion(prec)(q) err = abs(v2 - v1) logger.debug("err=%s" % err) if(err < eps): raise StopIteration() v1 = v2 cm_vals[tau] = "" except StopIteration: cm_vals[tau] = str(fq) else: v1 = dict() v2 = dict() err = dict() cm_vals[tau] = dict() for h in range(K.degree()): v1[h] = 1 v2[h] = 0 try: for prec in range(minprec, maxprec, 10): logger.debug("prec=%s" % prec) for h in range(K.degree()): fexp[h] = list() v2[h] = 0 for n in range(prec): c = f.coefficients(ZZ(prec))[n] cc = c.complex_embeddings(CF.prec())[h] v2[h] = v2[h] + cc * q ** n err[h] = abs(v2[h] - v1[h]) logger.debug("v1[%s]=%s" % (h, v1[h])) logger.debug("v2[%s]=%s" % (h, v2[h])) logger.debug("err[%s]=%s" % (h, err[h])) if(max(err.values()) < eps): raise StopIteration() v1[h] = v2[h] except StopIteration: pass for h in range(K.degree()): if(err[h] < eps): cm_vals[tau][h] = v2[h] else: cm_vals[tau][h] = "" logger.debug("vals=%s" % cm_vals) logger.debug("errs=%s" % err) tbl = dict() tbl['corner_label'] = ['$\tau$'] tbl['headersh'] = ['$\\rho=\zeta_{3}$', '$i$'] if(K == QQ): tbl['headersv'] = ['$f(\\tau)$'] tbl['data'] = [cm_vals] else: tbl['data'] = list() tbl['headersv'] = list() for h in range(K.degree()): tbl['headersv'].append("$\sigma_{%s}(f(\\tau))$" % h) row = list() for tau in points: row.append(cm_vals[tau][h]) tbl['data'].append(row) s = html_table(tbl) # s=html.table([cm_vals.keys(),cm_vals.values()]) return s
def get_values_at_CM_points(k, N=1, chi=0, fi=0, digits=12, verbose=0): r""" Computes and returns a list of values of f at a collection of CM points as complex floating point numbers. INPUT: - ''k'' -- positive integer : the weight - ''N'' -- positive integer (default 1) : level - ''chi'' -- non-neg. integer (default 0) use character nr. chi - ''fi'' -- non-neg. integer (default 0) We want to use the element nr. fi f=Newforms(N,k)[fi] -''digits'' -- we want this number of corrrect digits in the value OUTPUT: -''s'' string representation of a dictionary {I:f(I):rho:f(rho)}. TODO: Get explicit, algebraic values if possible! """ (t, f) = _get_newform(k, N, chi, fi) if (not t): return f bits = max(53, ceil(digits * 4)) CF = ComplexField(bits) RF = ComplexField(bits) eps = RF(10**-(digits + 1)) logger.debug("eps=" % eps) K = f.base_ring() cm_vals = dict() # the points we want are i and rho. More can be added later... rho = CyclotomicField(3).gen() zi = CyclotomicField(4).gen() points = [rho, zi] maxprec = 1000 # max size of q-expansion minprec = 10 # max size of q-expansion for tau in points: q = CF(exp(2 * pi * I * tau)) fexp = dict() if (K == QQ): v1 = CF(0) v2 = CF(1) try: for prec in range(minprec, maxprec, 10): logger.debug("prec=%s" % prec) v2 = f.q_expansion(prec)(q) err = abs(v2 - v1) logger.debug("err=%s" % err) if (err < eps): raise StopIteration() v1 = v2 cm_vals[tau] = "" except StopIteration: cm_vals[tau] = str(fq) else: v1 = dict() v2 = dict() err = dict() cm_vals[tau] = dict() for h in range(K.degree()): v1[h] = 1 v2[h] = 0 try: for prec in range(minprec, maxprec, 10): logger.debug("prec=%s" % prec) for h in range(K.degree()): fexp[h] = list() v2[h] = 0 for n in range(prec): c = f.coefficients(ZZ(prec))[n] cc = c.complex_embeddings(CF.prec())[h] v2[h] = v2[h] + cc * q**n err[h] = abs(v2[h] - v1[h]) logger.debug("v1[%s]=%s" % (h, v1[h])) logger.debug("v2[%s]=%s" % (h, v2[h])) logger.debug("err[%s]=%s" % (h, err[h])) if (max(err.values()) < eps): raise StopIteration() v1[h] = v2[h] except StopIteration: pass for h in range(K.degree()): if (err[h] < eps): cm_vals[tau][h] = v2[h] else: cm_vals[tau][h] = "" logger.debug("vals=%s" % cm_vals) logger.debug("errs=%s" % err) tbl = dict() tbl['corner_label'] = ['$\tau$'] tbl['headersh'] = ['$\\rho=\zeta_{3}$', '$i$'] if (K == QQ): tbl['headersv'] = ['$f(\\tau)$'] tbl['data'] = [cm_vals] else: tbl['data'] = list() tbl['headersv'] = list() for h in range(K.degree()): tbl['headersv'].append("$\sigma_{%s}(f(\\tau))$" % h) row = list() for tau in points: row.append(cm_vals[tau][h]) tbl['data'].append(row) s = html_table(tbl) # s=html.table([cm_vals.keys(),cm_vals.values()]) return s
# Copyright (C) 2016-2017, Edgar Costa # See LICENSE file for license details from sage.all import CC, Infinity, PolynomialRing, RealField, ZZ from sage.all import ceil, copy, gcd, log, norm, set_random_seed, sqrt, vector from AbelJacobi import AJ1, AJ2, PariIntNumInit, SetPariPrec from Divisor import Divisor from InvertAJglobal import InvertAJglobal set_random_seed(1) import random random.seed(1) digits = 150 prec = ceil(log(10) / log(2) * digits) SetPariPrec(digits + 50) PariIntNumInit(3) power = 6 threshold = 2**(prec * .5) ncurves = 8 #i = 8 needs more precision for i in range(ncurves): print "i = %s of %s" % (i + 1, ncurves) smoothQ = False ZT = PolynomialRing(ZZ, "T") T = ZT.gen() while not smoothQ: g = ZT.random_element(degree=6) # ZT([-4, 12, 0, -20, 0, 8, 1])# dg = g.derivative() smoothQ = gcd(g, dg) == 1 print "C: y^2 = %s" % g
def test_all(self): todo = [] from lmfdb.db_backend import db maxNk2 = db.mf_newforms.max('Nk2') for Nk2 in range(1, maxNk2 + 1): for N in ZZ(Nk2).divisors(): k = sqrt(Nk2/N) if k in ZZ: todo.append((N, int(k))) formerrors = list(self.all_newforms(todo)) spaceserrors = list(self.all_newspaces(todo)) errors = [] res = [] for k, io in enumerate([formerrors, spaceserrors]): for i, o in io: if not isinstance(o, list): if k == 0: command = "all_newforms" else: command = "all_newspaces" errors.append( [command, i] ) else: res.extend(o) if errors == []: print "No errors while running the tests!" else: print "Unexpected errors occurring while running:" for e in errors: print e broken_urls = [ u for l, u in res if u is None ] working_urls = [ (l, u) for l, u in res if u is not None] working_urls.sort(key= lambda elt: elt[0]) just_times = [ l for l, u in working_urls] total = len(working_urls) if broken_urls == []: print "All the pages passed the tets" if total > 0: print "Average loading time: %.2f" % (sum(just_times)/total,) print "Min: %.2f Max %.2f" % (just_times[0], just_times[-1]) print "Quartiles: %.2f %.2f %.2f" % tuple([just_times[ max(0, int(total*f) - 1)] for f in [0.25, 0.5, 0.75]]) print "Slowest pages:" for t, u in working_urls[-10:]: print "%.2f - %s" % (t,u) if total > 2: print "Histogram" h = 0.5 nbins = (just_times[-1] - just_times[0])/h while nbins < 50: h *= 0.5 nbins = (just_times[-1] - just_times[0])/h nbins = ceil(nbins) bins = [0]*nbins i = 0 for elt in just_times: while elt > (i + 1)*h + just_times[0]: i += 1 bins[i] += 1 for i, b in enumerate(bins): d = 100*float(b)/total print '%.2f\t|' %((i + 0.5)*h + just_times[0]) + '-'*(int(d)-1) + '| - %.2f%%' % d else: print "These pages didn't pass the tests:" for u in broken_urls: print u
def __init__(self, f, ring, verbose = False): """ input: f a polynomial over a number field ring: Complex Field (with some prescribed precision) where we will work over We represent a divisor z \in Pic**0 by a divisor in D on X such that z = [D - D_0] where D_0 is a fixed divisor of degree d_0 \deg D = d_0 A divisor D on X is then represented by vector space H**0(\delta - D) for this representation to be faithful we need \delta - D to be base point free for that is sufficient \deg \delta >= \deg D + 2g, as we will be dealing with divisors of degree d_0 and 2d_0 we pick \delta = 3 * D_0 a vector space H**0(-) is represented by a bases of rational functions on X and these functions are represented by its evaluation at an effective divisor Z During our computations every function will lie in H**0(3D_0) or H**0(6D_0). Hence, for this representation to be faithful, it is necessary and sufficient that H**0({3,6}D_0 - Z) = {0}, eg \deg D_0 = 6 d_0 + 1. If possible \supp D_0 \cap \supp Z = empty set would be ideal. In summary, a vector space W will be represented with \deg Z rows and \dim columns. """ self.verbose = verbose; assert is_CF(ring) self.R = ring; self.prec = ring.precision() self.f = f; self.a0 = list(f)[0]; self.an = list(f)[-1]; self.g = int(ceil( f.degree() / 2 ) - 1); self.d0 = 2 * self.g + 2; self.extraprec = self.prec + 3 * self.d0 + 16; self.Rextraprec = ComplexField(self.extraprec); self.Rdoubleextraprec = ComplexField(2*self.extraprec) self.Pi = self.Rdoubleextraprec.pi(); self.I = self.Rdoubleextraprec(0, 1); self.almostzero = self.R(2)**(- self.prec * 0.7); self.notzero = self.R(2)**(- self.prec * 0.1); self.lower = 0; # D_0 = (g + 1)*( \infty_{-} + \infty_{+} ) = (g + 1) * \infty # Pick the effective divisor Z, ie, the evaluation points # Pick evaluation points /!\ Weierstrass pts ! # in theory we only need \deg Z >= 6 d_0 + 1 # in practice we aim for >= 6 d_0 + 2 self.nZ = 6 * self.d0 + 2; if self.verbose: print "Using %s points on the unit circle, almost uniformly spaced, to represent each function" % ( self.nZ, ) n = self.nZ; n = ceil(self.nZ/2); Z=[] while len(Z) < self.nZ: # X computed in self.Rdoubleextraprec X = [ exp( 2 * k * self.I * self.Pi / n ) for k in range(n) ] Z = []; for i, x in enumerate(X): #y = (-1)**i * sqrt( f(x) ) #Z.append( (x, y) ) # # x in self.Rdoubleextraprec ! y = self.Rextraprec( sqrt( self.f(x) ) ) x = self.Rextraprec( x ) # making sure the points don't collide if y.abs() < 1e-2: Z.append( (x, y) ) else: Z.append( (x, y) ) Z.append( (x, -y) ) n += 1 self.Z = Z; self.nZ = len(Z); #alternatively self.Z = Z[:self.nZ], but this might lose some of the good properties of having the points uniformly on the unit circle # V represents H**0 (3 D_0) V = Matrix(self.Rextraprec, self.nZ, 3 * self.d0 + 1 - self.g) # \dim = 6g + 6 + 1 - g = 5 g + 7 # Vout represents H**0(D_0) Vout = Matrix(self.Rextraprec, self.nZ, self.d0 + 1 - self.g) # \dim = g + 3 # H**0(D_0) = <1, x, x**2, ..., x**(g + 1), y> # H**0(3*D_0) = <1, x, x**2, ...,x**g, x**(g + 1), y, x**(g + 2) , y x, ..., x**(g + 1 + 2g + 2), y x**(2g + 2)>, dim = 5 g + 7 = 1 + g + 2*(2*g + 3) Vexps = [None]* (3 * self.d0 + 1 - self.g) i = 0; for n in xrange( 3 * (self.g + 1) + 1): Vexps[i] = [ n, 0]; i += 1; if n > self.g: Vexps[i] = [ n - self.g - 1, 1]; i += 1; for i, (x, y) in enumerate(self.Z): for j in range( 3 * self.d0 + 1 - self.g): V[ i, j] = x ** Vexps[j][0] * y ** Vexps[j][1] for j in range( self.g + 2 ): Vout[i,j] = x**j Vout[ i, self.g + 2] = y self.V = V; self.Vout = Vout; self.Vexps = Vexps; # W0 represents H**0 (2 D_0) W0 = Matrix(self.Rextraprec, self.nZ, 2 * self.d0 + 1 - self.g) for i in range( self.nZ ): for j in range( 2 * self.d0 + 1 - self.g): W0[i,j] = V[i,j] # KV = Ker(V***) = col(V)**perp KV, upper, lower = EqnMatrix(V, 3 * self.d0 + 1 - self.g); assert self.threshold_check(upper, lower), "upper = %s lower = %s" % (RealField(35)(upper), RealField(35)(lower)) self.lower = max(self.lower, lower) self.KV = KV; self.W0 = W0;