/rev/f933bd327750
changeset: 1326:f933bd327750
user:      Marcel Keller <[email protected]>
date:      Fri Oct 23 13:50:19 2009 +0200
summary:   viff: Merged with main tree.

diffstat:

 MANIFEST.in                       |     1 -
 apps/aes.py                       |    30 +-
 apps/benchmark.py                 |   299 +++------
 apps/benchmark_classes.py         |   247 +++++++
 doc/active.txt                    |     4 +-
 doc/authors.txt                   |     1 +
 doc/conf.py                       |     2 +-
 doc/constants.txt                 |    24 +
 doc/development.txt               |    27 +-
 doc/hashbroadcast.txt             |    12 +
 doc/implementation.txt            |     6 +-
 doc/orlandi.txt                   |    15 +
 doc/program-counters.txt          |    72 +-
 doc/runtime.txt                   |    18 +-
 doc/todo.txt                      |     6 -
 doc/util.txt                      |     5 -
 epydoc.conf                       |    15 -
 run.py                            |    12 -
 viff/active.py                    |    60 +-
 viff/aes.py                       |    65 +-
 viff/comparison.py                |    13 +-
 viff/config.py                    |     2 -
 viff/constants.py                 |    32 +
 viff/equality.py                  |     3 -
 viff/field.py                     |     3 -
 viff/hash_broadcast.py            |   173 +++++
 viff/matrix.py                    |     2 -
 viff/montgomery_exponentiation.py |   166 +++++
 viff/orlandi.py                   |  1366 
++++++++++++++++++++++++++++++++++++++++++
 viff/paillier.py                  |    10 +-
 viff/passive.py                   |    43 +-
 viff/prss.py                      |     3 -
 viff/reactor.py                   |     4 +-
 viff/runtime.py                   |   171 +++-
 viff/shamir.py                    |     3 -
 viff/test/test_basic_runtime.py   |    72 +-
 viff/test/test_hash_broadcast.py  |   180 +++++
 viff/test/test_orlandi_runtime.py |   774 ++++++++++++++++++++++++
 viff/test/test_runtime.py         |    46 +-
 viff/test/test_thresholds.py      |    40 -
 viff/test/util.py                 |    10 +-
 viff/util.py                      |    32 +-
 42 files changed, 3441 insertions(+), 628 deletions(-)

diffs (truncated from 5330 to 800 lines):

diff -r 613aa672ba5e -r f933bd327750 MANIFEST.in
--- a/MANIFEST.in       Thu Oct 22 19:38:31 2009 +0200
+++ b/MANIFEST.in       Fri Oct 23 13:50:19 2009 +0200
@@ -1,5 +1,4 @@
 graft doc/api
-exclude epydoc.conf
 
 graft doc/html
 prune doc/html/.doctrees
diff -r 613aa672ba5e -r f933bd327750 apps/aes.py
--- a/apps/aes.py       Thu Oct 22 19:38:31 2009 +0200
+++ b/apps/aes.py       Fri Oct 23 13:50:19 2009 +0200
@@ -111,7 +111,7 @@
 
     for i in range(options.keylength / 8):
         inputter = i % 3 + 1
-        if (inputter == id):
+        if inputter == id:
             key.append(rt.input([inputter], GF256, ord("b")))
         else:
             key.append(rt.input([inputter], GF256))
@@ -125,36 +125,34 @@
 
     if options.active:
         if options.exponentiation is False:
-            max = 301
-            js = [3 + i * 15 + j for i in range(20) for j in range(7) + [8]]
-        elif options.exponentiation == 0:
-            max = 321
-            js = [2 + i * 16 + j for i in range(20) for j in range(13)]
+            max = 461
+            js = [3 + i * 23 + j for i in range(20)
+                  for j in range(0, 14, 2) + [15]]
+        elif options.exponentiation == 0 or options.exponentiation == 3:
+            max = 561
+            js = [1 + i * 28 + j * 2 for i in range(20) for j in range(13)]
         elif options.exponentiation == 1 or options.exponentiation == 2:
