3
* _rsa.c: C implementation of the RSA algorithm.
5
* Part of the Python Cryptography Toolkit
7
* Distribute and use freely; there are no restrictions on further
8
* dissemination and usage except those imposed by the laws of your
9
* country of residence.
16
#include <longintrepr.h> /* for conversions */
19
PyObject *_rsa_module;
23
longObjToMPZ (mpz_t m, PyLongObject * p)
33
for (i = 0; i < size; i++)
35
mpz_set_ui (temp, p->ob_digit[i]);
36
mpz_mul_2exp (temp2, temp, SHIFT * i);
37
mpz_add (m, m, temp2);
44
mpzToLongObj (mpz_t m)
46
/* borrowed from gmpy */
47
int size = (mpz_sizeinbase (m, 2) + SHIFT - 1) / SHIFT;
50
PyLongObject *l = _PyLong_New (size);
53
mpz_init_set (temp, m);
54
for (i = 0; i < size; i++)
56
l->ob_digit[i] = (digit) (mpz_get_ui (temp) & MASK);
57
mpz_fdiv_q_2exp (temp, temp, SHIFT);
60
while ((i > 0) && (l->ob_digit[i - 1] == 0))
64
return (PyObject *) l;
67
PyObject *rsaKey_new (PyObject *, PyObject *);
69
static PyMethodDef _rsa__methods__[] = {
70
{"construct", rsaKey_new, METH_VARARGS},
76
PyObject_HEAD mpz_t n;
85
rsaEncrypt (rsaKey * key, mpz_t v)
87
if (mpz_cmp (v, key->n) >= 0)
91
mpz_powm (v, v, key->e, key->n);
96
rsaDecrypt (rsaKey * key, mpz_t v)
98
if (mpz_cmp (v, key->n) >= 0)
102
if (mpz_size (key->d) == 0)
106
mpz_powm (v, v, key->d, key->n);
110
static void rsaKey_dealloc (rsaKey *);
111
static PyObject *rsaKey_getattr (rsaKey *, char *);
112
static PyObject *rsaKey__encrypt (rsaKey *, PyObject *);
113
static PyObject *rsaKey__decrypt (rsaKey *, PyObject *);
114
static PyObject *rsaKey__verify (rsaKey *, PyObject *);
115
static PyObject *rsaKey_size (rsaKey *, PyObject *);
116
static PyObject *rsaKey_hasprivate (rsaKey *, PyObject *);
118
PyObject *rsaError; /* raised on errors */
120
static PyTypeObject rsaKeyType = {
121
PyObject_HEAD_INIT (NULL) 0,
125
(destructor) rsaKey_dealloc, /* dealloc */
127
(getattrfunc) rsaKey_getattr, /* getattr */
138
static PyMethodDef rsaKey__methods__[] = {
139
{"_encrypt", (PyCFunction) rsaKey__encrypt, METH_VARARGS,
140
"Encrypt the given long."},
141
{"_decrypt", (PyCFunction) rsaKey__decrypt, METH_VARARGS,
142
"Decrypt the given long."},
143
{"_sign", (PyCFunction) rsaKey__decrypt, METH_VARARGS,
144
"Sign the given long."},
145
{"_verify", (PyCFunction) rsaKey__verify, METH_VARARGS,
146
"Verify that the signature is valid."},
147
{"size", (PyCFunction) rsaKey_size, METH_VARARGS,
148
"Return the number of bits that this key can handle."},
149
{"hasprivate", (PyCFunction) rsaKey_hasprivate, METH_VARARGS,
150
"Return 1 or 0 if this key does/doesn't have a private key."},
151
{NULL, NULL, 0, NULL}
155
rsaKey_new (PyObject * self, PyObject * args)
157
PyLongObject *n = NULL, *e = NULL, *d = NULL, *p = NULL, *q = NULL;
159
key = PyObject_New (rsaKey, &rsaKeyType);
165
PyArg_ParseTuple (args, "O!O!|O!O!O!", &PyLong_Type, &n,
167
&PyLong_Type, &d, &PyLong_Type, &p, &PyLong_Type, &q);
168
longObjToMPZ (key->n, n);
169
longObjToMPZ (key->e, e);
172
return (PyObject *) key;
174
longObjToMPZ (key->d, d);
179
longObjToMPZ (key->p, p);
180
longObjToMPZ (key->q, q);
188
return (PyObject *) key;
192
rsaKey_dealloc (rsaKey * key)
203
rsaKey_getattr (rsaKey * key, char *attr)
205
if (strcmp (attr, "n") == 0)
206
return mpzToLongObj (key->n);
207
else if (strcmp (attr, "e") == 0)
208
return mpzToLongObj (key->e);
209
else if (strcmp (attr, "d") == 0)
211
if (mpz_size (key->d) == 0)
213
PyErr_SetString (PyExc_AttributeError,
214
"rsaKey instance has no attribute 'd'");
217
return mpzToLongObj (key->d);
219
else if (strcmp (attr, "p") == 0)
221
if (mpz_size (key->p) == 0)
223
PyErr_SetString (PyExc_AttributeError,
224
"rsaKey instance has no attribute 'p'");
227
return mpzToLongObj (key->p);
229
else if (strcmp (attr, "q") == 0)
231
if (mpz_size (key->q) == 0)
233
PyErr_SetString (PyExc_AttributeError,
234
"rsaKey instance has no attribute 'q'");
237
return mpzToLongObj (key->q);
241
return Py_FindMethod (rsaKey__methods__, (PyObject *) key, attr);
246
rsaKey__encrypt (rsaKey * key, PyObject * args)
251
if (!(PyArg_ParseTuple (args, "O!", &PyLong_Type, &l)))
256
longObjToMPZ (v, (PyLongObject *) l);
257
result = rsaEncrypt (key, v);
260
PyErr_SetString (rsaError, "Plaintext too large");
263
r = (PyObject *) mpzToLongObj (v);
265
return Py_BuildValue ("N", r);
269
rsaKey__decrypt (rsaKey * key, PyObject * args)
274
if (!(PyArg_ParseTuple (args, "O!", &PyLong_Type, &l)))
279
longObjToMPZ (v, (PyLongObject *) l);
280
result = rsaDecrypt (key, v);
283
PyErr_SetString (rsaError, "Ciphertext too large");
286
else if (result == 2)
288
PyErr_SetString (rsaError, "Private key not available in this object");
291
r = mpzToLongObj (v);
293
return Py_BuildValue ("N", r);
297
rsaKey__verify (rsaKey * key, PyObject * args)
303
(args, "O!O!", &PyLong_Type, &l, &PyLong_Type, &lsig)))
309
longObjToMPZ (v, (PyLongObject *) l);
310
longObjToMPZ (vsig, (PyLongObject *) lsig);
311
rsaEncrypt (key, vsig);
312
if (mpz_cmp (v, vsig) == 0)
313
return Py_BuildValue ("i", 1);
315
return Py_BuildValue ("i", 0);
319
rsaKey_size (rsaKey * key, PyObject * args)
321
if (!PyArg_ParseTuple (args, ""))
323
return Py_BuildValue ("i", mpz_sizeinbase (key->n, 2) - 1);
327
rsaKey_hasprivate (rsaKey * key, PyObject * args)
329
if (!PyArg_ParseTuple (args, ""))
331
if (mpz_size (key->d) == 0)
332
return Py_BuildValue ("i", 0);
334
return Py_BuildValue ("i", 1);
341
rsaKeyType.ob_type = &PyType_Type;
342
_rsa_module = Py_InitModule ("_rsa", _rsa__methods__);
343
_rsa_dict = PyModule_GetDict (_rsa_module);
344
rsaError = PyErr_NewException ("_rsa.error", NULL, NULL);
345
PyDict_SetItemString (_rsa_dict, "error", rsaError);