Skip to content

gh-131876: extract _hashlib helpers into a separate directory [WIP] #135341

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
550 changes: 0 additions & 550 deletions .github/workflows/build.yml

Large diffs are not rendered by default.

28 changes: 0 additions & 28 deletions .github/workflows/lint.yml

This file was deleted.

41 changes: 28 additions & 13 deletions Makefile.pre.in
Original file line number Diff line number Diff line change
@@ -1481,6 +1481,12 @@ $(LIBEXPAT_A): $(LIBEXPAT_OBJS)
-rm -f $@
$(AR) $(ARFLAGS) $@ $(LIBEXPAT_OBJS)

##########################################################################
# '_hashlib', '_hmac' and HACL*-based modules helpers

Modules/_hashlib/hashlib_buffer.o: $(srcdir)/Modules/_hashlib/hashlib_buffer.c $(srcdir)/Modules/_hashlib/hashlib_buffer.h $(PYTHON_HEADERS)
$(CC) -I$(srcdir)/Modules/_hashlib -c $(PY_STDMODULE_CFLAGS) $(CCSHARED) -o $@ $(srcdir)/Modules/_hashlib/hashlib_buffer.c

##########################################################################
# HACL* library build
#
@@ -3323,22 +3329,31 @@ MODULE__CTYPES_TEST_DEPS=$(srcdir)/Modules/_ctypes/_ctypes_test_generated.c.h
MODULE__CTYPES_MALLOC_CLOSURE=@MODULE__CTYPES_MALLOC_CLOSURE@
MODULE__DECIMAL_DEPS=$(srcdir)/Modules/_decimal/docstrings.h @LIBMPDEC_INTERNAL@
MODULE__ELEMENTTREE_DEPS=$(srcdir)/Modules/pyexpat.c @LIBEXPAT_INTERNAL@
MODULE__HASHLIB_DEPS=$(srcdir)/Modules/hashlib.h
MODULE__IO_DEPS=$(srcdir)/Modules/_io/_iomodule.h

MODULE__HASHLIB_DEPS= \
$(srcdir)/Modules/_hashlib/hashlib_buffer.h \
$(srcdir)/Modules/_hashlib/hashlib_fetch.h \
$(srcdir)/Modules/_hashlib/hashlib_mutex.h

MODULE__HASHLIB_LDEPS= \
Modules/_hashlib/hashlib_buffer.o \
Modules/_hashlib/hashlib_fetch.o

# HACL*-based cryptographic primitives
MODULE__MD5_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_MD5_HEADERS) $(LIBHACL_MD5_LIB_@LIBHACL_LDEPS_LIBTYPE@)
MODULE__MD5_LDEPS=$(LIBHACL_MD5_LIB_@LIBHACL_LDEPS_LIBTYPE@)
MODULE__SHA1_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_SHA1_HEADERS) $(LIBHACL_SHA1_LIB_@LIBHACL_LDEPS_LIBTYPE@)
MODULE__SHA1_LDEPS=$(LIBHACL_SHA1_LIB_@LIBHACL_LDEPS_LIBTYPE@)
MODULE__SHA2_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_SHA2_HEADERS) $(LIBHACL_SHA2_LIB_@LIBHACL_LDEPS_LIBTYPE@)
MODULE__SHA2_LDEPS=$(LIBHACL_SHA2_LIB_@LIBHACL_LDEPS_LIBTYPE@)
MODULE__SHA3_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_SHA3_HEADERS) $(LIBHACL_SHA3_LIB_@LIBHACL_LDEPS_LIBTYPE@)
MODULE__SHA3_LDEPS=$(LIBHACL_SHA3_LIB_@LIBHACL_LDEPS_LIBTYPE@)
MODULE__BLAKE2_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_BLAKE2_HEADERS) $(LIBHACL_BLAKE2_LIB_@LIBHACL_LDEPS_LIBTYPE@)
MODULE__BLAKE2_LDEPS=$(LIBHACL_BLAKE2_LIB_@LIBHACL_LDEPS_LIBTYPE@)
MODULE__HMAC_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_HMAC_HEADERS) $(LIBHACL_HMAC_LIB_@LIBHACL_LDEPS_LIBTYPE@)
MODULE__HMAC_LDEPS=$(LIBHACL_HMAC_LIB_@LIBHACL_LDEPS_LIBTYPE@)
MODULE__MD5_DEPS=$(MODULE__HASHLIB_DEPS) $(LIBHACL_MD5_HEADERS) $(LIBHACL_MD5_LIB_@LIBHACL_LDEPS_LIBTYPE@)
MODULE__MD5_LDEPS=$(MODULE__HASHLIB_LDEPS) $(LIBHACL_MD5_LIB_@LIBHACL_LDEPS_LIBTYPE@)
MODULE__SHA1_DEPS=$(MODULE__HASHLIB_DEPS) $(LIBHACL_SHA1_HEADERS) $(LIBHACL_SHA1_LIB_@LIBHACL_LDEPS_LIBTYPE@)
MODULE__SHA1_LDEPS=$(MODULE__HASHLIB_LDEPS) $(LIBHACL_SHA1_LIB_@LIBHACL_LDEPS_LIBTYPE@)
MODULE__SHA2_DEPS=$(MODULE__HASHLIB_DEPS) $(LIBHACL_SHA2_HEADERS) $(LIBHACL_SHA2_LIB_@LIBHACL_LDEPS_LIBTYPE@)
MODULE__SHA2_LDEPS=$(MODULE__HASHLIB_LDEPS) $(LIBHACL_SHA2_LIB_@LIBHACL_LDEPS_LIBTYPE@)
MODULE__SHA3_DEPS=$(MODULE__HASHLIB_DEPS) $(LIBHACL_SHA3_HEADERS) $(LIBHACL_SHA3_LIB_@LIBHACL_LDEPS_LIBTYPE@)
MODULE__SHA3_LDEPS=$(MODULE__HASHLIB_LDEPS) $(LIBHACL_SHA3_LIB_@LIBHACL_LDEPS_LIBTYPE@)
MODULE__BLAKE2_DEPS=$(MODULE__HASHLIB_DEPS) $(LIBHACL_BLAKE2_HEADERS) $(LIBHACL_BLAKE2_LIB_@LIBHACL_LDEPS_LIBTYPE@)
MODULE__BLAKE2_LDEPS=$(MODULE__HASHLIB_LDEPS) $(LIBHACL_BLAKE2_LIB_@LIBHACL_LDEPS_LIBTYPE@)

