예제 #1
0
def agg_logrank_test(secfxp, d1, d2, n1, n2, agg_d1, agg_d2, stride):
    candidates = []
    maxT = len(d1)
    for start in range(0, maxT, stride):
        group = start // stride
        n_observed_events = agg_d1[group] + agg_d2[group]
        msn = min(stride, n_observed_events)  # upper bound
        stop = min(start + stride, maxT)
        logging.info(f'Interval {group + 1} (time {start + 1} to {stop})'
                     f' # observed events = {n_observed_events}')
        if msn == 0:
            continue

        oblivious_table = [[secfxp(0), secfxp(0), secfxp(1), secfxp(1)]] * msn
        ix = [secfxp(0)] * msn
        for j in range(start, stop):
            is_active = d1[j] + d2[j] != 0
            ix = mpc.if_else(is_active, [1 - mpc.sum(ix)] + ix[:-1], ix)
            select = mpc.scalar_mul(is_active, ix)
            new = [d1[j], d2[j], n1[j], n2[j]]
            for i in range(msn):
                oblivious_table[i] = mpc.if_else(select[i], new,
                                                 oblivious_table[i])
        candidates.extend(oblivious_table)
    return logrank_test(secfxp, *zip(*candidates))
예제 #2
0
 def __lt__(
         self, other
 ):  # NB: __lt__() is basic comparison as in Python's list.sort()
     c = mpc.in_prod([self.n, -self.d], [other.d, other.n]) < 0
     c = mpc.if_else(self.pos, c, 0)
     c = mpc.if_else(other.pos, c, 1)
     return c
예제 #3
0
 def test_if_else_if_swap(self):
     secfld = mpc.SecFld()
     a = secfld(0)
     b = secfld(1)
     c = secfld(1)
     self.assertEqual(mpc.run(mpc.output(c.if_else(a, b))), 0)
     self.assertEqual(mpc.run(mpc.output(mpc.if_swap(1 - c, a, b))), [0, 1])
     self.assertEqual(mpc.run(mpc.output(mpc.if_else(c, [a, b], [b, a]))),
                      [0, 1])
     self.assertEqual(mpc.run(mpc.output((1 - c).if_swap(a, b))), [0, 1])
     secint = mpc.SecInt()
     a = secint(-1)
     b = secint(1)
     c = secint(1)
     self.assertEqual(mpc.run(mpc.output(c.if_swap([a, b], [b, a])[0])),
                      [1, -1])
     self.assertEqual(mpc.run(mpc.output(mpc.if_else(1 - c, b, b))), 1)
     self.assertEqual(mpc.run(mpc.output(mpc.if_swap(c, a, b))), [1, -1])
     self.assertEqual(mpc.run(mpc.output((1 - c).if_else([a, b], [b, a]))),
                      [1, -1])
     secfxp = mpc.SecFxp()
     a = secfxp(-1.0)
     b = secfxp(1.0)
     c = secfxp(1)
     self.assertEqual(mpc.run(mpc.output(c.if_else([a, a], [b, b]))),
                      [-1.0, -1.0])
     self.assertEqual(mpc.run(mpc.output(mpc.if_swap(1 - c, a, b))),
                      [-1.0, 1.0])
     self.assertEqual(mpc.run(mpc.output(mpc.if_swap(c, 0.0, 1.0))),
                      [1.0, 0.0])
     self.assertEqual(mpc.run(mpc.output((1 - c).if_else(0.0, 1.0))), 1.0)
예제 #4
0
def argmax(x):
    argmax = type(x[0])(0)
    m = x[0]
    for i in range(1, len(x)):
        b = (m >= x[i])
        argmax = mpc.if_else(b, argmax, i)
        m = mpc.if_else(b, m, x[i])
    return argmax
