예제 #1
0
    def encap(cls, pk, seed=None):
        """IND-CCA encapsulation sans compression or extra hash

        :param cls: Kyber class, inherit and change constants to change defaults
        :param pk: public key
        :param seed: seed used for random sampling if provided

        .. note :: Resembles Algorithm 4 of the Kyber paper.

        """
        n = cls.n

        if seed is not None:
            set_random_seed(seed)

        m = random_vector(GF(2), n)
        m.set_immutable()
        set_random_seed(hash(m))  # NOTE: this is obviously not faithful

        K_ = random_vector(GF(2), n)
        K_.set_immutable()
        r = ZZ.random_element(0, 2**n-1)

        c = cls.enc(pk, m, r)

        K = hash((K_, c))  # NOTE: this obviously isn't a cryptographic hash
        return c, K
예제 #2
0
def gen_instance(n, q, h, alpha=None, m=None, seed=None, s=None):
    """
    Generate FHE-style LWE instance

    :param n:     dimension
    :param q:     modulus
    :param alpha: noise rate (default: 8/q)
    :param h:     hamming weight of the secret (default: 2/3n)
    :param m:     number of samples (default: n)

    """
    if seed is not None:
        set_random_seed(seed)

    q = next_prime(ceil(q) - 1, proof=False)
    if alpha is None:
        stddev = 3.2
    else:
        stddev = alpha * q / sqrt(2 * pi)

    #RR = parent(alpha*q)
    #stddev = alpha*q/RR(sqrt(2*pi))

    if m is None:
        m = n
    K = GF(q, proof=False)

    while 1:
        A = random_matrix(K, m, n)
        if A.rank() == n:
            break

    if s is not None:
        c = A * s

    else:
        if h is None:
            s = random_vector(ZZ, n, x=-1, y=1)
        else:
            S = [-1, 1]
            s = [S[randint(0, 1)] for i in range(h)]
            s += [0 for _ in range(n - h)]
            shuffle(s)
            s = vector(ZZ, s)
        c = A * s

    D = DiscreteGaussian(stddev)

    for i in range(m):
        c[i] += D()

    u = random_vector(K, m)

    print '(A, c) is n-dim LWE samples (with secret s) / (A, u) is uniform samples'

    return A, c, u, s
예제 #3
0
    def decap(cls, sk, pk, c):
        """IND-CCA decapsulation

        :param cls: Kyber class, inherit and change constants to change defaults
        :param sk: secret key
        :param pk: public key
        :param c: ciphertext

        .. note :: Resembles Algorithm 5 of the Kyber paper.

        """
        n = cls.n

        m = cls.dec(sk, c)
        m.set_immutable()
        set_random_seed(hash(m))  # NOTE: this is obviously not faithful

        K_ = random_vector(GF(2), n)
        K_.set_immutable()
        r = ZZ.random_element(0, 2**n-1)

        c_ = cls.enc(pk, m, r)

        if c == c_:
            return hash((K_, c))  # NOTE: this obviously isn't a cryptographic hash
        else:
            return hash(c)  # NOTE ignoring z
예제 #4
0
 def time_search_loop(p):
     y = random_vector(F, n)
     g = random_matrix(F, p, n).rows()
     scalars = [  [ Fstar[randint(0,q-2)] for i in range(p) ]
                      for s in range(100) ]
     before = process_time()
     for m in scalars:
         e = y - sum(m[i]*g[i] for i in range(p))
     return (process_time() - before)/100.
예제 #5
0
 def time_search_loop(p):
     y = random_vector(F, n)
     g = random_matrix(F, p, n).rows()
     scalars = [[Fstar[randint(0, q - 2)] for i in range(p)]
                for s in range(100)]
     before = time.clock()
     for m in scalars:
         e = y - sum(m[i] * g[i] for i in range(p))
         errs = e.hamming_weight()
     return (time.clock() - before) / 100.
 def time_search_loop(p):
     y = random_vector(F, n)
     g = random_matrix(F, p, n).rows()
     scalars = [  [ Fstar[randint(0,q-2)] for i in range(p) ]
                      for s in range(100) ]
     before = time.clock()
     for m in scalars:
         e = y - sum(m[i]*g[i] for i in range(p))
         errs = e.hamming_weight()
     return (time.clock() - before)/100.