MODULE__HMAC_DEPS=$(MODULE__HASHLIB_DEPS) $(LIBHACL_HMAC_HEADERS) $(LIBHACL_HMAC_LIB_@LIBHACL_LDEPS_LIBTYPE@)
MODULE__HMAC_LDEPS=$(MODULE__HASHLIB_LDEPS) $(LIBHACL_HMAC_LIB_@LIBHACL_LDEPS_LIBTYPE@)

MODULE__SOCKET_DEPS=$(srcdir)/Modules/socketmodule.h $(srcdir)/Modules/addrinfo.h $(srcdir)/Modules/getaddrinfo.c $(srcdir)/Modules/getnameinfo.c
MODULE__SSL_DEPS=$(srcdir)/Modules/_ssl.h $(srcdir)/Modules/_ssl/cert.c $(srcdir)/Modules/_ssl/debughelpers.c $(srcdir)/Modules/_ssl/misc.c $(srcdir)/Modules/_ssl_data_111.h $(srcdir)/Modules/_ssl_data_300.h $(srcdir)/Modules/socketmodule.h
40 changes: 40 additions & 0 deletions Modules/_hashlib/hashlib_buffer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include "hashlib_buffer.h"

int
_Py_hashlib_data_argument(PyObject **res, PyObject *data, PyObject *string)
{
if (data != NULL && string == NULL) {
/ called as H(data) or H(data=...)
*res = data;
return 1;
}
else if (data == NULL && string != NULL) {
/ called as H(string=...)
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"the 'string' keyword parameter is deprecated since "
"Python 3.15 and slated for removal in Python 3.19; "
"use the 'data' keyword parameter or pass the data "
"to hash as a positional argument instead", 1) < 0)
{
*res = NULL;
return -1;
}
*res = string;
return 1;
}
else if (data == NULL && string == NULL) {
/ fast path when no data is given
assert(!PyErr_Occurred());
*res = NULL;
return 0;
}
else {
/ called as H(data=..., string)
*res = NULL;
PyErr_SetString(PyExc_TypeError,
"'data' and 'string' are mutually exclusive "
"and support for 'string' keyword parameter "
"is slated for removal in a future version.");
return -1;
}
}
60 changes: 60 additions & 0 deletions Modules/_hashlib/hashlib_buffer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#ifndef _HASHLIB_HASHLIB_BUFFER_H
#define _HASHLIB_HASHLIB_BUFFER_H

#include "Python.h"

