summaryrefslogtreecommitdiffstats
path: root/Modules/_sha3/sha3module.c
diff options
context:
space:
mode:
authorMartin v. Löwis <martin@v.loewis.de>2014-01-03 13:05:06 (GMT)
committerMartin v. Löwis <martin@v.loewis.de>2014-01-03 13:05:06 (GMT)
commit24e43308b7e40c09717c1ab99014710fa5a01735 (patch)
treeb2a1198fbbb3e38ff6232785d474d6a0354a2648 /Modules/_sha3/sha3module.c
parentf3b46b4a66560945d4c80ac2f10764e3d7f71f8d (diff)
downloadcpython-24e43308b7e40c09717c1ab99014710fa5a01735.zip
cpython-24e43308b7e40c09717c1ab99014710fa5a01735.tar.gz
cpython-24e43308b7e40c09717c1ab99014710fa5a01735.tar.bz2
* Issue #16113: Remove sha3 module again.
Patch by Christian Heimes, with modifications.
Diffstat (limited to 'Modules/_sha3/sha3module.c')
-rw-r--r--Modules/_sha3/sha3module.c593
1 files changed, 0 insertions, 593 deletions
diff --git a/Modules/_sha3/sha3module.c b/Modules/_sha3/sha3module.c
deleted file mode 100644
index 71127d0..0000000
--- a/Modules/_sha3/sha3module.c
+++ /dev/null
@@ -1,593 +0,0 @@
-/* SHA3 module
- *
- * This module provides an interface to the SHA3 algorithm
- *
- * See below for information about the original code this module was
- * based upon. Additional work performed by:
- *
- * Andrew Kuchling (amk@amk.ca)
- * Greg Stein (gstein@lyra.org)
- * Trevor Perrin (trevp@trevp.net)
- * Gregory P. Smith (greg@krypto.org)
- *
- * Copyright (C) 2012 Christian Heimes (christian@python.org)
- * Licensed to PSF under a Contributor Agreement.
- *
- */
-
-#include "Python.h"
-#include "../hashlib.h"
-
-/* **************************************************************************
- * SHA-3 (Keccak)
- *
- * The code is based on KeccakReferenceAndOptimized-3.2.zip from 29 May 2012.
- *
- * The reference implementation is altered in this points:
- * - C++ comments are converted to ANSI C comments.
- * - All functions and globals are declared static.
- * - The typedef for UINT64 is commented out.
- * - KeccakF-1600-opt[32|64]-settings.h are commented out
- * - Some unused functions are commented out to silence compiler warnings.
- *
- * In order to avoid name clashes with other software I have to declare all
- * Keccak functions and global data as static. The C code is directly
- * included into this file in order to access the static functions.
- *
- * Keccak can be tuned with several paramenters. I try to explain all options
- * as far as I understand them. The reference implementation also contains
- * assembler code for ARM platforms (NEON instructions).
- *
- * Common
- * ======
- *
- * Options:
- * UseBebigokimisa, Unrolling
- *
- * - Unrolling: loop unrolling (24, 12, 8, 6, 4, 3, 2, 1)
- * - UseBebigokimisa: lane complementing
- *
- * 64bit platforms
- * ===============
- *
- * Additional options:
- * UseSSE, UseOnlySIMD64, UseMMX, UseXOP, UseSHLD
- *
- * Optimized instructions (disabled by default):
- * - UseSSE: use Stream SIMD extensions
- * o UseOnlySIMD64: limit to 64bit instructions, otherwise 128bit
- * o w/o UseOnlySIMD64: requires compiler agument -mssse3 or -mtune
- * - UseMMX: use 64bit MMX instructions
- * - UseXOP: use AMD's eXtended Operations (128bit SSE extension)
- *
- * Other:
- * - Unrolling: default 24
- * - UseBebigokimisa: default 1
- *
- * When neither UseSSE, UseMMX nor UseXOP is configured, ROL64 (rotate left
- * 64) is implemented as:
- * - Windows: _rotl64()
- * - UseSHLD: use shld (shift left) asm optimization
- * - otherwise: shift and xor
- *
- * UseBebigokimisa can't be used in combination with UseSSE, UseMMX or
- * UseXOP. UseOnlySIMD64 has no effect unless UseSSE is specified.
- *
- * Tests have shown that UseSSE + UseOnlySIMD64 is about three to four
- * times SLOWER than UseBebigokimisa. UseSSE and UseMMX are about two times
- * slower. (tested by CH and AP)
- *
- * 32bit platforms
- * ===============
- *
- * Additional options:
- * UseInterleaveTables, UseSchedule
- *
- * - Unrolling: default 2
- * - UseBebigokimisa: default n/a
- * - UseSchedule: ???, (1, 2, 3; default 3)
- * - UseInterleaveTables: use two 64k lookup tables for (de)interleaving
- * default: n/a
- *
- * schedules:
- * - 3: no UseBebigokimisa, Unrolling must be 2
- * - 2 + 1: ???
- *
- * *************************************************************************/
-
-#ifdef __sparc
- /* opt64 uses un-aligned memory access that causes a BUS error with msg
- * 'invalid address alignment' on SPARC. */
- #define KeccakOpt 32
-#elif SIZEOF_VOID_P == 8 && defined(PY_UINT64_T)
- /* opt64 works only for 64bit platforms with unsigned int64 */
- #define KeccakOpt 64
-#else
- /* opt32 is used for the remaining 32 and 64bit platforms */
- #define KeccakOpt 32
-#endif
-
-#if KeccakOpt == 64 && defined(PY_UINT64_T)
- /* 64bit platforms with unsigned int64 */
- #define Unrolling 24
- #define UseBebigokimisa
- typedef PY_UINT64_T UINT64;
-#elif KeccakOpt == 32 && defined(PY_UINT64_T)
- /* 32bit platforms with unsigned int64 */
- #define Unrolling 2
- #define UseSchedule 3
- typedef PY_UINT64_T UINT64;
-#else
- /* 32 or 64bit platforms without unsigned int64 */
- #define Unrolling 2
- #define UseSchedule 3
- #define UseInterleaveTables
-#endif
-
-/* replacement for brg_endian.h */
-#define IS_BIG_ENDIAN 4321
-#define IS_LITTLE_ENDIAN 1234
-#if PY_BIG_ENDIAN
-# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
-#else
-# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
-#endif
-
-/* inline all Keccak dependencies */
-#include "keccak/KeccakNISTInterface.h"
-#include "keccak/KeccakNISTInterface.c"
-#include "keccak/KeccakSponge.c"
-#if KeccakOpt == 64
- #include "keccak/KeccakF-1600-opt64.c"
-#elif KeccakOpt == 32
- #include "keccak/KeccakF-1600-opt32.c"
-#endif
-
-/* #define SHA3_BLOCKSIZE 200 // 1600 bits */
-#define SHA3_MAX_DIGESTSIZE 64 /* 512 bits */
-#define SHA3_state hashState
-#define SHA3_init Init
-#define SHA3_process Update
-#define SHA3_done Final
-#define SHA3_copystate(dest, src) memcpy(&(dest), &(src), sizeof(SHA3_state))
-#define SHA3_clearstate(state) memset(&(state), 0, sizeof(SHA3_state))
-
-/* The structure for storing SHA3 info */
-
-typedef struct {
- PyObject_HEAD
- int hashbitlen;
- SHA3_state hash_state;
-#ifdef WITH_THREAD
- PyThread_type_lock lock;
-#endif
-
-} SHA3object;
-
-static PyTypeObject SHA3type;
-
-
-static SHA3object *
-newSHA3object(int hashbitlen)
-{
- SHA3object *newobj;
-
- /* check hashbitlen */
- switch(hashbitlen) {
- /* supported hash length */
- case 224:
- break;
- case 256:
- break;
- case 384:
- break;
- case 512:
- break;
- case 0:
- /* arbitrarily-long output isn't supported by this module */
- default:
- /* everything else is an error */
- PyErr_SetString(PyExc_ValueError,
- "hashbitlen must be one of 224, 256, 384 or 512.");
- return NULL;
- }
- newobj = (SHA3object *)PyObject_New(SHA3object, &SHA3type);
- if (newobj == NULL) {
- return NULL;
- }
- newobj->hashbitlen = hashbitlen;
-#ifdef WITH_THREAD
- newobj->lock = NULL;
-#endif
- return newobj;
-}
-
-
-/* Internal methods for a hash object */
-
-static void
-SHA3_dealloc(SHA3object *self)
-{
- SHA3_clearstate(self->hash_state);
-#ifdef WITH_THREAD
- if (self->lock) {
- PyThread_free_lock(self->lock);
- }
-#endif
- PyObject_Del(self);
-}
-
-
-/* External methods for a hash object */
-
-PyDoc_STRVAR(SHA3_copy__doc__, "Return a copy of the hash object.");
-
-static PyObject *
-SHA3_copy(SHA3object *self, PyObject *unused)
-{
- SHA3object *newobj;
-
- if ((newobj = newSHA3object(self->hashbitlen)) == NULL) {
- return NULL;
- }
- ENTER_HASHLIB(self);
- SHA3_copystate(newobj->hash_state, self->hash_state);
- LEAVE_HASHLIB(self);
- return (PyObject *)newobj;
-}
-
-
-PyDoc_STRVAR(SHA3_digest__doc__,
-"Return the digest value as a string of binary data.");
-
-static PyObject *
-SHA3_digest(SHA3object *self, PyObject *unused)
-{
- unsigned char digest[SHA3_MAX_DIGESTSIZE];
- SHA3_state temp;
- HashReturn res;
-
- ENTER_HASHLIB(self);
- SHA3_copystate(temp, self->hash_state);
- LEAVE_HASHLIB(self);
- res = SHA3_done(&temp, digest);
- SHA3_clearstate(temp);
- if (res != SUCCESS) {
- PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 Final()");
- return NULL;
- }
- return PyBytes_FromStringAndSize((const char *)digest,
- self->hashbitlen / 8);
-}
-
-
-PyDoc_STRVAR(SHA3_hexdigest__doc__,
-"Return the digest value as a string of hexadecimal digits.");
-
-static PyObject *
-SHA3_hexdigest(SHA3object *self, PyObject *unused)
-{
- unsigned char digest[SHA3_MAX_DIGESTSIZE];
- SHA3_state temp;
- HashReturn res;
- PyObject *retval;
- Py_UCS1 *hex_digest;
- int digestlen, i, j;
-
- /* Get the raw (binary) digest value */
- ENTER_HASHLIB(self);
- SHA3_copystate(temp, self->hash_state);
- LEAVE_HASHLIB(self);
- res = SHA3_done(&temp, digest);
- SHA3_clearstate(temp);
- if (res != SUCCESS) {
- PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 Final()");
- return NULL;
- }
-
- /* Create a new string */
- digestlen = self->hashbitlen / 8;
- retval = PyUnicode_New(digestlen * 2, 127);
- if (!retval)
- return NULL;
- hex_digest = PyUnicode_1BYTE_DATA(retval);
-
- /* Make hex version of the digest */
- for(i=j=0; i < digestlen; i++) {
- unsigned char c;
- c = (digest[i] >> 4) & 0xf;
- hex_digest[j++] = Py_hexdigits[c];
- c = (digest[i] & 0xf);
- hex_digest[j++] = Py_hexdigits[c];
- }
-#ifdef Py_DEBUG
- assert(_PyUnicode_CheckConsistency(retval, 1));
-#endif
- return retval;
-}
-
-PyDoc_STRVAR(SHA3_update__doc__,
-"Update this hash object's state with the provided string.");
-
-static PyObject *
-SHA3_update(SHA3object *self, PyObject *args)
-{
- PyObject *obj;
- Py_buffer buf;
- HashReturn res;
-
- if (!PyArg_ParseTuple(args, "O:update", &obj))
- return NULL;
-
- GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
-
- /* add new data, the function takes the length in bits not bytes */
-#ifdef WITH_THREAD
- if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) {
- self->lock = PyThread_allocate_lock();
- }
- /* Once a lock exists all code paths must be synchronized. We have to
- * release the GIL even for small buffers as acquiring the lock may take
- * an unlimited amount of time when another thread updates this object
- * with lots of data. */
- if (self->lock) {
- Py_BEGIN_ALLOW_THREADS
- PyThread_acquire_lock(self->lock, 1);
- res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8);
- PyThread_release_lock(self->lock);
- Py_END_ALLOW_THREADS
- }
- else {
- res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8);
- }
-#else
- res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8);
-#endif
- LEAVE_HASHLIB(self);
-
- if (res != SUCCESS) {
- PyBuffer_Release(&buf);
- PyErr_SetString(PyExc_RuntimeError,
- "internal error in SHA3 Update()");
- return NULL;
- }
-
- PyBuffer_Release(&buf);
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyMethodDef SHA3_methods[] = {
- {"copy", (PyCFunction)SHA3_copy, METH_NOARGS,
- SHA3_copy__doc__},
- {"digest", (PyCFunction)SHA3_digest, METH_NOARGS,
- SHA3_digest__doc__},
- {"hexdigest", (PyCFunction)SHA3_hexdigest, METH_NOARGS,
- SHA3_hexdigest__doc__},
- {"update", (PyCFunction)SHA3_update, METH_VARARGS,
- SHA3_update__doc__},
- {NULL, NULL} /* sentinel */
-};
-
-static PyObject *
-SHA3_get_block_size(SHA3object *self, void *closure)
-{
- /* HMAC-SHA3 hasn't been specified yet and no official test vectors are
- * available. Thus block_size returns NotImplemented to prevent people
- * from using SHA3 with the hmac module.
- */
- Py_RETURN_NOTIMPLEMENTED;
-}
-
-static PyObject *
-SHA3_get_name(SHA3object *self, void *closure)
-{
- return PyUnicode_FromFormat("sha3_%i", self->hashbitlen);
-}
-
-static PyObject *
-SHA3_get_digest_size(SHA3object *self, void *closure)
-{
- return PyLong_FromLong(self->hashbitlen / 8);
-}
-
-
-static PyGetSetDef SHA3_getseters[] = {
- {"block_size", (getter)SHA3_get_block_size, NULL, NULL, NULL},
- {"name", (getter)SHA3_get_name, NULL, NULL, NULL},
- {"digest_size", (getter)SHA3_get_digest_size, NULL, NULL, NULL},
- {NULL} /* Sentinel */
-};
-
-static PyTypeObject SHA3type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "_sha3.SHA3", /* tp_name */
- sizeof(SHA3object), /* tp_size */
- 0, /* tp_itemsize */
- /* methods */
- (destructor)SHA3_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_reserved */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- 0, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- SHA3_methods, /* tp_methods */
- NULL, /* tp_members */
- SHA3_getseters, /* tp_getset */
-};
-
-
-/* constructor helper */
-static PyObject *
-SHA3_factory(PyObject *args, PyObject *kwdict, const char *fmt,
- int hashbitlen)
-{
- SHA3object *newobj = NULL;
- static char *kwlist[] = {"string", NULL};
- PyObject *data_obj = NULL;
- Py_buffer buf;
- HashReturn res;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwdict, fmt, kwlist,
- &data_obj)) {
- return NULL;
- }
-
- if (data_obj)
- GET_BUFFER_VIEW_OR_ERROUT(data_obj, &buf);
-
- if ((newobj = newSHA3object(hashbitlen)) == NULL) {
- goto error;
- }
-
- if (SHA3_init(&newobj->hash_state, hashbitlen) != SUCCESS) {
- PyErr_SetString(PyExc_RuntimeError,
- "internal error in SHA3 Update()");
- goto error;
- }
-
- if (data_obj) {
-#ifdef WITH_THREAD
- if (buf.len >= HASHLIB_GIL_MINSIZE) {
- /* invariant: New objects can't be accessed by other code yet,
- * thus it's safe to release the GIL without locking the object.
- */
- Py_BEGIN_ALLOW_THREADS
- res = SHA3_process(&newobj->hash_state, buf.buf, buf.len * 8);
- Py_END_ALLOW_THREADS
- }
- else {
- res = SHA3_process(&newobj->hash_state, buf.buf, buf.len * 8);
- }
-#else
- res = SHA3_process(&newobj->hash_state, buf.buf, buf.len * 8);
-#endif
- if (res != SUCCESS) {
- PyErr_SetString(PyExc_RuntimeError,
- "internal error in SHA3 Update()");
- goto error;
- }
- PyBuffer_Release(&buf);
- }
-
- return (PyObject *)newobj;
-
- error:
- if (newobj) {
- SHA3_dealloc(newobj);
- }
- if (data_obj) {
- PyBuffer_Release(&buf);
- }
- return NULL;
-
-}
-
-PyDoc_STRVAR(sha3_224__doc__,
-"sha3_224([string]) -> SHA3 object\n\
-\n\
-Return a new SHA3 hash object with a hashbit length of 28 bytes.");
-
-static PyObject *
-sha3_224(PyObject *self, PyObject *args, PyObject *kwdict)
-{
- return SHA3_factory(args, kwdict, "|O:sha3_224", 224);
-}
-
-
-PyDoc_STRVAR(sha3_256__doc__,
-"sha3_256([string]) -> SHA3 object\n\
-\n\
-Return a new SHA3 hash object with a hashbit length of 32 bytes.");
-
-static PyObject *
-sha3_256(PyObject *self, PyObject *args, PyObject *kwdict)
-{
- return SHA3_factory(args, kwdict, "|O:sha3_256", 256);
-}
-
-PyDoc_STRVAR(sha3_384__doc__,
-"sha3_384([string]) -> SHA3 object\n\
-\n\
-Return a new SHA3 hash object with a hashbit length of 48 bytes.");
-
-static PyObject *
-sha3_384(PyObject *self, PyObject *args, PyObject *kwdict)
-{
- return SHA3_factory(args, kwdict, "|O:sha3_384", 384);
-}
-
-PyDoc_STRVAR(sha3_512__doc__,
-"sha3_512([string]) -> SHA3 object\n\
-\n\
-Return a new SHA3 hash object with a hashbit length of 64 bytes.");
-
-static PyObject *
-sha3_512(PyObject *self, PyObject *args, PyObject *kwdict)
-{
- return SHA3_factory(args, kwdict, "|O:sha3_512", 512);
-}
-
-
-/* List of functions exported by this module */
-static struct PyMethodDef SHA3_functions[] = {
- {"sha3_224", (PyCFunction)sha3_224, METH_VARARGS|METH_KEYWORDS,
- sha3_224__doc__},
- {"sha3_256", (PyCFunction)sha3_256, METH_VARARGS|METH_KEYWORDS,
- sha3_256__doc__},
- {"sha3_384", (PyCFunction)sha3_384, METH_VARARGS|METH_KEYWORDS,
- sha3_384__doc__},
- {"sha3_512", (PyCFunction)sha3_512, METH_VARARGS|METH_KEYWORDS,
- sha3_512__doc__},
- {NULL, NULL} /* Sentinel */
-};
-
-
-/* Initialize this module. */
-static struct PyModuleDef _SHA3module = {
- PyModuleDef_HEAD_INIT,
- "_sha3",
- NULL,
- -1,
- SHA3_functions,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-PyMODINIT_FUNC
-PyInit__sha3(void)
-{
- PyObject *m;
-
- Py_TYPE(&SHA3type) = &PyType_Type;
- if (PyType_Ready(&SHA3type) < 0) {
- return NULL;
- }
-
- m = PyModule_Create(&_SHA3module);
- if (m == NULL)
- return NULL;
-
- Py_INCREF((PyObject *)&SHA3type);
- PyModule_AddObject(m, "SHA3Type", (PyObject *)&SHA3type);
- return m;
-}