Beispiel #1
0
    def test_secfld(self):
        secfld = mpc.SecFld(2, char=2)
        a = getrandbits(secfld, 1, True)
        a = mpc.run(mpc.output(a))
        self.assertGreaterEqual(int(a[0]), 0)
        self.assertLessEqual(int(a[0]), 1)

        secfld = mpc.SecFld(3)
        a = getrandbits(secfld, 1)
        a = mpc.run(mpc.output(a))
        self.assertGreaterEqual(int(a), 0)
        self.assertLessEqual(int(a), 1)
        a = mpc.run(mpc.output(randrange(secfld, 1, 3)))
        self.assertGreaterEqual(int(a), 1)
        self.assertLessEqual(int(a), 2)

        secfld = mpc.SecFld(256)
        a = getrandbits(secfld, 8)
        a = mpc.run(mpc.output(a))
        self.assertGreaterEqual(int(a), 0)
        self.assertLessEqual(int(a), 2**8 - 1)
        a = mpc.run(mpc.output(randrange(secfld, 256)))
        self.assertGreaterEqual(int(a), 0)
        self.assertLessEqual(int(a), 2**8 - 1)
        a = mpc.run(mpc.output(randint(secfld, 0, 2)))
        self.assertIn(a, [0, 1, 2])
        x = mpc.run(mpc.output(random_unit_vector(secfld, 2)))
        self.assertEqual(int(sum(x)), 1)
        x = mpc.run(mpc.output(random_permutation(secfld, range(1, 9))))
        self.assertSetEqual(set(map(int, x)), set(range(1, 9)))
        x = mpc.run(mpc.output(random_derangement(secfld, range(2))))
        self.assertListEqual(list(map(int, x)), [1, 0])

        secfld = mpc.SecFld(257)
        a = getrandbits(secfld, 8)
        a = mpc.run(mpc.output(a))
        self.assertGreaterEqual(int(a), 0)
        self.assertLessEqual(int(a), 2**8 - 1)
        a = mpc.run(mpc.output(randrange(secfld, 257)))
        self.assertGreaterEqual(int(a), 0)
        self.assertLessEqual(int(a), 2**8)
        a = mpc.run(mpc.output(randint(secfld, -1, 1)))
        self.assertIn(a, [-1, 0, 1])
        x = mpc.run(mpc.output(random_unit_vector(secfld, 1)))
        self.assertEqual(int(sum(x)), 1)
        x = mpc.run(mpc.output(random_permutation(secfld, range(1, 9))))
        self.assertSetEqual(set(map(int, x)), set(range(1, 9)))
        x = mpc.run(mpc.output(random_derangement(secfld, range(2))))
        self.assertListEqual(list(map(int, x)), [1, 0])
Beispiel #2
0
    def test_secfld(self):
        secfld = mpc.SecFld(2, char2=True)
        a = getrandbits(secfld, 1)
        a = mpc.run(mpc.output(a))
        self.assertGreaterEqual(int(a), 0)
        self.assertLessEqual(int(a), 1)

        secfld = mpc.SecFld(3)
        a = getrandbits(secfld, 1)
        a = mpc.run(mpc.output(a))
        self.assertGreaterEqual(int(a), 0)
        self.assertLessEqual(int(a), 1)
        a = mpc.run(mpc.output(randrange(secfld, 1, 3)))
        self.assertGreaterEqual(int(a), 1)
        self.assertLessEqual(int(a), 2)

        secfld = mpc.SecFld(256)
        a = getrandbits(secfld, 8)
        a = mpc.run(mpc.output(a))
        self.assertGreaterEqual(int(a), 0)
        self.assertLessEqual(int(a), 2**8 - 1)
        a = mpc.run(mpc.output(randrange(secfld, 256)))
        self.assertGreaterEqual(int(a), 0)
        self.assertLessEqual(int(a), 2**8 - 1)
        a = mpc.run(mpc.output(randint(secfld, 0, 2)))
        self.assertIn(a, [0, 1, 2])
        x = mpc.run(mpc.output(random_unit_vector(secfld, 6)))
        self.assertEqual(int(sum(x)), 1)
        x = mpc.run(mpc.output(random_permutation(secfld, range(1, 9))))
        self.assertSetEqual({a for a in range(1, 9)}, {int(a) for a in x})
        x = mpc.run(mpc.output(random_derangement(secfld, range(2))))
        self.assertListEqual([1, 0], [int(a) for a in x])

        secfld = mpc.SecFld(257)
        a = getrandbits(secfld, 8)
        a = mpc.run(mpc.output(a))
        self.assertGreaterEqual(int(a), 0)
        self.assertLessEqual(int(a), 2**8 - 1)
        a = mpc.run(mpc.output(randrange(secfld, 257)))
        self.assertGreaterEqual(int(a), 0)
        self.assertLessEqual(int(a), 2**8)
        a = mpc.run(mpc.output(randint(secfld, -1, 1)))
        self.assertIn(a, [-1, 0, 1])
        x = mpc.run(mpc.output(random_unit_vector(secfld, 6)))
        self.assertEqual(int(sum(x)), 1)
        x = mpc.run(mpc.output(random_permutation(secfld, range(1, 9))))
        self.assertSetEqual({a for a in range(1, 9)}, {int(a) for a in x})
        x = mpc.run(mpc.output(random_derangement(secfld, range(2))))
        self.assertListEqual([1, 0], [int(a) for a in x])