예제 #5
0
def argmax(xs, arg_ge):
    n = len(xs)
    if n == 1:
        return secint(0), xs[0]

    i0, max0 = argmax(xs[:n // 2], arg_ge)
    i1, max1 = argmax(xs[n // 2:], arg_ge)
    a, m = arg_ge(max0, max1)
    return mpc.if_else(a, n // 2 + i1, i0), m
예제 #6
0
def calculate_gains_for_thresholds(column, outcomes):
    gains = column.map(lambda _: None)
    is_right = column.map(lambda _: s(0))
    selection = [None for _ in range(len(column.values))]
    last_considered_value = s(-1)
    for index in reversed(range(len(column.values))):
        gains.values[index] = calculate_gain(is_right, outcomes)
        is_right.values[index] = s(1)
        is_duplicate = column.values[index] == last_considered_value
        selection[index] = ~is_duplicate
        last_considered_value = mpc.if_else(column.is_included(index),
                                            column.values[index],
                                            last_considered_value)
    return gains.select(selection)
예제 #7
0
# computes a database join function (sums by category)
# this code is written as a script, so we call mpc.run() on each individual mpc operation instead of
# calling it once on the whole operation as in mult3, innerprod
#
# this code was contributed by Berry Schoenmakers via private correspondence
#

from mpyc.runtime import mpc
from mpyc.seclists import seclist
secint = mpc.SecInt()

N = 25  # number of samples
C = 4  # number of categories

# deterministic input data
# (no mpc.input to assign different inputs to different parties)
categories = [(secint(i), secint(i % C)) for i in range(N)]
values = [(secint(i), secint(i)) for i in range(N)]

mpc.run(mpc.start())

s = seclist([0] * C, secint)

for i, c in categories:
    for j, v in values:
        s[c] += mpc.if_else(i == j, v, 0)

print(mpc.run(mpc.output(list(s))))

mpc.run(mpc.shutdown())
예제 #8
0
async def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '-i',
        '--dataset',
        type=int,
        metavar='I',
        help=('dataset 0=uvlp (default), 1=wiki, 2=tb2x2, 3=woody, '
              '4=LPExample_R20, 5=sc50b, 6=kb2, 7=LPExample'))
    parser.add_argument('-l',
                        '--bit-length',
                        type=int,
                        metavar='L',
                        help='override preset bit length for dataset')
    parser.set_defaults(dataset=0, bit_length=0)
    args = parser.parse_args()

    settings = [('uvlp', 24, 37 / 3), ('wiki', 24, 20), ('tb2x2', 18, 10.5),
                ('woody', 36, 540), ('LPExample_R20', 52, 3.441176),
                ('sc50b', 52, 70), ('kb2', 96, 1749.9204734889486),
                ('LPExample', 96, 1188806595)]
    name, bit_length, exact_max = settings[args.dataset]
    if args.bit_length:
        bit_length = args.bit_length

    with open(os.path.join('data', 'lp', name + '.csv')) as file:
        T = list(csv.reader(file))
    m = len(T) - 1
    n = len(T[0]) - 1
    secfxp = mpc.SecFxp(bit_length)
    print(
        f'Using secure {bit_length}-bit fixed-point numbers: {secfxp.__name__}'
    )
    print(f'dataset: {name} with {m} constraints and {n} variables')
    T[0][-1] = '0'  # initialize optimal value
    for i in range(m + 1):
        for j in range(n + 1):
            T[i][j] = secfxp(float(T[i][j]), integral=False)

    c = T[0][:-1]  # maximize c.x subject to A.x <= b, x >= 0
    A = [T[i + 1][:-1] for i in range(m)]
    b = [T[i + 1][-1] for i in range(m)]

    await mpc.start()

    cobasis = [secfxp(j) for j in range(n)]
    basis = [secfxp(n + i) for i in range(m)]

    iteration = 0
    while True:
        # find index of pivot column
        p_col_index, minimum = argmin_int(T[0][:-1])

        if await mpc.output(minimum >= 0):
            break  # maximum reached

        # find index of pivot row
        p_col = mpc.matrix_prod([p_col_index], T, True)[0]
        constraints = [[T[i][-1], p_col[i], p_col[i] > 0.0001]
                       for i in range(1, m + 1)]
        p_row_index, (_, pivot, _) = argmin_rat(constraints)

        # reveal progress a bit
        iteration += 1
        mx = await mpc.output(T[0][-1])
        p = await mpc.output(pivot)
        logging.info(f'Iteration {iteration}: {mx} pivot={p}')

        # swap basis entries
        delta = mpc.in_prod(basis, p_row_index) - mpc.in_prod(
            cobasis, p_col_index)
        cobasis = mpc.vector_add(cobasis, mpc.scalar_mul(delta, p_col_index))
        basis = mpc.vector_sub(basis, mpc.scalar_mul(delta, p_row_index))

        # update tableau Tij = Tij - (Til - bool(i==k))/Tkl * (Tkj + bool(j==l))
        p_col_index.append(secfxp(0))
        p_row_index.insert(0, secfxp(0))
        p_col = mpc.vector_sub(p_col, p_row_index)
        p_col = mpc.scalar_mul(1 / pivot, p_col)
        p_row = mpc.matrix_prod([p_row_index], T)[0]
        p_row = mpc.vector_add(p_row, p_col_index)
        T = mpc.gauss(T, secfxp(1), p_col, p_row)

    mx = await mpc.output(T[0][-1])
    rel_error = (mx - exact_max) / exact_max
    print(f'max = {mx} (error {rel_error:.3%}) in {iteration} iterations')

    logging.info('Solution x')
    x = [secfxp(0) for _ in range(n)]
    for i in range(m):
        u = mpc.unit_vector(basis[i], m + n)[:n]
        v = mpc.scalar_mul(T[i + 1][-1], u)
        x = mpc.vector_add(x, v)
    cx = mpc.in_prod(c, x)
    Ax = mpc.matrix_prod([x], A, True)[0]
    approx = lambda a: 1.01 * a + 0.0001
    Ax_bounded_by_b = mpc.all(Ax[i] <= approx(b[i]) for i in range(m))
    x_nonnegative = mpc.all(x[j] >= 0 for j in range(n))

    logging.info('Dual solution y')
    y = [secfxp(0) for _ in range(m)]
    for j in range(n):
        u = mpc.unit_vector(cobasis[j], m + n)[n:]
        v = mpc.scalar_mul(T[0][j], u)
        y = mpc.vector_sub(y, v)
    yb = mpc.in_prod(y, b)
    yA = mpc.matrix_prod([y], A)[0]
    approx = lambda a: mpc.if_else(a < 0, 1 / 1.01, 1.01) * a + 0.0001
    yA_bounded_by_c = mpc.all(yA[j] <= approx(c[j]) for j in range(n))
    y_nonpositive = mpc.all(y[i] <= 0 for i in range(m))

    cx_eq_yb = abs(cx - yb) <= 0.01 * abs(cx)
    check = mpc.all([
        cx_eq_yb, Ax_bounded_by_b, x_nonnegative, yA_bounded_by_c,
        y_nonpositive
    ])
    check = bool(await mpc.output(check))
    print(
        f'verification c.x == y.b, A.x <= b, x >= 0, y.A <= c, y <= 0: {check}'
    )

    x = await mpc.output(x)
    print(f'solution = {x}')

    await mpc.shutdown()
예제 #9
0
 def test_if_else(self):
     secfld = mpc.SecFld()
     a = secfld(0)
     b = secfld(1)
     c = secfld(1)
     self.assertEqual(mpc.run(mpc.output(mpc.if_else(c, a, b))), 0)
     self.assertEqual(mpc.run(mpc.output(mpc.if_else(1 - c, a, b))), 1)
     self.assertEqual(mpc.run(mpc.output(mpc.if_else(c, [a, b], [b, a]))),
                      [0, 1])
     self.assertEqual(
         mpc.run(mpc.output(mpc.if_else(1 - c, [a, b], [b, a]))), [1, 0])
     secint = mpc.SecInt()
     a = secint(-1)
     b = secint(1)
     c = secint(1)
     self.assertEqual(mpc.run(mpc.output(mpc.if_else(c, a, b))), -1)
     self.assertEqual(mpc.run(mpc.output(mpc.if_else(1 - c, a, b))), 1)
     self.assertEqual(mpc.run(mpc.output(mpc.if_else(c, [a, b], [b, a]))),
                      [-1, 1])
     self.assertEqual(
         mpc.run(mpc.output(mpc.if_else(1 - c, [a, b], [b, a]))), [1, -1])
     secfxp = mpc.SecFxp()
     a = secfxp(-1.0)
     b = secfxp(1.0)
     c = secfxp(1)
     self.assertEqual(mpc.run(mpc.output(mpc.if_else(c, a, b))), -1.0)
     self.assertEqual(mpc.run(mpc.output(mpc.if_else(1 - c, a, b))), 1.0)
     self.assertEqual(mpc.run(mpc.output(mpc.if_else(c, 0.0, 1.0))), 0.0)
     self.assertEqual(mpc.run(mpc.output(mpc.if_else(1 - c, 0.0, 1.0))),
                      1.0)
예제 #10
0
m = len(mpc.parties)

if m%2 == 0:
    print('OT runs with odd number of parties only.')
    sys.exit()

t = m//2
message = [(None, None)] * t
choice = [None] * t
if mpc.pid == 0:
    print('You are the trusted third party.')
elif 1 <= mpc.pid <= t:
    message[mpc.pid - 1] = (random.randint(0, 99), random.randint(0, 99))
    print(f'You are sender {mpc.pid} holding messages '
          f'{message[mpc.pid - 1][0]} and {message[mpc.pid - 1][1]}.')
else:
    choice[mpc.pid - t - 1] = random.randint(0, 1)
    print(f'You are receiver {mpc.pid - t} with random choice bit {choice[mpc.pid - t - 1]}.')

mpc.run(mpc.start())

secnum = mpc.SecInt()
for i in range(1, t+1):
    x = mpc.input([secnum(message[i-1][0]), secnum(message[i-1][1])], i)
    b = mpc.input(secnum(choice[i-1]), t + i)
    a = mpc.run(mpc.output(mpc.if_else(b, x[1], x[0]), t + i))
    if a is not None:
        print(f'You have received message {a}.')

mpc.run(mpc.shutdown())
예제 #11
0
 def arg_le_rat(x0, x1):
     n0, d0 = x0
     n1, d1 = x1
     a = mpc.in_prod([n0, d0], [d1, -n1]) >= 0
     m = mpc.if_else(a, [n1, d1], [n0, d0])
     return a, m
예제 #12
0
 def arg_le_int(x0, x1):
     a = x0 >= x1
     m = mpc.if_else(a, x1, x0)
     return a, m
예제 #13
0
        sec_noise0, sec_noise1 = secfxp(None), secfxp(None)

    # Secret-share both noise values with every other party
    all_sec_noises0 = mpc.input(sec_noise0, senders=list(range(1, M)))
    all_sec_noises1 = mpc.input(sec_noise1, senders=list(range(1, M)))

    # Collectively (and securely) draw M-1 random bits (one for each client)
    # These will be use to select which noise to use (0 or 1), for all clients
    sec_selection_bits = mpc.random_bits(secfxp, M - 1)

    sec_chosen_noises = []
    for client_id, selection_bit_for_client in enumerate(sec_selection_bits):
        # If b is 0, we select noise0 from this client
        # If b is 1, we select noise1 from this client
        sec_chosen_noise = mpc.if_else(selection_bit_for_client,
                                       all_sec_noises1[client_id],
                                       all_sec_noises0[client_id])
        sec_chosen_noises.append(sec_chosen_noise)

    # Aggregate the secure noise values from all parties
    total_sec_noise = scalar_add_all(sec_chosen_noises)

    # Find the secure maximum in the aggregated array of votes
    sec_max = mpc.max(total_sec_votes)

    # Add the aggregated noise to this max value
    noisy_sec_max = sec_max + total_sec_noise

    # Reveal (=recombine the shares) of this noisy maximum
    noisy_max = float(mpc.run(mpc.output(noisy_sec_max)))
예제 #14
0
    # Convert them to secure type
    sec_noise0, sec_noise1 = secfxp(noise0), secfxp(noise1)

    # Secret-share both noise values with every other party
    all_sec_noises0 = mpc.input(sec_noise0)
    all_sec_noises1 = mpc.input(sec_noise1)

    # Generate a random selection bit
    b = mpc.random_bit(
        secfxp
    )  # FIXME: Will be the SAME random bit for every party (want a DIFFERENT one)

    # This will choose to keep noise0 or noise1 depending on the value of b
    # b is not known by the party, this is an hence an oblivious choice
    chosen_sec_noises = mpc.if_else(b, all_sec_noises1, all_sec_noises0)
    ###################################################################################

    # Aggregate the secure noise values from all parties
    total_sec_noise = scalar_add_all(chosen_sec_noises)

    # Find the secure maximum in the aggregated array of votes
    sec_max = mpc.max(total_sec_votes)

    # Add the aggregated noise to this max value
    noisy_sec_max = sec_max + total_sec_noise

    # Reveal (=recombine the shares) of this noisy maximum
    noisy_max = float(mpc.run(mpc.output(noisy_sec_max, receivers=range(0,
                                                                        M))))
예제 #15
0
def if_else(condition, if_true, if_false):
    if isinstance(if_true, tuple) and isinstance(if_false, tuple):
        return tuple(if_else(condition, list(if_true), list(if_false)))
    else:
        return mpc.if_else(condition, if_true, if_false)