@@ -472,29 +472,48 @@ SHA3_TYPE_SPEC(sha3_384_spec, "sha3_384", sha3_384_slots);
472
472
SHA3_TYPE_SLOTS (sha3_512_slots , sha3_512__doc__ , SHA3_methods , SHA3_getseters );
473
473
SHA3_TYPE_SPEC (sha3_512_spec , "sha3_512" , sha3_512_slots );
474
474
475
+ /*
476
+ * Compute the digest of SHAKE object.
477
+ *
478
+ * If 'hex' is false, the output is the raw binary digest as bytes.
479
+ * Otherwise, the output is its hexadecimal (string) representation.
480
+ */
475
481
static PyObject *
476
- _SHAKE_digest ( PyObject * op , unsigned long digestlen , int hex )
482
+ _sha3_shake_compute_digest ( SHA3object * self , uint32_t digestlen , bool hex )
477
483
{
478
- unsigned char * digest = NULL ;
484
+ uint8_t * digest = NULL ;
479
485
PyObject * result = NULL ;
480
- SHA3object * self = _SHA3object_CAST (op );
481
-
482
- if (digestlen >= (1 << 29 )) {
483
- PyErr_SetString (PyExc_ValueError , "length is too large" );
486
+ #define MAX_SHAKE_DIGESTSIZE (1 << 29)
487
+ if (digestlen >= MAX_SHAKE_DIGESTSIZE ) {
488
+ PyErr_Format (PyExc_ValueError ,
489
+ "SHAKE digest length must be < %" PRIu32 ,
490
+ MAX_SHAKE_DIGESTSIZE );
484
491
return NULL ;
485
492
}
486
- digest = (unsigned char * )PyMem_Malloc (digestlen );
493
+ #undef MAX_SHAKE_DIGESTSIZE
494
+
495
+ /*
496
+ * The HACL* function fails if the algorithm is not SHAKE, which is not
497
+ * the case as the caller is _sha3_shake_{128,256}[hex]digest_impl(),
498
+ * or if the output length is zero.
499
+ *
500
+ * In the latter case, we follow the existing behavior
501
+ * and return an empty digest, without raising an error.
502
+ */
503
+ if (digestlen == 0 ) {
504
+ return Py_GetConstant (
505
+ hex ? Py_CONSTANT_EMPTY_STR : Py_CONSTANT_EMPTY_BYTES
506
+ );
507
+ }
508
+
509
+ digest = PyMem_Malloc (digestlen );
487
510
if (digest == NULL ) {
488
511
return PyErr_NoMemory ();
489
512
}
490
513
491
- /* Get the raw (binary) digest value. The HACL functions errors out if:
492
- * - the algorithm is not shake -- not the case here
493
- * - the output length is zero -- we follow the existing behavior and return
494
- * an empty digest, without raising an error */
495
- if (digestlen > 0 ) {
496
- (void )Hacl_Hash_SHA3_squeeze (self -> hash_state , digest , digestlen );
497
- }
514
+ ENTER_HASHLIB (self );
515
+ (void )Hacl_Hash_SHA3_squeeze (self -> hash_state , digest , digestlen );
516
+ LEAVE_HASHLIB (self );
498
517
if (hex ) {
499
518
result = _Py_strhex ((const char * )digest , digestlen );
500
519
}
@@ -509,32 +528,32 @@ _SHAKE_digest(PyObject *op, unsigned long digestlen, int hex)
509
528
/*[clinic input]
510
529
_sha3.shake_128.digest
511
530
512
- length: unsigned_long
531
+ length: uint32
513
532
514
533
Return the digest value as a bytes object.
515
534
[clinic start generated code]*/
516
535
517
536
static PyObject *
518
- _sha3_shake_128_digest_impl (SHA3object * self , unsigned long length )
519
- /*[clinic end generated code: output=2313605e2f87bb8f input=93d6d6ff32904f18 ]*/
537
+ _sha3_shake_128_digest_impl (SHA3object * self , uint32_t length )
538
+ /*[clinic end generated code: output=b8be6cd55400959c input=8a6901d3d699ee26 ]*/
520
539
{
521
- return _SHAKE_digest (( PyObject * ) self , length , 0 );
540
+ return _sha3_shake_compute_digest ( self , length , false );
522
541
}
523
542
524
543
525
544
/*[clinic input]
526
545
_sha3.shake_128.hexdigest
527
546
528
- length: unsigned_long
547
+ length: uint32
529
548
530
549
Return the digest value as a string of hexadecimal digits.
531
550
[clinic start generated code]*/
532
551
533
552
static PyObject *
534
- _sha3_shake_128_hexdigest_impl (SHA3object * self , unsigned long length )
535
- /*[clinic end generated code: output=bf8e2f1e490944a8 input=562d74e7060b56ab ]*/
553
+ _sha3_shake_128_hexdigest_impl (SHA3object * self , uint32_t length )
554
+ /*[clinic end generated code: output=cc1abb908d8ac614 input=acab18f97f8af822 ]*/
536
555
{
537
- return _SHAKE_digest (( PyObject * ) self , length , 1 );
556
+ return _sha3_shake_compute_digest ( self , length , true );
538
557
}
539
558
540
559
static PyObject *
0 commit comments