Beispiel #3
0
    def test_secfxp(self):
        secfxp = mpc.SecFxp()
        a = getrandbits(secfxp, 10)
        self.assertTrue(a.integral)
        a = mpc.run(mpc.output(a))
        self.assertGreaterEqual(int(a), 0)
        self.assertLessEqual(int(a), 2**10 - 1)

        x = mpc.run(mpc.output(random_unit_vector(secfxp, 3)))
        self.assertEqual(int(sum(x)), 1)

        x = mpc.run(mpc.output(random_permutation(secfxp, range(1, 9))))
        self.assertSetEqual(set(map(int, x)), set(range(1, 9)))
        x = mpc.run(mpc.output(random_derangement(secfxp, [0.0, 1.0])))
        self.assertListEqual(list(map(int, x)), [1, 0])

        a = mpc.run(mpc.output(choice(secfxp, [0.08, 0.09, 0.1, 0.11, 0.12])))
        self.assertAlmostEqual(a, 0.1, 1)

        a = mpc.run(mpc.output(random(secfxp)))
        self.assertGreaterEqual(a, 0)
        self.assertLessEqual(a, 1)
        a = mpc.run(mpc.output(uniform(secfxp, 13.13, 13.17)))
        self.assertGreaterEqual(a, 13.13)
        self.assertLessEqual(a, 13.17)
        a = mpc.run(mpc.output(uniform(secfxp, -13.13, -13.17)))
        self.assertGreaterEqual(a, -13.17)
        self.assertLessEqual(a, -13.13)
Beispiel #4
0
async def _quickselect(x, k):
    """Return kth order statistic, 0 <= k < n with n=len(x).

    If all elements of x are distinct, no information on x is leaked.
    If x contains duplicate elements, ties in comparisons are broken evenly, which
    ultimately leaks some information on the distribution of duplicate elements.

    Average running time (dominated by number of secure comparisons, and number of
    conversions of integer indices to unit vectors) is linear in n.
    """
    stype = type(x[0])
    await runtime.returnType(stype)
    n = len(x)
    if n == 1:
        return x[0]

    f = stype.field.frac_length
    y = runtime.random_bits(stype, n)
    p = runtime.in_prod(x, random.random_unit_vector(stype, n))  # random pivot
    z = [(x[i] - p) * 2 < y[i] * 2**-f
         for i in range(n)]  # break ties x[i] == p uniformly at random
    s = int(await runtime.output(runtime.sum(z)))
    if k >= s:  # take complement
        k = k - s
        z = [1 - a for a in z]
        s = n - s
    # 0 <= k < s
    w = [stype(0)] * s
    for i in range(n):
        j = runtime.sum(z[:i + 1])  # 0 <= j <= s
        u = runtime.unit_vector(j,
                                s)  # TODO: exploit that j <= i+1 to shorten u
        v = runtime.scalar_mul(z[i] * x[i], u)
        w = runtime.vector_add(w, v)
    return _quickselect(w, k)
