示例#1
0
def norm_search(p, d):
    md = None
    if (d % 4) != 1:
        for nn in range(1, 20000):
            for mm in [nn**2 * d + p, nn**2 * d - p]:
                if issq(mm):
                    m2 = int(sqrt(mm))
                    if (gcd(nn, p) == 1) or (gcd(m2, p) == 1):
                        md = QuadInt(d, m2, nn)
                        break
    return md
示例#2
0
def coset_reps(qq):
    r"""
    Yield coset representatives for Gamma(q) in SL(2, Z).
    """
    zq2 = itertools.product(range(qq), range(qq))

    #
    # this pattern matching no longer seems to work in python 3.6
    #
    # f=lambda (cc, dd):gcd(cc, gcd(dd, qq))==1
    #
    # so replace it with this:
    #

    def f(pair):
        cc, dd = pair
        return gcd(cc, gcd(dd, qq)) == 1

    for (cc, dd) in filter(f, zq2):
        ii = 0
        if cc == 0:
            if dd != 1:
                cc = qq
        while True:
            if gcd(cc, dd - ii * qq) == 1:
                dd -= ii * qq
                break
            elif gcd(cc, dd + ii * qq) == 1:
                dd += ii * qq
                break
            ii += 1
        # cc and dd are now relatively prime.
        zq2 = itertools.product(range(qq), range(qq))
        for (aa, bb) in zq2:
            quot, rem = divmod(aa * dd - bb * cc, qq)
            if rem == 1:
                # now aa*dd-bb*cc = 1 (mod qq)
                for (ee, ff) in [(ee, ff) for ee in range(-2 * qq, 2 * qq)
                                 for ff in range(-2 * qq, 2 * qq)]:
                    if (aa + ee * qq) * dd - (bb + ff * qq) * cc == 1:
                        yieldval = np.array(
                            [[aa + ee * qq, bb + ff * qq], [cc, dd]],
                            dtype=int)
                        # now normalize so that the image of D under this
                        # transformation lies between -1/2 and q-1/2.
                        f = mat_to_fcn(yieldval)
                        mm = int(floor(f([0.5j])[0].real))
                        yieldval = np.array([[1, mm % qq - mm], [0, 1]],
                                            dtype=int).dot(yieldval)
                        yield yieldval
                        break
示例#3
0
def cont_frac_quad(a, b, c, d):
    r"""
    Yield the continued fraction for (a+b*sqrt(d))/c
    """
    sqd = mpmath.sqrt(d)
    while True:
        m = int((mpmath.mpf(a) + sqd * mpmath.mpf(b)) / mpmath.mpf(c))
        yield m
        a1p = (a - c * m)
        a1 = c * a1p
        b1 = -c * b
        c1 = a1p**2 - d * b**2
        g = gcd(c * gcd(a1p, b), c1)
        a, b, c = a1 // g, b1 // g, c1 // g
def all_reduced_forms(disc):
    """
    Return a list of all reduced forms with
    negative discriminant D.
    """
    if disc >= 0:
        raise ValueError("discriminant must be negative")
    retval = []
    for a in range(1, int(sqrt(-disc / 3.0) + 1.0)):
        for b in range(-a + 1, a + 1):
            c, r = divmod(b**2 - disc, 4 * a)
            if r == 0:
                if gcd(gcd(a, abs(b)), c) == 1:
                    if a <= c and ((a != c) or (b >= 0)):
                        retval.append((a, b, c))
    return sorted(list(set(retval)))
def solve_common_factors(ciphertexts, modulos, exponents):
    plaintexts = []
    factors_found = []
    for i in range(len(modulos)):
        for j in range(i + 1, len(modulos)):
            calc_gcd = gcd(modulos[i], modulos[j])
            if calc_gcd > 1:
                factors_found.append([i, j, calc_gcd])

    for mod_pair in factors_found:

        # Get factors of n1 and n2
        calc_gcd = mod_pair[2]
        q1 = modulos[mod_pair[0]] / calc_gcd
        q2 = modulos[mod_pair[1]] / calc_gcd

        # Decrypt c1
        c1 = ciphertexts[mod_pair[0]]
        e1 = exponents[mod_pair[0]]
        p1 = decrypt(c1, e1, modulos[mod_pair[0]], p=calc_gcd, q=q1)

        # Decrypt c2
        c2 = ciphertexts[mod_pair[1]]
        e2 = exponents[mod_pair[1]]
        p2 = decrypt(c2, e2, modulos[mod_pair[1]], p=calc_gcd, q=q2)

        plaintexts.append(p1)
        plaintexts.append(p2)
    return plaintexts
示例#6
0
def legendre_ch(d):
    """
    Return the mod abs(disc Q[√d]) Legendre character.

    This is the character ch with modulus D=abs(disc Q[√d])
    such that for any odd prime p, ch(p)=(d/p) (i.e.

    ch(p)=0 if p|d
    ch(p)=1 if d is a square mod p
    ch(p)=-1 if d is not a square mod p
    """
    if not squarefree(d):
        raise ValueError('%d is not square free' % (d, ))

    abs_disc = abs(discriminant(d))

    vals = [0] * abs_disc

    for k in range(abs_disc):
        if gcd(abs_disc, k) == 1:
            n = k
            while True:
                if isprime(n) and n % 2 == 1:
                    vals[k] = legendre(d, n)
                    break
                n += abs_disc
    return lambda a: vals[a % abs_disc]