/*
* Given an buffer-like OBJ, fill in the buffer VIEW with the result
* of PyObject_GetBuffer.
*
* On error, set an exception and execute the ERRACTION statements,
* e.g. 'return NULL' or 'goto error'.
*
* Parameters
*
* OBJ An object supporting the buffer API.
* VIEW A Py_buffer pointer to fill.
* ERRACTION The statements to execute on error.
*/
#define GET_BUFFER_VIEW_OR_ERROR(OBJ, VIEW, ERRACTION) \
do { \
if (PyUnicode_Check((OBJ))) { \
PyErr_SetString(PyExc_TypeError, \
"strings must be encoded before hashing"); \
ERRACTION; \
} \
if (!PyObject_CheckBuffer((OBJ))) { \
PyErr_SetString(PyExc_TypeError, \
"object supporting the buffer API required"); \
ERRACTION; \
} \
if (PyObject_GetBuffer((OBJ), (VIEW), PyBUF_SIMPLE) == -1) { \
ERRACTION; \
} \
if ((VIEW)->ndim > 1) { \
PyErr_SetString(PyExc_BufferError, \
"buffer must be one-dimensional"); \
PyBuffer_Release((VIEW)); \
ERRACTION; \
} \
} while(0)

/* Specialization of GET_BUFFER_VIEW_OR_ERROR() returning NULL on error. */
#define GET_BUFFER_VIEW_OR_ERROUT(OBJ, VIEW) \
GET_BUFFER_VIEW_OR_ERROR(OBJ, VIEW, return NULL)

/*
* Allow to use the 'data' or 'string' keyword in hashlib.new()
* and other hash functions named constructors.
*
* - If 'data' and 'string' are both non-NULL, set an exception and return -1.
* - If 'data' and 'string' are both NULL, set '*res' to NULL and return 0.
* - Otherwise, set '*res' to 'data' or 'string' and return 1. A deprecation
* warning is set when 'string' is specified.
*
* The symbol is exported for '_hashlib' and HACL*-based extension modules.
*/
PyAPI_FUNC(int)
_Py_hashlib_data_argument(PyObject **res, PyObject *data, PyObject *string);

#endif / !_HASHLIB_HASHLIB_BUFFER_H
1 change: 1 addition & 0 deletions Modules/_hashlib/hashlib_fetch.c
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "hashlib_fetch.h"
130 changes: 130 additions & 0 deletions Modules/_hashlib/hashlib_fetch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
* Interface for fetching a message digest from a digest-like identifier.
*
* The following table summaries the possible algorthms:
*
* +----------+--------------+--------------+---------------------------------+
* | Family | Algorithm | Python Name | Notes |
* +==========+==============+==============+=================================+
* | MD @ |
* | +--------------+--------------+---------------------------------+
* | | MD5 | "md5" | |
* +----------+--------------+--------------+---------------------------------+
* | SHA1 @ |
* | +--------------+--------------+---------------------------------+
* | | SHA1-160 | "sha1" | |
* +----------+--------------+--------------+---------------------------------+
* | SHA2 @ |
* | +--------------+--------------+---------------------------------+
* | | SHA2-224 | "sha224" | |
* | | SHA2-256 | "sha256" | |
* | | SHA2-384 | "sha384" | |
* | | SHA2-512 | "sha512" | |
* +----------+--------------+--------------+---------------------------------+
* | SHA2t @ Truncated SHA2-512 |
* | +--------------+--------------+---------------------------------+
* | | SHA2-512/224 | "sha512_224" | |
* | | SHA2-512/256 | "sha512_256" | |
* +----------+--------------+--------------+---------------------------------+
* | SHA3 @ |
* | +--------------+--------------+---------------------------------+
* | | SHA3-224 | "sha3_224" | |
* | | SHA3-256 | "sha3_256" | |
* | | SHA3-384 | "sha3_384" | |
* | | SHA3-512 | "sha3_512" | |
* +----------+--------------+--------------+---------------------------------+
* | SHA3-XOF @ Extensible Output Functions |
* | +--------------+--------------+---------------------------------+
* | | SHAKE-128 | "shake_128" | |
* | | SHAKE-256 | "shake_256" | |
* +----------+--------------+--------------+---------------------------------+
* | BLAKE2 @ |
* | +--------------+--------------+---------------------------------+
* | | BLAKE2b | "blake2b" | |
* | | BLAKE2s | "blake2s" | |
* +----------+--------------+--------------+---------------------------------+
*/

#ifndef _HASHLIB_HASHLIB_FETCH_H
#define _HASHLIB_HASHLIB_FETCH_H

#include "Python.h"

#define Py_HASHLIB_MD_NS(ATTR) Py_hashlib_message_digest_ ## ATTR
#define Py_HASHLIB_MD_FAMILY(FAMILY_ID) Py_HASHLIB_MD_NS(family_ ## FAMILY_ID)
#define Py_HASHLIB_MD_MEMBER(MEMBER_ID) Py_HASHLIB_MD_NS(member_ ## MEMBER_ID)

