def is_represented_by_unit(a,c,p): #we can forget about powers of p, because they are units; then we can work with integers a, c, p = ZZ(a), ZZ(c), ZZ(p) vala = ZZ(0) valc = ZZ(0) while a % p == 0: vala += 1 a = ZZ(a / p) while c % p == 0: valc += 1 c = ZZ(c/p) aa = a.abs() # verbose('is_rep_by_unit aa=%s, cc=%s'%(aa,cc_mod_aa)) G = Zmod(aa) cc = G(c) Gp = G(p) res = [] sizeG = G.unit_group_order() expn = G.unit_group_exponent() # verbose('Group of order=%s'%sizeG) try: n0 = discrete_log(cc,Gp,sizeG,operation = '*') n0 = n0 % expn if n0 > expn/2: n0 -= expn res.append( p**ZZ(n0 + valc) ) except (ValueError,RuntimeError): pass try: n0 = discrete_log(cc,-Gp,sizeG,operation = '*') n0 = n0 % expn if n0 > expn/2: n0 -= expn res.append( ZZ(-1)**n0 * p**ZZ(n0 + valc) ) except (ValueError,RuntimeError): pass return res
def encode(self, m, S): ''' encodes a vector m (in Zmod(q)^n) to index set S ''' zinv = prod([self.zinv[i] for i in S]) m = vector(Zmod(self.q), m) zero = vector(Zmod(self.q), self.D_sigmap_I()) # random encoding of 0 c = self.Rq(list(zero + m)) return c * zinv
def __init__(self, params, asym=False): # set parameters (self.alpha, self.beta, self.rho, self.rho_f, self.eta, self.bound, self.n, self.k) = params self.x0 = ZZ(1) self.primes = [random_prime(2**self.eta, lbound = 2**(self.eta - 1), proof=False) for i in range(self.n)] primes = self.primes self.x0 = prod(primes) # generate CRT coefficients self.coeff = [ZZ((self.x0/p_i) * ZZ(Zmod(p_i)(self.x0/p_i)**(-1))) for p_i in primes] # generate secret g_i self.g = [random_prime(2**self.alpha, proof=False) for i in range(self.n)] # generate zs and zs^(-1) z = [] zinv = [] # generate z and z^(-1) if not asym: while True: z = ZZ.random_element(self.x0) try: zinv = ZZ(Zmod(self.x0)(z)**(-1)) break except ZeroDivisionError: ''' Error occurred, retry sampling ''' z, self.zinv = zip(*[(z,zinv) for i in range(self.k)]) else: # asymmetric version for i in range(self.k): while True: z_i = ZZ.random_element(self.x0) try: zinv_i = ZZ(Zmod(self.x0)(z_i)**(-1)) break except ZeroDivisionError: ''' Error occurred, retry sampling ''' z.append(z_i) zinv.append(zinv_i) self.zinv = zinv # generate p_zt zk = Zmod(self.x0)(1) self.p_zt = 0 for z_i in z: zk *= Zmod(self.x0)(z_i) for i in range(self.n): self.p_zt += Zmod(self.x0)(ZZ(Zmod(self.primes[i])(self.g[i])**(-1) * Zmod(self.primes[i])(zk)) * ZZ.random_element(2**self.beta) * (self.x0/self.primes[i])) self.p_zt = Zmod(self.x0)(self.p_zt)
def _explode_embedding_list(v0,M,emblist,power = 1): p = v0.codomain().base_ring().prime() list_embeddings = [] for tau0,gtau_orig in emblist: gtau = gtau_orig**power verbose('gtau = %s'%gtau) ## First method for u1 in is_represented_by_unit(M,ZZ(gtau[0,0]),p): u_M1 = matrix(QQ,2,2,[u1**-1,0,0,u1]) gtau1 = u_M1 * gtau tau01 = tau0 / (u1**2) if gtau1[0,0] % M == 1: list_embeddings.append((tau01,gtau1,1)) elif gtau1[0,0] % M == -1: list_embeddings.append((tau01,-gtau1,1)) ## Second method if M > 1: a_inv = ZZ((1/Zmod(M)(gtau[0,0])).lift()) for u2 in is_represented_by_unit(M,a_inv,p): u_M2 = matrix(QQ,2,2,[u2,0,0,u2**-1]) gtau2 = u_M2 * gtau tau02 = u2**2 * tau0 #act_flt(u_M2,tau0) if gtau2[0,0] % M == 1: list_embeddings.append((tau02,gtau2,1)) elif gtau1[0,0] % M == -1: list_embeddings.append((tau02,-gtau2,1)) verbose('Found %s embeddings...'%len(list_embeddings)) return list_embeddings
def factorize_matrix(m,M): #assert is_in_Gamma_1(m,M,determinant_condition = False) assert m.det().abs() == 1 a,b,c,d = m.list() if QQ(a).denominator() != 1: raise RuntimeError #return [m] assert a % M == 1 aabs = ZZ(a).abs() Zm = Zmod(M) for alphamul in sorted(range(-aabs.sqrt(50)/M,aabs.sqrt(50)/M),key = lambda x: ZZ(x).abs()): alpha = 1 + M*alphamul if alpha.abs() >= aabs: continue delta0 = (Zm(alpha)**(-1)).lift() for delta in xrange(delta0-10*M,delta0+10*M,M): if alpha * delta == 1: continue gamma0 = ZZ( (alpha*delta -1) / M) c1vec = gamma0.divisors() for c1 in c1vec: ulentry = (a*delta-b*c1*M).abs() urentry = (b*alpha-a*gamma0/c1).abs() if ulentry < aabs and urentry < b.abs(): gamma = c1*M beta = ZZ(gamma0/c1) r1 = Matrix(QQ,2,2,[alpha,beta,gamma,delta]) r2 = m*r1.adjugate() assert r1.determinant() == 1 assert is_in_Gamma_1(r1,M,determinant_condition = False) assert is_in_Gamma_1(r1,M,determinant_condition = False) V1 = factorize_matrix(r1,M) V2 = factorize_matrix(r2,M) return V2 + V1 return [m]
def double_integral(Phi, tau1, tau2, r, s): if r == [0, 0] or s == [0, 0]: raise ValueError, 'r and s must be valid projective coordinates.' if r[0] == 0 and s[1] == 0: # From 0 to infinity return double_integral_zero_infty(Phi, tau1, tau2) elif s[1] == 0: a, b = r if b < 0: a, b = -a, -b if b == 0: return 1 if b == 1: return double_integral(Phi, tau1 - a / b, tau2 - a / b, [0, 1], [1, 0]) else: d = (1 / (Zmod(b)(a))).lift() if 2 * d > b: d -= b c = ZZ((a * d - 1) / b) rr = [c, d] if d >= 0 else [-c, -d] i1 = double_integral(Phi, (b * tau1 - a) / (d * tau1 - c), (b * tau2 - a) / (d * tau2 - c), [0, 1], [1, 0]) i2 = double_integral(Phi, tau1, tau2, rr, [1, 0]) return i1 * i2 else: i1 = double_integral(Phi, tau1, tau2, r, [1, 0]) i2 = double_integral(Phi, tau1, tau2, s, [1, 0]) return i1 / i2
def __init__(self, base_field, length, designed_distance, primitive_root=None, offset=1, jump_size=1, b=0): """ TESTS: ``designed_distance`` must be between 1 and ``length`` (inclusive), otherwise an exception is raised:: sage: C = codes.BCHCode(GF(2), 15, 16) Traceback (most recent call last): ... ValueError: designed_distance must belong to [1, n] """ if not (0 < designed_distance <= length): raise ValueError("designed_distance must belong to [1, n]") if base_field not in Fields() or not base_field.is_finite(): raise ValueError("base_field has to be a finite field") q = base_field.cardinality() s = Zmod(length)(q).multiplicative_order() if gcd(jump_size, q ** s - 1) != 1: raise ValueError("jump_size must be coprime with the order of " "the multiplicative group of the splitting field") D = [(offset + jump_size * i) % length for i in range(designed_distance - 1)] super(BCHCode, self).__init__(field=base_field, length=length, D=D, primitive_root=primitive_root) self._default_decoder_name = "UnderlyingGRS" self._jump_size = jump_size self._offset = offset self._designed_distance = designed_distance
def image_mod_n(self): r""" Return the image of this group modulo `N`, as a subgroup of `SL(2, \ZZ / N\ZZ)`. This is just the trivial subgroup. EXAMPLE:: sage: Gamma(3).image_mod_n() Matrix group over Ring of integers modulo 3 with 1 generators: [[[1, 0], [0, 1]]] """ return MatrixGroup([matrix(Zmod(self.level()), 2, 2, 1)])
def lift(A, N): r""" Lift a matrix A from SL_m(Z/NZ) to SL_m(Z). Follows Shimura, Lemma 1.38, p21. """ assert A.is_square() assert A.determinant() != 0 m = A.nrows() if m == 1: return identity_matrix(1) D, U, V = A.smith_form() if U.determinant() == -1: U = matrix(2, 2, [-1, 0, 0, 1]) * U if V.determinant() == -1: V = V * matrix(2, 2, [-1, 0, 0, 1]) D = U * A * V assert U.determinant() == 1 assert V.determinant() == 1 a = [D[i, i] for i in range(m)] b = prod(a[1:]) W = identity_matrix(m) W[0, 0] = b W[1, 0] = b - 1 W[0, 1] = 1 X = identity_matrix(m) X[0, 1] = -a[1] Ap = D.parent()(D) Ap[0, 0] = 1 Ap[1, 0] = 1 - a[0] Ap[1, 1] *= a[0] assert (W * U * A * V * X).change_ring(Zmod(N)) == Ap.change_ring(Zmod(N)) Cp = diagonal_matrix(a[1:]) Cp[0, 0] *= a[0] C = lift(Cp, N) Cpp = block_diagonal_matrix(identity_matrix(1), C) Cpp[1, 0] = 1 - a[0] return (~U * ~W * Cpp * ~X * ~V).change_ring(ZZ)
def __init__(self, params, asym=False): (self.n, self.q, sigma, self.sigma_prime, self.k) = params S, x = PolynomialRing(ZZ, 'x').objgen() self.R = S.quotient_ring(S.ideal(x**self.n + 1)) Sq = PolynomialRing(Zmod(self.q), 'x') self.Rq = Sq.quotient_ring(Sq.ideal(x**self.n + 1)) # draw z_is uniformly from Rq and compute its inverse in Rq if asym: z = [self.Rq.random_element() for i in range(self.k)] self.zinv = [z_i**(-1) for z_i in z] else: # or do symmetric version z = self.Rq.random_element() zinv = z**(-1) z, self.zinv = zip(*[(z, zinv) for i in range(self.k)]) # set up some discrete Gaussians DGSL_sigma = DGSL(ZZ**self.n, sigma) self.D_sigma = lambda: self.Rq(list(DGSL_sigma())) # discrete Gaussian in ZZ^n with stddev sigma_prime, yields random level-0 encodings DGSL_sigmap_ZZ = DGSL(ZZ**self.n, self.sigma_prime) self.D_sigmap_ZZ = lambda: self.Rq(list(DGSL_sigmap_ZZ())) # draw g repeatedly from a Gaussian distribution of Z^n (with param sigma) # until g^(-1) in QQ[x]/<x^n + 1> is small (< n^2) Sk = PolynomialRing(QQ, 'x') K = Sk.quotient_ring(Sk.ideal(x**self.n + 1)) while True: l = self.D_sigma() ginv_K = K(mod_near_poly(l, self.q))**(-1) ginv_size = vector(ginv_K).norm() if ginv_size < self.n**2: g = self.Rq(l) self.ginv = g**(-1) break # discrete Gaussian in I = <g>, yields random encodings of 0 short_g = vector(ZZ, mod_near_poly(g, self.q)) DGSL_sigmap_I = DGSL(short_g, self.sigma_prime) self.D_sigmap_I = lambda: self.Rq(list(DGSL_sigmap_I())) # compute zero-testing parameter p_zt # randomly draw h (in Rq) from a discrete Gaussian with param q^(1/2) self.h = self.Rq(list(DGSL(ZZ**self.n, round(sqrt(self.q)))())) # create p_zt self.p_zt = self.ginv * self.h * prod(z)
def _find_limits_manin_trick(tau,gtau): if gtau[0,0] == 0: return [(1-1/tau,tau-1)] else: a,c,b,d = gtau.list() if b < 0: a,b,c,d = -a,-b,-c,-d if b == 0: return [] if b == 1: return _find_limits_manin_trick(tau-a/b,M2Z([0,-1,1,0])) else: d = (1/(Zmod(b)(a))).lift() if 2*d > b : d -= b c = ZZ((a*d-1)/b) if d < 0: a,b,c,d = -a,-b,-c,-d return _find_limits_manin_trick((b*tau-a)/(d*tau-c),M2Z([0,-1,1,0])) + _find_limits_manin_trick(tau,M2Z([-c,a,-d,b]))
def _rho_unramified(self, g): r""" Calculate the action of ``g`` on the type space, in the unramified (even level) case. Uses the two standard generators, and a solution of the word problem in `{\rm SL}_2(\ZZ / p^u \ZZ)`. INPUT: - ``g`` -- 4-tuple of integers (or more generally anything that can be converted into an element of the matrix group `{\rm SL}_2(\ZZ / p^u \ZZ)`). EXAMPLE:: sage: from sage.modular.local_comp.type_space import example_type_space sage: T = example_type_space(2) sage: T._rho_unramified([2,1,1,1]) [-1 1 -1 1] [ 0 0 0 1] [ 1 -1 0 1] [ 1 -2 1 0] sage: T._rho_unramified([1,-2,1,-1]) == T._rho_unramified([2,1,1,1]) * T._rho_unramified([0,-1,1,0]) True """ f = self.prime()**self.u() from sage.groups.matrix_gps.all import SL G = SL(2, Zmod(f)) gg = G(g) s = G([1, 1, 0, 1]) t = G([0, -1, 1, 0]) S = self._unipmat T = self._second_gen_unramified() w = gg.word_problem([s, t]) answer = S**0 for (x, n) in w: if x == s: answer = answer * S**n elif x == t: answer = answer * T**n return answer
def __call__(self, x, check=True): r""" Attempt to convert `x` into an element of self. This converts `x` into an element of `SL(2, \ZZ)`. If ``check`` is True (the default) it checks if the resulting element is in self, and otherwise raises an error. EXAMPLE:: sage: G = MatrixGroup([matrix(Zmod(2), 2, [1,1,1,0])]) sage: H = sage.modular.arithgroup.congroup_generic.CongruenceSubgroupFromGroup(G) sage: H(1) [1 0] [0 1] sage: H([0,-1,1,0]) Traceback (most recent call last): ... TypeError: Element [ 0 -1] [ 1 0] not in group sage: H([1,2,0,1]) [1 2] [0 1] sage: H(SL2Z([0,-1,1,0]), check=False) [ 0 -1] [ 1 0] sage: H([1,2,0,1]).parent() Modular Group SL(2,Z) """ from sage.modular.arithgroup.all import SL2Z x = SL2Z(x, check=check) if not check: return x else: y = x.matrix().change_ring(Zmod(self.level())) if y in self.image_mod_n(): return x else: raise TypeError, "Element %s not in group" % x