예제 #7
0
def test_skipper_cpa_enc(skipper=Skipper4, kyber=Kyber, t=128, l=None, exhaustive=False):
    if not exhaustive:
        for i in range(t):
            pk, sk = kyber.key_gen(seed=i)
            m0 = random_vector(GF(2), kyber.n)
            c = skipper.enc(kyber, pk, m0, seed=i, l=l)
            m1 = kyber.dec(sk, c)
            assert(m0 == m1)
    else:
        # exhaustive test
        for i in range(16):
            pk, sk = kyber.key_gen(seed=i)
            for m0 in FreeModule(GF(2), kyber.n):
                c = skipper.enc(kyber, pk, m0, seed=i, l=l)
                m1 = kyber.dec(sk, c)
                assert(m0 == m1)
예제 #8
0
def test_kyber_cpa(cls=Kyber, t=16):
    """
    Test correctness of IND-CPA encryption/decryption.

    TESTS::

        sage: test_kyber_cpa(Kyber)
        sage: test_kyber_cpa(MiniKyber)

    .. note :: An ``AssertionError`` if decrypted plaintext does not match original.

    """
    for i in range(t):
        pk, sk = cls.key_gen(seed=i)
        m0 = random_vector(GF(2), cls.n)
        c = cls.enc(pk, m0, seed=i)
        m1 = cls.dec(sk, c)
        assert (m0 == m1)
예제 #9
0
def gen_fhe_instance(n, q, alpha=None, h=None, m=None, seed=None):
    """
    Generate FHE-style LWE instance

    :param n:     dimension
    :param q:     modulus
    :param alpha: noise rate (default: 8/q)
    :param h:     hamming weight of the secret (default: 2/3n)
    :param m:     number of samples (default: n)

    """
    if seed is not None:
        set_random_seed(seed)

    q = next_prime(ceil(q)-1, proof=False)
    if alpha is None:
        alpha = ZZ(8)/q

    n, alpha, q = preprocess_params(n, alpha, q)

    stddev = stddevf(alpha*q)

    if m is None:
        m = n
    K = GF(q, proof=False)
    A = random_matrix(K, m, n)

    if h is None:
        s = random_vector(ZZ, n, x=-1, y=1)
    else:
        S = [-1, 1]
        s = [S[randint(0, 1)] for i in range(h)]
        s += [0 for _ in range(n-h)]
        shuffle(s)
        s = vector(ZZ, s)
    c = A*s

    D = DiscreteGaussian(stddev)

    for i in range(m):
        c[i] += D()

    return A, c
예제 #10
0
def gen_fhe_instance(n, q, alpha=None, h=None, m=None, seed=None):
    """
    Generate FHE-style LWE instance

    :param n:     dimension
    :param q:     modulus
    :param alpha: noise rate (default: 8/q)
    :param h:     hamming weight of the secret (default: 2/3n)
    :param m:     number of samples (default: n)

    """
    if seed is not None:
        set_random_seed(seed)

    q = next_prime(ceil(q) - 1, proof=False)
    if alpha is None:
        alpha = ZZ(8) / q

    n, alpha, q = preprocess_params(n, alpha, q)

    stddev = stddevf(alpha * q)

    if m is None:
        m = n
    K = GF(q, proof=False)
    A = random_matrix(K, m, n)

    if h is None:
        s = random_vector(ZZ, n, x=-1, y=1)
    else:
        S = [-1, 1]
        s = [S[randint(0, 1)] for i in range(h)]
        s += [0 for _ in range(n - h)]
        shuffle(s)
        s = vector(ZZ, s)
    c = A * s

    D = DiscreteGaussian(stddev)

    for i in range(m):
        c[i] += D()

    return A, c
예제 #11
0
파일: smurf.py 프로젝트: fchapoton/Zeta
def get_totally_nonperp_vector(vectors, strategy='random'):
    """
    Construct a vector 'w' such that w * v != 0 for all v in vectors.
    """
    vectors = list(vectors)  # We want to allow generators.

    if not vectors:
        return None

    n = len(vectors[0])
    for k in (k for k in itertools.count() for _ in range((k + 1) * n)):
        if strategy == 'random':
            v = random_vector(n, x=-k, y=k + 2)
        elif strategy == 'moment':
            v = vector(ZZ, [1] + [k**i for i in range(1, n)])
        else:
            raise TypeError('unknown strategy')

        if 0 in (v * w for w in vectors):
            continue
        return v
예제 #12
0
 def keygen(self):
     return random_vector(F, self.k)
예제 #13
0
def random_vector_in_span(M, n = None):
    m = M.nrows()
    if n is None:
        n = M.ncols()
    L = random_vector(M.base_ring() ,n);
    return [ sum( [ L[j]*M[i,j] for j in range(n) ] ) for i in range(m) ]