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

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

Issue 16113: Add SHA-3 (Keccak) support
Patch Set: Created 7 years 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
« no previous file with comments | « Modules/_sha3/keccak/KeccakSponge.h ('k') | setup.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
22 /* **************************************************************************
23 * SHA-3 (Keccak)
24 *
25 * The code is based on KeccakReferenceAndOptimized-3.2.zip from 29 May 2012.
26 *
27 * The reference implementation is altered in this points:
28 * - C++ comments are converted to ANSI C comments.
29 * - All functions and globals are declared static.
30 * - The typedef for UINT64 is commented out.
31 * - brg_endian.h is removed.
32 * - KeccakF-1600-opt[32|64]-settings.h are commented out
33 * - Some unused functions are commented out to silence compiler warnings.
34 *
35 * In order to avoid name clashes with other software I have to declare all
36 * Keccak functions and global data as static. The C code is directly
37 * included into this file in order to access the static functions.
38 *
39 * Keccak can be tuned with several paramenters. I try to explain all options
40 * as far as I understand them. The reference implementation also contains
41 * assembler code for ARM platforms (NEON instructions).
42 *
43 * Common
44 * ======
45 *
46 * Options:
47 * UseBebigokimisa, Unrolling
48 *
49 * - Unrolling: loop unrolling (24, 12, 8, 6, 4, 3, 2, 1)
50 * - UseBebigokimisa: lane complementing
51 *
52 * 64bit platforms
53 * ===============
54 *
55 * Additional options:
56 * UseSSE, UseOnlySIMD64, UseMMX, UseXOP, UseSHLD
57 *
58 * Optimized instructions (disabled by default):
59 * - UseSSE: use Stream SIMD extensions
60 * o UseOnlySIMD64: limit to 64bit instructions, otherwise 128bit
61 * - UseMMX: use 64bit MMX instructions
62 * - UseXOP: use AMD's eXtended Operations (128bit SSE extension)
63 *
64 * Other:
65 * - Unrolling: default 24
66 * - UseBebigokimisa: default 1
67 *
68 * When neither UseSSE, UseMMX nor UseXOP is configured, ROL64 (rotate left
69 * 64) is implemented as:
70 * - Windows: _rotl64()
71 * - UseSHLD: use shld (shift left) asm optimization
72 * - otherwise: shift and xor
73 *
74 * UseBebigokimisa can't be used in combination with UseSSE, UseMMX or
75 * UseXOP. UseOnlySIMD64 has no effect unless UseSSE is specified.
76 *
77 * 32bit platforms
78 * ===============
79 *
80 * Additional options:
81 * UseInterleaveTables, UseSchedule
82 *
83 * - Unrolling: default 2
84 * - UseBebigokimisa: default n/a
85 * - UseSchedule: ???, (1, 2, 3; default 3)
86 * - UseInterleaveTables: use two 64k lookup tables for (de)interleaving
87 * default: n/a
88 *
89 * schedules:
90 * - 3: no UseBebigokimisa, Unrolling must be 2
91 * - 2 + 1:
92 *
93 * *************************************************************************/
94
95 /* tunable options */
96 #if SIZEOF_VOID_P == 8
97 /* 64bit platforms */
98 #define Unrolling 24
99 /* All X86_64 platforms should support SIMD64 */
100 #if ((defined(__GNUC__) && defined(__amd64)) || \
101 (defined(_MSV_VER) && defined(_M_X64)))
102 #define UseSSE
103 #define UseOnlySIMD64
104 #else
105 #define UseBebigokimisa
106 #endif
107 /*
108 #define UseSSE
109 #define UseOnlySIMD64
110 #define UseXOP
111 #define UseMMX
112 #define UseSHLD
113 */
114 #if defined(UseSSE) || defined(UseMMX) || defined(UseXOP)
115 #ifdef UseBebigokimisa
116 #undef UseBebigokimisa
117 #endif
118 #endif
119 #elif SIZEOF_VOID_P == 4
120 /* 32bit platforms */
121 #define Unrolling 2
122 #define UseSchedule 3
123 /*
124 #define UseBebigokimisa
125 #define UseInterleaveTables
126 */
127 #else
128 #error "sizeof(void*) not in 32, 64"
129 #endif /* SIZEOF_VOID_P */
130
131 /* overwrite Keccak typedefs and defines with sane values from Python.h */
132 #ifdef PY_UINT64_T
133 typedef PY_UINT64_T UINT64;
134 #else
135 typedef unsigned long long int UINT64;
136 #endif
137
138 /* replacement for brg_endian.h */
139 #define IS_BIG_ENDIAN BIG_ENDIAN
140 #define IS_LITTLE_ENDIAN LITTLE_ENDIAN
141 #define PLATFORM_BYTE_ORDER BYTE_ORDER
142
143 #include "keccak/KeccakNISTInterface.h"
144 #include "keccak/KeccakNISTInterface.c"
145 #include "keccak/KeccakSponge.c"
146 #if SIZEOF_VOID_P == 8
147 /* 64bit platforms */
148 #include "keccak/KeccakF-1600-opt64.c"
149 #elif SIZEOF_VOID_P == 4
150 /* 32bit platforms */
151 #include "keccak/KeccakF-1600-opt32.c"
152 #else
153 #error "sizeof(void*) not in 32, 64"
154 #endif
155
156 #define SHA3_BLOCKSIZE 200 /* 1600 bits */
157 #define SHA3_MAX_DIGESTSIZE 64 /* 512 bits */
158 #define SHA3_state hashState
159 #define SHA3_init Init
160 #define SHA3_process Update
161 #define SHA3_done Final
162 #define SHA3_copystate(dest, src) memcpy(&(dest), &(src), sizeof(SHA3_state))
163 #define SHA3_clearstate(state) memset(&(state), 0, sizeof(SHA3_state))
164
165 /* The structure for storing SHA3 info */
166
167 typedef struct {
168 PyObject_HEAD
169 int hashbitlen;
170 SHA3_state hash_state;
171 #ifdef WITH_THREAD
172 PyThread_type_lock lock;
173 #endif
174
175 } SHA3object;
176
177 static PyTypeObject SHA3type;
178
179
180 static SHA3object *
181 newSHA3object(int hashbitlen)
182 {
183 SHA3object *newobj;
184
185 /* check hashbitlen */
186 switch(hashbitlen) {
187 /* supported hash length */
188 case 224:
189 break;
190 case 256:
191 break;
192 case 384:
193 break;
194 case 512:
195 break;
196 case 0:
197 /* arbitrarily-long output isn't supported by this module */
198 default:
199 /* everything else is an error */
200 PyErr_SetString(PyExc_ValueError,
201 "hashbitlen must be one of 224, 256, 384 or 512.");
202 return NULL;
203 }
204 newobj = (SHA3object *)PyObject_New(SHA3object, &SHA3type);
205 if (newobj == NULL) {
206 return NULL;
207 }
208 newobj->hashbitlen = hashbitlen;
209 #ifdef WITH_THREAD
210 newobj->lock = NULL;
211 #endif
212 return newobj;
213 }
214
215
216 /* Internal methods for a hash object */
217
218 static void
219 SHA3_dealloc(SHA3object *self)
220 {
221 SHA3_clearstate(self->hash_state);
222 #ifdef WITH_THREAD
223 if (self->lock) {
224 PyThread_free_lock(self->lock);
225 }
226 #endif
227 PyObject_Del(self);
228 }
229
230
231 /* External methods for a hash object */
232
233 PyDoc_STRVAR(SHA3_copy__doc__, "Return a copy of the hash object.");
234
235 static PyObject *
236 SHA3_copy(SHA3object *self, PyObject *unused)
237 {
238 SHA3object *newobj;
239
240 if ((newobj = newSHA3object(self->hashbitlen)) == NULL) {
241 return NULL;
242 }
243 ENTER_HASHLIB(self);
244 SHA3_copystate(newobj->hash_state, self->hash_state);
245 LEAVE_HASHLIB(self);
246 return (PyObject *)newobj;
247 }
248
249
250 PyDoc_STRVAR(SHA3_digest__doc__,
251 "Return the digest value as a string of binary data.");
252
253 static PyObject *
254 SHA3_digest(SHA3object *self, PyObject *unused)
255 {
256 unsigned char digest[SHA3_MAX_DIGESTSIZE];
257 SHA3_state temp;
258 HashReturn res;
259
260 ENTER_HASHLIB(self);
261 SHA3_copystate(temp, self->hash_state);
262 LEAVE_HASHLIB(self);
263 res = SHA3_done(&temp, digest);
264 SHA3_clearstate(temp);
265 if (res != SUCCESS) {
266 PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 Final()");
267 return NULL;
268 }
269 return PyBytes_FromStringAndSize((const char *)digest,
270 self->hashbitlen / 8);
271 }
272
273
274 PyDoc_STRVAR(SHA3_hexdigest__doc__,
275 "Return the digest value as a string of hexadecimal digits.");
276
277 static PyObject *
278 SHA3_hexdigest(SHA3object *self, PyObject *unused)
279 {
280 unsigned char digest[SHA3_MAX_DIGESTSIZE];
281 SHA3_state temp;
282 HashReturn res;
283 PyObject *retval;
284 Py_UCS1 *hex_digest;
285 int digestlen, i, j;
286
287 /* Get the raw (binary) digest value */
288 ENTER_HASHLIB(self);
289 SHA3_copystate(temp, self->hash_state);
290 LEAVE_HASHLIB(self);
291 res = SHA3_done(&temp, digest);
292 SHA3_clearstate(temp);
293 if (res != SUCCESS) {
294 PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 Final()");
295 return NULL;
296 }
297
298 /* Create a new string */
299 digestlen = self->hashbitlen / 8;
300 retval = PyUnicode_New(digestlen * 2, 127);
301 if (!retval)
302 return NULL;
303 hex_digest = PyUnicode_1BYTE_DATA(retval);
304
305 /* Make hex version of the digest */
306 for(i=j=0; i < digestlen; i++) {
307 unsigned char c;
308 c = (digest[i] >> 4) & 0xf;
309 hex_digest[j++] = Py_hexdigits[c];
310 c = (digest[i] & 0xf);
311 hex_digest[j++] = Py_hexdigits[c];
312 }
313 assert(_PyUnicode_CheckConsistency(retval, 1));
314 return retval;
315 }
316
317 PyDoc_STRVAR(SHA3_update__doc__,
318 "Update this hash object's state with the provided string.");
319
320 static PyObject *
321 SHA3_update(SHA3object *self, PyObject *args)
322 {
323 PyObject *obj;
324 Py_buffer buf;
325 HashReturn res;
326
327 if (!PyArg_ParseTuple(args, "O:update", &obj))
328 return NULL;
329
330 GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
331
332 /* add new data, the function takes the length in bits not bytes */
333 #ifdef WITH_THREADS
334 if (self->lock == NULL && buf.len >= GIL_RELEASE_MINSIZE) {
335 self->lock = PyThread_allocate_lock();
336 }
337 /* Once a lock exists all code paths must be syncronized. We have to
338 * release the GIL even for small buffers as acquiring the lock may take
339 * an unlimited amount of time when another thread updates this object
340 * with lots of data. */
341 if (self->lock) {
342 Py_BEGIN_ALLOW_THREADS
343 PyThread_acquire_lock(self->lock, 1);
344 res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8);
345 PyThread_release_lock(self->lock);
346 Py_END_ALLOW_THREADS
347 }
348 else {
349 res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8);
350 }
351 #else
352 res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8);
353 #endif
354 LEAVE_HASHLIB(self);
355
356 if (res != SUCCESS) {
357 PyBuffer_Release(&buf);
358 PyErr_SetString(PyExc_RuntimeError,
359 "internal error in SHA3 Update()");
360 return NULL;
361 }
362
363 PyBuffer_Release(&buf);
364 Py_INCREF(Py_None);
365 return Py_None;
366 }
367
368 static PyMethodDef SHA3_methods[] = {
369 {"copy", (PyCFunction)SHA3_copy, METH_NOARGS,
370 SHA3_copy__doc__},
371 {"digest", (PyCFunction)SHA3_digest, METH_NOARGS,
372 SHA3_digest__doc__},
373 {"hexdigest", (PyCFunction)SHA3_hexdigest, METH_NOARGS,
374 SHA3_hexdigest__doc__},
375 {"update", (PyCFunction)SHA3_update, METH_VARARGS,
376 SHA3_update__doc__},
377 {NULL, NULL} /* sentinel */
378 };
379
380 static PyObject *
381 SHA3_get_block_size(SHA3object *self, void *closure)
382 {
383 return PyLong_FromLong(SHA3_BLOCKSIZE);
384 }
385
386 static PyObject *
387 SHA3_get_name(SHA3object *self, void *closure)
388 {
389 return PyUnicode_FromFormat("sha3_%i", self->hashbitlen);
390 }
391
392 static PyObject *
393 SHA3_get_digest_size(SHA3object *self, void *closure)
394 {
395 return PyLong_FromLong(self->hashbitlen / 8);
396 }
397
398
399 static PyGetSetDef SHA3_getseters[] = {
400 {"block_size", (getter)SHA3_get_block_size, NULL, NULL, NULL},
401 {"name", (getter)SHA3_get_name, NULL, NULL, NULL},
402 {"digest_size", (getter)SHA3_get_digest_size, NULL, NULL, NULL},
403 {NULL} /* Sentinel */
404 };
405
406 static PyTypeObject SHA3type = {
407 PyVarObject_HEAD_INIT(NULL, 0)
408 "_sha3.SHA3", /* tp_name */
409 sizeof(SHA3object), /* tp_size */
410 0, /* tp_itemsize */
411 /* methods */
412 (destructor)SHA3_dealloc, /* tp_dealloc */
413 0, /* tp_print */
414 0, /* tp_getattr */
415 0, /* tp_setattr */
416 0, /* tp_reserved */
417 0, /* tp_repr */
418 0, /* tp_as_number */
419 0, /* tp_as_sequence */
420 0, /* tp_as_mapping */
421 0, /* tp_hash */
422 0, /* tp_call */
423 0, /* tp_str */
424 0, /* tp_getattro */
425 0, /* tp_setattro */
426 0, /* tp_as_buffer */
427 Py_TPFLAGS_DEFAULT, /* tp_flags */
428 0, /* tp_doc */
429 0, /* tp_traverse */
430 0, /* tp_clear */
431 0, /* tp_richcompare */
432 0, /* tp_weaklistoffset */
433 0, /* tp_iter */
434 0, /* tp_iternext */
435 SHA3_methods, /* tp_methods */
436 NULL, /* tp_members */
437 SHA3_getseters, /* tp_getset */
438 };
439
440
441 /* constructor helper */
442 static PyObject *
443 SHA3_factory(PyObject *args, PyObject *kwdict, const char *fmt,
444 int hashbitlen)
445 {
446 SHA3object *newobj = NULL;
447 static char *kwlist[] = {"string", NULL};
448 PyObject *data_obj = NULL;
449 Py_buffer buf;
450 HashReturn res;
451
452 if (!PyArg_ParseTupleAndKeywords(args, kwdict, fmt, kwlist,
453 &data_obj)) {
454 return NULL;
455 }
456
457 if (data_obj)
458 GET_BUFFER_VIEW_OR_ERROUT(data_obj, &buf);
459
460 if ((newobj = newSHA3object(hashbitlen)) == NULL) {
461 goto error;
462 }
463
464 if (SHA3_init(&newobj->hash_state, hashbitlen) != SUCCESS) {
465 PyErr_SetString(PyExc_RuntimeError,
466 "internal error in SHA3 Update()");
467 goto error;
468 }
469
470 if (data_obj) {
471 #ifdef WITH_THREADS
472 if (buf.len >= GIL_RELEASE_MINSIZE) {
473 /* invariant: New objects can't be accessed by other code yet,
474 * thus it's safe to release the GIL without locking the object.
475 */
476 Py_BEGIN_ALLOW_THREADS
477 res = SHA3_process(&newobj->hash_state, buf.buf, buf.len * 8);
478 Py_END_ALLOW_THREADS
479 }
480 else {
481 res = SHA3_process(&newobj->hash_state, buf.buf, buf.len * 8);
482 }
483 #else
484 res = SHA3_process(&newobj->hash_state, buf.buf, buf.len * 8);
485 #endif
486 if (res != SUCCESS) {
487 PyErr_SetString(PyExc_RuntimeError,
488 "internal error in SHA3 Update()");
489 goto error;
490 }
491 PyBuffer_Release(&buf);
492 }
493
494 return (PyObject *)newobj;
495
496 error:
497 if (newobj) {
498 SHA3_clearstate(newobj->hash_state);
499 /* self->lock is always NULL */
500 }
501 if (data_obj) {
502 PyBuffer_Release(&buf);
503 }
504 return NULL;
505
506 }
507
508 PyDoc_STRVAR(sha3_224__doc__,
509 "sha3_224([string]) -> SHA3 object\n\
510 \n\
511 Return a new SHA3 hash object with a hashbit length of 28 bytes.");
512
513 static PyObject *
514 sha3_224(PyObject *self, PyObject *args, PyObject *kwdict)
515 {
516 return SHA3_factory(args, kwdict, "|O:sha3_224", 224);
517 }
518
519
520 PyDoc_STRVAR(sha3_256__doc__,
521 "sha3_256([string]) -> SHA3 object\n\
522 \n\
523 Return a new SHA3 hash object with a hashbit length of 32 bytes.");
524
525 static PyObject *
526 sha3_256(PyObject *self, PyObject *args, PyObject *kwdict)
527 {
528 return SHA3_factory(args, kwdict, "|O:sha3_256", 256);
529 }
530
531 PyDoc_STRVAR(sha3_384__doc__,
532 "sha3_384([string]) -> SHA3 object\n\
533 \n\
534 Return a new SHA3 hash object with a hashbit length of 48 bytes.");
535
536 static PyObject *
537 sha3_384(PyObject *self, PyObject *args, PyObject *kwdict)
538 {
539 return SHA3_factory(args, kwdict, "|O:sha3_384", 384);
540 }
541
542 PyDoc_STRVAR(sha3_512__doc__,
543 "sha3_512([string]) -> SHA3 object\n\
544 \n\
545 Return a new SHA3 hash object with a hashbit length of 64 bytes.");
546
547 static PyObject *
548 sha3_512(PyObject *self, PyObject *args, PyObject *kwdict)
549 {
550 return SHA3_factory(args, kwdict, "|O:sha3_512", 512);
551 }
552
553
554 /* List of functions exported by this module */
555 static struct PyMethodDef SHA3_functions[] = {
556 {"sha3_224", (PyCFunction)sha3_224, METH_VARARGS|METH_KEYWORDS,
557 sha3_224__doc__},
558 {"sha3_256", (PyCFunction)sha3_256, METH_VARARGS|METH_KEYWORDS,
559 sha3_256__doc__},
560 {"sha3_384", (PyCFunction)sha3_384, METH_VARARGS|METH_KEYWORDS,
561 sha3_384__doc__},
562 {"sha3_512", (PyCFunction)sha3_512, METH_VARARGS|METH_KEYWORDS,
563 sha3_512__doc__},
564 {NULL, NULL} /* Sentinel */
565 };
566
567
568 /* Initialize this module. */
569 static struct PyModuleDef _SHA3module = {
570 PyModuleDef_HEAD_INIT,
571 "_sha3",
572 NULL,
573 -1,
574 SHA3_functions,
575 NULL,
576 NULL,
577 NULL,
578 NULL
579 };
580
581 PyMODINIT_FUNC
582 PyInit__sha3(void)
583 {
584 Py_TYPE(&SHA3type) = &PyType_Type;
585 if (PyType_Ready(&SHA3type) < 0) {
586 return NULL;
587 }
588
589 return PyModule_Create(&_SHA3module);
590 }
OLDNEW
« no previous file with comments | « Modules/_sha3/keccak/KeccakSponge.h ('k') | setup.py » ('j') | no next file with comments »

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