-            max = 261
-            js = [1 + i * 13 + j for i in range(20) for j in range(11)]
-        elif options.exponentiation == 3:
-            max = 301
-            js = [1 + i * 15 + j for i in range(20) for j in range(13)]
+            max = 481
+            js = [1 + i * 24 + j * 2 for i in range(20) for j in range(11)]
 
         if options.exponentiation == 4:
-            pcs = [(1, 2 + 130 * options.count + 141 * i + j, 1, 0)
+            pcs = [(2, 1 + i, 2 + 2 * j)
                    for i in range(10 * options.count)
                    for j in range(140)] + \
-                  [(2, 18, k) + (121,) * i + (4 + 6 * j, l, 1, 0)
+                  [(3, 17, k) + (121,) * i + (4 + 6 * j, 1 + 2 * l)
                    for k in range(1, options.count + 1)
                    for i in range(10)
                    for j in range(20)
-                   for l in range(1, 7)]
+                   for l in range(6)]
         else:
-            pcs = [(2, 18, k) + (max,) * i + (j, 1, 0)
+            pcs = [(2, 17, k) + (max,) * i + (j,)
                    for k in range(1, options.count + 1)
                    for i in range(10)
                    for j in js]
         program_desc[("generate_triples", (GF256,))] = pcs
 
     if options.exponentiation == 4:
-        pcs = [(2, 18, k) + (121,) * i + (1 + j * 6, 0)
+        pcs = [(3, 17, k) + (121,) * i + (1 + j * 6,)
                for k in range(1, options.count + 1)
                for i in range(10)
                for j in range(20)]
diff -r 613aa672ba5e -r f933bd327750 apps/benchmark.py
--- a/apps/benchmark.py Thu Oct 22 19:38:31 2009 +0200
+++ b/apps/benchmark.py Fri Oct 23 13:50:19 2009 +0200
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 
-# Copyright 2007, 2008 VIFF Development Team.
+# Copyright 2007, 2008, 2009 VIFF Development Team.
 #
 # This file is part of VIFF, the Virtual Ideal Functionality Framework.
 #
@@ -57,55 +57,59 @@
 import time
 from math import log
 from optparse import OptionParser
-import operator
-from pprint import pformat
 
 import viff.reactor
 viff.reactor.install()
 from twisted.internet import reactor
 
-from viff.field import GF, GF256, FakeGF
-from viff.runtime import Runtime, create_runtime, gather_shares, \
-    make_runtime_class
+from viff.field import GF, FakeGF
+from viff.runtime import Runtime, create_runtime, make_runtime_class
 from viff.passive import PassiveRuntime
 from viff.active import BasicActiveRuntime, \
     TriplesHyperinvertibleMatricesMixin, TriplesPRSSMixin
 from viff.comparison import ComparisonToft05Mixin, ComparisonToft07Mixin
 from viff.equality import ProbabilisticEqualityMixin
 from viff.paillier import PaillierRuntime
+from viff.orlandi import OrlandiRuntime
 from viff.config import load_config
-from viff.util import find_prime, rand
+from viff.util import find_prime
+
+from benchmark_classes import SelfcontainedBenchmarkStrategy, \
+    NeededDataBenchmarkStrategy, ParallelBenchmark, SequentialBenchmark, 
BinaryOperation, NullaryOperation
+
+# Hack in order to avoid Maximum recursion depth exceeded
+# exception;
+sys.setrecursionlimit(5000)
+
 
 last_timestamp = time.time()
-start = 0
 
+operations = {"mul"       : ("mul", [], BinaryOperation),
+              "compToft05": ("ge", [ComparisonToft05Mixin], BinaryOperation),
+              "compToft07": ("ge", [ComparisonToft07Mixin], BinaryOperation),
+              "eq"        : ("eq", [ProbabilisticEqualityMixin], 
BinaryOperation),
+              "triple_gen": ("triple_gen", [], NullaryOperation)}
 
-def record_start(what):
-    global start
-    start = time.time()
-    print "*" * 64
-    print "Started", what
+runtimes = {"PassiveRuntime": PassiveRuntime,
+            "PaillierRuntime": PaillierRuntime,
+            "BasicActiveRuntime": BasicActiveRuntime,
+            "OrlandiRuntime": OrlandiRuntime}
 
-
-def record_stop(_, what):
-    stop = time.time()
-    print
-    print "Total time used: %.3f sec" % (stop-start)
-    print "Time per %s operation: %.0f ms" % (what, 1000*(stop-start) / count)
-    print "*" * 6
-
-
-operations = ["mul", "compToft05", "compToft07", "eq"]
+mixins = {"TriplesHyperinvertibleMatricesMixin" : 
TriplesHyperinvertibleMatricesMixin,
+          "TriplesPRSSMixin": TriplesPRSSMixin,
+          "ComparisonToft05Mixin": ComparisonToft05Mixin,
+          "ComparisonToft07Mixin": ComparisonToft07Mixin,
+          "ProbabilisticEqualityMixin": ProbabilisticEqualityMixin}
 
 parser = OptionParser(usage="Usage: %prog [options] config_file")
 parser.add_option("-m", "--modulus",
                   help="lower limit for modulus (can be an expression)")
-parser.add_option("-a", "--active", action="store_true",
-                  help="use actively secure runtime")
-parser.add_option("--passive", action="store_false", dest="active",
-                  help="use passively secure runtime")
-parser.add_option("-2", "--twoplayer", action="store_true",
-                  help="use twoplayer runtime")
+parser.add_option("-r", "--runtime", type="choice", choices=runtimes.keys(),
+                  help="the name of the basic runtime to test")
+parser.add_option("-n", "--num_players", action="store_true", 
dest="num_players",
+                  help="number of players")
+parser.add_option("--mixins", type="string",
+                  help="Additional mixins which must be added to the runtime")
 parser.add_option("--prss", action="store_true",
                   help="use PRSS for preprocessing")
 parser.add_option("--hyper", action="store_false", dest="prss",
@@ -114,7 +118,7 @@
                   help="corruption threshold")
 parser.add_option("-c", "--count", type="int",
                   help="number of operations")
-parser.add_option("-o", "--operation", type="choice", choices=operations,
+parser.add_option("-o", "--operation", type="choice", 
choices=operations.keys(),
                   help="operation to benchmark")
 parser.add_option("-p", "--parallel", action="store_true",
                   help="execute operations in parallel")
@@ -122,17 +126,33 @@
                   help="execute operations in sequence")
 parser.add_option("-f", "--fake", action="store_true",
                   help="skip local computations using fake field elements")
+parser.add_option("--args", type="string",
+                  help=("additional arguments to the runtime, the format is "
+                        "a comma separated list of id=value pairs e.g. "
+                        "--args s=1,d=0,lambda=1"))
+parser.add_option("--needed_data", type="string",
+                  help=("name of a file containing already computed "
+                        "dictionary of needed_data. Useful for skipping "
+                        "generating the needed data, which usually "
+                        "elliminates half the execution time. Format of file: "
+                        "\"{('random_triple', (Zp,)): [(3, 1), (3, 4)]}\""))
+parser.add_option("--pc", type="string",
+                  help=("The program counter to start from when using "
+                        "explicitly provided needed_data. Format: [3,0]"))
 
 parser.set_defaults(modulus=2**65, threshold=1, count=10,
-                    active=False, twoplayer=False, prss=True,
-                    operation=operations[0], parallel=True, fake=False)
+                    runtime="PassiveRuntime", mixins="", num_players=2, 
prss=True,
+                    operation="mul", parallel=True, fake=False,
+                    args="", needed_data="")
+
+print "*" * 60
 
 # Add standard VIFF options.
 Runtime.add_options(parser)
 
 (options, args) = parser.parse_args()
 
-if len(args) == 0:
+if not args:
     parser.error("you must specify a config file")
 
 id, players = load_config(args[0])
@@ -146,189 +166,76 @@
 else:
     Field = GF
 
+
 Zp = Field(find_prime(options.modulus))
 print "Using field elements (%d bit modulus)" % log(Zp.modulus, 2)
 
+
 count = options.count
 print "I am player %d, will %s %d numbers" % (id, options.operation, count)
 
-# Defining the protocol as a class makes it easier to write the
-# callbacks in the order they are called. This class is a base class
-# that executes the protocol by calling the run_test method.
-class Benchmark:
 
-    def __init__(self, rt, operation):
-        self.rt = rt
-        self.operation = operation
-        self.sync_preprocess()
+# Identify the base runtime class.
+base_runtime_class = runtimes[options.runtime]
 
-    def sync_preprocess(self):
-        print "Synchronizing preprocessing"
-        sys.stdout.flush()
-        sync = self.rt.synchronize()
-        self.rt.schedule_callback(sync, self.preprocess)
+# Identify the additional mixins.
+actual_mixins = []
+if options.mixins:
+    actual_mixins = [mixins[mixin] for mixin in options.mixins.split(',')]
 
-    def preprocess(self, _):
-        program_desc = {}
 
-        if isinstance(self.rt, BasicActiveRuntime):
-            # TODO: Make this optional and maybe automatic. The
-            # program descriptions below were found by carefully
-            # studying the output reported when the benchmarks were
-            # run with no preprocessing. So they are quite brittle.
-            if self.operation == operator.mul:
-                key = ("generate_triples", (Zp,))
-                desc = [(i, 1, 0) for i in range(3, 3 + count)]
-                program_desc.setdefault(key, []).extend(desc)
-            elif isinstance(self.rt, ComparisonToft05Mixin):
-                key = ("generate_triples", (GF256,))
-                desc = sum([[(c, 64, i, 1, 1, 0) for i in range(2, 33)] +
-                            [(c, 64, i, 3, 1, 0) for i in range(17, 33)]
-                            for c in range(3 + 2*count, 3 + 3*count)],
-                           [])
-                program_desc.setdefault(key, []).extend(desc)
-            elif isinstance(self.rt, ComparisonToft07Mixin):
-                key = ("generate_triples", (Zp,))
-                desc = sum([[(c, 2, 4, i, 2, 1, 0) for i in range(1, 33)] +
-                            [(c, 2, 4, 99, 2, 1, 0)] +
-                            [(c, 2, 4, i, 1, 0) for i in range(65, 98)]
-                            for c in range(3 + 2*count, 3 + 3*count)],
-                           [])
-                program_desc.setdefault(key, []).extend(desc)
-
-        if program_desc:
-            print "Starting preprocessing"
-            record_start("preprocessing")
-            preproc = self.rt.preprocess(program_desc)
-            preproc.addCallback(record_stop, "preprocessing")
-            self.rt.schedule_callback(preproc, self.begin)
-        else:
-            print "Need no preprocessing"
-            self.begin(None)
-
-    def begin(self, _):
-        print "Runtime ready, generating shares"
-        self.a_shares = []
-        self.b_shares = []
-        for i in range(count):
-            inputter = (i % len(self.rt.players)) + 1
-            if inputter == self.rt.id:
-                a = rand.randint(0, Zp.modulus)
-                b = rand.randint(0, Zp.modulus)
-            else:
-                a, b = None, None
-            self.a_shares.append(self.rt.input([inputter], Zp, a))
-            self.b_shares.append(self.rt.input([inputter], Zp, b))
-        shares_ready = gather_shares(self.a_shares + self.b_shares)
-        self.rt.schedule_callback(shares_ready, self.sync_test)
-
-    def sync_test(self, _):
-        print "Synchronizing test start."
-        sys.stdout.flush()
-        sync = self.rt.synchronize()
-        self.rt.schedule_callback(sync, self.countdown, 3)
-
-    def countdown(self, _, seconds):
-        if seconds > 0:
-            print "Starting test in %d" % seconds
-            sys.stdout.flush()
-            reactor.callLater(1, self.countdown, None, seconds - 1)
-        else:
-            print "Starting test now"
-            sys.stdout.flush()
-            self.run_test(None)
-
-    def run_test(self, _):
-        raise NotImplemented("Override this abstract method in a sub class.")
-
-    def finished(self, _):
-        sys.stdout.flush()
-
-        if self.rt._needed_data:
-            print "Missing pre-processed data:"
-            for (func, args), pcs in self.rt._needed_data.iteritems():
-                print "* %s%s:" % (func, args)
-                print "  " + pformat(pcs).replace("\n", "\n  ")
-
-        self.rt.shutdown()
-
-# This class implements a benchmark where run_test executes all
-# operations in parallel.
-class ParallelBenchmark(Benchmark):
-
-    def run_test(self, _):
-        c_shares = []
-        record_start("parallel test")
-        while self.a_shares and self.b_shares:
-            a = self.a_shares.pop()
-            b = self.b_shares.pop()
-            c_shares.append(self.operation(a, b))
-
-        done = gather_shares(c_shares)
-        done.addCallback(record_stop, "parallel test")
-        self.rt.schedule_callback(done, self.finished)
-
-# A benchmark where the operations are executed one after each other.
-class SequentialBenchmark(Benchmark):
-
-    def run_test(self, _):
-        record_start("sequential test")
-        self.single_operation(None)
-
-    def single_operation(self, _):
-        if self.a_shares and self.b_shares:
-            a = self.a_shares.pop()
-            b = self.b_shares.pop()
-            c = self.operation(a, b)
-            self.rt.schedule_callback(c, self.single_operation)
-        else:
-            record_stop(None, "sequential test")
-            self.finished(None)
-
-mixins = []
-if options.twoplayer:
-    # Then there is just one possible runtime:
-    operation = operator.mul
-    base_runtime_class = PaillierRuntime
-else:
-    # There are several options for a multiplayer runtime:
-    if options.active:
-        base_runtime_class = BasicActiveRuntime
-        if options.prss:
-            mixins.append(TriplesPRSSMixin)
-        else:
-            mixins.append(TriplesHyperinvertibleMatricesMixin)
-    else:
-        base_runtime_class = PassiveRuntime
-
-    if options.operation == "mul":
-        operation = operator.mul
-    elif options.operation == "compToft05":
-        operation = operator.ge
-        mixins.append(ComparisonToft05Mixin)
-    elif options.operation == "compToft07":
-        operation = operator.ge
-        mixins.append(ComparisonToft07Mixin)
-    elif options.operation == "eq":
-        operation = operator.eq
-        mixins.append(ProbabilisticEqualityMixin)
+# Identify the operation and it mixin dependencies.
+operation = operations[options.operation][0]
+actual_mixins += operations[options.operation][1]
+operation_arity = operations[options.operation][2]
 
 print "Using the base runtime: %s." % base_runtime_class
-if mixins:
+if actual_mixins:
     print "With the following mixins:"
-    for mixin in mixins:
-        print "- %s" % mixin
+    for mixin in actual_mixins:
+        print "- %s" % mixin.__name__
 
-runtime_class = make_runtime_class(base_runtime_class, mixins)
+runtime_class = make_runtime_class(base_runtime_class, actual_mixins)
+
+pre_runtime = create_runtime(id, players, options.threshold,
+                             options, runtime_class)
+
+def update_args(runtime, options):
+    args = {}
+    if options.args:
+        for arg in options.args.split(','):
+            id, value = arg.split('=')
+            args[id] = long(value)
+        runtime.set_args(args)
+    return runtime
+
+
+pre_runtime.addCallback(update_args, options)
 
 if options.parallel:
     benchmark = ParallelBenchmark
 else:
     benchmark = SequentialBenchmark
 
-pre_runtime = create_runtime(id, players, options.threshold,
-                             options, runtime_class)
-pre_runtime.addCallback(benchmark, operation)
+needed_data = ""
+if options.needed_data:
+    needed_data = eval(open(options.needed_data).read())
+
+if options.needed_data and options.pc:
+    bases = (benchmark, NeededDataBenchmarkStrategy, operation_arity, object)
+    options.pc = eval(options.pc)
+else:
+    bases = (benchmark, SelfcontainedBenchmarkStrategy, operation_arity, 
object)
+
+print "Using the Benchmark bases:"
+for b in bases:
+    print "- %s" % b.__name__
+benchmark = type("ExtendedBenchmark", bases, {})
+
+def do_benchmark(runtime, operation, benchmark, field, count, *args):
+    benchmark(runtime, operation, field, count).benchmark(*args)
+
+pre_runtime.addCallback(do_benchmark, operation, benchmark, Zp, count, 
needed_data, options.pc)
 
 print "#### Starting reactor ###"
 reactor.run()
diff -r 613aa672ba5e -r f933bd327750 apps/benchmark_classes.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/benchmark_classes.py Fri Oct 23 13:50:19 2009 +0200
@@ -0,0 +1,247 @@
+# Copyright 2009 VIFF Development Team.
+#
+# This file is part of VIFF, the Virtual Ideal Functionality Framework.
+#
+# VIFF is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License (LGPL) as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# VIFF is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+# Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with VIFF. If not, see <http://www.gnu.org/licenses/>.
+
+import sys
+import time
+
+from pprint import pformat
+
+from twisted.internet.defer import gatherResults
+
+from viff.runtime import gather_shares
+from viff.util import rand
+
+start = 0
+
+
+def record_start(what):
+    global start
+    start = time.time()
+    print "*" * 64
+    print "Started", what
+
+
+def record_stop(x, what, count):
+    stop = time.time()
+    print
+    print "Total time used: %.3f sec" % (stop-start)
+    print "Time per %s operation: %.0f ms" % (what, 1000*(stop-start) / count)
+    print "*" * 6
+    return x
+
+
+class Benchmark(object):
+    """Abstract base class for all Benchmarks.
+
+    For concrete classes see the `ParallelBenchmark` and
+    `SequentialBenchmark` classes. A concrete class must be mixed with
+    a `BenchmarkStrategy` and an `Operator`.
+    """
+
+    def __init__(self, rt, operation, field, count):
+        self.rt = rt
+        self.operation = getattr(rt, operation)
+        self.pc = None
+        self.field = field
+        self.count = count
+
+    def preprocess(self, needed_data):
+        print "Preprocess", needed_data
+        if needed_data:
+            print "Starting preprocessing"
+            record_start("preprocessing")
+            preproc = self.rt.preprocess(needed_data)
+            preproc.addCallback(record_stop, "preprocessing", self.count)
+            return preproc
+        else:
+            print "Need no preprocessing"
+            return None
+
+    def test(self, d, termination_function):
+        self.rt.schedule_callback(d, self.generate_operation_arguments)
+        self.rt.schedule_callback(d, self.sync_test)
+        self.rt.schedule_callback(d, self.run_test)
+        self.rt.schedule_callback(d, self.sync_test)
+        self.rt.schedule_callback(d, self.finished, termination_function)
+        return d
+
+    def sync_test(self, x):
+        print "Synchronizing test start."
+        sys.stdout.flush()
+        sync = self.rt.synchronize()
+        self.rt.schedule_callback(sync, lambda y: x)
+        return sync
+
+    def run_test(self, _):
+        raise NotImplementedError
+
+    def finished(self, needed_data, termination_function):
+        sys.stdout.flush()
+
+        if self.rt._needed_data:
+            print "Missing pre-processed data:"
+            for (func, args), pcs in needed_data.iteritems():
+                print "* %s%s:" % (func, args)
+                print "  " + pformat(pcs).replace("\n", "\n  ")
+
+        return termination_function(needed_data)
+
+
+class ParallelBenchmark(Benchmark):
+    """This class implements a benchmark where run_test executes all
+    operations in parallel."""
+
+    def run_test(self, shares):
+        print "rt", self.rt.program_counter, self.pc
+        if self.pc != None:
+            self.rt.program_counter = self.pc
+        else:
+            self.pc = list(self.rt.program_counter)
+        c_shares = []
+        record_start("parallel test")
+        while not self.is_operation_done():
+            c_shares.append(self.do_operation())
+
+        done = gatherResults(c_shares)
+        done.addCallback(record_stop, "parallel test", self.count)
+        def f(x):
+            needed_data = self.rt._needed_data
+            self.rt._needed_data = {}
+            return needed_data
+        done.addCallback(f)
+        return done
+
+
+class SequentialBenchmark(Benchmark):
+    """A benchmark where the operations are executed one after each
+    other."""
+
+    def run_test(self, _, termination_function, d):
+        record_start("sequential test")
+        self.single_operation(None, termination_function)
+
+    def single_operation(self, _, termination_function):
+        if not self.is_operation_done():
+            c = self.do_operation()
+            self.rt.schedule_callback(c, self.single_operation, 
termination_function)
+        else:
+            record_stop(None, "sequential test", self.count)
+            self.finished(None, termination_function)
+
+
+class Operation(object):
+    """An abstract mixin which encapsulate the behaviour of an operation.
+
+    An operation can be nullary, unary, binary, etc.
+    """
+
+    def generate_operation_arguments(self, _):
+        """Generate the input need for performing the operation.
+
+        Returns: None.
+        """
+        raise NotImplementedError
+
+    def is_operation_done(self):
+        """Returns true if there are no more operations to perform.
+        Used in sequential tests.
+
+        Returns: Boolean.
+        """
+        raise NotImplementedError
+
+    def do_operation(self):
+        """Perform the operation.
+
+        Returns: A share containing the result of the operation.
+        """
+        raise NotImplementedError
+
+class BinaryOperation(Operation):
+    """A binary operation."""
+
+    def generate_operation_arguments(self, _):
+        print "Generate operation arguments", self.rt.program_counter
+        print "Runtime ready, generating shares"
+        self.a_shares = []
+        self.b_shares = []
+        for i in range(self.count):
+            inputter = (i % len(self.rt.players)) + 1
+            if inputter == self.rt.id:
+                a = rand.randint(0, self.field.modulus)
+                b = rand.randint(0, self.field.modulus)
+            else:
+                a, b = None, None
+            self.a_shares.append(self.rt.input([inputter], self.field, a))
+            self.b_shares.append(self.rt.input([inputter], self.field, b))
+        shares_ready = gather_shares(self.a_shares + self.b_shares)
+        return shares_ready
+
+    def is_operation_done(self):
+        return not (self.a_shares and self.b_shares)
+
+    def do_operation(self):
+        a = self.a_shares.pop()
+        b = self.b_shares.pop()
+        return self.operation(a, b)
+
+
+class NullaryOperation(Operation):
+    """A nullary operation."""
+
+    def generate_operation_arguments(self, _):
+        self.nullary_tests = self.count
+        return None
+
+    def is_operation_done(self):
+        return self.nullary_tests == 0
+
+    def do_operation(self):
+        self.nullary_tests -= 1
+        return self.operation(self.field)
+
+
+class BenchmarkStrategy(object):
+    """A benchmark strategy defines how the benchmark is done."""
+
+    def benchmark(self, *args):
+        raise NotImplementedError
+
+
+class SelfcontainedBenchmarkStrategy(BenchmarkStrategy):
+    """In a self contained benchmark strategy, all the needed data is
+    generated on the fly."""
+
+    def benchmark(self, *args):
+        sys.stdout.flush()
+        sync = self.rt.synchronize()
+        self.test(sync, lambda x: x)
+        self.rt.schedule_callback(sync, self.preprocess)
+        self.test(sync, lambda x: self.rt.shutdown())
+
+
+class NeededDataBenchmarkStrategy(BenchmarkStrategy):
+    """In a needed data benchmark strategy, all the needed data has to
+    have been generated before the test is run."""
+
+    def benchmark(self, needed_data, pc, *args):
+        self.pc = pc
+        sys.stdout.flush()
+        sync = self.rt.synchronize()
+        self.rt.schedule_callback(sync, lambda x: needed_data)
+        self.rt.schedule_callback(sync, self.preprocess)
+        self.test(sync, lambda x: self.rt.shutdown())
diff -r 613aa672ba5e -r f933bd327750 doc/active.txt
--- a/doc/active.txt    Thu Oct 22 19:38:31 2009 +0200
+++ b/doc/active.txt    Fri Oct 23 13:50:19 2009 +0200
@@ -1,6 +1,6 @@
 
-Actively Secure Protocols
-=========================
+A Thresholdbased Actively Secure Runtime
+========================================
 
 .. automodule:: viff.active
 
diff -r 613aa672ba5e -r f933bd327750 doc/authors.txt
--- a/doc/authors.txt   Thu Oct 22 19:38:31 2009 +0200
+++ b/doc/authors.txt   Fri Oct 23 13:50:19 2009 +0200
@@ -15,6 +15,7 @@
 * Marcel Keller <[email protected]>
 * Tord Reistad
 * Ivan Damgård
+* Janus Dam Nielsen <[email protected]>
 
 If you have been forgotten, then please checkout `the repository`_,
 add yourself to the list and `send us a patch`_!
diff -r 613aa672ba5e -r f933bd327750 doc/conf.py
--- a/doc/conf.py       Thu Oct 22 19:38:31 2009 +0200
+++ b/doc/conf.py       Fri Oct 23 13:50:19 2009 +0200
@@ -63,7 +63,7 @@
 today_fmt = '%B %d, %Y'
 
 # List of documents that shouldn't be included in the build.
-unused_docs = ['api/api-objects'] # Generated by epydoc.
+unused_docs = []
 
 # If true, '()' will be appended to :func: etc. cross-reference text.
 #add_function_parentheses = True
diff -r 613aa672ba5e -r f933bd327750 doc/constants.txt
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/constants.txt Fri Oct 23 13:50:19 2009 +0200
@@ -0,0 +1,24 @@
+Constants Module
+================
+
+.. automodule:: viff.constants
+
+   .. attribute:: SHARE
+                  ECHO
+                  READY
+                  SEND
+                  PAILLIER
+                  TEXT
+
+      Constants used by :class:`ShareExchanger` and others when sending 
+      shares and other messages. They serve to distinguish messages sent 
+      with the same program counter from one another.
+
+   .. attribute::INCONSISTENTHASH
+                  OK
+                  HASH
+                  SIGNAL
+
+      Constants used by :class:`HashBroadcastMixin` when sending shares
+      and other messages. They serve to distinguish messages sent with
+      the same program counter from one another.
diff -r 613aa672ba5e -r f933bd327750 doc/development.txt
--- a/doc/development.txt       Thu Oct 22 19:38:31 2009 +0200
+++ b/doc/development.txt       Fri Oct 23 13:50:19 2009 +0200
@@ -21,7 +21,7 @@
 also work offline and take advantage of the many fast operations
 offered by Mercurial.
 
-.. _Mercurial: http://www.selenic.com/mercurial/
+.. _Mercurial: http://mercurial.selenic.com/
 
 After installing Mercurial you can checkout a copy of the source using
 this command line::
@@ -67,8 +67,7 @@
 your own address first to make sure everything looks okay. You can get
 the full list of options using ``hg help email``.
 
-.. _patchbomb: http://www.selenic.com/mercurial/
-                      wiki/index.cgi/PatchbombExtension
+.. _patchbomb: http://mercurial.selenic.com/wiki/PatchbombExtension
 
 The advantage of using patchbomb is that allows everybody to go over
 the code and comment on it before the changesets are pulled into the
@@ -77,6 +76,24 @@
 the changes into the repository, just as if the changesets had been
 pulled using ``hg pull``.
 
+Commit Messages
+"""""""""""""""
+
+Please format your commit messages as follows::
_______________________________________________
viff-commits mailing list
[email protected]
http://lists.viff.dk/listinfo.cgi/viff-commits-viff.dk

Reply via email to