예제 #1
0
파일: finfields.py 프로젝트: dfischer/mpyc
def pGF(modulus, f=0):
    """Create a finite field for given prime modulus."""
    if isinstance(modulus, tuple):
        p, n, w = modulus
    else:
        p = modulus
        if p == 2:
            n, w = 1, 1
        else:
            n, w = 2, -1
    if not gmpy2.is_prime(p):
        raise ValueError('modulus is not a prime')

    GFElement = type(f'GF({p})', (PrimeFieldElement, ), {'__slots__': ()})
    GFElement.modulus = p
    GFElement.order = p
    GFElement.characteristic = p
    GFElement.ext_deg = 1
    GFElement.byte_length = (GFElement.order.bit_length() + 7) >> 3
    GFElement.frac_length = f
    GFElement.rshift_factor = int(gmpy2.invert(1 << f,
                                               p))  # cache (1/2)^f mod p
    GFElement.is_signed = True
    GFElement.nth = n
    GFElement.root = w % p
    return GFElement
예제 #2
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.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)
예제 #3
0
def GF(modulus, f=0):
    """Create a Galois (finite) field for given prime modulus."""
    if isinstance(modulus, tuple):
        p, n, w = modulus
    else:
        p = modulus
        if p == 2:
            n, w = 1, 1
        else:
            n, w = 2, -1

    if (p, f) in _field_cache:
        return _field_cache[(p, f)]

    if not gmpy2.is_prime(p):
        raise ValueError(f'{p} is not a prime')

    GFElement = type(f'GF({p})', (PrimeFieldElement, ), {'__slots__': ()})
    GFElement.modulus = p
    GFElement.order = p
    GFElement.is_signed = True
    GFElement.nth = n
    GFElement.root = w % p
    GFElement.frac_length = f
    GFElement.rshift_factor = int(gmpy2.invert(1 << f,
                                               p))  # cache (1/2)^f mod p
    _field_cache[(p, f)] = GFElement
    return GFElement
예제 #4
0
파일: finfields.py 프로젝트: dfischer/mpyc
    def __rshift__(self, other):
        """Right shift."""
        if not isinstance(other, int):
            return NotImplemented

        if other == self.frac_length:
            rsf = self.rshift_factor
        else:
            rsf = int(gmpy2.invert(1 << other, self.modulus))
        return type(self)(self.value * rsf)
예제 #5
0
파일: finfields.py 프로젝트: dfischer/mpyc
    def __irshift__(self, other):
        if not isinstance(other, int):
            return NotImplemented

        if other == self.frac_length:
            rsf = self.rshift_factor
        else:
            rsf = int(gmpy2.invert(1 << other, self.modulus))
        self.value *= rsf
        self.value %= self.modulus
        return self
예제 #6
0
    def _gcd(cls, a, b):
        p = cls.p
        while b:
            a, b = b, cls._mod(a, b)

        # ensure monic a
        if a and a[-1] != 1:
            a1 = int(gmpy2.invert(a[-1], p))
            for i in range(len(a) - 1):
                a[i] *= a1
                a[i] %= p
            a[-1] = 1
        return a
예제 #7
0
파일: dsa.py 프로젝트: lschoe/mpyc
    def verify(self, M, S):
        """DSA signature verification."""
        g = self.group.generator
        q = self.group.order
        H = self.H
        y = self.y
        r, s = S

        if not (0 < r < q and 0 < s < q):
            return False

        w = int(invert(s, q))  # s^-1 mod q
        u_1 = H(M)*w % q
        u_2 = r*w % q
        v = self.to_int((g^u_1) @ (y^u_2)) % q
        return v == r
예제 #8
0
    def _invert(cls, a, b):
        p = cls.p
        if b == []:
            raise ZeroDivisionError('division by zero polynomial')

        s, s1 = [1], []
        while b:
            a, (q, b) = b, cls._divmod(a, b)
            s, s1 = s1, cls._sub(s, cls._mul(q, s1))
        if len(a) != 1:
            raise ZeroDivisionError('inverse does not exist')

        # ensure monic a
        a1 = int(gmpy2.invert(a[0], p))
        for i in range(len(s)):
            s[i] *= a1
            s[i] %= p
        return s
예제 #9
0
def pGF(p, f, n, w):
    """Create a finite field for given prime modulus p."""
    if not gmpy2.is_prime(p):
        raise ValueError('modulus is not a prime')

    GFp = type(f'GF({p})', (PrimeFieldElement, ), {'__slots__': ()})
    GFp.__doc__ = 'Class of prime field elements.'
    GFp.modulus = p
    GFp.order = p
    GFp.characteristic = p
    GFp.ext_deg = 1
    GFp.byte_length = (GFp.order.bit_length() + 7) >> 3
    GFp._frac_length = f
    GFp._rshift_factor = int(gmpy2.invert(1 << f, p))  # cache (1/2)^f mod p
    GFp.is_signed = True
    GFp.nth = n
    GFp.root = w % p
    return GFp
예제 #10
0
    def _divmod(cls, a, b):
        p = cls.p
        if b == []:
            raise ZeroDivisionError('division by zero polynomial')

        m = len(a)
        n = len(b)
        if m < n:
            return [], a[:]

        b1 = int(gmpy2.invert(b[-1], p))
        q, r = [0] * (m - n + 1), a[:]
        for i in range(m - n, -1, -1):
            if len(r) >= i + n:
                q[i] = q_i = (r[-1] * b1) % p
                for j in range(n):
                    r[i + j] -= q_i * b[j]
                    r[i + j] %= p
                while r and not r[-1]:
                    r.pop()
        return q, r
예제 #11
0
    def _gcdext(cls, a, b):
        p = cls.p
        s, s1 = [1], []
        t, t1 = [], [1]
        while b:
            a, (q, b) = b, cls._divmod(a, b)
            s, s1 = s1, cls._sub(s, cls._mul(q, s1))
            t, t1 = t1, cls._sub(t, cls._mul(q, t1))

        # ensure monic a
        if a and a[-1] != 1:
            a1 = int(gmpy2.invert(a[-1], p))
            for i in range(len(a) - 1):
                a[i] *= a1
                a[i] %= p
            a[-1] = 1
            for i in range(len(s)):
                s[i] *= a1
                s[i] %= p
            for i in range(len(t)):
                t[i] *= a1
                t[i] %= p
        return a, s, t
예제 #12
0
    def _mod(cls, a, b):
        p = cls.p
        if b is None:  # see _powmod()
            return a  # NB: in-place

        if b == []:
            raise ZeroDivisionError('division by zero polynomial')

        m = len(a)
        n = len(b)
        if m < n:
            return a[:]

        b1 = int(gmpy2.invert(b[-1], p))
        r = a[:]
        for i in range(m - n, -1, -1):
            if len(r) >= i + n:
                q_i = (r[-1] * b1) % p
                for j in range(n):
                    r[i + j] -= q_i * b[j]
                    r[i + j] %= p
                while r and not r[-1]:
                    r.pop()
        return r
예제 #13
0
파일: finfields.py 프로젝트: dfischer/mpyc
 def reciprocal(self):
     """Multiplicative inverse."""
     return type(self)(int(gmpy2.invert(self.value, self.modulus)))
예제 #14
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)
예제 #15
0
 def _reciprocal(cls, a):
     return int(gmpy2.invert(a, cls.modulus))