Beispiel #5
0
    def test_secfxp(self):
        secfxp = mpc.SecFxp()
        a = getrandbits(secfxp, 10)
        self.assertTrue(a.integral)
        a = mpc.run(mpc.output(a))
        self.assertGreaterEqual(int(a), 0)
        self.assertLessEqual(int(a), 2**10 - 1)

        x = mpc.run(mpc.output(random_unit_vector(secfxp, 6)))
        self.assertEqual(int(sum(x)), 1)

        x = mpc.run(mpc.output(random_permutation(secfxp, range(1, 9))))
        self.assertSetEqual({a for a in range(1, 9)}, {int(a) for a in x})
        x = mpc.run(mpc.output(random_derangement(secfxp, range(2))))
        self.assertListEqual([1, 0], [int(a) for a in x])

        a = mpc.run(mpc.output(choice(secfxp, [0.8, 0.9, 1.0, 1.1, 1.2])))
        self.assertAlmostEqual(float(a), 1.0, 0)
        a = mpc.run(mpc.output(choice(secfxp, [0.08, 0.09, 0.1, 0.11, 0.12])))
        self.assertAlmostEqual(float(a), 0.1, 1)

        a = mpc.run(mpc.output(random(secfxp)))
        self.assertGreaterEqual(float(a), 0)
        self.assertLessEqual(float(a), 1)
        a = mpc.run(mpc.output(uniform(secfxp, 13.13, 13.17)))
        self.assertGreaterEqual(float(a), 13.13)
        self.assertLessEqual(float(a), 13.17)
        a = mpc.run(mpc.output(uniform(secfxp, -13.13, -13.17)))
        self.assertGreaterEqual(float(a), -13.17)
        self.assertLessEqual(float(a), -13.13)
Beispiel #6
0
 def random(sectype, length, offset=0):
     n = length
     return secindex(random_unit_vector(sectype, n), offset=offset)
