Skip to content

Commit 37ce72b

Browse files
committed
Fix interface compatibility with blake3 package.
Touched up the blake3 object interface so it's a better match with the the "blake3" package on PyPI: * derive_key_context is now a (Unicode) string. * Added a reset() method. * Enforce that key, if specified, is exactly 32 bytes. * Error strings used in exceptions are converging with what's in the "blake3" package. Also, improved the setup.py build logic: * It now preserves the .o files from one build to another. * It does time stamp comparisons, so it rebuilds the .o file if it's out of date. * It remembers if building an extension completely failed. In short, it now behaves completely properly like a normal "make". It never extraneously re-tries a compilation.
1 parent 14d2b41 commit 37ce72b

File tree

5 files changed

+169
-87
lines changed

5 files changed

+169
-87
lines changed

Lib/test/test_hashlib.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -819,7 +819,7 @@ def test_blake3_vectors(self):
819819
test_vectors = json.load(f)
820820

821821
blake3_key = test_vectors['key'].encode('ascii')
822-
blake3_derive_key_context = test_vectors['context_string'].encode('ascii')
822+
blake3_derive_key_context = test_vectors['context_string']
823823

824824
def test(case):
825825
nonlocal data

Modules/_blake3/blake3_impl.c

+46-16
Original file line numberDiff line numberDiff line change
@@ -58,21 +58,31 @@ _blake3.blake3.__new__ as py_blake3_new
5858
/
5959
*
6060
key: Py_buffer(c_default="NULL", py_default="b''") = None
61-
derive_key_context: Py_buffer(c_default="NULL", py_default="b''") = None
62-
max_threads: size_t = 1
61+
derive_key_context: unicode(c_default="NULL") = None
62+
max_threads: Py_ssize_t = -1
6363
usedforsecurity: bool = True
6464
6565
Return a new BLAKE3 hash object.
6666
[clinic start generated code]*/
6767

6868
static PyObject *
6969
py_blake3_new_impl(PyTypeObject *type, PyObject *data, Py_buffer *key,
70-
Py_buffer *derive_key_context, size_t max_threads,
70+
PyObject *derive_key_context, Py_ssize_t max_threads,
7171
int usedforsecurity)
72-
/*[clinic end generated code: output=6e24ea74302a9e97 input=3d50acf8631d64ae]*/
72+
/*[clinic end generated code: output=5520c7ccfcc0ea6c input=484a9211624e61a2]*/
7373
{
74-
if ((key->obj != NULL) && (derive_key_context->obj != NULL)) {
75-
PyErr_SetString(PyExc_ValueError, "cannot specify both key and derive_key_context");
74+
if ((derive_key_context != NULL) && !PyUnicode_GetLength(derive_key_context)) {
75+
PyErr_SetString(PyExc_ValueError, "empty derive_key_context string is invalid");
76+
return NULL;
77+
}
78+
79+
if ((key->obj != NULL) && (derive_key_context != NULL)) {
80+
PyErr_SetString(PyExc_ValueError, "key and derive_key_context can't be used together");
81+
return NULL;
82+
}
83+
84+
if ((max_threads < 1) && (max_threads != -1)) {
85+
PyErr_SetString(PyExc_ValueError, "invalid value for max_threads");
7686
return NULL;
7787
}
7888

@@ -83,19 +93,22 @@ py_blake3_new_impl(PyTypeObject *type, PyObject *data, Py_buffer *key,
8393

8494
/* Initialize with key */
8595
if ((key->obj != NULL) && key->len) {
86-
if (key->len > BLAKE3_KEY_LEN) {
87-
PyErr_Format(PyExc_ValueError,
88-
"maximum key length is %d bytes",
89-
BLAKE3_KEY_LEN);
96+
if (key->len != BLAKE3_KEY_LEN) {
97+
PyErr_SetString(PyExc_ValueError, "key must be exactly 32 bytes");
9098
goto error;
9199
}
92100

93101
uint8_t key_array[BLAKE3_KEY_LEN];
94102
memset(key_array, 0, sizeof(key_array));
95103
memcpy(key_array, key->buf, key->len);
96104
blake3_hasher_init_keyed(&self->self, key_array);
97-
} else if ((derive_key_context->obj != NULL) && derive_key_context->len) {
98-
blake3_hasher_init_derive_key_raw(&self->self, derive_key_context->buf, derive_key_context->len);
105+
} else if (derive_key_context != NULL) {
106+
Py_ssize_t length;
107+
const char *utf8_key_context = PyUnicode_AsUTF8AndSize(derive_key_context, &length);
108+
if (!utf8_key_context) {
109+
goto error;
110+
}
111+
blake3_hasher_init_derive_key_raw(&self->self, utf8_key_context, length);
99112
} else {
100113
blake3_hasher_init(&self->self);
101114
}
@@ -123,6 +136,22 @@ py_blake3_new_impl(PyTypeObject *type, PyObject *data, Py_buffer *key,
123136
return NULL;
124137
}
125138

139+
/*[clinic input]
140+
_blake3.blake3.reset
141+
142+
Reset this hash object to its initial state.
143+
[clinic start generated code]*/
144+
145+
static PyObject *
146+
_blake3_blake3_reset_impl(BLAKE3Object *self)
147+
/*[clinic end generated code: output=d03fd37d58b87017 input=ba958463850a68df]*/
148+
{
149+
ENTER_HASHLIB(self);
150+
blake3_hasher_reset(&self->self);
151+
LEAVE_HASHLIB(self);
152+
Py_RETURN_NONE;
153+
}
154+
126155
/*[clinic input]
127156
_blake3.blake3.copy
128157
@@ -256,10 +285,11 @@ _blake3_blake3_hexdigest_impl(BLAKE3Object *self, size_t length, size_t seek)
256285

257286

258287
static PyMethodDef py_blake3_methods[] = {
259-
_BLAKE3_BLAKE3_COPY_METHODDEF
260-
_BLAKE3_BLAKE3_DIGEST_METHODDEF
261-
_BLAKE3_BLAKE3_HEXDIGEST_METHODDEF
262288
_BLAKE3_BLAKE3_UPDATE_METHODDEF
289+
_BLAKE3_BLAKE3_HEXDIGEST_METHODDEF
290+
_BLAKE3_BLAKE3_DIGEST_METHODDEF
291+
_BLAKE3_BLAKE3_COPY_METHODDEF
292+
_BLAKE3_BLAKE3_RESET_METHODDEF
263293
{NULL, NULL}
264294
};
265295

@@ -327,7 +357,7 @@ py_blake3_dealloc(PyObject *o)
327357
{
328358
BLAKE3Object *self = (BLAKE3Object *)o;
329359

330-
/* Try not to leave state in memory. */
360+
/* Don't leave state in memory. */
331361
secure_zero_memory(&self->self, sizeof(self->self));
332362
if (self->lock) {
333363
PyThread_free_lock(self->lock);

Modules/_blake3/blake3module.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ blake3_exec(PyObject *m)
108108
ADD_INT("block_length", BLAKE3_BLOCK_LEN);
109109
ADD_INT("chunk_length", BLAKE3_CHUNK_LEN);
110110
ADD_INT("max_depth", BLAKE3_MAX_DEPTH);
111+
ADD_INT("AUTO", -1);
111112

112113
ADD_CONSTANT("supports_multithreading", Py_False);
113114

@@ -135,4 +136,4 @@ PyMODINIT_FUNC
135136
PyInit__blake3(void)
136137
{
137138
return PyModuleDef_Init(&blake3_module);
138-
}
139+
}

Modules/_blake3/clinic/blake3_impl.c.h

+40-16
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)