示例#1
0
文件: fingroups.py 项目: lschoe/mpyc
def ClassGroup(Delta=None, l=None):
    """Create type for class group, given (bit length l of) discriminant Delta.

    The following conditions are imposed on discriminant Delta:

        - Delta < 0, only supporting class groups of imaginary quadratic field
        - Delta = 1 (mod 4), preferably Delta = 1 (mod 8)
        - -Delta is prime

    This implies that Delta is a fundamental discriminant.
    """
    if l is not None:
        if Delta is None:
            # find fundamental discriminant Delta of bit length l >= 2
            p = next_prime(1 << l-1)
            while p != 3 and p != 11 and p%8 != 7:
                p = next_prime(p)
            Delta = int(-p)  # D = 1 mod 4, and even D = 1 mod 8 if possible (and -D is prime)
    elif Delta is None:
        Delta = -3
    if Delta%4 != 1:
        raise ValueError('discriminant required to be 1 modulo 4, preferably 1 modulo 8')

    if Delta >= 0 or not is_prime(-Delta):
        raise ValueError('negative prime discriminant required')

    return _ClassGroup(Delta)
示例#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 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
示例#4
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)
示例#5
0
def _find_safe_prime(l):
    """Find safe prime p of bit length l, l>=2.

    Hence, q=(p-1)/2 is also prime (except when l=2 and p=3).
    It is also ensured that p=3 (mod 4), hence p is a Blum prime.
    """
    IKE_options_l_k = {
        768: 149686,
        1024: 129093,
        1536: 741804,
        2048: 124476,
        3072: 1690314,
        4096: 240904,
        6144: 929484,
        8192: 4743158
    }
    if l in IKE_options_l_k:
        # Compute pi to the required precision.
        decimal.setcontext(decimal.Context(prec=round(l / math.log2(10))))
        # See https://docs.python.org/3/library/decimal.html for following recipe:
        decimal.getcontext().prec += 2  # extra digits for intermediate steps
        three = decimal.Decimal(3)
        lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 24
        while s != lasts:
            lasts = s
            n, na = n + na, na + 8
            d, da = d + da, da + 32
            t = (t * n) / d
            s += t
        decimal.getcontext().prec -= 2
        pi_l = +s  # NB: unary plus applies the new precision

        # Following https://kivinen.iki.fi/primes to compute IKE prime p:
        k = IKE_options_l_k[l]
        fixedbits = 64
        epi = math.floor(pi_l * 2**(l - 2 * fixedbits - 2)) + k
        p = 2**l - 2**(l - fixedbits) - 1 + epi * 2**fixedbits
    else:
        if l == 2:
            p = 3
        else:
            q = next_prime(1 << l - 2)
            while not is_prime(2 * q + 1):
                q = next_prime(q)
            # q is a Sophie Germain prime
            p = int(2 * q + 1)
    return p
示例#6
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)
示例#7
0
def SecFld(order=None,
           modulus=None,
           char=None,
           ext_deg=None,
           min_order=None,
           signed=False):
    """Secure finite field of order q = p**d.

    Order q >= min_order.
    Field is prime (d = 1) by default and if modulus is prime.
    Extension degree d > 1 if order is a prime power p**d with d > 1,
    if modulus is a polynomial or a string or an integer > char,
    or if ext_deg is an integer > 1, or if min_order > char.
    """
    # TODO: raise errors instead of assert statements
    if order is not None:
        p, d = gmpy2.factor_prime_power(order)
        char = char or p
        assert char == p
        ext_deg = ext_deg or d
        assert ext_deg == d
    # order now represented by (char, ext_deg)

    if isinstance(modulus, str):
        char = char or 2
        modulus = gfpx.GFpX(char)(modulus)
    if isinstance(modulus, int):
        if char and modulus > char:
            modulus = gfpx.GFpX(char)(modulus)
    if isinstance(modulus, gfpx.Polynomial):
        char = char or modulus.p
        assert char == modulus.p
        ext_deg = ext_deg or modulus.degree()
    elif isinstance(modulus, int):
        char = char or modulus
        assert char == modulus
        ext_deg = ext_deg or 1
        assert ext_deg == 1
    else:
        assert modulus is None
        if min_order is None:
            char = char or 2
            ext_deg = ext_deg or 1
            min_order = char**ext_deg
        else:
            if char is None:
                ext_deg = ext_deg or 1
                root, exact = gmpy2.iroot(min_order, ext_deg)
                min_char = root + (not exact
                                   )  # ceiling of min_order^(1/ext_deg)
                char = int(gmpy2.next_prime(min_char - 1))
            else:
                if ext_deg is None:
                    ext_deg = math.ceil(math.log(min_order, char))

        if ext_deg == 1:
            modulus = char
        else:
            modulus = finfields.find_irreducible(char, ext_deg)

    order = order or char**ext_deg
    min_order = min_order or order
    assert min_order <= order
    field = finfields.GF(modulus)
    assert runtime.threshold == 0 or field.order > len(runtime.parties), \
        'Field order must exceed number of parties, unless threshold is 0.'
    # TODO: field.order >= number of parties for MDS
    field.is_signed = signed
    return _SecFld(field)
示例#8
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)