view viff/test/test_orlandi_runtime.py @ 1538:9d4f9551644c
Added computation-id option.
This changeset adds a command line option to VIFF allowing users to
specify a computation id.
Prior to this changeset, any computation involving pseudo-random
secret sharing (which for the time being boils down to computations
done with the PassiveRuntime) could only be run one time using the
same set of VIFF player configuration files. If more than one
computation was executed with the same set of configuration files, the
security of the system would be broken.
With this changeset, multiple computations can be run securely with
the same set of configuration files as long as each computation is run
with a unique computation id.
| author |
Tomas Toft <ttoft at cs.au.dk> |
| date |
Wed Aug 11 16:09:32 2010 +0200 (21 months ago) |
| parents |
80841840990f |
| children |
|
line source
1 # Copyright 2009 VIFF Development Team.
3 # This file is part of VIFF, the Virtual Ideal Functionality Framework.
5 # VIFF is free software: you can redistribute it and/or modify it
6 # under the terms of the GNU Lesser General Public License (LGPL) as
7 # published by the Free Software Foundation, either version 3 of the
8 # License, or (at your option) any later version.
10 # VIFF is distributed in the hope that it will be useful, but WITHOUT
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
13 # Public License for more details.
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with VIFF. If not, see <http://www.gnu.org/licenses/>.
20 from twisted.internet.defer import gatherResults, DeferredList
22 from viff.test.util import RuntimeTestCase, protocol
23 from viff.runtime import gather_shares, Share
24 from viff.paillierutil import NaClPaillier
25 from viff.config import generate_configs
31 from pypaillier import encrypt_r, decrypt, tripple_2c, tripple_3a
32 from viff.orlandi import OrlandiRuntime, OrlandiShare
33 pypaillier = "Imported"
44 from viff.field import FieldElement, GF
46 from viff.util import rand
48 sys.setrecursionlimit(10000)
50 def _get_triple(runtime, field):
52 Ca = commitment.commit(6, 0, 0)
53 a = OrlandiShare(runtime, field, field(2), (n, n), Ca)
54 Cb = commitment.commit(12, 0, 0)
55 b = OrlandiShare(runtime, field, field(4), (n, n), Cb)
56 Cc = commitment.commit(72, 0, 0)
57 c = OrlandiShare(runtime, field, field(24), (n, n), Cc)
61 class OrlandiBasicCommandsTest(RuntimeTestCase):
62 """Test for basic commands."""
67 runtime_class = OrlandiRuntime
70 def test_secret_share(self, runtime):
71 """Test sharing of random numbers."""
73 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
75 def check((xi, (rho1, rho2), Cr)):
76 # Check that we got the expected number of shares.
77 self.assert_type(xi, FieldElement)
78 self.assert_type(rho1, FieldElement)
79 self.assert_type(rho2, FieldElement)
80 self.assert_type(Cr, commitment.Commitment)
83 share = runtime.secret_share([1], self.Zp, 42)
85 share = runtime.secret_share([1], self.Zp)
86 share.addCallback(check)
90 def test_open_secret_share(self, runtime):
91 """Test sharing and open of a number."""
93 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
96 self.assertEquals(v, 42)
99 x = runtime.secret_share([1], self.Zp, 42)
101 x = runtime.secret_share([1], self.Zp)
107 def test_open_multiple_secret_share(self, runtime):
108 """Test sharing and open of a number."""
110 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
113 for inx, v in enumerate(ls):
114 self.assertEquals(v, (inx + 1) * 42)
117 x = runtime.secret_share([1], self.Zp, 42)
119 x = runtime.secret_share([1], self.Zp)
121 y = runtime.secret_share([1], self.Zp, 84)
123 y = runtime.secret_share([1], self.Zp)
124 d = runtime.open_multiple_values([x, y])
129 def test_open_two_secret_share(self, runtime):
130 """Test sharing and open of a number."""
132 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
135 self.assertEquals(a, 42)
136 self.assertEquals(b, 84)
139 x = runtime.secret_share([1], self.Zp, 42)
141 x = runtime.secret_share([1], self.Zp)
143 y = runtime.secret_share([1], self.Zp, 84)
145 y = runtime.secret_share([1], self.Zp)
146 d = runtime.open_two_values(x, y)
151 def test_random_share(self, runtime):
152 """Test creation of a random shared number."""
154 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
157 self.assertEquals(True, True)
159 x = runtime.random_share(self.Zp)
165 def test_plus(self, runtime):
166 """Test addition of two numbers."""
168 Zp = GF(6277101735386680763835789423176059013767194773182842284081)
170 Cx = commitment.commit(7, 4, 5)
171 x = (Zp(2), (Zp(2), Zp(2)), Cx)
172 y = (Zp(2), (Zp(2), Zp(2)), Cx)
173 zi, (rho1, rho2), Cz = runtime._plus((x, y), Zp)
174 self.assertEquals(zi, Zp(4))
175 self.assertEquals(rho1, 4)
176 self.assertEquals(rho2, 4)
177 self.assertEquals(Cz, Cx * Cx)
181 def test_sum(self, runtime):
182 """Test addition of two numbers."""
184 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
190 self.assertEquals(v, x1 + y1)
193 x2 = runtime.secret_share([1], self.Zp, x1)
195 x2 = runtime.secret_share([1], self.Zp)
198 y2 = runtime.secret_share([3], self.Zp, y1)
200 y2 = runtime.secret_share([3], self.Zp)
202 z2 = runtime.add(x2, y2)
208 def test_sum_plus(self, runtime):
209 """Test addition of two numbers."""
211 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
217 self.assertEquals(v, x1 + y1)
220 x2 = runtime.secret_share([1], self.Zp, x1)
222 x2 = runtime.secret_share([1], self.Zp)
225 y2 = runtime.secret_share([3], self.Zp, y1)
227 y2 = runtime.secret_share([3], self.Zp)
235 def test_sum_constant(self, runtime):
236 """Test addition of two numbers."""
238 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
244 self.assertEquals(v, x1 + y1)
247 x2 = runtime.secret_share([1], self.Zp, x1)
249 x2 = runtime.secret_share([1], self.Zp)
257 def test_sub(self, runtime):
258 """Test subtration of two numbers."""
260 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
266 self.assertEquals(v, x1 - y1)
269 x2 = runtime.secret_share([1], self.Zp, x1)
271 x2 = runtime.secret_share([1], self.Zp)
274 y2 = runtime.secret_share([3], self.Zp, y1)
276 y2 = runtime.secret_share([3], self.Zp)
278 z2 = runtime.sub(x2, y2)
284 def test_sub_minus(self, runtime):
285 """Test subtration of two numbers."""
287 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
293 self.assertEquals(v, x1 - y1)
296 x2 = runtime.secret_share([1], self.Zp, x1)
298 x2 = runtime.secret_share([1], self.Zp)
301 y2 = runtime.secret_share([3], self.Zp, y1)
303 y2 = runtime.secret_share([3], self.Zp)
311 def test_sub_constant(self, runtime):
312 """Test subtration of two numbers."""
314 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
320 self.assertEquals(v, x1 - y1)
323 x2 = runtime.secret_share([1], self.Zp, x1)
325 x2 = runtime.secret_share([1], self.Zp)
333 def test_sub_constant_left(self, runtime):
334 """Test subtraction of a public number and secret shared number."""
336 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
342 self.assertEquals(v, y1 - x1)
345 x2 = runtime.secret_share([1], self.Zp, x1)
347 x2 = runtime.secret_share([1], self.Zp)
358 class OrlandiAdvancedCommandsTest(RuntimeTestCase):
359 """Test for advanced commands."""
364 runtime_class = OrlandiRuntime
368 def generate_configs(self, *args):
371 keys = generate_configs(paillier=NaClPaillier(1024), *args)
376 def test_shift(self, runtime):
377 """Test addition of the shift command."""
379 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
382 self.assertEquals(v, 42)
384 x = runtime.shift([2], self.Zp, 42)
390 def test_shift_two_inputters(self, runtime):
391 """Test addition of the shift command."""
393 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
396 self.assertEquals(v, 42)
398 x, y = runtime.shift([1,3], self.Zp, 42)
400 d1.addCallback(check)
402 d2.addCallback(check)
403 return DeferredList([d1, d2])
406 def test_shift_two_consequtive_inputters(self, runtime):
407 """Test addition of the shift command."""
409 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
413 self.assertEquals(runtime.program_counter, [0, 4])
415 x = runtime.shift([1], self.Zp, 42)
416 y = runtime.shift([2], self.Zp, 42)
417 r = gather_shares([x, y])
422 def test_shift_two_consequtive_inputters2(self, runtime):
423 """Test addition of the shift command."""
425 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
428 self.assertEquals(v, 42)
431 self.assertEquals(x, 42)
432 self.assertEquals(y, 42)
434 x = runtime.shift([1], self.Zp, 42)
435 y = runtime.shift([2], self.Zp, 42)
436 r = gather_shares([runtime.open(x), runtime.open(y)])
441 def test_input(self, runtime):
442 """Test of many uses of the input command."""
444 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
450 for i in range(count):
451 inputter = (i % len(runtime.players)) + 1
452 if inputter == runtime.id:
453 a = rand.randint(0, self.Zp.modulus)
454 b = rand.randint(0, self.Zp.modulus)
457 a_shares.append(runtime.input([inputter], self.Zp, a))
458 b_shares.append(runtime.input([inputter], self.Zp, b))
459 shares_ready = gather_shares(a_shares + b_shares)
463 def test_basic_multiply(self, runtime):
464 """Test multiplication of two numbers."""
466 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
472 self.assertEquals(v, x1 * y1)
474 x2 = runtime.shift([2], self.Zp, x1)
475 y2 = runtime.shift([3], self.Zp, y1)
477 a, b, c = _get_triple(self, self.Zp)
478 z2 = runtime._basic_multiplication(x2, y2, a, b, c)
484 def test_mul_mul(self, runtime):
485 """Test multiplication of two numbers."""
487 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
493 self.assertEquals(v, x1 * y1)
495 triples = runtime.random_triple(self.Zp, 1)
497 def do_mult(triples):
498 runtime.triples = triples
499 x2 = runtime.shift([2], self.Zp, x1)
500 y2 = runtime.shift([3], self.Zp, y1)
506 r = gatherResults(triples)
507 runtime.schedule_callback(r, do_mult)
511 def test_basic_multiply_constant_right(self, runtime):
512 """Test multiplication of two numbers."""
514 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
520 self.assertEquals(v, x1 * y1)
522 x2 = runtime.shift([1], self.Zp, x1)
524 a, b, c = _get_triple(self, self.Zp)
525 z2 = runtime._basic_multiplication(x2, self.Zp(y1), a, b, c)
531 def test_basic_multiply_constant_left(self, runtime):
532 """Test multiplication of two numbers."""
534 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
540 self.assertEquals(v, x1 * y1)
542 x2 = runtime.shift([1], self.Zp, x1)
544 a, b, c = _get_triple(self, self.Zp)
545 z2 = runtime._basic_multiplication(self.Zp(y1), x2, a, b, c)
551 def test_constant_multiplication_constant_left(self, runtime):
552 """Test multiplication of two numbers."""
554 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
560 self.assertEquals(v, x1 * y1)
562 x2 = runtime.shift([1], self.Zp, x1)
564 z2 = runtime._cmul(self.Zp(y1), x2, self.Zp)
570 def test_constant_multiplication_constant_right(self, runtime):
571 """Test multiplication of two numbers."""
573 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
579 self.assertEquals(v, x1 * y1)
581 x2 = runtime.shift([1], self.Zp, x1)
583 z2 = runtime._cmul(x2, self.Zp(y1), self.Zp)
589 def test_constant_multiplication_constant_None(self, runtime):
590 """Test multiplication of two numbers."""
592 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
597 x2 = runtime.shift([1], self.Zp, x1)
598 y2 = runtime.shift([1], self.Zp, y1)
601 def test_sum_poly1(self, runtime):
602 """Test implementation of sum_poly."""
604 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
607 f.append((self.Zp(7), (self.Zp(7), self.Zp(7)), self.Zp(7)))
608 f.append((self.Zp(9), (self.Zp(9), self.Zp(9)), self.Zp(9)))
609 f.append((self.Zp(13), (self.Zp(13), self.Zp(13)), self.Zp(13)))
611 x, (rho1, rho2), Cx = runtime.sum_poly(1, f)
612 self.assertEquals(x, 29)
613 self.assertEquals(rho1, 29)
614 self.assertEquals(rho2, 29)
615 self.assertEquals(Cx, 819)
619 def test_sum_poly2(self, runtime):
620 """Test implementation of sum_poly."""
622 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
624 Cf1 = commitment.commit(21, 21, 21)
625 Cf2 = commitment.commit(27, 27, 27)
626 Cf3 = commitment.commit(39, 39, 39)
629 f.append((self.Zp(7), (self.Zp(7), self.Zp(7)), Cf1))
630 f.append((self.Zp(9), (self.Zp(9), self.Zp(9)), Cf2))
631 f.append((self.Zp(13), (self.Zp(13), self.Zp(13)), Cf3))
633 x, (rho1, rho2), Cx = runtime.sum_poly(3, f)
634 self.assertEquals(x, 453)
635 self.assertEquals(rho1, 453)
636 self.assertEquals(rho2, 453)
637 self.assertEquals(Cx, Cf1**3 * Cf2**9 * Cf3**27)
641 def test_delta(self, runtime):
642 """Test implementation of compute_delta."""
644 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
646 delta = runtime.compute_delta(3)
647 self.assertEquals(delta[0], 7)
648 self.assertEquals(delta[1], -21)
649 self.assertEquals(delta[2], 35)
650 self.assertEquals(delta[3], -35)
651 self.assertEquals(delta[4], 21)
652 self.assertEquals(delta[5], -7)
653 self.assertEquals(delta[6], 1)
658 def test_leak_mul(self, runtime):
659 """Test leaktolerant multiplication of two numbers."""
660 commitment.set_reference_string(long(2), long(6))
662 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
672 self.assertEquals(v, x1 * y1)
674 x2 = runtime.shift([1], self.Zp, x1)
675 y2 = runtime.shift([2], self.Zp, y1)
677 triples = runtime.random_triple(self.Zp, 2*runtime.d + 1)
680 z2 = runtime.leak_tolerant_mul(x2, y2, triples)
684 r = gatherResults(triples)
685 runtime.schedule_callback(r, cont)
689 def test_leak_mul1(self, runtime):
690 """Test leaktolerant multiplication of two numbers."""
691 commitment.set_reference_string(long(2), long(6))
693 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
706 self.assertEquals(v, x1 * y1)
708 x2 = runtime.shift([1], self.Zp, x1)
709 y2 = runtime.shift([2], self.Zp, y1)
711 triples = runtime.random_triple(self.Zp, 2*runtime.d + 1)
714 z2 = runtime.leak_tolerant_mul(x2, y2, triples)
718 r = gatherResults(triples)
719 runtime.schedule_callback(r, cont)
723 class TripleGenTest(RuntimeTestCase):
724 """Test for generation of triples."""
729 runtime_class = OrlandiRuntime
733 def generate_configs(self, *args):
736 keys = generate_configs(paillier=NaClPaillier(1024), *args)
740 def test_tripleGen(self, runtime):
741 """Test the triple_gen command."""
743 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
749 def check((a, b, c)):
750 self.assertEquals(c, a * b)
752 def open((triple, _)):
753 d1 = runtime.open(triple.a)
754 d2 = runtime.open(triple.b)
755 d3 = runtime.open(triple.c)
756 d = gatherResults([d1, d2, d3])
759 d = runtime.triple_gen(self.Zp)
760 d.addCallbacks(open, runtime.error_handler)
764 def test_tripleGen2(self, runtime):
765 """Test the triple_gen command."""
767 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
769 def check((a, b, c, dx, dy, dz)):
770 self.assertEquals(c, a * b)
771 self.assertEquals(dz, dx * dy)
773 def open(((t1, control), (t2, _))):
774 d1 = runtime.open(t1.a)
775 d2 = runtime.open(t1.b)
776 d3 = runtime.open(t1.c)
777 dx = runtime.open(t2.a)
778 dy = runtime.open(t2.b)
779 dz = runtime.open(t2.c)
780 d = gatherResults([d1, d2, d3, dx, dy, dz])
783 t1 = runtime.triple_gen(self.Zp)
784 t2 = runtime.triple_gen(self.Zp)
785 d = gatherResults([t1, t2])
786 d.addCallbacks(open, runtime.error_handler)
790 def test_tripleTest(self, runtime):
791 """Test the triple_test command."""
793 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
795 def check((a, b, c)):
796 self.assertEquals(c, a * b)
798 def open((triple, _)):
799 d1 = runtime.open(triple.a)
800 d2 = runtime.open(triple.b)
801 d3 = runtime.open(triple.c)
802 d = gatherResults([d1, d2, d3])
805 d = runtime.triple_test(self.Zp)
806 d.addCallbacks(open, runtime.error_handler)
810 def test_random_triple(self, runtime):
811 """Test the triple_combiner command."""
813 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
816 for x in xrange(len(ls) // 3):
820 self.assertEquals(c, a * b)
825 d1 = runtime.open(triple.a)
826 d2 = runtime.open(triple.b)
827 d3 = runtime.open(triple.c)
832 d = gatherResults(ds)
835 d = gatherResults(runtime.random_triple(self.Zp, 1))
836 d.addCallbacks(open, runtime.error_handler)
840 def test_random_triple3_parallel(self, runtime):
841 """Test the triple_combiner command."""
843 self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
846 for x in xrange(len(ls) // 3):
850 self.assertEquals(c, a * b)
855 d1 = runtime.open(triple.a)
856 d2 = runtime.open(triple.b)
857 d3 = runtime.open(triple.c)
862 d = gatherResults(ds)
865 a = gatherResults(runtime.random_triple(self.Zp, 1))
866 b = gatherResults(runtime.random_triple(self.Zp, 1))
867 c = gatherResults(runtime.random_triple(self.Zp, 1))
868 d = gatherResults([a, b, c])
869 d.addCallbacks(open, runtime.error_handler)
873 def skip_tests(module_name):
874 OrlandiAdvancedCommandsTest.skip = "Skipped due to missing " + module_name + " module."
875 OrlandiBasicCommandsTest.skip = "Skipped due to missing " + module_name + " module."
876 TripleGenTest.skip = "Skipped due to missing " + module_name + " module."
879 skip_tests("commitment")
882 skip_tests("pypaillier")