Пример #1
0
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
Пример #2
0
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
Пример #3
0
    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
Пример #4
0
    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)
Пример #5
0
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
Пример #6
0
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]
Пример #7
0
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
Пример #8
0
    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
Пример #9
0
    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)])
Пример #10
0
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)
Пример #11
0
    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)
Пример #12
0
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]))
Пример #13
0
    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
Пример #14
0
    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