# HG changeset patch
# User Janus Dam Nielsen <[email protected]>
# Date 1254816324 -7200
# Node ID 2704f20bab087cc127acb0961acba98768a0123c
# Parent abe7f8ef29b1620b69666ff34bae3e8cdb469f8a
Replace the current implementation of _get_triple with a call to random triple.
Implement the preprocessing interface.
diff --git a/viff/orlandi.py b/viff/orlandi.py
--- a/viff/orlandi.py
+++ b/viff/orlandi.py
@@ -495,8 +495,17 @@
field = getattr(share_x, "field", getattr(share_y, "field", None))
- a, b, c = self._get_triple(field)
- return self._basic_multiplication(share_x, share_y, a, b, c)
+ def finish_mul((a, b, c)):
+ return self._basic_multiplication(share_x, share_y, a, b, c)
+
+ # This will be the result, a Share object.
+ result = Share(self, share_x.field)
+ # This is the Deferred we will do processing on.
+ triple = self._get_triple(field)
+ triple = self.schedule_complex_callback(triple, finish_mul)
+ # We add the result to the chains in triple.
+ triple.chainDeferred(result)
+ return result
def _additive_constant(self, zero, field_element):
"""Greate an additive constant.
@@ -588,14 +597,11 @@
return c
def _get_triple(self, field):
- n = field(0)
- Ca = commitment.commit(6, 0, 0)
- a = OrlandiShare(self, field, field(2), (n, n), Ca)
- Cb = commitment.commit(12, 0, 0)
- b = OrlandiShare(self, field, field(4), (n, n), Cb)
- Cc = commitment.commit(72, 0, 0)
- c = OrlandiShare(self, field, field(24), (n, n), Cc)
- return (a, b, c)
+ c, d = self.random_triple(field, 1)
+ def f(ls):
+ return ls[0]
+ d.addCallbacks(f, self.error_handler)
+ return d
def _basic_multiplication(self, share_x, share_y, triple_a, triple_b,
triple_c):
"""Multiplication of shares give a triple.
@@ -1011,7 +1017,7 @@
return result
- def random_triple(self, field):
+ def random_triple(self, field, number_of_requested_triples):
"""Generate a list of triples ``(a, b, c)`` where ``c = a * b``.
The triple ``(a, b, c)`` is secure in the Fcrs-hybrid model.
@@ -1019,15 +1025,16 @@
"""
self.program_counter[-1] += 1
- number_of_multiplications = 1
M = []
-
- for x in xrange((1 + self.s_lambda) * (2 * self.d + 1) *
number_of_multiplications):
+
+# print "Generating %i triples... relax, have a brak..." % ((1 +
self.s_lambda) * (2 * self.d + 1) * number_of_requested_triples)
+
+ for x in xrange((1 + self.s_lambda) * (2 * self.d + 1) *
number_of_requested_triples):
M.append(self.triple_test(field))
def step3(ls):
"""Coin-flip a subset test_set of M of size lambda(2d + 1)M."""
- size = self.s_lambda * (2 * self.d + 1) * number_of_multiplications
+ size = self.s_lambda * (2 * self.d + 1) *
number_of_requested_triples
inx = 0
p_half = field.modulus // 2
def coin_flip(v, ls, test_set):
@@ -1235,18 +1242,18 @@
return dls_all
def step6(M_without_test_set):
- """Partition M without test_set in number_of_multiplications
+ """Partition M without test_set in number_of_requested_triples
random subsets M_i of size (2d + 1).
"""
subsets = []
size = 2 * self.d + 1
- for x in xrange(number_of_multiplications):
+ for x in xrange(number_of_requested_triples):
subsets.append([])
def put_in_set(v, M_without_test_set, subsets):
if 0 == len(M_without_test_set):
return subsets
- v = v.value % number_of_multiplications
+ v = v.value % number_of_requested_triples
if size > len(subsets[v]):
subsets[v].append(M_without_test_set.pop(0))
r = self.random_share(field)
@@ -1295,8 +1302,11 @@
# do actual communication
self.activate_reactor()
- return result
-
+ s = Share(self, field)
+ def f(ls, s):
+ s.callback(ls)
+ result.addCallbacks(f, self.error_handler, callbackArgs=(s,))
+ return number_of_requested_triples, s
def error_handler(self, ex):
print "Error: ", ex
diff --git a/viff/test/test_orlandi_runtime.py
b/viff/test/test_orlandi_runtime.py
--- a/viff/test/test_orlandi_runtime.py
+++ b/viff/test/test_orlandi_runtime.py
@@ -261,7 +261,7 @@
runtime_class = OrlandiRuntime
- timeout = 60
+ timeout = 800
@protocol
def test_shift(self, runtime):
@@ -556,13 +556,15 @@
x2 = runtime.shift([1], self.Zp, x1)
y2 = runtime.shift([2], self.Zp, y1)
- M = []
- for j in xrange(1, 2*runtime.d + 2):
- M.append(_get_triple(self, self.Zp))
- z2 = runtime.leak_tolerant_mul(x2, y2, M)
- d = runtime.open(z2)
- d.addCallback(check)
- return d
+ c, sls = runtime.random_triple(self.Zp, 2*runtime.d + 1)
+
+ def cont(M):
+ z2 = runtime.leak_tolerant_mul(x2, y2, M)
+ d = runtime.open(z2)
+ d.addCallback(check)
+ return d
+ sls.addCallbacks(cont, runtime.error_handler)
+ return sls
z2 = runtime._cmul(y2, x2, self.Zp)
self.assertEquals(z2, None)
@@ -672,7 +674,95 @@
d = gatherResults(ds)
d.addCallback(check)
return d
- d = runtime.random_triple(self.Zp)
+ c, d = runtime.random_triple(self.Zp, 1)
d.addCallbacks(open, runtime.error_handler)
return d
+ @protocol
+ def test_random_triple3_parallel(self, runtime):
+ """Test the triple_combiner command."""
+
+ self.Zp =
GF(6277101735386680763835789423176059013767194773182842284081)
+
+ def check(ls):
+ for x in xrange(len(ls) // 3):
+ a = ls[x * 3]
+ b = ls[x * 3 + 1]
+ c = ls[x * 3 + 2]
+ self.assertEquals(c, a * b)
+
+ def open(ls):
+ ds = []
+ for [(a, b, c)] in ls:
+ d1 = runtime.open(a)
+ d2 = runtime.open(b)
+ d3 = runtime.open(c)
+ ds.append(d1)
+ ds.append(d2)
+ ds.append(d3)
+
+ d = gatherResults(ds)
+ d.addCallback(check)
+ return d
+ ac, a = runtime.random_triple(self.Zp, 1)
+ bc, b = runtime.random_triple(self.Zp, 1)
+ cc, c = runtime.random_triple(self.Zp, 1)
+ d = gather_shares([a, b, c])
+ d.addCallbacks(open, runtime.error_handler)
+ return d
+
+ @protocol
+ def test_random_triple_parallel(self, runtime):
+ """Test the triple_combiner command."""
+
+ self.Zp =
GF(6277101735386680763835789423176059013767194773182842284081)
+
+ def check(ls):
+ for x in xrange(len(ls) // 3):
+ a = ls[x * 3]
+ b = ls[x * 3 + 1]
+ c = ls[x * 3 + 2]
+ self.assertEquals(c, a * b)
+
+ def open(ls):
+ ds = []
+ for [(a, b, c)] in ls:
+ d1 = runtime.open(a)
+ d2 = runtime.open(b)
+ d3 = runtime.open(c)
+ ds.append(d1)
+ ds.append(d2)
+ ds.append(d3)
+
+ d = gatherResults(ds)
+ d.addCallback(check)
+ return d
+
+ a_shares = []
+ b_shares = []
+ c_shares = []
+
+ def cont(x):
+ while a_shares and b_shares:
+ a = a_shares.pop()
+ b = b_shares.pop()
+ print "computing..."
+ c_shares.append(runtime.mul(a, b))
+ done = gather_shares(c_shares)
+ return done
+
+ count = 5
+
+ for i in range(count):
+ inputter = (i % len(runtime.players)) + 1
+ if inputter == runtime.id:
+ a = rand.randint(0, self.Zp.modulus)
+ b = rand.randint(0, self.Zp.modulus)
+ else:
+ a, b = None, None
+ a_shares.append(runtime.input([inputter], self.Zp, a))
+ b_shares.append(runtime.input([inputter], self.Zp, b))
+ shares_ready = gather_shares(a_shares + b_shares)
+
+ runtime.schedule_callback(shares_ready, cont)
+ return shares_ready
_______________________________________________
viff-patches mailing list
[email protected]
http://lists.viff.dk/listinfo.cgi/viff-patches-viff.dk