示例#7
0
def ideal_class_number(dd):
    r"""
    Return the ideal class number of Q[√d], for squarefree integer dd.
    """
    if not squarefree(dd):
        raise ValueError("%d is not squarefree." % (dd, ))

    if dd == 1:
        return 1

    abs_disc = abs(discriminant(dd))

    ch = legendre_ch(dd)

    z = np.exp(2.0j * np.pi / abs_disc)
    rho = np.abs(1.0 / np.sqrt(abs(abs_disc)) * sum(
        ch(k) * np.log(1 - z**(-k))
        for k in range(1, abs_disc) if gcd(k, abs_disc) == 1))

    k = kappa(dd)

    # magically rho should be an integral multiple of kappa.
    # make sure this is true before we return the rounded answer.
    assert (abs(round(rho / k) - rho / k) < 0.001)

    return int(round(rho / k))
示例#8
0
def L_one_chi(ch, m):
    r"""
    Compute the value of the Dirichlet L-series L(s, ch) at s=1.
    """
    zz = np.exp(2.0j * np.pi / m)
    return -(1.0 / m) * sum(
        gs_numerical(ch, m, k) * np.log(1 - zz**(-k))
        for k in range(1, m) if gcd(k, m) == 1)
 def conjugates(self):
     """
     Yield the conjugates of the cyclotomic integer.
     """
     nc = len(self.coefs)
     for k in range(nc):
         if gcd(k, nc) == 1:
             yield CyclotomicInteger(
                 [self.coefs[ii * k % nc] for ii in range(nc)])
def genus(a, b, c):
    def f(xx, yy):
        return a * xx**2 + b * xx * yy + c * yy**2

    disc = form_disc(a, b, c)
    val = sorted(
        list(
            set([
                f(x, y) % (-disc) for x in range(-disc) for y in range(-disc)
            ])))
    return filter(lambda xx: gcd(xx, -disc) == 1, val)
示例#11
0
def eisenstein(k, z):
    """
    Return the value phi_0, k(z) of the Eisenstein series of weight k at z.
    """

    if z.imag <= 0:
        raise ValueError("z not in the upper half plane.")

    nmax = _eisenstein_bound(1e-08, k, z)

    retval = 0.0
    for nn in range(nmax, 0, -1):
        for (cc, dd) in _rectangle_n_points(nn):
            if cc >= 0 and (cc > 0 or dd > 0) and gcd(cc, dd) == 1:
                vv = 1 / (cc * z + dd)**(2 * k)
                retval += vv
    return retval
示例#12
0
def poincare(k, nu, z):
    """
    Return the value of the Poincare series of weight k and character nu at z.
    """

    if z.imag <= 0:
        raise ValueError("z not in the upper half plane.")

    nmax = _eisenstein_bound(1e-08, k, z)

    retval = 0.0
    for nn in range(nmax, 0, -1):
        for (cc, dd) in _rectangle_n_points(nn):
            if cc >= 0 and (cc > 0 or dd > 0) and gcd(cc, dd) == 1:
                bb, aa = euclidean_algorithm(cc, dd)
                Tz = (aa * z - bb) / (cc * z + dd)
                vv = np.exp(
                    2.0 * np.pi * nu * 1.0j * Tz) / (cc * z + dd)**(2 * k)
                retval += vv
    return retval
示例#13
0
 def f(pair):
     cc, dd = pair
     return gcd(cc, gcd(dd, qq)) == 1
示例#14
0
 def test_gcd(self):
     self.assertEqual(gcd(2 * 3 * 5, 3 * 5 * 7), 3 * 5)
示例#15
0
 def generate_public_key(self):
     public_key = 2
     while public_key < self.phi:
         if math.gcd(public_key, self.phi) == 1:
             return public_key
         public_key += 1
示例#16
0
 def test_euclidean_algorithm2(self):
     for a in range(-100, +100):
         for b in range(-100, +100):
             x, y = euclidean_algorithm(a, b)
             self.assertEqual(gcd(a, b), x * a + y * b, 'gcd != x*a+y*b')
示例#17
0
 def test_euclidean_algorithm(self):
     a = 89
     b = 55
     x, y = euclidean_algorithm(a, b)
     self.assertEqual(abs(gcd(a, b)), abs(x * a + y * b))
示例#18
0
    for y in range(x + 1, 100):
        num = [a for a in str(x)]
        den = [a for a in str(y)]

        if num[-1] == 0:
            pass

        elif num[-1] == den[0]:
            num.remove(num[-1])
            num = int("".join(num))

            den.remove(den[0])
            den = int("".join(den))

            if den == 0:
                pass

            else:
                check = num / den
                actual = x / y

                if check == actual:
                    top.append(x)
                    bottom.append(y)

top = reduce(lambda x, y: x * y, top)
bottom = reduce(lambda x, y: x * y, bottom)
div = gcd(top, bottom)

bottom /= div
print(bottom)
 def test_phi(self):
     for nn in range(1, 100):
         nresid = sum(1 for kk in range(1, nn+1) if gcd(nn, kk) == 1)
         self.assertEqual(nresid, phi(nn))