コード例 #1
0
ファイル: fingroups.py プロジェクト: vishalbelsare/mpyc
    def encode(cls, m):
        """Encode message m in the first coefficient of a form."""
        D = cls.discriminant
        gap = cls.gap
        assert (m +
                1) * gap <= isqrt(-D) / 2  # ensure M (and Z) will be reduced
        assert gap % 4 == 0
        for i in range(0, gap, 4):
            a_0 = i + 3
            b_0 = int(powmod(D, (a_0 + 1) // 4, a_0))
            if (b_0**2 - D) % a_0 == 0:
                # NB: gcd(a_0,b_0)=1 because -D is prime
                a_m = m * gap + i + 3
                b_m = int(powmod(D, (a_m + 1) // 4, a_m))
                if (b_m**2 - D) % a_m == 0:
                    # NB: gcd(a_m,b_m)=1 because -D is prime
                    b_m = a_m - b_m if D % 2 != b_m % 2 else b_m
                    c_m = (b_m**2 - D) // (4 * a_m)
                    M = cls((a_m, b_m, c_m), check=False)
                    b_0 = a_0 - b_0 if D % 2 != b_0 % 2 else b_0
                    c_0 = (b_0**2 - D) // (4 * a_0)
                    Z = cls((a_0, b_0, c_0), check=False)
                    return M, Z  # NB: M and Z are reduced

        raise ValueError('message encoding failed, try larger gap')
コード例 #2
0
def find_prime_root(l, blum=True, n=1):
    """Find smallest prime of bit length at least l satisfying given constraints.

    Default is to return Blum primes (primes p with p % 4 == 3).
    Also, a primitive root w is returned of prime order at least n (0 < w < p).
    """
    if l <= 2:
        if not blum:
            p = 2
            assert n == 1
            w = 1
        else:
            p = 3
            n, w = 2, p - 1
    elif n <= 2:
        p = gmpy2.next_prime(1 << l - 1)
        if blum:
            while p % 4 != 3:
                p = gmpy2.next_prime(p)
        p = int(p)
        w = p - 1 if n == 2 else 1
    else:
        assert blum
        if not gmpy2.is_prime(n):
            n = gmpy2.next_prime(n)
        p = 1 + 2 * n * (3 + 2 * ((1 << l - 3) // n))
        while not gmpy2.is_prime(p):
            p += 4 * n

        a = 2
        while (w := gmpy2.powmod(a, (p - 1) // n, p)) == 1:
            a += 1
        p, w = int(p), int(w)
コード例 #3
0
ファイル: fingroups.py プロジェクト: lschoe/mpyc
def SchnorrGroup(p=None, q=None, g=None, l=None, n=None):
    """Create type for Schnorr group of odd prime order q.

    If q is not given, q will be the smallest n-bit prime, n>=2.
    If p is not given, p will be the least l-bit prime, l>n, such that q divides p-1.

    If l and/or n are not given, default bit lengths will be set (2<=n<l).
    """
    n_l = ((160, 1024), (192, 1536), (224, 2048), (256, 3072), (384, 7680))
    if p is None:
        if q is None:
            if n is None:
                if l is None:
                    l = 2048
                n = next((n for n, _ in n_l if _ >= l), 512)
            q = next_prime(1 << n-1)
        else:
            if n is None:
                n = q.bit_length()
            assert q%2 and is_prime(q)
        if l is None:
            l = next((l for _, l in n_l if _ >= n), 15360)

        # n-bit prime q
        w = (1 << l-2) // q + 1  # w*q >= 2^(l-2), so p = 2*w*q + 1 > 2^(l-1)
        p = 2*w*q + 1
        while not is_prime(p):
            p += 2*q
        # 2^(l-1) < p < 2^l
    else:
        assert q is not None  # if p is given, q must be given as well
        assert (p - 1) % q == 0
        assert q%2 and is_prime(q)
        assert is_prime(p)
        if l is None:
            l = p.bit_length()
        if n is None:
            n = q.bit_length()
    assert l == p.bit_length()
    assert n == q.bit_length()

    p = int(p)
    q = int(q)
    if g is None:
        w = (p-1) // q
        i = 2
        while True:
            g = powmod(i, w, p)
            if g != 1 and powmod(g, q, p) == 1:
                break
            i += 1
        g = int(g)
    return _SchnorrGroup(p, q, g)
コード例 #4
0
ファイル: finfields.py プロジェクト: dfischer/mpyc
    def sqrt(self, INV=False):
        a = self.value
        p = self.modulus
        if p == 2:
            return type(self)(a)

        if p & 3 == 3:
            if INV:
                p4 = (p * 3 - 5) >> 2  # a**p4 == a**(-1/2) == 1/sqrt(a) mod p
            else:
                p4 = (p + 1) >> 2
            return type(self)(int(gmpy2.powmod(a, p4, p)))

        # 1 (mod 4) primes are covered using Cipolla-Lehmer's algorithm.
        # find b s.t. b^2 - 4*a is not a square
        b = 1
        while gmpy2.legendre(b * b - 4 * a, p) != -1:
            b += 1

        # compute u*X + v = X^{(p+1)/2} mod f, for f = X^2 - b*X + a
        u, v = 0, 1
        e = (p + 1) >> 1
        for i in range(e.bit_length() - 1, -1, -1):
            u2 = (u * u) % p
            u = ((u << 1) * v + b * u2) % p
            v = (v * v - a * u2) % p
            if (e >> i) & 1:
                u, v = (v + b * u) % p, (-a * u) % p
        if INV:
            return type(self)(v).reciprocal()

        return type(self)(v)
コード例 #5
0
ファイル: test_gmpy.py プロジェクト: zhongyu1997/mpyc
    def test_basic(self):
        self.assertFalse(gmpy.is_prime(1))
        self.assertTrue(gmpy.is_prime(2))
        self.assertTrue(gmpy.is_prime(101))
        self.assertFalse(gmpy.is_prime(561))
        self.assertTrue(gmpy.is_prime(2**16 + 1))
        self.assertFalse(gmpy.is_prime(41041))

        self.assertEqual(gmpy.next_prime(1), 2)
        self.assertEqual(gmpy.next_prime(2), 3)
        self.assertEqual(gmpy.next_prime(256), 257)

        self.assertEqual(gmpy.powmod(3, 256, 257), 1)

        self.assertEqual(gmpy.invert(3, 257), 86)
        self.assertRaises(ZeroDivisionError, gmpy.invert, 2, 4)

        self.assertEqual(gmpy.legendre(0, 101), 0)
        self.assertEqual(gmpy.legendre(42, 101), -1)
        self.assertEqual(gmpy.legendre(54, 101), 1)

        self.assertTrue(gmpy.is_square(625))
        self.assertFalse(gmpy.is_square(652))

        self.assertEqual(gmpy.isqrt(0), 0)
        self.assertEqual(gmpy.isqrt(1225), 35)

        self.assertTrue(gmpy.iroot(0, 10)[1])
        self.assertFalse(gmpy.iroot(1226, 2)[1])
        self.assertEqual(gmpy.iroot(1226, 2)[0], 35)
        self.assertEqual(gmpy.iroot(3**10 + 42, 10)[0], 3)
コード例 #6
0
    def sqrt(self, INV=False):
        """Modular (inverse) square roots."""
        a = self.value
        p = type(self).modulus
        if p == 2:
            return type(self)(a)
        if p & 3 == 3:
            if INV:
                q = (3 * p - 5) // 4  # a**q == a**(-1/2) == 1/sqrt(a) mod p
            else:
                q = (p + 1) // 4
            return type(self)(int(gmpy2.powmod(a, q, p)))

        # 1 (mod 4) primes are covered using Cipolla-Lehmer's algorithm.
        # find b s.t. b^2 - 4*a is not a square (maybe cache this for p)
        b = 1
        while gmpy2.legendre(b * b - 4 * a, p) != -1:
            b += 1

        # compute u*X + v = X^{(p+1)/2} mod f, for f = X^2 - b*X + a
        u, v = 0, 1
        e = (p + 1) // 2
        for i in range(e.bit_length() - 1, -1, -1):
            u2 = (u * u) % p
            u = ((u << 1) * v + b * u2) % p
            v = (v * v - a * u2) % p
            if (e >> i) & 1:
                u, v = (v + b * u) % p, (-a * u) % p
        if INV:
            return type(self)(v)._reciprocal()
        else:
            return type(self)(v)
コード例 #7
0
def find_prime_root(l, blum=True, n=1):
    """Find smallest prime of bit length l satisfying given constraints.

    Default is to return Blum primes (primes p with p % 4 == 3).
    Also, a primitive root w is returned of prime order at least n.
    """
    if l == 1:
        assert not blum
        assert n == 1
        p = 2
        w = 1
    elif n <= 2:
        n = 2
        w = -1
        p = gmpy2.next_prime(2**(l - 1))
        if blum:
            while p % 4 != 3:
                p = gmpy2.next_prime(p)
        p = int(p)
    else:
        assert blum
        if not gmpy2.is_prime(n):
            n = int(gmpy2.next_prime(n))
        p = 1 + n * (1 + (n**2) % 4 + 4 * ((2**(l - 2)) // n))
        while not gmpy2.is_prime(p):
            p += 4 * n

        a = 1
        w = 1
        while w == 1:
            a += 1
            w = gmpy2.powmod(a, (p - 1) // n, p)
        p, w = int(p), int(w)
    return p, n, w
コード例 #8
0
    def _sqrt(cls, a, INV=False):
        p = cls.modulus
        if a == 0:
            if INV:
                raise ZeroDivisionError('no inverse sqrt of 0')

            return a

        if p == 2:
            return a

        if p & 3 == 3:
            if INV:
                p4 = (p * 3 - 5) >> 2  # a**p4 == a**(-1/2) == 1/sqrt(a) mod p
            else:
                p4 = (p + 1) >> 2
            return int(gmpy2.powmod(a, p4, p))

        # 1 (mod 4) primes are covered using Cipolla-Lehmer's algorithm.
        # find b s.t. b^2 - 4*a is not a square
        b = 1
        while gmpy2.legendre(b * b - 4 * a, p) != -1:
            b += 1

        # compute u*X + v = X^{(p+1)/2} mod f, for f = X^2 - b*X + a
        u, v = 0, 1
        e = (p + 1) >> 1
        for i in range(e.bit_length() - 1, -1, -1):
            u2 = (u * u) % p
            u = ((u << 1) * v + b * u2) % p
            v = (v * v - a * u2) % p
            if (e >> i) & 1:
                u, v = (v + b * u) % p, (-a * u) % p
        if INV:
            v = cls._reciprocal(v)

        return v
コード例 #9
0
ファイル: finfields.py プロジェクト: dfischer/mpyc
    def __pow__(self, other):
        """Exponentiation."""
        if not isinstance(other, int):
            return NotImplemented

        return type(self)(int(gmpy2.powmod(self.value, other, self.modulus)))
コード例 #10
0
    def test_basic(self):
        self.assertFalse(gmpy.is_prime(1))
        self.assertTrue(gmpy.is_prime(2))
        self.assertTrue(gmpy.is_prime(101))
        self.assertFalse(gmpy.is_prime(561))
        self.assertTrue(gmpy.is_prime(2**16 + 1))
        self.assertFalse(gmpy.is_prime(41041))

        self.assertEqual(gmpy.next_prime(1), 2)
        self.assertEqual(gmpy.next_prime(2), 3)
        self.assertEqual(gmpy.next_prime(256), 257)

        self.assertEqual(gmpy.powmod(3, 256, 257), 1)

        self.assertEqual(gmpy.gcdext(3, 257), (1, 86, -1))
        self.assertEqual(gmpy.gcdext(1234, 257), (1, -126, 605))
        self.assertEqual(gmpy.gcdext(-1234 * 3, -257 * 3), (3, 126, -605))

        def te_s_t(a, b):
            g, s, t = gmpy.gcdext(a, b)
            if abs(a) == abs(b):
                test_s = s == 0
            elif b == 0 or abs(b) == 2 * g:
                test_s = s == bool(a > 0) - bool(a < 0)  # sign of a
            else:
                test_s = abs(s) < abs(b) / (2 * g)
            if abs(a) == abs(b) or a == 0 or abs(a) == 2 * g:
                test_t = t == bool(b > 0) - bool(b < 0)  # sign of b
            else:
                test_t = abs(t) < abs(a) / (2 * g)
            return g == a * s + b * t and test_s and test_t

        self.assertTrue(
            all((te_s_t(0, 0), te_s_t(0, -1), te_s_t(1, 0), te_s_t(-1, 1))))
        self.assertTrue(te_s_t(-1234, 257))
        self.assertTrue(te_s_t(-12537, -257))
        self.assertTrue(te_s_t(-11 * 1234, -11 * 2567))
        self.assertTrue(te_s_t(1234, -2 * 1234))
        self.assertTrue(te_s_t(-2 * 12364, 12364))

        # self.assertEqual(gmpy.invert(3, -1), 0)  # pending gmpy2 issue if modulus is 1 or -1
        self.assertEqual(gmpy.invert(3, 257), 86)
        self.assertRaises(ZeroDivisionError, gmpy.invert, 2, 0)
        self.assertRaises(ZeroDivisionError, gmpy.invert, 2, 4)

        self.assertEqual(gmpy.legendre(0, 101), 0)
        self.assertEqual(gmpy.legendre(42, 101), -1)
        self.assertEqual(gmpy.legendre(54, 101), 1)
        self.assertRaises(ValueError, gmpy.legendre, 1, 2)
        self.assertEqual(gmpy.jacobi(9, 99), 0)
        self.assertEqual(gmpy.jacobi(43, 99), -1)
        self.assertEqual(gmpy.jacobi(53, 99), 1)
        self.assertRaises(ValueError, gmpy.jacobi, 1, 20)
        self.assertEqual(gmpy.kronecker(0, 0), 0)
        self.assertEqual(gmpy.kronecker(-1, 0), 1)
        self.assertEqual(gmpy.kronecker(43, -98), -1)
        self.assertEqual(gmpy.kronecker(-53, -98), 1)
        self.assertEqual(gmpy.kronecker(-54, -98), 0)

        self.assertTrue(gmpy.is_square(625))
        self.assertFalse(gmpy.is_square(652))

        self.assertEqual(gmpy.isqrt(0), 0)
        self.assertEqual(gmpy.isqrt(1225), 35)

        self.assertTrue(gmpy.iroot(0, 10)[1])
        self.assertFalse(gmpy.iroot(1226, 2)[1])
        self.assertEqual(gmpy.iroot(1226, 2)[0], 35)
        self.assertEqual(gmpy.iroot(3**10 + 42, 10)[0], 3)
コード例 #11
0
 def __pow__(self, exponent):
     """Exponentiation."""
     return type(self)(int(
         gmpy2.powmod(self.value, exponent,
                      type(self).modulus)))