#define Py_HASHLIB_MD_NAMES Py_HASHLIB_MD_NS(NAMES)
#define Py_HASHLIB_MD_COUNT Py_ARRAY_LENGTH(Py_HASHLIB_MD_NAMES)
#define Py_HASHLIB_MD_NAME(MEMBER_ID) \
( \
assert(Py_HASHLIB_MD_NAME(MEMBER_ID) < Py_HASHLIB_MD_COUNT), \
Py_HASHLIB_MD_NAMES[Py_HASHLIB_MD_MEMBER(MEMBER_ID)] \
)

typedef enum {
Py_HASHLIB_MD_FAMILY(MD) = 0,
Py_HASHLIB_MD_FAMILY(SHA1),
Py_HASHLIB_MD_FAMILY(SHA2),
Py_HASHLIB_MD_FAMILY(SHA2t),
Py_HASHLIB_MD_FAMILY(SHA3),
Py_HASHLIB_MD_FAMILY(SHA3_XOF),
Py_HASHLIB_MD_FAMILY(BLAKE2),
} Py_HASHLIB_MD_NS(family);

typedef enum {
/* MD-family */
Py_HASHLIB_MD_MEMBER(md5) = 0,
/* SHA-1 family */
Py_HASHLIB_MD_MEMBER(sha1),
/* SHA-2 family */
Py_HASHLIB_MD_MEMBER(sha224),
Py_HASHLIB_MD_MEMBER(sha256),
Py_HASHLIB_MD_MEMBER(sha384),
Py_HASHLIB_MD_MEMBER(sha512),
/* Truncated SHA-2 family */
Py_HASHLIB_MD_MEMBER(sha512_224),
Py_HASHLIB_MD_MEMBER(sha512_256),
/* SHA-3 family */
Py_HASHLIB_MD_MEMBER(sha3_224),
Py_HASHLIB_MD_MEMBER(sha3_256),
Py_HASHLIB_MD_MEMBER(sha3_384),
Py_HASHLIB_MD_MEMBER(sha3_512),
/* SHA-3 XOF SHAKE family */
Py_HASHLIB_MD_MEMBER(shake_128),
Py_HASHLIB_MD_MEMBER(shake_256),
/* BLAKE-2 family */
Py_HASHLIB_MD_MEMBER(blake2b),
Py_HASHLIB_MD_MEMBER(blake2s),
} Py_HASHLIB_MD_NS(member);

static const char *Py_HASHLIB_MD_NAMES[] = {
#define DECL_MESSAGE_DIGEST_NAME(ID) [Py_HASHLIB_MD_MEMBER(ID)] = #ID
/* MD-family */
DECL_MESSAGE_DIGEST_NAME(md5),
/* SHA-1 family */
DECL_MESSAGE_DIGEST_NAME(sha1),
/* SHA-2 family */
DECL_MESSAGE_DIGEST_NAME(sha224),
DECL_MESSAGE_DIGEST_NAME(sha256),
DECL_MESSAGE_DIGEST_NAME(sha384),
DECL_MESSAGE_DIGEST_NAME(sha512),
/* Truncated SHA-2 family */
DECL_MESSAGE_DIGEST_NAME(sha512_224),
DECL_MESSAGE_DIGEST_NAME(sha512_256),
/* SHA-3 family */
DECL_MESSAGE_DIGEST_NAME(sha3_224),
DECL_MESSAGE_DIGEST_NAME(sha3_256),
DECL_MESSAGE_DIGEST_NAME(sha3_384),
DECL_MESSAGE_DIGEST_NAME(sha3_512),
/* SHA-3 XOF SHAKE family */
DECL_MESSAGE_DIGEST_NAME(shake_128),
DECL_MESSAGE_DIGEST_NAME(shake_256),
/* BLAKE-2 family */
DECL_MESSAGE_DIGEST_NAME(blake2b),
DECL_MESSAGE_DIGEST_NAME(blake2s),
#undef DECL_MESSAGE_DIGEST_NAME
NULL /* sentinel */
};

#endif / !_HASHLIB_HASHLIB_FETCH_H
Loading
Oops, something went wrong.
Loading
Oops, something went wrong.

Follow Lee on X/Twitter - Father, Husband, Serial builder creating AI, crypto, games & web tools. We are friends :) AI Will Come To Life!

Check out: eBank.nz (Art Generator) | Netwrck.com (AI Tools) | Text-Generator.io (AI API) | BitBank.nz (Crypto AI) | ReadingTime (Kids Reading) | RewordGame | BigMultiplayerChess | WebFiddle | How.nz | Helix AI Assistant