46e6ad89 |
1 | /* -*-c-*- |
46e6ad89 |
2 | * |
3 | * Secret sharing |
4 | * |
5 | * (c) 2005 Straylight/Edgeware |
6 | */ |
7 | |
b2687a0a |
8 | /*----- Licensing notice --------------------------------------------------* |
46e6ad89 |
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. |
b2687a0a |
16 | * |
46e6ad89 |
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. |
b2687a0a |
21 | * |
46e6ad89 |
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 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 PyTypeObject gfshare_pytype_skel = { |
65 | PyObject_HEAD_INIT(&PyType_Type) 0, /* Header */ |
c461c9b3 |
66 | "GFShare", /* @tp_name@ */ |
46e6ad89 |
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@ */ |
963a6148 |
96 | 0, /* @tp_iternext@ */ |
46e6ad89 |
97 | 0, /* @tp_methods@ */ |
98 | 0, /* @tp_members@ */ |
99 | gfshare_pygetset, /* @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 | char *p; |
116 | int n; |
117 | unsigned t; |
118 | grand *r = &rand_global; |
119 | gfshare_pyobj *s; |
120 | char *kwlist[] = { "threshold", "secret", "rng", 0 }; |
121 | if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&s#|O&:new", kwlist, |
122 | convuint, &t, &p, &n, 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, n); |
127 | gfshare_mkshares(&s->s, r, 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, PyString_AS_STRING(rc)); |
141 | end: |
142 | return (rc); |
143 | } |
144 | |
145 | static 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 PyTypeObject gfsharesplit_pytype_skel = { |
153 | PyObject_HEAD_INIT(&PyType_Type) 0, /* Header */ |
c461c9b3 |
154 | "GFShareSplit", /* @tp_name@ */ |
46e6ad89 |
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 | "Binary field secret sharing: split secret into shares.", |
178 | |
179 | 0, /* @tp_traverse@ */ |
180 | 0, /* @tp_clear@ */ |
181 | 0, /* @tp_richcompare@ */ |
182 | 0, /* @tp_weaklistoffset@ */ |
183 | 0, /* @tp_iter@ */ |
963a6148 |
184 | 0, /* @tp_iternext@ */ |
46e6ad89 |
185 | gfsharesplit_pymethods, /* @tp_methods@ */ |
186 | 0, /* @tp_members@ */ |
187 | 0, /* @tp_getset@ */ |
188 | 0, /* @tp_base@ */ |
189 | 0, /* @tp_dict@ */ |
190 | 0, /* @tp_descr_get@ */ |
191 | 0, /* @tp_descr_set@ */ |
192 | 0, /* @tp_dictoffset@ */ |
193 | 0, /* @tp_init@ */ |
194 | PyType_GenericAlloc, /* @tp_alloc@ */ |
195 | gfsharesplit_pynew, /* @tp_new@ */ |
196 | 0, /* @tp_free@ */ |
197 | 0 /* @tp_is_gc@ */ |
198 | }; |
199 | |
200 | static PyObject *gfsharejoin_pynew(PyTypeObject *ty, |
201 | PyObject *arg, PyObject *kw) |
202 | { |
203 | unsigned t, sz; |
204 | gfshare_pyobj *s; |
205 | char *kwlist[] = { "threshold", "size", 0 }; |
206 | if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&:new", kwlist, |
207 | convuint, &t, convuint, &sz)) |
208 | goto end; |
209 | if (!t || t > 255) VALERR("threshold must be nonzero and < 256"); |
210 | s = (gfshare_pyobj *)ty->tp_alloc(ty, 0); |
211 | gfshare_create(&s->s, t, sz); |
212 | return ((PyObject *)s); |
213 | end: |
214 | return (0); |
215 | } |
216 | |
217 | static PyObject *gfsmeth_addedp(PyObject *me, PyObject *arg) |
218 | { |
219 | unsigned i; |
220 | if (!PyArg_ParseTuple(arg, "O&:addedp", convuint, &i)) goto end; |
221 | if (i > 254) VALERR("index must be < 255"); |
222 | return (getbool(gfshare_addedp(GFSHARE_S(me), i))); |
223 | end: |
224 | return (0); |
225 | } |
226 | |
227 | static PyObject *gfsmeth_add(PyObject *me, PyObject *arg) |
228 | { |
229 | unsigned i; |
230 | char *p; |
231 | int n; |
232 | if (!PyArg_ParseTuple(arg, "O&s#:add", convuint, &i, &p, &n)) goto end; |
233 | if (i > 254) VALERR("index must be < 255"); |
234 | if (n != GFSHARE_S(me)->sz) VALERR("bad share size"); |
235 | if (gfshare_addedp(GFSHARE_S(me), i)) VALERR("this share already added"); |
236 | if (GFSHARE_S(me)->i >= GFSHARE_S(me)->t) VALERR("enough shares already"); |
237 | gfshare_add(GFSHARE_S(me), i, p); |
238 | return (PyInt_FromLong(GFSHARE_S(me)->t - GFSHARE_S(me)->i)); |
239 | end: |
240 | return (0); |
241 | } |
242 | |
243 | static PyObject *gfsmeth_combine(PyObject *me, PyObject *arg) |
244 | { |
245 | PyObject *rc = 0; |
246 | if (!PyArg_ParseTuple(arg, ":combine")) goto end; |
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), PyString_AS_STRING(rc)); |
250 | end: |
251 | return (rc); |
252 | } |
253 | |
254 | static 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 | METH (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 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 PyTypeObject gfsharejoin_pytype_skel = { |
274 | PyObject_HEAD_INIT(&PyType_Type) 0, /* Header */ |
c461c9b3 |
275 | "GFShareJoin", /* @tp_name@ */ |
46e6ad89 |
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 | "Binary field secret sharing: join shares to recover secret.", |
299 | |
300 | 0, /* @tp_traverse@ */ |
301 | 0, /* @tp_clear@ */ |
302 | 0, /* @tp_richcompare@ */ |
303 | 0, /* @tp_weaklistoffset@ */ |
304 | 0, /* @tp_iter@ */ |
963a6148 |
305 | 0, /* @tp_iternext@ */ |
46e6ad89 |
306 | gfsharejoin_pymethods, /* @tp_methods@ */ |
307 | 0, /* @tp_members@ */ |
308 | gfsharejoin_pygetset, /* @tp_getset@ */ |
309 | 0, /* @tp_base@ */ |
310 | 0, /* @tp_dict@ */ |
311 | 0, /* @tp_descr_get@ */ |
312 | 0, /* @tp_descr_set@ */ |
313 | 0, /* @tp_dictoffset@ */ |
314 | 0, /* @tp_init@ */ |
315 | PyType_GenericAlloc, /* @tp_alloc@ */ |
316 | gfsharejoin_pynew, /* @tp_new@ */ |
317 | 0, /* @tp_free@ */ |
318 | 0 /* @tp_is_gc@ */ |
319 | }; |
320 | |
321 | /*----- Prime-field secret-sharing ----------------------------------------*/ |
322 | |
323 | typedef struct share_pyobj { |
324 | PyObject_HEAD |
325 | share s; |
326 | } share_pyobj; |
327 | |
328 | static PyTypeObject |
329 | *share_pytype, *sharesplit_pytype, *sharejoin_pytype; |
330 | #define SHARE_PYCHECK(o) PyObject_TypeCheck((o), share_pytype) |
331 | #define SHARESPLIT_PYCHECK(o) PyObject_TypeCheck((o), sharesplit_pytype) |
332 | #define SHAREJOIN_PYCHECK(o) PyObject_TypeCheck((o), sharejoin_pytype) |
333 | #define SHARE_S(o) (&((share_pyobj *)(o))->s) |
334 | |
335 | static void share_pydealloc(PyObject *me) |
336 | { |
337 | share_destroy(SHARE_S(me)); |
338 | FREEOBJ(me); |
339 | } |
340 | |
341 | static PyObject *sget_threshold(PyObject *me, void *hunoz) |
342 | { return (PyInt_FromLong(SHARE_S(me)->t)); } |
343 | static PyObject *sget_modulus(PyObject *me, void *hunoz) |
344 | { return (mp_pywrap(SHARE_S(me)->p)); } |
345 | |
346 | static PyGetSetDef share_pygetset[]= { |
347 | #define GETSETNAME(op, name) s##op##_##name |
348 | GET (threshold, "S.threshold -> THRESHOLD") |
349 | GET (modulus, "S.modulus -> MODULUS") |
350 | #undef GETSETNAME |
351 | { 0 } |
352 | }; |
353 | |
354 | static PyTypeObject share_pytype_skel = { |
355 | PyObject_HEAD_INIT(&PyType_Type) 0, /* Header */ |
c461c9b3 |
356 | "Share", /* @tp_name@ */ |
46e6ad89 |
357 | sizeof(share_pyobj), /* @tp_basicsize@ */ |
358 | 0, /* @tp_itemsize@ */ |
359 | |
360 | share_pydealloc, /* @tp_dealloc@ */ |
361 | 0, /* @tp_print@ */ |
362 | 0, /* @tp_getattr@ */ |
363 | 0, /* @tp_setattr@ */ |
364 | 0, /* @tp_compare@ */ |
365 | 0, /* @tp_repr@ */ |
366 | 0, /* @tp_as_number@ */ |
367 | 0, /* @tp_as_sequence@ */ |
368 | 0, /* @tp_as_mapping@ */ |
369 | 0, /* @tp_hash@ */ |
370 | 0, /* @tp_call@ */ |
371 | 0, /* @tp_str@ */ |
372 | 0, /* @tp_getattro@ */ |
373 | 0, /* @tp_setattro@ */ |
374 | 0, /* @tp_as_buffer@ */ |
375 | Py_TPFLAGS_DEFAULT | /* @tp_flags@ */ |
376 | Py_TPFLAGS_BASETYPE, |
377 | |
378 | /* @tp_doc@ */ |
379 | "Prime-field secret sharing base class.", |
380 | |
381 | 0, /* @tp_traverse@ */ |
382 | 0, /* @tp_clear@ */ |
383 | 0, /* @tp_richcompare@ */ |
384 | 0, /* @tp_weaklistoffset@ */ |
385 | 0, /* @tp_iter@ */ |
963a6148 |
386 | 0, /* @tp_iternext@ */ |
46e6ad89 |
387 | 0, /* @tp_methods@ */ |
388 | 0, /* @tp_members@ */ |
389 | share_pygetset, /* @tp_getset@ */ |
390 | 0, /* @tp_base@ */ |
391 | 0, /* @tp_dict@ */ |
392 | 0, /* @tp_descr_get@ */ |
393 | 0, /* @tp_descr_set@ */ |
394 | 0, /* @tp_dictoffset@ */ |
395 | 0, /* @tp_init@ */ |
396 | PyType_GenericAlloc, /* @tp_alloc@ */ |
397 | abstract_pynew, /* @tp_new@ */ |
398 | 0, /* @tp_free@ */ |
399 | 0 /* @tp_is_gc@ */ |
400 | }; |
401 | |
402 | static PyObject *sharesplit_pynew(PyTypeObject *ty, |
403 | PyObject *arg, PyObject *kw) |
404 | { |
405 | mp *sec = 0; |
406 | unsigned t; |
407 | grand *r = &rand_global; |
408 | mp *m = 0; |
409 | share_pyobj *s; |
410 | char *kwlist[] = { "threshold", "secret", "modulus", "rng", 0 }; |
505af5a6 |
411 | if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&|O&O&:new", kwlist, |
46e6ad89 |
412 | convuint, &t, convmp, &sec, |
413 | convmp, &m, convgrand, &r)) |
414 | goto end; |
415 | if (!t) VALERR("threshold must be nonzero"); |
416 | s = (share_pyobj *)ty->tp_alloc(ty, 0); |
417 | share_create(&s->s, t); |
418 | s->s.p = m; |
419 | share_mkshares(&s->s, r, sec); |
420 | mp_drop(sec); |
421 | return ((PyObject *)s); |
422 | end: |
423 | mp_drop(m); |
424 | mp_drop(sec); |
425 | return (0); |
426 | } |
427 | |
428 | static PyObject *smeth_get(PyObject *me, PyObject *arg) |
429 | { |
430 | unsigned i; |
431 | PyObject *rc = 0; |
432 | if (!PyArg_ParseTuple(arg, "O&:get", convuint, &i)) goto end; |
433 | rc = mp_pywrap(share_get(SHARE_S(me), MP_NEW, i)); |
434 | end: |
435 | return (rc); |
436 | } |
437 | |
438 | static PyMethodDef sharesplit_pymethods[] = { |
439 | #define METHNAME(name) smeth_##name |
440 | METH (get, "S.get(I) -> SHARE") |
441 | #undef METHNAME |
442 | { 0 } |
443 | }; |
444 | |
445 | static PyTypeObject sharesplit_pytype_skel = { |
446 | PyObject_HEAD_INIT(&PyType_Type) 0, /* Header */ |
c461c9b3 |
447 | "ShareSplit", /* @tp_name@ */ |
46e6ad89 |
448 | sizeof(share_pyobj), /* @tp_basicsize@ */ |
449 | 0, /* @tp_itemsize@ */ |
450 | |
451 | share_pydealloc, /* @tp_dealloc@ */ |
452 | 0, /* @tp_print@ */ |
453 | 0, /* @tp_getattr@ */ |
454 | 0, /* @tp_setattr@ */ |
455 | 0, /* @tp_compare@ */ |
456 | 0, /* @tp_repr@ */ |
457 | 0, /* @tp_as_number@ */ |
458 | 0, /* @tp_as_sequence@ */ |
459 | 0, /* @tp_as_mapping@ */ |
460 | 0, /* @tp_hash@ */ |
461 | 0, /* @tp_call@ */ |
462 | 0, /* @tp_str@ */ |
463 | 0, /* @tp_getattro@ */ |
464 | 0, /* @tp_setattro@ */ |
465 | 0, /* @tp_as_buffer@ */ |
466 | Py_TPFLAGS_DEFAULT | /* @tp_flags@ */ |
467 | Py_TPFLAGS_BASETYPE, |
468 | |
469 | /* @tp_doc@ */ |
470 | "Prime field secret sharing: split secret into shares.", |
471 | |
472 | 0, /* @tp_traverse@ */ |
473 | 0, /* @tp_clear@ */ |
474 | 0, /* @tp_richcompare@ */ |
475 | 0, /* @tp_weaklistoffset@ */ |
476 | 0, /* @tp_iter@ */ |
963a6148 |
477 | 0, /* @tp_iternext@ */ |
46e6ad89 |
478 | sharesplit_pymethods, /* @tp_methods@ */ |
479 | 0, /* @tp_members@ */ |
480 | 0, /* @tp_getset@ */ |
481 | 0, /* @tp_base@ */ |
482 | 0, /* @tp_dict@ */ |
483 | 0, /* @tp_descr_get@ */ |
484 | 0, /* @tp_descr_set@ */ |
485 | 0, /* @tp_dictoffset@ */ |
486 | 0, /* @tp_init@ */ |
487 | PyType_GenericAlloc, /* @tp_alloc@ */ |
488 | sharesplit_pynew, /* @tp_new@ */ |
489 | 0, /* @tp_free@ */ |
490 | 0 /* @tp_is_gc@ */ |
491 | }; |
492 | |
493 | static PyObject *sharejoin_pynew(PyTypeObject *ty, |
494 | PyObject *arg, PyObject *kw) |
495 | { |
496 | unsigned t; |
497 | mp *m = 0; |
498 | share_pyobj *s; |
499 | char *kwlist[] = { "threshold", "modulus", 0 }; |
500 | if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&:new", kwlist, |
501 | convuint, &t, convmp, &m)) |
502 | goto end; |
503 | if (!t) VALERR("threshold must be nonzero"); |
504 | s = (share_pyobj *)ty->tp_alloc(ty, 0); |
505 | share_create(&s->s, t); |
506 | s->s.p = m; |
507 | return ((PyObject *)s); |
508 | end: |
509 | mp_drop(m); |
510 | return (0); |
511 | } |
512 | |
513 | static PyObject *smeth_addedp(PyObject *me, PyObject *arg) |
514 | { |
515 | unsigned i; |
516 | if (!PyArg_ParseTuple(arg, "O&:addedp", convuint, &i)) goto end; |
517 | return (getbool(share_addedp(SHARE_S(me), i))); |
518 | end: |
519 | return (0); |
520 | } |
521 | |
522 | static PyObject *smeth_add(PyObject *me, PyObject *arg) |
523 | { |
524 | unsigned i; |
525 | mp *s = 0; |
526 | PyObject *rc = 0; |
527 | if (!PyArg_ParseTuple(arg, "O&O&:add", convuint, &i, convmp, &s)) goto end; |
528 | if (MP_NEGP(s) || MP_CMP(s, >=, SHARE_S(me)->p)) |
529 | VALERR("share out of range"); |
530 | if (share_addedp(SHARE_S(me), i)) VALERR("this share already added"); |
531 | if (SHARE_S(me)->i >= SHARE_S(me)->t) VALERR("enough shares already"); |
532 | share_add(SHARE_S(me), i, s); |
533 | rc = PyInt_FromLong(SHARE_S(me)->t - SHARE_S(me)->i); |
534 | end: |
535 | mp_drop(s); |
536 | return (rc); |
537 | } |
538 | |
539 | static PyObject *smeth_combine(PyObject *me, PyObject *arg) |
540 | { |
541 | PyObject *rc = 0; |
542 | if (!PyArg_ParseTuple(arg, ":combine")) goto end; |
543 | if (SHARE_S(me)->i < SHARE_S(me)->t) VALERR("not enough shares yet"); |
544 | rc = mp_pywrap(share_combine(SHARE_S(me))); |
545 | end: |
546 | return (rc); |
547 | } |
548 | |
549 | static PyMethodDef sharejoin_pymethods[] = { |
550 | #define METHNAME(name) smeth_##name |
551 | METH (addedp, "S.addedp(I) -> BOOL") |
552 | METH (add, "S.add(I, SHARE) -> REMAIN") |
553 | METH (combine, "S.combine() -> SECRET") |
554 | #undef METHNAME |
555 | { 0 } |
556 | }; |
557 | |
558 | static PyObject *sget_remain(PyObject *me, void *hunoz) |
559 | { return (PyInt_FromLong(SHARE_S(me)->t - SHARE_S(me)->i)); } |
560 | |
561 | static PyGetSetDef sharejoin_pygetset[]= { |
562 | #define GETSETNAME(op, name) s##op##_##name |
563 | GET (remain, "S.remain -> REMAIN") |
564 | #undef GETSETNAME |
565 | { 0 } |
566 | }; |
567 | |
568 | static PyTypeObject sharejoin_pytype_skel = { |
569 | PyObject_HEAD_INIT(&PyType_Type) 0, /* Header */ |
c461c9b3 |
570 | "ShareJoin", /* @tp_name@ */ |
46e6ad89 |
571 | sizeof(share_pyobj), /* @tp_basicsize@ */ |
572 | 0, /* @tp_itemsize@ */ |
573 | |
574 | share_pydealloc, /* @tp_dealloc@ */ |
575 | 0, /* @tp_print@ */ |
576 | 0, /* @tp_getattr@ */ |
577 | 0, /* @tp_setattr@ */ |
578 | 0, /* @tp_compare@ */ |
579 | 0, /* @tp_repr@ */ |
580 | 0, /* @tp_as_number@ */ |
581 | 0, /* @tp_as_sequence@ */ |
582 | 0, /* @tp_as_mapping@ */ |
583 | 0, /* @tp_hash@ */ |
584 | 0, /* @tp_call@ */ |
585 | 0, /* @tp_str@ */ |
586 | 0, /* @tp_getattro@ */ |
587 | 0, /* @tp_setattro@ */ |
588 | 0, /* @tp_as_buffer@ */ |
589 | Py_TPFLAGS_DEFAULT | /* @tp_flags@ */ |
590 | Py_TPFLAGS_BASETYPE, |
591 | |
592 | /* @tp_doc@ */ |
593 | "Prime field secret sharing: join shares to recover secret.", |
594 | |
595 | 0, /* @tp_traverse@ */ |
596 | 0, /* @tp_clear@ */ |
597 | 0, /* @tp_richcompare@ */ |
598 | 0, /* @tp_weaklistoffset@ */ |
599 | 0, /* @tp_iter@ */ |
963a6148 |
600 | 0, /* @tp_iternext@ */ |
46e6ad89 |
601 | sharejoin_pymethods, /* @tp_methods@ */ |
602 | 0, /* @tp_members@ */ |
603 | sharejoin_pygetset, /* @tp_getset@ */ |
604 | 0, /* @tp_base@ */ |
605 | 0, /* @tp_dict@ */ |
606 | 0, /* @tp_descr_get@ */ |
607 | 0, /* @tp_descr_set@ */ |
608 | 0, /* @tp_dictoffset@ */ |
609 | 0, /* @tp_init@ */ |
610 | PyType_GenericAlloc, /* @tp_alloc@ */ |
611 | sharejoin_pynew, /* @tp_new@ */ |
612 | 0, /* @tp_free@ */ |
613 | 0 /* @tp_is_gc@ */ |
614 | }; |
615 | |
616 | /*----- Global stuff ------------------------------------------------------*/ |
617 | |
618 | void share_pyinit(void) |
619 | { |
620 | INITTYPE(gfshare, root); |
621 | INITTYPE(gfsharesplit, gfshare); |
622 | INITTYPE(gfsharejoin, gfshare); |
623 | INITTYPE(share, root); |
624 | INITTYPE(sharesplit, share); |
625 | INITTYPE(sharejoin, share); |
626 | } |
627 | |
628 | void share_pyinsert(PyObject *mod) |
629 | { |
630 | INSERT("GFShare", gfshare_pytype); |
631 | INSERT("GFShareSplit", gfsharesplit_pytype); |
632 | INSERT("GFShareJoin", gfsharejoin_pytype); |
633 | INSERT("Share", share_pytype); |
634 | INSERT("ShareSplit", sharesplit_pytype); |
635 | INSERT("ShareJoin", sharejoin_pytype); |
636 | } |
637 | |
638 | /*----- That's all, folks -------------------------------------------------*/ |