5 * Public-key cryptography
7 * (c) 2004 Straylight/Edgeware
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of the Python interface to Catacomb.
14 * Catacomb/Python is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * Catacomb/Python is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with Catacomb/Python; if not, write to the Free Software Foundation,
26 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 /*----- Header files ------------------------------------------------------*/
31 #include "catacomb-python.h"
33 /*----- DSA and similar ---------------------------------------------------*/
35 typedef struct dsa_pyobj
{
37 PyObject
*G
, *u
, *p
, *rng
, *hash
;
41 static PyTypeObject
*dsapub_pytype
, *dsapriv_pytype
;
42 static PyTypeObject
*kcdsapub_pytype
, *kcdsapriv_pytype
;
43 #define DSA_D(o) (&((dsa_pyobj *)(o))->d)
44 #define DSA_G(o) (((dsa_pyobj *)(o))->G)
45 #define DSA_U(o) (((dsa_pyobj *)(o))->u)
46 #define DSA_P(o) (((dsa_pyobj *)(o))->p)
47 #define DSA_RNG(o) (((dsa_pyobj *)(o))->rng)
48 #define DSA_HASH(o) (((dsa_pyobj *)(o))->hash)
50 static void dsa_pydealloc(PyObject
*me
)
52 dsa_pyobj
*g
= (dsa_pyobj
*)me
;
53 Py_DECREF(g
->G
); Py_DECREF(g
->u
); Py_DECREF(g
->p
);
54 Py_DECREF(g
->rng
); Py_DECREF(g
->hash
);
58 static PyObject
*dsa_setup(PyTypeObject
*ty
, PyObject
*G
, PyObject
*u
,
59 PyObject
*p
, PyObject
*rng
, PyObject
*hash
)
63 g
= PyObject_New(dsa_pyobj
, ty
);
64 if (GROUP_G(G
) != GE_G(p
) && !group_samep(GROUP_G(G
), GE_G(p
)))
65 TYERR("public key not from group");
69 } else if ((g
->d
.u
= getmp(u
)) == 0)
73 g
->d
.r
= GRAND_R(rng
);
74 g
->d
.h
= GCHASH_CH(hash
);
75 g
->G
= G
; Py_INCREF(G
); g
->u
= u
; Py_INCREF(u
); g
->p
= p
; Py_INCREF(p
);
76 rng
= g
->rng
; Py_INCREF(rng
); g
->hash
= hash
; Py_INCREF(hash
);
77 return ((PyObject
*)g
);
83 static PyObject
*dsapub_pynew(PyTypeObject
*ty
,
84 PyObject
*arg
, PyObject
*kw
)
86 PyObject
*G
, *p
, *u
= 0, *rng
= rand_pyobj
, *hash
= sha_pyobj
;
88 char *kwlist
[] = { "G", "p", "u", "hash", "rng", 0 };
90 if (!PyArg_ParseTupleAndKeywords(arg
, kw
, "O!O!O!|OO!:new", kwlist
,
95 grand_pytype
, &rng
) ||
96 (rc
= dsa_setup(dsapub_pytype
, G
, u
, p
, rng
, hash
)) == 0)
102 static PyObject
*dsameth_beginhash(PyObject
*me
, PyObject
*arg
)
104 if (!PyArg_ParseTuple(arg
, ":beginhash")) return (0);
105 return (ghash_pywrap(DSA_HASH(me
), gdsa_beginhash(DSA_D(me
)), f_freeme
));
108 static PyObject
*dsameth_endhash(PyObject
*me
, PyObject
*arg
)
112 if (!PyArg_ParseTuple(arg
, "O&:endhash", convghash
, &h
)) return (0);
113 gdsa_endhash(DSA_D(me
), h
);
115 rc
= bytestring_pywrap(0, GH_CLASS(h
)->hashsz
);
116 GH_DONE(h
, PyString_AS_STRING(rc
));
121 static PyObject
*dsameth_sign(PyObject
*me
, PyObject
*arg
, PyObject
*kw
)
123 gdsa_sig s
= GDSA_SIG_INIT
;
128 char *kwlist
[] = { "msg", "k", 0 };
130 if (!PyArg_ParseTupleAndKeywords(arg
, kw
, "s#|O&:sign", kwlist
,
133 if (n
!= DSA_D(me
)->h
->hashsz
)
134 VALERR("bad message length (doesn't match hash size)");
135 gdsa_sign(DSA_D(me
), &s
, p
, k
);
136 rc
= Py_BuildValue("(NN)", mp_pywrap(s
.r
), mp_pywrap(s
.s
));
142 static PyObject
*dsameth_verify(PyObject
*me
, PyObject
*arg
)
146 gdsa_sig s
= GDSA_SIG_INIT
;
149 if (!PyArg_ParseTuple(arg
, "s#(O&O&):verify",
150 &p
, &n
, convmp
, &s
.r
, convmp
, &s
.s
))
152 if (n
!= DSA_D(me
)->h
->hashsz
)
153 VALERR("bad message length (doesn't match hash size)");
154 rc
= getbool(gdsa_verify(DSA_D(me
), &s
, p
));
161 static PyObject
*dsapriv_pynew(PyTypeObject
*ty
,
162 PyObject
*arg
, PyObject
*kw
)
164 PyObject
*G
, *p
, *u
= Py_None
, *rng
= rand_pyobj
, *hash
= sha_pyobj
;
166 char *kwlist
[] = { "G", "p", "u", "hash", "rng", 0 };
168 if (!PyArg_ParseTupleAndKeywords(arg
, kw
, "O!O!|O!OO!:new", kwlist
,
172 gchash_pytype
, &hash
,
173 grand_pytype
, &rng
) ||
174 (rc
= dsa_setup(dsapriv_pytype
, G
, p
, u
, rng
, hash
)) == 0)
180 static PyMethodDef dsapub_pymethods
[] = {
181 #define METHNAME(name) dsameth_##name
182 METH (beginhash
, "D.beginhash() -> hash object")
183 METH (endhash
, "D.endhash(H) -> BYTES")
184 METH (verify
, "D.verify(MSG, (R, S)) -> true/false")
189 static PyMethodDef dsapriv_pymethods
[] = {
190 #define METHNAME(name) dsameth_##name
191 KWMETH(sign
, "D.sign(MSG, k = K) -> R, S")
196 static PyMemberDef dsapub_pymembers
[] = {
197 #define MEMBERSTRUCT dsa_pyobj
198 MEMBER(G
, T_OBJECT
, READONLY
, "D.G -> group to work in")
199 MEMBER(p
, T_OBJECT
, READONLY
, "D.p -> public key (group element")
200 MEMBER(rng
, T_OBJECT
, READONLY
, "D.rng -> random number generator")
201 MEMBER(hash
, T_OBJECT
, READONLY
, "D.hash -> hash class")
206 static PyMemberDef dsapriv_pymembers
[] = {
207 #define MEMBERSTRUCT dsa_pyobj
208 MEMBER(u
, T_OBJECT
, READONLY
, "D.u -> private key (exponent)")
213 static PyTypeObject dsapub_pytype_skel
= {
214 PyObject_HEAD_INIT(0) 0, /* Header */
215 "catacomb.DSAPub", /* @tp_name@ */
216 sizeof(dsa_pyobj
), /* @tp_basicsize@ */
217 0, /* @tp_itemsize@ */
219 dsa_pydealloc
, /* @tp_dealloc@ */
221 0, /* @tp_getattr@ */
222 0, /* @tp_setattr@ */
223 0, /* @tp_compare@ */
225 0, /* @tp_as_number@ */
226 0, /* @tp_as_sequence@ */
227 0, /* @tp_as_mapping@ */
231 0, /* @tp_getattro@ */
232 0, /* @tp_setattro@ */
233 0, /* @tp_as_buffer@ */
234 Py_TPFLAGS_DEFAULT
| /* @tp_flags@ */
238 "DSA public key information.",
240 0, /* @tp_traverse@ */
242 0, /* @tp_richcompare@ */
243 0, /* @tp_weaklistoffset@ */
245 0, /* @tp_iternext@ */
246 dsapub_pymethods
, /* @tp_methods@ */
247 dsapub_pymembers
, /* @tp_members@ */
251 0, /* @tp_descr_get@ */
252 0, /* @tp_descr_set@ */
253 0, /* @tp_dictoffset@ */
255 PyType_GenericAlloc
, /* @tp_alloc@ */
256 dsapub_pynew
, /* @tp_new@ */
261 static PyTypeObject dsapriv_pytype_skel
= {
262 PyObject_HEAD_INIT(0) 0, /* Header */
263 "catacomb.DSAPriv", /* @tp_name@ */
264 sizeof(dsa_pyobj
), /* @tp_basicsize@ */
265 0, /* @tp_itemsize@ */
267 0, /* @tp_dealloc@ */
269 0, /* @tp_getattr@ */
270 0, /* @tp_setattr@ */
271 0, /* @tp_compare@ */
273 0, /* @tp_as_number@ */
274 0, /* @tp_as_sequence@ */
275 0, /* @tp_as_mapping@ */
279 0, /* @tp_getattro@ */
280 0, /* @tp_setattro@ */
281 0, /* @tp_as_buffer@ */
282 Py_TPFLAGS_DEFAULT
| /* @tp_flags@ */
286 "DSA private key information.",
288 0, /* @tp_traverse@ */
290 0, /* @tp_richcompare@ */
291 0, /* @tp_weaklistoffset@ */
293 0, /* @tp_iternext@ */
294 dsapriv_pymethods
, /* @tp_methods@ */
295 dsapriv_pymembers
, /* @tp_members@ */
299 0, /* @tp_descr_get@ */
300 0, /* @tp_descr_set@ */
301 0, /* @tp_dictoffset@ */
303 PyType_GenericAlloc
, /* @tp_alloc@ */
304 dsapriv_pynew
, /* @tp_new@ */
309 static PyObject
*kcdsapub_pynew(PyTypeObject
*ty
,
310 PyObject
*arg
, PyObject
*kw
)
312 PyObject
*G
, *p
, *u
= 0, *rng
= rand_pyobj
, *hash
= has160_pyobj
;
314 char *kwlist
[] = { "G", "p", "u", "hash", "rng", 0 };
316 if (!PyArg_ParseTupleAndKeywords(arg
, kw
, "O!O!O!|OO!:new", kwlist
,
320 gchash_pytype
, &hash
,
321 grand_pytype
, &rng
) ||
322 (rc
= dsa_setup(kcdsapub_pytype
, G
, p
, u
, rng
, hash
)) == 0)
328 static PyObject
*kcdsapriv_pynew(PyTypeObject
*ty
,
329 PyObject
*arg
, PyObject
*kw
)
331 PyObject
*G
, *p
, *u
= Py_None
, *rng
= rand_pyobj
, *hash
= has160_pyobj
;
333 char *kwlist
[] = { "G", "p", "u", "hash", "rng", 0 };
335 if (!PyArg_ParseTupleAndKeywords(arg
, kw
, "O!O!|O!OO!:new", kwlist
,
339 gchash_pytype
, &hash
,
340 grand_pytype
, &rng
) ||
341 (rc
= dsa_setup(kcdsapriv_pytype
, G
, p
, u
, rng
, hash
)) == 0)
347 static PyObject
*kcdsameth_beginhash(PyObject
*me
, PyObject
*arg
)
349 if (!PyArg_ParseTuple(arg
, ":beginhash")) return (0);
350 return (ghash_pywrap(DSA_HASH(me
), gkcdsa_beginhash(DSA_D(me
)), f_freeme
));
353 static PyObject
*kcdsameth_endhash(PyObject
*me
, PyObject
*arg
)
357 if (!PyArg_ParseTuple(arg
, "O&:endhash", convghash
, &h
)) return (0);
358 gkcdsa_endhash(DSA_D(me
), h
);
360 rc
= bytestring_pywrap(0, GH_CLASS(h
)->hashsz
);
361 GH_DONE(h
, PyString_AS_STRING(rc
));
366 static PyObject
*kcdsameth_sign(PyObject
*me
, PyObject
*arg
, PyObject
*kw
)
368 gkcdsa_sig s
= GKCDSA_SIG_INIT
;
372 PyObject
*r
= 0, *rc
= 0;
373 char *kwlist
[] = { "msg", "k", 0 };
375 if (!PyArg_ParseTupleAndKeywords(arg
, kw
, "s#|O&:sign", kwlist
,
378 if (n
!= DSA_D(me
)->h
->hashsz
)
379 VALERR("bad message length (doesn't match hash size)");
380 r
= bytestring_pywrap(0, DSA_D(me
)->h
->hashsz
);
381 s
.r
= (octet
*)PyString_AS_STRING(r
);
382 gkcdsa_sign(DSA_D(me
), &s
, p
, k
);
383 rc
= Py_BuildValue("(NN)", r
, mp_pywrap(s
.s
));
390 static PyObject
*kcdsameth_verify(PyObject
*me
, PyObject
*arg
)
394 gkcdsa_sig s
= GKCDSA_SIG_INIT
;
397 if (!PyArg_ParseTuple(arg
, "s#(s#O&):verify",
398 &p
, &n
, &s
.r
, &rn
, convmp
, &s
.s
))
400 if (n
!= DSA_D(me
)->h
->hashsz
)
401 VALERR("bad message length (doesn't match hash size)");
402 if (rn
!= DSA_D(me
)->h
->hashsz
)
403 VALERR("bad signature `r' length (doesn't match hash size)");
404 rc
= getbool(gkcdsa_verify(DSA_D(me
), &s
, p
));
410 static PyMethodDef kcdsapub_pymethods
[] = {
411 #define METHNAME(name) kcdsameth_##name
412 METH (beginhash
, "D.beginhash() -> hash object")
413 METH (endhash
, "D.endhash(H) -> BYTES")
414 METH (verify
, "D.verify(MSG, (R, S)) -> true/false")
419 static PyMethodDef kcdsapriv_pymethods
[] = {
420 #define METHNAME(name) kcdsameth_##name
421 KWMETH(sign
, "D.sign(MSG, k = K) -> R, S")
426 static PyTypeObject kcdsapub_pytype_skel
= {
427 PyObject_HEAD_INIT(0) 0, /* Header */
428 "catacomb.KCDSAPub", /* @tp_name@ */
429 sizeof(dsa_pyobj
), /* @tp_basicsize@ */
430 0, /* @tp_itemsize@ */
432 dsa_pydealloc
, /* @tp_dealloc@ */
434 0, /* @tp_getattr@ */
435 0, /* @tp_setattr@ */
436 0, /* @tp_compare@ */
438 0, /* @tp_as_number@ */
439 0, /* @tp_as_sequence@ */
440 0, /* @tp_as_mapping@ */
444 0, /* @tp_getattro@ */
445 0, /* @tp_setattro@ */
446 0, /* @tp_as_buffer@ */
447 Py_TPFLAGS_DEFAULT
| /* @tp_flags@ */
451 "KCDSA public key information.",
453 0, /* @tp_traverse@ */
455 0, /* @tp_richcompare@ */
456 0, /* @tp_weaklistoffset@ */
458 0, /* @tp_iternext@ */
459 kcdsapub_pymethods
, /* @tp_methods@ */
460 dsapub_pymembers
, /* @tp_members@ */
464 0, /* @tp_descr_get@ */
465 0, /* @tp_descr_set@ */
466 0, /* @tp_dictoffset@ */
468 PyType_GenericAlloc
, /* @tp_alloc@ */
469 kcdsapub_pynew
, /* @tp_new@ */
474 static PyTypeObject kcdsapriv_pytype_skel
= {
475 PyObject_HEAD_INIT(0) 0, /* Header */
476 "catacomb.KCDSAPriv", /* @tp_name@ */
477 sizeof(dsa_pyobj
), /* @tp_basicsize@ */
478 0, /* @tp_itemsize@ */
480 0, /* @tp_dealloc@ */
482 0, /* @tp_getattr@ */
483 0, /* @tp_setattr@ */
484 0, /* @tp_compare@ */
486 0, /* @tp_as_number@ */
487 0, /* @tp_as_sequence@ */
488 0, /* @tp_as_mapping@ */
492 0, /* @tp_getattro@ */
493 0, /* @tp_setattro@ */
494 0, /* @tp_as_buffer@ */
495 Py_TPFLAGS_DEFAULT
| /* @tp_flags@ */
499 "KCDSA private key information.",
501 0, /* @tp_traverse@ */
503 0, /* @tp_richcompare@ */
504 0, /* @tp_weaklistoffset@ */
506 0, /* @tp_iternext@ */
507 kcdsapriv_pymethods
, /* @tp_methods@ */
508 dsapriv_pymembers
, /* @tp_members@ */
512 0, /* @tp_descr_get@ */
513 0, /* @tp_descr_set@ */
514 0, /* @tp_dictoffset@ */
516 PyType_GenericAlloc
, /* @tp_alloc@ */
517 kcdsapriv_pynew
, /* @tp_new@ */
522 /*----- RSA ---------------------------------------------------------------*/
524 typedef struct rsapub_pyobj
{
530 #define RSA_PUB(o) (&((rsapub_pyobj *)(o))->pub)
531 #define RSA_PUBCTX(o) (&((rsapub_pyobj *)(o))->pubctx)
533 typedef struct rsapriv_pyobj
{
542 #define RSA_PRIV(o) (&((rsapriv_pyobj *)(o))->priv)
543 #define RSA_PRIVCTX(o) (&((rsapriv_pyobj *)(o))->privctx)
544 #define RSA_RNG(o) (((rsapriv_pyobj *)(o))->rng)
546 static PyTypeObject
*rsapub_pytype
, *rsapriv_pytype
;
548 static PyObject
*rsapub_pynew(PyTypeObject
*ty
,
549 PyObject
*arg
, PyObject
*kw
)
553 char *kwlist
[] = { "n", "e", 0 };
555 if (!PyArg_ParseTupleAndKeywords(arg
, kw
, "O&O&:new", kwlist
,
556 convmp
, &rp
.n
, convmp
, &rp
.e
))
558 o
= (rsapub_pyobj
*)ty
->tp_alloc(ty
, 0);
560 rsa_pubcreate(&o
->pubctx
, &o
->pub
);
561 return ((PyObject
*)o
);
567 static void rsapub_pydealloc(PyObject
*me
)
569 rsa_pubdestroy(RSA_PUBCTX(me
));
570 rsa_pubfree(RSA_PUB(me
));
574 static PyObject
*rsaget_n(PyObject
*me
, void *hunoz
)
575 { return mp_pywrap(MP_COPY(RSA_PUB(me
)->n
)); }
577 static PyObject
*rsaget_e(PyObject
*me
, void *hunoz
)
578 { return mp_pywrap(MP_COPY(RSA_PUB(me
)->e
)); }
580 static PyObject
*rsameth_pubop(PyObject
*me
, PyObject
*arg
)
585 if (!PyArg_ParseTuple(arg
, "O&:pubop", convmp
, &x
)) goto end
;
586 rc
= mp_pywrap(rsa_pubop(RSA_PUBCTX(me
), MP_NEW
, x
));
592 static PyObject
*rsapriv_dopywrap(PyTypeObject
*ty
,
593 rsa_priv
*rp
, PyObject
*rng
)
597 o
= (rsapriv_pyobj
*)ty
->tp_alloc(ty
, 0);
601 rsa_privcreate(&o
->privctx
, &o
->priv
, &rand_global
);
602 rsa_pubcreate(&o
->pubctx
, &o
->pub
);
608 return ((PyObject
*)o
);
611 PyObject
*rsapriv_pywrap(rsa_priv
*rp
)
612 { return rsapriv_dopywrap(rsapriv_pytype
, rp
, 0); }
614 static PyObject
*rsapriv_pynew(PyTypeObject
*ty
,
615 PyObject
*arg
, PyObject
*kw
)
618 PyObject
*rng
= Py_None
;
620 { "n", "e", "d", "p", "q", "dp", "dq", "q_inv", "rng", 0 };
622 if (!PyArg_ParseTupleAndKeywords(arg
, kw
, "|O&O&O&O&O&O&O&O&O:new", kwlist
,
623 convmp
, &rp
.n
, convmp
, &rp
.e
,
625 convmp
, &rp
.p
, convmp
, &rp
.q
,
626 convmp
, &rp
.dp
, convmp
, &rp
.dq
,
630 if (rsa_recover(&rp
)) VALERR("couldn't construct private key");
631 if (rng
!= Py_None
&& !GRAND_PYCHECK(rng
))
632 TYERR("not a random number source");
634 return (rsapriv_dopywrap(ty
, &rp
, rng
));
640 static void rsapriv_pydealloc(PyObject
*me
)
642 RSA_PRIVCTX(me
)->r
= &rand_global
;
643 rsa_privdestroy(RSA_PRIVCTX(me
));
644 rsa_privfree(RSA_PRIV(me
));
645 Py_DECREF(RSA_RNG(me
));
649 static PyObject
*rsaget_d(PyObject
*me
, void *hunoz
)
650 { return mp_pywrap(MP_COPY(RSA_PRIV(me
)->d
)); }
652 static PyObject
*rsaget_p(PyObject
*me
, void *hunoz
)
653 { return mp_pywrap(MP_COPY(RSA_PRIV(me
)->p
)); }
655 static PyObject
*rsaget_q(PyObject
*me
, void *hunoz
)
656 { return mp_pywrap(MP_COPY(RSA_PRIV(me
)->q
)); }
658 static PyObject
*rsaget_dp(PyObject
*me
, void *hunoz
)
659 { return mp_pywrap(MP_COPY(RSA_PRIV(me
)->dp
)); }
661 static PyObject
*rsaget_dq(PyObject
*me
, void *hunoz
)
662 { return mp_pywrap(MP_COPY(RSA_PRIV(me
)->dq
)); }
664 static PyObject
*rsaget_q_inv(PyObject
*me
, void *hunoz
)
665 { return mp_pywrap(MP_COPY(RSA_PRIV(me
)->q_inv
)); }
667 static PyObject
*rsaget_rng(PyObject
*me
, void *hunoz
)
668 { RETURN_OBJ(RSA_RNG(me
)); }
670 static int rsaset_rng(PyObject
*me
, PyObject
*val
, void *hunoz
)
675 else if (val
!= Py_None
&& !GRAND_PYCHECK(val
))
676 TYERR("expected grand or None");
677 Py_DECREF(RSA_RNG(me
));
685 static PyObject
*rsameth_privop(PyObject
*me
, PyObject
*arg
, PyObject
*kw
)
687 PyObject
*rng
= RSA_RNG(me
);
690 char *kwlist
[] = { "x", "rng", 0 };
692 if (!PyArg_ParseTupleAndKeywords(arg
, kw
, "O&|O:privop", kwlist
,
695 if (rng
!= Py_None
&& !GRAND_PYCHECK(rng
))
696 TYERR("not a random number source");
697 RSA_PRIVCTX(me
)->r
= (rng
== Py_None
) ?
0 : GRAND_R(rng
);
698 rc
= mp_pywrap(rsa_privop(RSA_PRIVCTX(me
), MP_NEW
, x
));
704 static PyObject
*meth__RSAPriv_generate(PyObject
*me
,
705 PyObject
*arg
, PyObject
*kw
)
707 grand
*r
= &rand_global
;
712 char *kwlist
[] = { "class", "nbits", "event", "rng", "nsteps", 0 };
715 if (!PyArg_ParseTupleAndKeywords(arg
, kw
, "OO&|O&O&O&:generate", kwlist
,
716 &me
, convuint
, &nbits
, convpgev
, &evt
,
717 convgrand
, &r
, convuint
, &n
))
719 if (rsa_gen(&rp
, nbits
, r
, n
, evt
.proc
, evt
.ctx
))
721 rc
= rsapriv_pywrap(&rp
);
727 static PyGetSetDef rsapub_pygetset
[] = {
728 #define GETSETNAME(op, name) rsa##op##_##name
735 static PyMethodDef rsapub_pymethods
[] = {
736 #define METHNAME(name) rsameth_##name
737 METH (pubop
, "R.pubop(X) -> X^E (mod N)")
742 static PyGetSetDef rsapriv_pygetset
[] = {
743 #define GETSETNAME(op, name) rsa##op##_##name
747 GET (dp
, "R.dp -> D mod (P - 1)")
748 GET (dq
, "R.dq -> D mod (Q - 1)")
749 GET (q_inv
, "R.q_inv -> Q^{-1} mod P")
750 GETSET(rng
, "R.rng -> random number source for blinding")
755 static PyMethodDef rsapriv_pymethods
[] = {
756 #define METHNAME(name) rsameth_##name
757 KWMETH(privop
, "R.privop(X, rng = None) -> X^D (mod N)")
762 static PyTypeObject rsapub_pytype_skel
= {
763 PyObject_HEAD_INIT(0) 0, /* Header */
764 "catacomb.RSAPub", /* @tp_name@ */
765 sizeof(rsapub_pyobj
), /* @tp_basicsize@ */
766 0, /* @tp_itemsize@ */
768 rsapub_pydealloc
, /* @tp_dealloc@ */
770 0, /* @tp_getattr@ */
771 0, /* @tp_setattr@ */
772 0, /* @tp_compare@ */
774 0, /* @tp_as_number@ */
775 0, /* @tp_as_sequence@ */
776 0, /* @tp_as_mapping@ */
780 0, /* @tp_getattro@ */
781 0, /* @tp_setattro@ */
782 0, /* @tp_as_buffer@ */
783 Py_TPFLAGS_DEFAULT
| /* @tp_flags@ */
787 "RSA public key information.",
789 0, /* @tp_traverse@ */
791 0, /* @tp_richcompare@ */
792 0, /* @tp_weaklistoffset@ */
794 0, /* @tp_iternext@ */
795 rsapub_pymethods
, /* @tp_methods@ */
796 0, /* @tp_members@ */
797 rsapub_pygetset
, /* @tp_getset@ */
800 0, /* @tp_descr_get@ */
801 0, /* @tp_descr_set@ */
802 0, /* @tp_dictoffset@ */
804 PyType_GenericAlloc
, /* @tp_alloc@ */
805 rsapub_pynew
, /* @tp_new@ */
810 static PyTypeObject rsapriv_pytype_skel
= {
811 PyObject_HEAD_INIT(0) 0, /* Header */
812 "catacomb.RSAPriv", /* @tp_name@ */
813 sizeof(rsapriv_pyobj
), /* @tp_basicsize@ */
814 0, /* @tp_itemsize@ */
816 rsapriv_pydealloc
, /* @tp_dealloc@ */
818 0, /* @tp_getattr@ */
819 0, /* @tp_setattr@ */
820 0, /* @tp_compare@ */
822 0, /* @tp_as_number@ */
823 0, /* @tp_as_sequence@ */
824 0, /* @tp_as_mapping@ */
828 0, /* @tp_getattro@ */
829 0, /* @tp_setattro@ */
830 0, /* @tp_as_buffer@ */
831 Py_TPFLAGS_DEFAULT
| /* @tp_flags@ */
835 "RSA private key information.",
837 0, /* @tp_traverse@ */
839 0, /* @tp_richcompare@ */
840 0, /* @tp_weaklistoffset@ */
842 0, /* @tp_iternext@ */
843 rsapriv_pymethods
, /* @tp_methods@ */
844 0, /* @tp_members@ */
845 rsapriv_pygetset
, /* @tp_getset@ */
848 0, /* @tp_descr_get@ */
849 0, /* @tp_descr_set@ */
850 0, /* @tp_dictoffset@ */
852 PyType_GenericAlloc
, /* @tp_alloc@ */
853 rsapriv_pynew
, /* @tp_new@ */
858 /*----- RSA padding schemes -----------------------------------------------*/
860 static PyObject
*meth__p1crypt_encode(PyObject
*me
,
861 PyObject
*arg
, PyObject
*kw
)
871 char *kwlist
[] = { "msg", "nbits", "ep", "rng", 0 };
873 p1
.r
= &rand_global
; ep
= 0; epsz
= 0;
874 if (!PyArg_ParseTupleAndKeywords(arg
, kw
, "s#O&|s#O&:encode", kwlist
,
875 &m
, &msz
, convulong
, &nbits
,
876 &ep
, &epsz
, convgrand
, &p1
.r
))
879 p1
.ep
= ep
; p1
.epsz
= epsz
;
880 if (epsz
+ msz
+ 11 > sz
) VALERR("buffer underflow");
882 x
= pkcs1_cryptencode(MP_NEW
, m
, msz
, b
, sz
, nbits
, &p1
);
889 static PyObject
*meth__p1crypt_decode(PyObject
*me
,
890 PyObject
*arg
, PyObject
*kw
)
901 char *kwlist
[] = { "ct", "nbits", "ep", "rng", 0 };
903 p1
.r
= &rand_global
; ep
= 0; epsz
= 0;
904 if (!PyArg_ParseTupleAndKeywords(arg
, kw
, "O&O&|s#O&:decode", kwlist
,
905 convmp
, &x
, convulong
, &nbits
,
906 &ep
, &epsz
, convgrand
, &p1
.r
))
909 p1
.ep
= ep
; p1
.epsz
= epsz
;
910 if (epsz
+ 11 > sz
) VALERR("buffer underflow");
912 if ((n
= pkcs1_cryptdecode(x
, b
, sz
, nbits
, &p1
)) < 0)
913 VALERR("decryption failed");
914 rc
= bytestring_pywrap(b
, n
);
921 static PyObject
*meth__p1sig_encode(PyObject
*me
,
922 PyObject
*arg
, PyObject
*kw
)
932 char *kwlist
[] = { "msg", "nbits", "ep", "rng", 0 };
934 p1
.r
= &rand_global
; ep
= 0; epsz
= 0;
935 if (!PyArg_ParseTupleAndKeywords(arg
, kw
, "s#O&|s#O&:encode", kwlist
,
936 &m
, &msz
, convulong
, &nbits
,
937 &ep
, &epsz
, convgrand
, &p1
.r
))
940 p1
.ep
= ep
; p1
.epsz
= epsz
;
941 if (epsz
+ msz
+ 11 > sz
) VALERR("buffer underflow");
943 x
= pkcs1_sigencode(MP_NEW
, m
, msz
, b
, sz
, nbits
, &p1
);
950 static PyObject
*meth__p1sig_decode(PyObject
*me
,
951 PyObject
*arg
, PyObject
*kw
)
963 char *kwlist
[] = { "msg", "sig", "nbits", "ep", "rng", 0 };
965 p1
.r
= &rand_global
; ep
= 0; epsz
= 0;
966 if (!PyArg_ParseTupleAndKeywords(arg
, kw
, "OO&O&|s#O&:decode", kwlist
,
967 &hukairz
, convmp
, &x
, convulong
, &nbits
,
968 &ep
, &epsz
, convgrand
, &p1
.r
))
971 p1
.ep
= ep
; p1
.epsz
= epsz
;
972 if (epsz
+ 10 > sz
) VALERR("buffer underflow");
974 if ((n
= pkcs1_sigdecode(x
, 0, 0, b
, sz
, nbits
, &p1
)) < 0)
975 VALERR("verification failed");
976 rc
= bytestring_pywrap(b
, n
);
983 static PyObject
*meth__oaep_encode(PyObject
*me
,
984 PyObject
*arg
, PyObject
*kw
)
994 char *kwlist
[] = { "msg", "nbits", "mgf", "hash", "ep", "rng", 0 };
996 o
.r
= &rand_global
; o
.cc
= &sha_mgf
; o
.ch
= &sha
; ep
= 0; epsz
= 0;
997 if (!PyArg_ParseTupleAndKeywords(arg
, kw
, "s#O&|O&O&s#O&:encode", kwlist
,
998 &m
, &msz
, convulong
, &nbits
,
1005 o
.ep
= ep
; o
.epsz
= epsz
;
1006 if (2 * o
.ch
->hashsz
+ 2 + msz
> sz
) VALERR("buffer underflow");
1008 x
= oaep_encode(MP_NEW
, m
, msz
, b
, sz
, nbits
, &o
);
1015 static PyObject
*meth__oaep_decode(PyObject
*me
,
1016 PyObject
*arg
, PyObject
*kw
)
1021 unsigned long nbits
;
1027 char *kwlist
[] = { "ct", "nbits", "mgf", "hash", "ep", "rng", 0 };
1029 o
.r
= &rand_global
; o
.cc
= &sha_mgf
; o
.ch
= &sha
; ep
= 0; epsz
= 0;
1030 if (!PyArg_ParseTupleAndKeywords(arg
, kw
, "O&O&|O&O&s#O&:decode", kwlist
,
1031 convmp
, &x
, convulong
, &nbits
,
1032 convgccipher
, &o
.cc
,
1038 o
.ep
= ep
; o
.epsz
= epsz
;
1039 if (2 * o
.ch
->hashsz
> sz
) VALERR("buffer underflow");
1041 if ((n
= oaep_decode(x
, b
, sz
, nbits
, &o
)) < 0)
1042 VALERR("decryption failed");
1043 rc
= bytestring_pywrap(b
, n
);
1050 static PyObject
*meth__pss_encode(PyObject
*me
,
1051 PyObject
*arg
, PyObject
*kw
)
1056 unsigned long nbits
;
1061 char *kwlist
[] = { "msg", "nbits", "mgf", "hash", "saltsz", "rng", 0 };
1063 p
.cc
= &sha_mgf
; p
.ch
= &sha
; p
.r
= &rand_global
; p
.ssz
= (size_t)-1;
1064 if (!PyArg_ParseTupleAndKeywords(arg
, kw
, "s#O&|O&O&O&O&:encode", kwlist
,
1065 &m
, &msz
, convulong
, &nbits
,
1066 convgccipher
, &p
.cc
,
1072 if (p
.ssz
== (size_t)-1) p
.ssz
= p
.ch
->hashsz
;
1073 if (p
.ch
->hashsz
+ p
.ssz
+ 2 > sz
) VALERR("buffer underflow");
1075 x
= pss_encode(MP_NEW
, m
, msz
, b
, sz
, nbits
, &p
);
1082 static PyObject
*meth__pss_decode(PyObject
*me
,
1083 PyObject
*arg
, PyObject
*kw
)
1088 unsigned long nbits
;
1095 { "msg", "sig", "nbits", "mgf", "hash", "saltsz", "rng", 0 };
1097 p
.cc
= &sha_mgf
; p
.ch
= &sha
; p
.r
= &rand_global
; p
.ssz
= (size_t)-1;
1098 if (!PyArg_ParseTupleAndKeywords(arg
, kw
, "s#O&O&|O&O&O&O&:decode", kwlist
,
1099 &m
, &msz
, convmp
, &x
, convulong
, &nbits
,
1100 convgccipher
, &p
.cc
,
1106 if (p
.ssz
== (size_t)-1) p
.ssz
= p
.ch
->hashsz
;
1107 if (p
.ch
->hashsz
+ p
.ssz
+ 2 > sz
) VALERR("buffer underflow");
1109 if ((n
= pss_decode(x
, m
, msz
, b
, sz
, nbits
, &p
)) < 0)
1110 VALERR("verification failed");
1111 rc
= Py_None
; Py_INCREF(rc
);
1118 /*----- Global stuff ------------------------------------------------------*/
1120 static PyMethodDef methods
[] = {
1121 #define METHNAME(name) meth_##name
1122 KWMETH(_p1crypt_encode
, 0)
1123 KWMETH(_p1crypt_decode
, 0)
1124 KWMETH(_p1sig_encode
, 0)
1125 KWMETH(_p1sig_decode
, 0)
1126 KWMETH(_oaep_encode
, 0)
1127 KWMETH(_oaep_decode
, 0)
1128 KWMETH(_pss_encode
, 0)
1129 KWMETH(_pss_decode
, 0)
1130 KWMETH(_RSAPriv_generate
, "\
1131 generate(NBITS, [event = pgen_nullev, rng = rand, nsteps = 0]) -> R")
1136 void pubkey_pyinit(void)
1138 INITTYPE(dsapub
, root
);
1139 INITTYPE(dsapriv
, dsapub
);
1140 INITTYPE(kcdsapub
, root
);
1141 INITTYPE(kcdsapriv
, kcdsapub
);
1142 INITTYPE(rsapub
, root
);
1143 INITTYPE(rsapriv
, rsapub
);
1144 addmethods(methods
);
1147 void pubkey_pyinsert(PyObject
*mod
)
1149 INSERT("DSAPub", dsapub_pytype
);
1150 INSERT("DSAPriv", dsapriv_pytype
);
1151 INSERT("KCDSAPub", kcdsapub_pytype
);
1152 INSERT("KCDSAPriv", kcdsapriv_pytype
);
1153 INSERT("RSAPub", rsapub_pytype
);
1154 INSERT("RSAPriv", rsapriv_pytype
);
1157 /*----- That's all, folks -------------------------------------------------*/