示例#1
0
def _SecFld(field):
    l = (field.order - 1).bit_length()
    name = f'SecFld{l}({field.__name__})'
    secfld = type(name, (SecureFiniteField, ), {'__slots__': ()})
    secfld.__doc__ = 'Class of secret-shared finite field elements.'
    t = runtime.threshold
    m = len(runtime.parties)
    q = field.order
    if t == 0 or m < q:  # TODO: cover case m=q using MDS codes
        secfld.subfield = None
        secfld.field = field
    else:
        secfld.subfield = field
        assert field.ext_deg == 1  # TODO: cover case ext_deg > 1
        e = math.ceil(math.log(m + 1, q))  # ensure q**e > m with e>=2
        modulus = finfields.find_irreducible(field.characteristic, e)
        secfld.field = finfields.GF(modulus)

        @classmethod
        def out_conv(cls, a):  # field -> subfield
            assert a.value.degree() <= 0
            return cls.subfield(int(a))

        secfld._output_conversion = out_conv
    secfld.bit_length = l
    globals(
    )[name] = secfld  # TODO: check name dynamic SecureFiniteField type sufficiently unique
    return secfld
示例#2
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)