algorithms.c: Add bindings for STROBE.
[catacomb-python] / share.c
1 /* -*-c-*-
2 *
3 * Secret sharing
4 *
5 * (c) 2005 Straylight/Edgeware
6 */
7
8 /*----- Licensing notice --------------------------------------------------*
9 *
10 * This file is part of the Python interface to Catacomb.
11 *
12 * Catacomb/Python is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * Catacomb/Python is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with Catacomb/Python; if not, write to the Free Software Foundation,
24 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 */
26
27 /*----- Header files ------------------------------------------------------*/
28
29 #include "catacomb-python.h"
30
31 /*----- GF(2^8)-based secret-sharing --------------------------------------*/
32
33 typedef struct gfshare_pyobj {
34 PyObject_HEAD
35 gfshare s;
36 } gfshare_pyobj;
37
38 static PyTypeObject
39 *gfshare_pytype, *gfsharesplit_pytype, *gfsharejoin_pytype;
40 #define GFSHARE_PYCHECK(o) PyObject_TypeCheck((o), gfshare_pytype)
41 #define GFSHARESPLIT_PYCHECK(o) PyObject_TypeCheck((o), gfsharesplit_pytype)
42 #define GFSHAREJOIN_PYCHECK(o) PyObject_TypeCheck((o), gfsharejoin_pytype)
43 #define GFSHARE_S(o) (&((gfshare_pyobj *)(o))->s)
44
45 static void gfshare_pydealloc(PyObject *me)
46 {
47 gfshare_destroy(GFSHARE_S(me));
48 FREEOBJ(me);
49 }
50
51 static PyObject *gfsget_threshold(PyObject *me, void *hunoz)
52 { return (PyInt_FromLong(GFSHARE_S(me)->t)); }
53 static PyObject *gfsget_size(PyObject *me, void *hunoz)
54 { return (PyInt_FromLong(GFSHARE_S(me)->sz)); }
55
56 static const PyGetSetDef gfshare_pygetset[]= {
57 #define GETSETNAME(op, name) gfs##op##_##name
58 GET (threshold, "S.threshold -> THRESHOLD")
59 GET (size, "S.size -> SECRETSZ")
60 #undef GETSETNAME
61 { 0 }
62 };
63
64 static const PyTypeObject gfshare_pytype_skel = {
65 PyVarObject_HEAD_INIT(0, 0) /* Header */
66 "GFShare", /* @tp_name@ */
67 sizeof(gfshare_pyobj), /* @tp_basicsize@ */
68 0, /* @tp_itemsize@ */
69
70 gfshare_pydealloc, /* @tp_dealloc@ */
71 0, /* @tp_print@ */
72 0, /* @tp_getattr@ */
73 0, /* @tp_setattr@ */
74 0, /* @tp_compare@ */
75 0, /* @tp_repr@ */
76 0, /* @tp_as_number@ */
77 0, /* @tp_as_sequence@ */
78 0, /* @tp_as_mapping@ */
79 0, /* @tp_hash@ */
80 0, /* @tp_call@ */
81 0, /* @tp_str@ */
82 0, /* @tp_getattro@ */
83 0, /* @tp_setattro@ */
84 0, /* @tp_as_buffer@ */
85 Py_TPFLAGS_DEFAULT | /* @tp_flags@ */
86 Py_TPFLAGS_BASETYPE,
87
88 /* @tp_doc@ */
89 "Binary-field secret sharing base class.",
90
91 0, /* @tp_traverse@ */
92 0, /* @tp_clear@ */
93 0, /* @tp_richcompare@ */
94 0, /* @tp_weaklistoffset@ */
95 0, /* @tp_iter@ */
96 0, /* @tp_iternext@ */
97 0, /* @tp_methods@ */
98 0, /* @tp_members@ */
99 PYGETSET(gfshare), /* @tp_getset@ */
100 0, /* @tp_base@ */
101 0, /* @tp_dict@ */
102 0, /* @tp_descr_get@ */
103 0, /* @tp_descr_set@ */
104 0, /* @tp_dictoffset@ */
105 0, /* @tp_init@ */
106 PyType_GenericAlloc, /* @tp_alloc@ */
107 abstract_pynew, /* @tp_new@ */
108 0, /* @tp_free@ */
109 0 /* @tp_is_gc@ */
110 };
111
112 static PyObject *gfsharesplit_pynew(PyTypeObject *ty,
113 PyObject *arg, PyObject *kw)
114 {
115 struct bin in;
116 unsigned t;
117 grand *r = &rand_global;
118 gfshare_pyobj *s;
119 static const char *const kwlist[] = { "threshold", "secret", "rng", 0 };
120 if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&|O&:new", KWLIST,
121 convuint, &t, convbin, &in,
122 convgrand, &r))
123 goto end;
124 if (!t || t > 255) VALERR("threshold must be nonzero and < 256");
125 s = (gfshare_pyobj *)ty->tp_alloc(ty, 0);
126 gfshare_create(&s->s, t, in.sz);
127 gfshare_mkshares(&s->s, r, in.p);
128 return ((PyObject *)s);
129 end:
130 return (0);
131 }
132
133 static PyObject *gfsmeth_get(PyObject *me, PyObject *arg)
134 {
135 unsigned i;
136 PyObject *rc = 0;
137 if (!PyArg_ParseTuple(arg, "O&:get", convuint, &i)) goto end;
138 if (i >= 255) VALERR("index must be < 255");
139 rc = bytestring_pywrap(0, GFSHARE_S(me)->sz);
140 gfshare_get(GFSHARE_S(me), i, BIN_PTR(rc));
141 end:
142 return (rc);
143 }
144
145 static const PyMethodDef gfsharesplit_pymethods[] = {
146 #define METHNAME(name) gfsmeth_##name
147 METH (get, "S.get(I) -> SHARE")
148 #undef METHNAME
149 { 0 }
150 };
151
152 static const PyTypeObject gfsharesplit_pytype_skel = {
153 PyVarObject_HEAD_INIT(0, 0) /* Header */
154 "GFShareSplit", /* @tp_name@ */
155 sizeof(gfshare_pyobj), /* @tp_basicsize@ */
156 0, /* @tp_itemsize@ */
157
158 gfshare_pydealloc, /* @tp_dealloc@ */
159 0, /* @tp_print@ */
160 0, /* @tp_getattr@ */
161 0, /* @tp_setattr@ */
162 0, /* @tp_compare@ */
163 0, /* @tp_repr@ */
164 0, /* @tp_as_number@ */
165 0, /* @tp_as_sequence@ */
166 0, /* @tp_as_mapping@ */
167 0, /* @tp_hash@ */
168 0, /* @tp_call@ */
169 0, /* @tp_str@ */
170 0, /* @tp_getattro@ */
171 0, /* @tp_setattro@ */
172 0, /* @tp_as_buffer@ */
173 Py_TPFLAGS_DEFAULT | /* @tp_flags@ */
174 Py_TPFLAGS_BASETYPE,
175
176 /* @tp_doc@ */
177 "GFShareSplit(THRESHOLD, SECRET, [rng = rand]): binary-field sharing:\n"
178 " split secret into shares.",
179
180 0, /* @tp_traverse@ */
181 0, /* @tp_clear@ */
182 0, /* @tp_richcompare@ */
183 0, /* @tp_weaklistoffset@ */
184 0, /* @tp_iter@ */
185 0, /* @tp_iternext@ */
186 PYMETHODS(gfsharesplit), /* @tp_methods@ */
187 0, /* @tp_members@ */
188 0, /* @tp_getset@ */
189 0, /* @tp_base@ */
190 0, /* @tp_dict@ */
191 0, /* @tp_descr_get@ */
192 0, /* @tp_descr_set@ */
193 0, /* @tp_dictoffset@ */
194 0, /* @tp_init@ */
195 PyType_GenericAlloc, /* @tp_alloc@ */
196 gfsharesplit_pynew, /* @tp_new@ */
197 0, /* @tp_free@ */
198 0 /* @tp_is_gc@ */
199 };
200
201 static PyObject *gfsharejoin_pynew(PyTypeObject *ty,
202 PyObject *arg, PyObject *kw)
203 {
204 unsigned t, sz;
205 gfshare_pyobj *s;
206 static const char *const kwlist[] = { "threshold", "size", 0 };
207 if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&:new", KWLIST,
208 convuint, &t, convuint, &sz))
209 goto end;
210 if (!t || t > 255) VALERR("threshold must be nonzero and < 256");
211 s = (gfshare_pyobj *)ty->tp_alloc(ty, 0);
212 gfshare_create(&s->s, t, sz);
213 return ((PyObject *)s);
214 end:
215 return (0);
216 }
217
218 static PyObject *gfsmeth_addedp(PyObject *me, PyObject *arg)
219 {
220 unsigned i;
221 if (!PyArg_ParseTuple(arg, "O&:addedp", convuint, &i)) goto end;
222 if (i > 254) VALERR("index must be < 255");
223 return (getbool(gfshare_addedp(GFSHARE_S(me), i)));
224 end:
225 return (0);
226 }
227
228 static PyObject *gfsmeth_add(PyObject *me, PyObject *arg)
229 {
230 unsigned i;
231 struct bin s;
232 if (!PyArg_ParseTuple(arg, "O&O&:add", convuint, &i, convbin, &s))
233 goto end;
234 if (i > 254) VALERR("index must be < 255");
235 if (s.sz != GFSHARE_S(me)->sz) VALERR("bad share size");
236 if (gfshare_addedp(GFSHARE_S(me), i)) VALERR("this share already added");
237 if (GFSHARE_S(me)->i >= GFSHARE_S(me)->t) VALERR("enough shares already");
238 gfshare_add(GFSHARE_S(me), i, s.p);
239 return (PyInt_FromLong(GFSHARE_S(me)->t - GFSHARE_S(me)->i));
240 end:
241 return (0);
242 }
243
244 static PyObject *gfsmeth_combine(PyObject *me)
245 {
246 PyObject *rc = 0;
247 if (GFSHARE_S(me)->i < GFSHARE_S(me)->t) VALERR("not enough shares yet");
248 rc = bytestring_pywrap(0, GFSHARE_S(me)->sz);
249 gfshare_combine(GFSHARE_S(me), BIN_PTR(rc));
250 end:
251 return (rc);
252 }
253
254 static const PyMethodDef gfsharejoin_pymethods[] = {
255 #define METHNAME(name) gfsmeth_##name
256 METH (addedp, "S.addedp(I) -> BOOL")
257 METH (add, "S.add(I, SHARE) -> REMAIN")
258 NAMETH(combine, "S.combine() -> SECRET")
259 #undef METHNAME
260 { 0 }
261 };
262
263 static PyObject *gfsget_remain(PyObject *me, void *hunoz)
264 { return (PyInt_FromLong(GFSHARE_S(me)->t - GFSHARE_S(me)->i)); }
265
266 static const PyGetSetDef gfsharejoin_pygetset[]= {
267 #define GETSETNAME(op, name) gfs##op##_##name
268 GET (remain, "S.remain -> REMAIN")
269 #undef GETSETNAME
270 { 0 }
271 };
272
273 static const PyTypeObject gfsharejoin_pytype_skel = {
274 PyVarObject_HEAD_INIT(0, 0) /* Header */
275 "GFShareJoin", /* @tp_name@ */
276 sizeof(gfshare_pyobj), /* @tp_basicsize@ */
277 0, /* @tp_itemsize@ */
278
279 gfshare_pydealloc, /* @tp_dealloc@ */
280 0, /* @tp_print@ */
281 0, /* @tp_getattr@ */
282 0, /* @tp_setattr@ */
283 0, /* @tp_compare@ */
284 0, /* @tp_repr@ */
285 0, /* @tp_as_number@ */
286 0, /* @tp_as_sequence@ */
287 0, /* @tp_as_mapping@ */
288 0, /* @tp_hash@ */
289 0, /* @tp_call@ */
290 0, /* @tp_str@ */
291 0, /* @tp_getattro@ */
292 0, /* @tp_setattro@ */
293 0, /* @tp_as_buffer@ */
294 Py_TPFLAGS_DEFAULT | /* @tp_flags@ */
295 Py_TPFLAGS_BASETYPE,
296
297 /* @tp_doc@ */
298 "GFShareJoin(THRESHOLD, SIZE): binary field sharing:\n"
299 " join shares to recover secret.",
300
301 0, /* @tp_traverse@ */
302 0, /* @tp_clear@ */
303 0, /* @tp_richcompare@ */
304 0, /* @tp_weaklistoffset@ */
305 0, /* @tp_iter@ */
306 0, /* @tp_iternext@ */
307 PYMETHODS(gfsharejoin), /* @tp_methods@ */
308 0, /* @tp_members@ */
309 PYGETSET(gfsharejoin), /* @tp_getset@ */
310 0, /* @tp_base@ */
311 0, /* @tp_dict@ */
312 0, /* @tp_descr_get@ */
313 0, /* @tp_descr_set@ */
314 0, /* @tp_dictoffset@ */
315 0, /* @tp_init@ */
316 PyType_GenericAlloc, /* @tp_alloc@ */
317 gfsharejoin_pynew, /* @tp_new@ */
318 0, /* @tp_free@ */
319 0 /* @tp_is_gc@ */
320 };
321
322 /*----- Prime-field secret-sharing ----------------------------------------*/
323
324 typedef struct share_pyobj {
325 PyObject_HEAD
326 share s;
327 } share_pyobj;
328
329 static PyTypeObject
330 *share_pytype, *sharesplit_pytype, *sharejoin_pytype;
331 #define SHARE_PYCHECK(o) PyObject_TypeCheck((o), share_pytype)
332 #define SHARESPLIT_PYCHECK(o) PyObject_TypeCheck((o), sharesplit_pytype)
333 #define SHAREJOIN_PYCHECK(o) PyObject_TypeCheck((o), sharejoin_pytype)
334 #define SHARE_S(o) (&((share_pyobj *)(o))->s)
335
336 static void share_pydealloc(PyObject *me)
337 {
338 share_destroy(SHARE_S(me));
339 FREEOBJ(me);
340 }
341
342 static PyObject *sget_threshold(PyObject *me, void *hunoz)
343 { return (PyInt_FromLong(SHARE_S(me)->t)); }
344 static PyObject *sget_modulus(PyObject *me, void *hunoz)
345 { return (mp_pywrap(SHARE_S(me)->p)); }
346
347 static const PyGetSetDef share_pygetset[]= {
348 #define GETSETNAME(op, name) s##op##_##name
349 GET (threshold, "S.threshold -> THRESHOLD")
350 GET (modulus, "S.modulus -> MODULUS")
351 #undef GETSETNAME
352 { 0 }
353 };
354
355 static const PyTypeObject share_pytype_skel = {
356 PyVarObject_HEAD_INIT(0, 0) /* Header */
357 "Share", /* @tp_name@ */
358 sizeof(share_pyobj), /* @tp_basicsize@ */
359 0, /* @tp_itemsize@ */
360
361 share_pydealloc, /* @tp_dealloc@ */
362 0, /* @tp_print@ */
363 0, /* @tp_getattr@ */
364 0, /* @tp_setattr@ */
365 0, /* @tp_compare@ */
366 0, /* @tp_repr@ */
367 0, /* @tp_as_number@ */
368 0, /* @tp_as_sequence@ */
369 0, /* @tp_as_mapping@ */
370 0, /* @tp_hash@ */
371 0, /* @tp_call@ */
372 0, /* @tp_str@ */
373 0, /* @tp_getattro@ */
374 0, /* @tp_setattro@ */
375 0, /* @tp_as_buffer@ */
376 Py_TPFLAGS_DEFAULT | /* @tp_flags@ */
377 Py_TPFLAGS_BASETYPE,
378
379 /* @tp_doc@ */
380 "Prime-field secret sharing base class.",
381
382 0, /* @tp_traverse@ */
383 0, /* @tp_clear@ */
384 0, /* @tp_richcompare@ */
385 0, /* @tp_weaklistoffset@ */
386 0, /* @tp_iter@ */
387 0, /* @tp_iternext@ */
388 0, /* @tp_methods@ */
389 0, /* @tp_members@ */
390 PYGETSET(share), /* @tp_getset@ */
391 0, /* @tp_base@ */
392 0, /* @tp_dict@ */
393 0, /* @tp_descr_get@ */
394 0, /* @tp_descr_set@ */
395 0, /* @tp_dictoffset@ */
396 0, /* @tp_init@ */
397 PyType_GenericAlloc, /* @tp_alloc@ */
398 abstract_pynew, /* @tp_new@ */
399 0, /* @tp_free@ */
400 0 /* @tp_is_gc@ */
401 };
402
403 static PyObject *sharesplit_pynew(PyTypeObject *ty,
404 PyObject *arg, PyObject *kw)
405 {
406 mp *sec = 0;
407 unsigned t;
408 grand *r = &rand_global;
409 mp *m = 0;
410 share_pyobj *s;
411 static const char *const kwlist[] =
412 { "threshold", "secret", "modulus", "rng", 0 };
413
414 if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&|O&O&:new", KWLIST,
415 convuint, &t, convmp, &sec,
416 convmp, &m, convgrand, &r))
417 goto end;
418 if (!t) VALERR("threshold must be nonzero");
419 s = (share_pyobj *)ty->tp_alloc(ty, 0);
420 share_create(&s->s, t);
421 s->s.p = m;
422 share_mkshares(&s->s, r, sec);
423 mp_drop(sec);
424 return ((PyObject *)s);
425 end:
426 mp_drop(m);
427 mp_drop(sec);
428 return (0);
429 }
430
431 static PyObject *smeth_get(PyObject *me, PyObject *arg)
432 {
433 unsigned i;
434 PyObject *rc = 0;
435 if (!PyArg_ParseTuple(arg, "O&:get", convuint, &i)) goto end;
436 rc = mp_pywrap(share_get(SHARE_S(me), MP_NEW, i));
437 end:
438 return (rc);
439 }
440
441 static const PyMethodDef sharesplit_pymethods[] = {
442 #define METHNAME(name) smeth_##name
443 METH (get, "S.get(I) -> SHARE")
444 #undef METHNAME
445 { 0 }
446 };
447
448 static const PyTypeObject sharesplit_pytype_skel = {
449 PyVarObject_HEAD_INIT(0, 0) /* Header */
450 "ShareSplit", /* @tp_name@ */
451 sizeof(share_pyobj), /* @tp_basicsize@ */
452 0, /* @tp_itemsize@ */
453
454 share_pydealloc, /* @tp_dealloc@ */
455 0, /* @tp_print@ */
456 0, /* @tp_getattr@ */
457 0, /* @tp_setattr@ */
458 0, /* @tp_compare@ */
459 0, /* @tp_repr@ */
460 0, /* @tp_as_number@ */
461 0, /* @tp_as_sequence@ */
462 0, /* @tp_as_mapping@ */
463 0, /* @tp_hash@ */
464 0, /* @tp_call@ */
465 0, /* @tp_str@ */
466 0, /* @tp_getattro@ */
467 0, /* @tp_setattro@ */
468 0, /* @tp_as_buffer@ */
469 Py_TPFLAGS_DEFAULT | /* @tp_flags@ */
470 Py_TPFLAGS_BASETYPE,
471
472 /* @tp_doc@ */
473 "ShareSplit(THRESHOLD, SECRET, [modulus = ?], [rng = rand]):\n"
474 " prime field secret sharing: split secret into shares.",
475
476 0, /* @tp_traverse@ */
477 0, /* @tp_clear@ */
478 0, /* @tp_richcompare@ */
479 0, /* @tp_weaklistoffset@ */
480 0, /* @tp_iter@ */
481 0, /* @tp_iternext@ */
482 PYMETHODS(sharesplit), /* @tp_methods@ */
483 0, /* @tp_members@ */
484 0, /* @tp_getset@ */
485 0, /* @tp_base@ */
486 0, /* @tp_dict@ */
487 0, /* @tp_descr_get@ */
488 0, /* @tp_descr_set@ */
489 0, /* @tp_dictoffset@ */
490 0, /* @tp_init@ */
491 PyType_GenericAlloc, /* @tp_alloc@ */
492 sharesplit_pynew, /* @tp_new@ */
493 0, /* @tp_free@ */
494 0 /* @tp_is_gc@ */
495 };
496
497 static PyObject *sharejoin_pynew(PyTypeObject *ty,
498 PyObject *arg, PyObject *kw)
499 {
500 unsigned t;
501 mp *m = 0;
502 share_pyobj *s;
503 static const char *const kwlist[] = { "threshold", "modulus", 0 };
504 if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&:new", KWLIST,
505 convuint, &t, convmp, &m))
506 goto end;
507 if (!t) VALERR("threshold must be nonzero");
508 s = (share_pyobj *)ty->tp_alloc(ty, 0);
509 share_create(&s->s, t);
510 s->s.p = m;
511 return ((PyObject *)s);
512 end:
513 mp_drop(m);
514 return (0);
515 }
516
517 static PyObject *smeth_addedp(PyObject *me, PyObject *arg)
518 {
519 unsigned i;
520 if (!PyArg_ParseTuple(arg, "O&:addedp", convuint, &i)) goto end;
521 return (getbool(share_addedp(SHARE_S(me), i)));
522 end:
523 return (0);
524 }
525
526 static PyObject *smeth_add(PyObject *me, PyObject *arg)
527 {
528 unsigned i;
529 mp *s = 0;
530 PyObject *rc = 0;
531 if (!PyArg_ParseTuple(arg, "O&O&:add", convuint, &i, convmp, &s)) goto end;
532 if (MP_NEGP(s) || MP_CMP(s, >=, SHARE_S(me)->p))
533 VALERR("share out of range");
534 if (share_addedp(SHARE_S(me), i)) VALERR("this share already added");
535 if (SHARE_S(me)->i >= SHARE_S(me)->t) VALERR("enough shares already");
536 share_add(SHARE_S(me), i, s);
537 rc = PyInt_FromLong(SHARE_S(me)->t - SHARE_S(me)->i);
538 end:
539 mp_drop(s);
540 return (rc);
541 }
542
543 static PyObject *smeth_combine(PyObject *me)
544 {
545 PyObject *rc = 0;
546 if (SHARE_S(me)->i < SHARE_S(me)->t) VALERR("not enough shares yet");
547 rc = mp_pywrap(share_combine(SHARE_S(me)));
548 end:
549 return (rc);
550 }
551
552 static const PyMethodDef sharejoin_pymethods[] = {
553 #define METHNAME(name) smeth_##name
554 METH (addedp, "S.addedp(I) -> BOOL")
555 METH (add, "S.add(I, SHARE) -> REMAIN")
556 NAMETH(combine, "S.combine() -> SECRET")
557 #undef METHNAME
558 { 0 }
559 };
560
561 static PyObject *sget_remain(PyObject *me, void *hunoz)
562 { return (PyInt_FromLong(SHARE_S(me)->t - SHARE_S(me)->i)); }
563
564 static const PyGetSetDef sharejoin_pygetset[]= {
565 #define GETSETNAME(op, name) s##op##_##name
566 GET (remain, "S.remain -> REMAIN")
567 #undef GETSETNAME
568 { 0 }
569 };
570
571 static const PyTypeObject sharejoin_pytype_skel = {
572 PyVarObject_HEAD_INIT(0, 0) /* Header */
573 "ShareJoin", /* @tp_name@ */
574 sizeof(share_pyobj), /* @tp_basicsize@ */
575 0, /* @tp_itemsize@ */
576
577 share_pydealloc, /* @tp_dealloc@ */
578 0, /* @tp_print@ */
579 0, /* @tp_getattr@ */
580 0, /* @tp_setattr@ */
581 0, /* @tp_compare@ */
582 0, /* @tp_repr@ */
583 0, /* @tp_as_number@ */
584 0, /* @tp_as_sequence@ */
585 0, /* @tp_as_mapping@ */
586 0, /* @tp_hash@ */
587 0, /* @tp_call@ */
588 0, /* @tp_str@ */
589 0, /* @tp_getattro@ */
590 0, /* @tp_setattro@ */
591 0, /* @tp_as_buffer@ */
592 Py_TPFLAGS_DEFAULT | /* @tp_flags@ */
593 Py_TPFLAGS_BASETYPE,
594
595 /* @tp_doc@ */
596 "ShareJoin(THRESHOLD, MODULUS): prime field secret sharing:\n"
597 " join shares to recover secret.",
598
599 0, /* @tp_traverse@ */
600 0, /* @tp_clear@ */
601 0, /* @tp_richcompare@ */
602 0, /* @tp_weaklistoffset@ */
603 0, /* @tp_iter@ */
604 0, /* @tp_iternext@ */
605 PYMETHODS(sharejoin), /* @tp_methods@ */
606 0, /* @tp_members@ */
607 PYGETSET(sharejoin), /* @tp_getset@ */
608 0, /* @tp_base@ */
609 0, /* @tp_dict@ */
610 0, /* @tp_descr_get@ */
611 0, /* @tp_descr_set@ */
612 0, /* @tp_dictoffset@ */
613 0, /* @tp_init@ */
614 PyType_GenericAlloc, /* @tp_alloc@ */
615 sharejoin_pynew, /* @tp_new@ */
616 0, /* @tp_free@ */
617 0 /* @tp_is_gc@ */
618 };
619
620 /*----- Global stuff ------------------------------------------------------*/
621
622 void share_pyinit(void)
623 {
624 INITTYPE(gfshare, root);
625 INITTYPE(gfsharesplit, gfshare);
626 INITTYPE(gfsharejoin, gfshare);
627 INITTYPE(share, root);
628 INITTYPE(sharesplit, share);
629 INITTYPE(sharejoin, share);
630 }
631
632 void share_pyinsert(PyObject *mod)
633 {
634 INSERT("GFShare", gfshare_pytype);
635 INSERT("GFShareSplit", gfsharesplit_pytype);
636 INSERT("GFShareJoin", gfsharejoin_pytype);
637 INSERT("Share", share_pytype);
638 INSERT("ShareSplit", sharesplit_pytype);
639 INSERT("ShareJoin", sharejoin_pytype);
640 }
641
642 /*----- That's all, folks -------------------------------------------------*/