changeset 1447:2921ecae2a23

cdefer: Implemented ShareList in C.
author Marcel Keller <mkeller@cs.au.dk>
date Fri, 16 Jul 2010 14:35:19 +0200
parents feb70913ce98
children 6b3ea4d579d6
files apps/aes.py viff/boost.py viff/cdefer.c
diffstat 3 files changed, 230 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/apps/aes.py	Thu Jun 17 17:38:32 2010 +0200
+++ b/apps/aes.py	Fri Jul 16 14:35:19 2010 +0200
@@ -26,12 +26,14 @@
 import sys
 
 import viff.boost
-viff.boost.install()
+viff.boost.installDeferred()
 
 import viff.reactor
 viff.reactor.install()
 from twisted.internet import reactor
 
+viff.boost.installShare()
+
 from viff.field import GF256
 from viff.runtime import Runtime, create_runtime, gather_shares
 from viff.config import load_config
@@ -111,6 +113,7 @@
     rt.schedule_complex_callback(g, fin)
 
 def share_key(rt):
+    print "Sharing key."
     key =  []
 
     for i in range(options.keylength / 8):
@@ -124,6 +127,7 @@
     rt.schedule_complex_callback(s, encrypt, rt, key)
 
 def preprocess(rt):
+    print "Starting preprocessing."
     start = time.time()
     program_desc = {}
     online_phase = 2
--- a/viff/boost.py	Thu Jun 17 17:38:32 2010 +0200
+++ b/viff/boost.py	Fri Jul 16 14:35:19 2010 +0200
@@ -21,7 +21,7 @@
 from twisted.python import failure
 
 import viff.cdefer
-from viff.cdefer import Deferred
+from viff.cdefer import Deferred, Share, ShareList
 
 
 # DeferredList copied here to base it on cdefer
@@ -105,7 +105,12 @@
 FAILURE = False
 
 
-def install():
+def installDeferred():
     global viff
     twisted.internet.defer.Deferred = viff.cdefer.Deferred
     twisted.internet.defer.DeferredList = DeferredList
+
+def installShare():
+    import viff.runtime
+    viff.runtime.Share = Share
+    viff.runtime.ShareList = ShareList
--- a/viff/cdefer.c	Thu Jun 17 17:38:32 2010 +0200
+++ b/viff/cdefer.c	Fri Jul 16 14:35:19 2010 +0200
@@ -781,6 +781,7 @@
   {"result", T_OBJECT_EX, offsetof(cdefer_Deferred, result), 0, 0},
   {"paused", T_INT, offsetof(cdefer_Deferred, paused), READONLY, 0},
   {"called", T_INT, offsetof(cdefer_Deferred, called), READONLY, 0},
+  {"n_callbacks", T_INT, offsetof(cdefer_Deferred, n_callbacks), READONLY, 0},
   {0, 0, 0, 0, 0}
 };
 
@@ -1171,6 +1172,217 @@
     0,                          /*tp_weaklist*/
 };
 