Beispiel #7
0
    def test_secint(self):
        secint = mpc.SecInt()
        a = mpc.run(mpc.output(getrandbits(secint, 10)))
        self.assertGreaterEqual(a, 0)
        self.assertLessEqual(a, 2**10 - 1)

        x = mpc.run(mpc.output(random_unit_vector(secint, 4)))
        self.assertEqual(sum(x), 1)

        a = mpc.run(mpc.output(randrange(secint, 37)))  # French roulette
        self.assertGreaterEqual(a, 0)
        self.assertLessEqual(a, 36)
        a = mpc.run(mpc.output(randrange(secint, 1, 7)))  # one die
        self.assertGreaterEqual(a, 1)
        self.assertLessEqual(a, 6)
        a = mpc.run(mpc.output(randrange(secint, 1, 7) + randrange(secint, 1, 7)))  # two dice
        self.assertGreaterEqual(a, 2)
        self.assertLessEqual(a, 12)
        a = mpc.run(mpc.output(randrange(secint, 1, 32, 2)))
        self.assertGreaterEqual(a, 1)
        self.assertLessEqual(a, 31)
        self.assertEqual(a % 2, 1)
        a = mpc.run(mpc.output(randint(secint, -1, 1)))
        self.assertIn(a, [-1, 0, 1])

        x = list(range(8))
        shuffle(secint, x)
        shuffle(secint, x)
        x = mpc.run(mpc.output(x))
        self.assertSetEqual(set(x), set(range(8)))
        x = mpc.run(mpc.output(random_permutation(secint, 8)))
        self.assertSetEqual(set(x), set(range(8)))
        x = mpc.run(mpc.output(random_derangement(secint, 2)))
        self.assertListEqual(x, [1, 0])
        x = mpc.run(mpc.output(random_derangement(secint, range(1, 9))))
        self.assertSetEqual(set(x), set(range(1, 9)))

        x = mpc.run(mpc.output(choice(secint, [1, 2, 3, 4, 5])))
        self.assertIn(x, [1, 2, 3, 4, 5])
        x = mpc.run(mpc.output(choice(secint, [secint(-100), secint(200), secint(-300)])))
        self.assertIn(x, [-100, 200, -300])
        x = mpc.run(mpc.output(mpc.sum(choices(secint, [0, 1], k=5))))  # uniform
        self.assertGreaterEqual(x, 0)
        self.assertLessEqual(x, 5)
        x = mpc.run(mpc.output(mpc.sum(choices(secint, [0, 1], [25, 75]))))  # Bernoulli
        self.assertGreaterEqual(x, 0)
        self.assertLessEqual(x, 1)
        x = mpc.run(mpc.output(mpc.sum(choices(secint, [0, 1], [25, 75], k=10))))  # binomial
        self.assertGreaterEqual(x, 0)
        self.assertLessEqual(x, 10)

        x = mpc.run(mpc.output(sample(secint, [2**i for i in range(16)], 8)))
        self.assertGreaterEqual(sum(x), 2**8 - 1)
        self.assertLessEqual(sum(x), 2**8 * (2**8 - 1))
        x = mpc.run(mpc.output(sample(secint, range(10**8), 10)))
        self.assertGreaterEqual(min(x), 0)
        self.assertLessEqual(max(x), 10**8 - 1)

        x = mpc.run(mpc.output(sample(secint, range(1000000, 3000000, 1000), 10)))
        self.assertGreaterEqual(min(x) // 1000, 1000)
        self.assertLessEqual(max(x) // 1000, 3000)
        self.assertEqual(sum(x) % 1000, 0)
Beispiel #8
0
async def _quickselect(x, ks):
    """Return kth order statistics for k in ks, where 0 <= k < n with n=len(x).

    If all elements of x are distinct, no information on x is leaked.
    If x contains duplicate elements, ties in comparisons are broken evenly, which
    ultimately leaks some information on the distribution of duplicate elements.

    Average running time (dominated by number of secure comparisons, and number of
    conversions of integer indices to unit vectors) is linear in n, for fixed ks.
    """
    # TODO: consider adding case ks is an int instead of a list
    # TODO: try to make implementation below competitive with straightforward "sort and pick"
    # approach; slowness due to expensive computation of w_left (and w_right). Also note
    # advantage of sorting that there is no privacy leakage.
    if len(ks) >= 3:
        y = runtime.sorted(x)
        return [y[k] for k in ks]

    if not ks:
        return []

    n = len(x)
    if n == 1:
        return [x[0]]

    sectype = type(x[0])
    await runtime.returnType(sectype, len(ks))

    f = sectype.frac_length
    while True:
        y = runtime.random_bits(sectype, n)
        p = runtime.in_prod(x, random.random_unit_vector(sectype, n))  # random pivot
        z = [2*(x[i] - p) < y[i] * 2**-f for i in range(n)]  # break ties x[i] == p evenly
        s = int(await runtime.output(runtime.sum(z)))
        if 0 < s < n:
            break

    ks_left = [k for k in ks if k < s]
    ks_right = [k - s for k in ks if k >= s]
    if not ks_left:
        ks_left = ks_right
        ks_right = []
        z = [1-a for a in z]
        s = n - s
    zx = runtime.schur_prod(z, x)
    sectype_0 = sectype(0)
    w_left = [sectype_0] * s
    if ks_right:
        w_right = [sectype_0] * (n - s)
    for i in range(n):
        j = runtime.sum(z[:i+1])  # 0 <= j <= i+1
        m = min(i+2, s)  # i+2 to avoid wrap around when i+1 < s still
        u_left = runtime.unit_vector(j, m)
        v_left = runtime.scalar_mul(zx[i], u_left)
        v_left.extend([sectype_0] * (s - m))
        w_left = runtime.vector_add(w_left, v_left)
        if ks_right:  # TODO: save some work by computing w_left and w_right together
            j = i+1 - j
            m = min(i+2, n - s)  # i+2 to avoid wrap around when i+1 < n - s still
            u_right = runtime.unit_vector(j, m)
            v_right = runtime.scalar_mul(x[i] - zx[i], u_right)
            v_right.extend([sectype_0] * (n - s - m))
            w_right = runtime.vector_add(w_right, v_right)
    w = _quickselect(w_left, ks_left)
    if ks_right:
        w.extend(_quickselect(w_right, ks_right))
    return w
Beispiel #9
0
 def choice(self):
     length = len(self.samples)
     included = random_unit_vector(secint, length)
     selected = [self.samples[i] * included[i] for i in range(length)]
     return reduce(operator.add, selected)