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

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