+typedef struct {
+    cdefer_Share share;
+    PyObject* results;
+    int missing_shares;
+} cdefer_ShareList;
+
+static struct PyMemberDef cdefer_ShareList_members[] = {
+    {"results", T_OBJECT_EX, offsetof(cdefer_ShareList, results), 0, 0},
+    {"missing_shares", T_INT, offsetof(cdefer_ShareList, missing_shares), 0, 0},
+    {0, 0, 0, 0, 0}
+};
+
+static void cdefer_ShareList_dealloc(PyObject *o) {
+    cdefer_ShareList *self;
+    self = (cdefer_ShareList *)o;
+    Py_XDECREF(self->results);
+    cdefer_Share_dealloc((PyObject *)&self->share);
+}
+
+static int cdefer_ShareList_traverse(PyObject *o, visitproc visit, void *arg) {
+    cdefer_ShareList *self;
+    self = (cdefer_ShareList *)o;
+    Py_VISIT(self->results);
+    return cdefer_Share_traverse((PyObject *)&self->share, visit, arg);
+}
+
+static int cdefer_ShareList_clear(PyObject *o) {
+    cdefer_ShareList *self;
+    self = (cdefer_ShareList *)o;
+    Py_CLEAR(self->results);
+    return cdefer_Share_clear((PyObject *)&self->share);
+}
+
+static int cdefer_ShareList_init(cdefer_ShareList *self, PyObject *args,
+				 PyObject *kwargs)
+{
+    PyObject *shares, *callback_fired, *result;
+    PyListObject *tmp = 0;
+    cdefer_Share *first_item;
+    int n_shares, threshold = 0, i;
+    static char *argnames[] = {"shares", "threshold", NULL};
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i", argnames,
+				     &shares, &threshold))
+        return -1;
+
+    if (!PyList_Check(shares)) {
+	tmp = (PyListObject *)PyList_New(0);
+	
+	if (!_PyList_Extend(tmp, shares))
+	    return -1;
+
+	shares = (PyObject *)tmp;
+    }
+
+    n_shares = PyList_Size(shares);
+
+    if (n_shares < 0)
+	return -1;
+
+    if (n_shares < 1) {
+	PyErr_SetString(PyExc_AssertionError, "Cannot create empty ShareList");
+	return -1;
+    }
+
+    if (threshold < 0 || threshold > n_shares) {
+	PyErr_SetString(PyExc_AssertionError, "Threshold out of range");
+	return -1;
+    }
+
+    first_item = (cdefer_Share *)PyList_GET_ITEM(shares, 0);
+    args = Py_BuildValue("(OO)", first_item->runtime, first_item->field);
+    kwargs = PyDict_New();
+
+    if (!args || !kwargs)
+	return -1;
+
+    cdefer_Share_init(&(self->share), args, kwargs);
+    Py_DECREF(args);
+    Py_DECREF(kwargs);
+
+    Py_XDECREF(self->results);
+    self->results = PyList_New(n_shares);
+
+    if (!self->results)
+	return -1;
+
+    if (threshold == 0)
+	self->missing_shares = n_shares;
+    else
+	self->missing_shares = threshold;
+
+    callback_fired = PyObject_GetAttrString((PyObject *)self,
+					    "_callback_fired");
+
+    if (!callback_fired)
+	return -1;
+
+    // combine loops, unlike Python code
+    for (i = 0; i < n_shares; i++) {
+	Py_INCREF(Py_None);
+	PyList_SET_ITEM(self->results, i, Py_None);
+
+	args = Py_BuildValue("(iO)", i, Py_True);
+	Py_INCREF(Py_None);
+	result = cdefer_Deferred__addCallbacks((cdefer_Deferred *)
+					       PyList_GET_ITEM(shares, i),
+					       callback_fired, Py_None, args,
+					       Py_None, Py_None, Py_None);
+	Py_DECREF(Py_None);
+	Py_DECREF(args);
+	Py_DECREF(result);
+
+	if (!result)
+	    return -1;
+    }
+
+    Py_DECREF(callback_fired);
+    Py_XDECREF(tmp);
+
+    return 0;
+}
+
+static PyObject *cdefer_ShareList_callback_fired(cdefer_ShareList *self,
+						 PyObject *args,
+						 PyObject *kwargs) {
+    PyObject *result, *success, *tmp;
+    int index;
+    static char *argnames[] = {"result", "index", "success", NULL};
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiO", argnames,
+				     &result, &index, &success))
+	return NULL;
+
+    tmp = PyList_GET_ITEM(self->results, index);
+    PyList_SET_ITEM(self->results, index, Py_BuildValue("(OO)", success,
+						    result));
+    Py_XDECREF(tmp);
+    self->missing_shares--;
+
+    if (!self->share.deferred.called && self->missing_shares == 0) {
+	args = Py_BuildValue("(O)", self->results);
+	kwargs = PyDict_New();
+	tmp = cdefer_Deferred_callback((cdefer_Deferred *)self,
+				       args, kwargs);
+	Py_DECREF(args);
+	Py_DECREF(kwargs);
+
+	if (!tmp)
+	    return NULL;
+
+	Py_DECREF(tmp);
+    }
+
+    Py_INCREF(result);
+    return result;
+}
+
+static struct PyMethodDef cdefer_ShareList_methods[] = {
+    {"_callback_fired", (PyCFunction)cdefer_ShareList_callback_fired,
+     METH_VARARGS|METH_KEYWORDS, 0},
+    {0, 0, 0, 0}
+};
+
+static PyTypeObject cdefer_ShareListType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                          /*ob_size*/
+    "cdefer.ShareList",         /*tp_name*/
+    sizeof(cdefer_ShareList),   /*tp_basicsize*/
+    0,                          /*tp_itemsize*/
+    (destructor)cdefer_ShareList_dealloc,      /*tp_dealloc*/
+    0,                          /*tp_print*/
+    0,                          /*tp_getattr*/
+    0,                          /*tp_setattr*/
+    0,                          /*tp_compare*/
+    0,                          /*tp_repr*/
+    0,                          /*tp_as_number*/
+    0,                          /*tp_as_sequence*/
+    0,                          /*tp_as_mapping*/
+    0,                          /*tp_hash */
+    0,                          /*tp_call*/
+    0,                          /*tp_str*/
+    0,                          /*tp_getattro*/
+    0,                          /*tp_setattro*/
+    0,                          /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+    0,                          /*tp_doc*/
+    (traverseproc)cdefer_ShareList_traverse,   /*tp_traverse*/
+    (inquiry)cdefer_ShareList_clear,           /*tp_clear*/
+    0,                          /*tp_richcompare*/
+    0,                          /*tp_weaklistoffset*/
+    0,                          /*tp_iter*/
+    0,                          /*tp_iternext*/
+    cdefer_ShareList_methods,   /*tp_methods*/
+    cdefer_ShareList_members,   /*tp_members*/
+    0,                          /*tp_getset*/
+    &cdefer_ShareType,          /*tp_base*/
+    0,                          /*tp_dict*/
+    0,                          /*tp_descr_get*/
+    0,                          /*tp_descr_set*/
+    0,                          /*tp_dictoffset*/
+    (initproc)cdefer_ShareList_init,          /*tp_init*/
+    0,                          /*tp_alloc*/
+    0,                          /*tp_new*/
+    0,                          /*tp_free*/
+    0,                          /*tp_is_gc*/
+    0,                          /*tp_bases*/
+    0,                          /*tp_mro*/
+    0,                          /*tp_cache*/
+    0,                          /*tp_subclasses*/
+    0,                          /*tp_weaklist*/
+};
+
 #ifndef PyMODINIT_FUNC  /* declarations for DLL import/export */
 #define PyMODINIT_FUNC void
 #endif
@@ -1236,6 +1448,12 @@
     Py_INCREF(&cdefer_ShareType);
     PyModule_AddObject(m, "Share", (PyObject *)&cdefer_ShareType);
 
+    if (PyType_Ready(&cdefer_ShareListType) < 0)
+	return;
+
+    Py_INCREF(&cdefer_ShareListType);
+    PyModule_AddObject(m, "ShareList", (PyObject *)&cdefer_ShareListType);
+
     return;
 Error:
     Py_XDECREF(f);