Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(28069)

Side by Side Diff: Modules/_sha3/sha3module.c

Issue 16113: Add SHA-3 (Keccak) support
Patch Set: Created 6 years, 11 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /* SHA3 module
2 *
3 * This module provides an interface to the SHA3 algorithm
4 *
5 * See below for information about the original code this module was
6 * based upon. Additional work performed by:
7 *
8 * Andrew Kuchling (amk@amk.ca)
9 * Greg Stein (gstein@lyra.org)
10 * Trevor Perrin (trevp@trevp.net)
11 *
12 * Copyright (C) 2012 Christian Heimes (christian@python.org)
13 * Licensed to PSF under a Contributor Agreement.
14 *
15 */
16
17 /* SHA3 objects */
18
19 #include "Python.h"
20 #include "../hashlib.h"
21 #include "keccak/KeccakNISTInterface.h"
22
23 /* In order to avoid name clashes with other software I had to declare all
24 * Kebbak functions and global data as static. The code is directly included
gregory.p.smith 2012/10/05 08:29:56 Kebbak or Keccak? be consistent in our ASCII spel
christian.heimes 2012/10/05 11:16:27 It's a typo. The SHA-3 algorithm is called Keccak.
25 * here to access the static functions.
26 */
27 #include "keccak/KeccakNISTInterface.c"
28 #include "keccak/KeccakSponge.c"
29 #if SIZEOF_VOID_P == 4
30 #include "keccak/KeccakF-1600-opt32.c"
31 #elif SIZEOF_VOID_P == 8
32 #include "keccak/KeccakF-1600-opt64.c"
33 #endif
34
35 #define SHA3_BLOCKSIZE 200 /* 1600 bits */
36 #define SHA3_MAX_DIGESTSIZE 64 /* 512 bits */
37 #define SHA3_state hashState
38 #define SHA3_init Init
39 #define SHA3_process Update
40 #define SHA3_done Final
41 #define SHA3_copystate(dest, src) memcpy(&dest, &src, sizeof(SHA3_state))
42 #define SHA3_clearstate(state) memset(&state, 0, sizeof(SHA3_state))
43
44 /* The structure for storing SHA3 info */
45
46 typedef struct {
47 PyObject_HEAD
48 int hashbitlen;
49 SHA3_state hash_state;
50 } SHA3object;
51
52 static PyTypeObject SHA3type;
53
54
55 static SHA3object *
56 newSHA3object(int hashbitlen)
57 {
58 SHA3object *newobj;
59
60 /* check hashbitlen */
61 switch(hashbitlen) {
62 /* supported hash length */
63 case 224:
64 break;
65 case 256:
66 break;
67 case 384:
68 break;
69 case 512:
70 break;
71 case 0:
72 /* arbitrarily-long output isn't supported by this module */
73 default:
74 /* everything else is an error */
75 PyErr_SetString(PyExc_ValueError,
76 "hashbitlen must be one of 224, 256, 384 or 512.");
77 return NULL;
78 }
79 newobj = (SHA3object *)PyObject_New(SHA3object, &SHA3type);
80 newobj->hashbitlen = hashbitlen;
81 return newobj;
82 }
83
84
85 /* Internal methods for a hash object */
86
87 static void
88 SHA3_dealloc(PyObject *ptr)
89 {
90 PyObject_Del(ptr);
91 }
92
93 static int
94 SHA3_clear(SHA3object *self)
95 {
96 SHA3_clearstate(self->hash_state);
97 return 0;
98 }
99
100
101 /* External methods for a hash object */
102
103 PyDoc_STRVAR(SHA3_copy__doc__, "Return a copy of the hash object.");
104
105 static PyObject *
106 SHA3_copy(SHA3object *self, PyObject *unused)
107 {
108 SHA3object *newobj;
109
110 if ((newobj = newSHA3object(self->hashbitlen)) == NULL) {
111 return NULL;
112 }
113 SHA3_copystate(newobj->hash_state, self->hash_state);
114 return (PyObject *)newobj;
115 }
116
117
118 PyDoc_STRVAR(SHA3_digest__doc__,
119 "Return the digest value as a string of binary data.");
120
121 static PyObject *
122 SHA3_digest(SHA3object *self, PyObject *unused)
123 {
124 unsigned char digest[SHA3_MAX_DIGESTSIZE];
125 SHA3_state temp;
126 HashReturn res;
127
128 SHA3_copystate(temp, self->hash_state);
129 res = SHA3_done((hashState*)&temp, digest);
130 SHA3_clearstate(temp);
131 if (res != SUCCESS) {
132 PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 Final()");
133 return NULL;
134 }
135 return PyBytes_FromStringAndSize((const char *)digest,
136 self->hashbitlen / 8);
137 }
138
139
140 PyDoc_STRVAR(SHA3_hexdigest__doc__,
141 "Return the digest value as a string of hexadecimal digits.");
142
143 static PyObject *
144 SHA3_hexdigest(SHA3object *self, PyObject *unused)
145 {
146 unsigned char digest[SHA3_MAX_DIGESTSIZE];
147 SHA3_state temp;
148 HashReturn res;
149 PyObject *retval;
150 Py_UCS1 *hex_digest;
151 int digestlen, i, j;
152
153 /* Get the raw (binary) digest value */
154 SHA3_copystate(temp, self->hash_state);
155 res = SHA3_done((hashState*)&temp, digest);
156 SHA3_clearstate(temp);
157 if (res != SUCCESS) {
158 PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 Final()");
159 return NULL;
160 }
161
162 /* Create a new string */
163 digestlen = self->hashbitlen / 8;
164 retval = PyUnicode_New(digestlen * 2, 127);
165 if (!retval)
166 return NULL;
167 hex_digest = PyUnicode_1BYTE_DATA(retval);
168
169 /* Make hex version of the digest */
gregory.p.smith 2012/10/05 08:29:56 fyi - this hexdigest loop is copied in all of our
christian.heimes 2012/10/05 11:16:27 Agreed! http://bugs.python.org/issue4821
170 for(i=j=0; i < digestlen; i++) {
171 unsigned char c;
172 c = (digest[i] >> 4) & 0xf;
173 hex_digest[j++] = Py_hexdigits[c];
174 c = (digest[i] & 0xf);
175 hex_digest[j++] = Py_hexdigits[c];
176 }
177 assert(_PyUnicode_CheckConsistency(retval, 1));
178 return retval;
179 }
180
181 PyDoc_STRVAR(SHA3_update__doc__,
182 "Update this hash object's state with the provided string.");
183
184 static PyObject *
185 SHA3_update(SHA3object *self, PyObject *args)
186 {
187 PyObject *obj;
188 Py_buffer buf;
189 HashReturn res;
190
191 if (!PyArg_ParseTuple(args, "O:update", &obj))
192 return NULL;
193
194 GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
195
196 /* add new data, the function takes the length in bits not bytes */
197 res = SHA3_process((hashState*)&self->hash_state, buf.buf, buf.len * 8);
AntoinePitrou 2012/10/04 23:39:50 You may want to release the GIL when the buffer is
christian.heimes 2012/10/05 11:16:27 The next patch will release the GIL.
198 if (res != SUCCESS) {
199 PyBuffer_Release(&buf);
200 PyErr_SetString(PyExc_RuntimeError,
201 "internal error in SHA3 Update()");
202 return NULL;
203 }
204
205 PyBuffer_Release(&buf);
206 Py_INCREF(Py_None);
207 return Py_None;
208 }
209
210 static PyMethodDef SHA3_methods[] = {
211 {"copy", (PyCFunction)SHA3_copy, METH_NOARGS,
212 SHA3_copy__doc__},
213 {"digest", (PyCFunction)SHA3_digest, METH_NOARGS,
214 SHA3_digest__doc__},
215 {"hexdigest", (PyCFunction)SHA3_hexdigest, METH_NOARGS,
216 SHA3_hexdigest__doc__},
217 {"update", (PyCFunction)SHA3_update, METH_VARARGS,
218 SHA3_update__doc__},
219 {NULL, NULL} /* sentinel */
220 };
221
222 static PyObject *
223 SHA3_get_block_size(SHA3object *self, void *closure)
224 {
225 return PyLong_FromLong(SHA3_BLOCKSIZE);
226 }
227
228 static PyObject *
229 SHA3_get_name(SHA3object *self, void *closure)
230 {
231 return PyUnicode_FromFormat("sha3_%i", self->hashbitlen);
232 }
233
234 static PyObject *
235 SHA3_get_digest_size(SHA3object *self, void *closure)
236 {
237 return PyLong_FromLong(self->hashbitlen / 8);
238 }
239
240
241 static PyGetSetDef SHA3_getseters[] = {
242 {"block_size", (getter)SHA3_get_block_size, NULL, NULL, NULL},
243 {"name", (getter)SHA3_get_name, NULL, NULL, NULL},
244 {"digest_size", (getter)SHA3_get_digest_size, NULL, NULL, NULL},
245 {NULL} /* Sentinel */
246 };
247
248 static PyTypeObject SHA3type = {
249 PyVarObject_HEAD_INIT(NULL, 0)
250 "_sha3.SHA3", /* tp_name */
251 sizeof(SHA3object), /* tp_size */
252 0, /* tp_itemsize */
253 /* methods */
254 SHA3_dealloc, /* tp_dealloc */
255 0, /* tp_print */
256 0, /* tp_getattr */
257 0, /* tp_setattr */
258 0, /* tp_reserved */
259 0, /* tp_repr */
260 0, /* tp_as_number */
261 0, /* tp_as_sequence */
262 0, /* tp_as_mapping */
263 0, /* tp_hash */
264 0, /* tp_call */
265 0, /* tp_str */
266 0, /* tp_getattro */
267 0, /* tp_setattro */
268 0, /* tp_as_buffer */
269 Py_TPFLAGS_DEFAULT, /* tp_flags */
270 0, /* tp_doc */
271 0, /* tp_traverse */
272 (inquiry)SHA3_clear, /* tp_clear */
AntoinePitrou 2012/10/04 23:39:50 tp_clear is only used if the type is GC-enabled, w
christian.heimes 2012/10/05 11:16:27 Thanks, I've moved the SHA3_clearstate() call to t
273 0, /* tp_richcompare */
274 0, /* tp_weaklistoffset */
275 0, /* tp_iter */
276 0, /* tp_iternext */
277 SHA3_methods, /* tp_methods */
278 NULL, /* tp_members */
279 SHA3_getseters, /* tp_getset */
280 };
281
282
283 /* constructor helper */
284 static PyObject *
285 SHA3_factory(PyObject *args, PyObject *kwdict, const char *fmt,
286 int hashbitlen)
287 {
288 SHA3object *newobj = NULL;
289 static char *kwlist[] = {"string", NULL};
290 PyObject *data_obj = NULL;
291 Py_buffer buf;
292
293 if (!PyArg_ParseTupleAndKeywords(args, kwdict, fmt, kwlist,
294 &data_obj)) {
295 return NULL;
296 }
297
298 if (data_obj)
299 GET_BUFFER_VIEW_OR_ERROUT(data_obj, &buf);
300
301 if ((newobj = newSHA3object(hashbitlen)) == NULL) {
302 goto error;
303 }
304
305 if (SHA3_init((hashState*)&newobj->hash_state, hashbitlen) != SUCCESS) {
306 PyErr_SetString(PyExc_RuntimeError,
307 "internal error in SHA3 Update()");
308 goto error;
309 }
310
311 if (data_obj) {
312 if (SHA3_process(&newobj->hash_state, buf.buf, buf.len * 8) != SUCCESS) {
AntoinePitrou 2012/10/04 23:39:50 Same remark as in update() (about the GIL).
313 PyErr_SetString(PyExc_RuntimeError,
314 "internal error in SHA3 Update()");
315 goto error;
316 }
317 PyBuffer_Release(&buf);
318 }
319
320 return (PyObject *)newobj;
321
322 error:
323 if (newobj) {
324 SHA3_clearstate(newobj->hash_state);
325 }
326 if (data_obj) {
327 PyBuffer_Release(&buf);
328 }
329 return NULL;
330
331 }
332
333 PyDoc_STRVAR(sha3_224__doc__,
334 "sha3_224([string]) -> SHA3 object\n\
335 \n\
336 Return a new SHA3 hash object with a hashbit length of 28 bytes.");
337
338 static PyObject *
339 sha3_224(PyObject *self, PyObject *args, PyObject *kwdict)
340 {
341 return SHA3_factory(args, kwdict, "|O:sha3_224", 224);
342 }
343
344
345 PyDoc_STRVAR(sha3_256__doc__,
346 "sha3_256([string]) -> SHA3 object\n\
347 \n\
348 Return a new SHA3 hash object with a hashbit length of 32 bytes.");
349
350 static PyObject *
351 sha3_256(PyObject *self, PyObject *args, PyObject *kwdict)
352 {
353 return SHA3_factory(args, kwdict, "|O:sha3_256", 256);
354 }
355
356 PyDoc_STRVAR(sha3_384__doc__,
357 "sha3_384([string]) -> SHA3 object\n\
358 \n\
359 Return a new SHA3 hash object with a hashbit length of 48 bytes.");
360
361 static PyObject *
362 sha3_384(PyObject *self, PyObject *args, PyObject *kwdict)
363 {
364 return SHA3_factory(args, kwdict, "|O:sha3_384", 384);
365 }
366
367 PyDoc_STRVAR(sha3_512__doc__,
368 "sha3_512([string]) -> SHA3 object\n\
369 \n\
370 Return a new SHA3 hash object with a hashbit length of 64 bytes.");
371
372 static PyObject *
373 sha3_512(PyObject *self, PyObject *args, PyObject *kwdict)
374 {
375 return SHA3_factory(args, kwdict, "|O:sha3_512", 512);
376 }
377
378
379 /* List of functions exported by this module */
380 static struct PyMethodDef SHA3_functions[] = {
381 {"sha3_224", (PyCFunction)sha3_224, METH_VARARGS|METH_KEYWORDS,
382 sha3_224__doc__},
383 {"sha3_256", (PyCFunction)sha3_256, METH_VARARGS|METH_KEYWORDS,
384 sha3_256__doc__},
385 {"sha3_384", (PyCFunction)sha3_384, METH_VARARGS|METH_KEYWORDS,
386 sha3_384__doc__},
387 {"sha3_512", (PyCFunction)sha3_512, METH_VARARGS|METH_KEYWORDS,
388 sha3_512__doc__},
389 {NULL, NULL} /* Sentinel */
390 };
391
392
393 /* Initialize this module. */
394 static struct PyModuleDef _SHA3module = {
395 PyModuleDef_HEAD_INIT,
396 "_sha3",
397 NULL,
398 -1,
399 SHA3_functions,
400 NULL,
401 NULL,
402 NULL,
403 NULL
404 };
405
406 PyMODINIT_FUNC
407 PyInit__sha3(void)
408 {
409 Py_TYPE(&SHA3type) = &PyType_Type;
410 if (PyType_Ready(&SHA3type) < 0) {
411 return NULL;
412 }
413
414 return PyModule_Create(&_SHA3module);
415 }
OLDNEW

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+