@@ -358,19 +358,72 @@ static PyHash_FuncDef PyHash_Func = {fnv, "fnv", 8 * SIZEOF_PY_HASH_T,
358358# define ROTATE (x , b ) (uint64_t)( ((x) << (b)) | ( (x) >> (64 - (b))) )
359359#endif
360360
361- #define HALF_ROUND (a ,b ,c ,d ,s ,t ) \
362- a += b; c += d; \
361+ #define HALF_ROUND (a ,b ,c ,d ,s ,t ) \
362+ a += b; c += d; \
363363 b = ROTATE(b, s) ^ a; \
364364 d = ROTATE(d, t) ^ c; \
365365 a = ROTATE(a, 32);
366366
367- #define DOUBLE_ROUND (v0 ,v1 ,v2 ,v3 ) \
368- HALF_ROUND(v0,v1,v2,v3,13,16); \
369- HALF_ROUND(v2,v1,v0,v3,17,21); \
370- HALF_ROUND(v0,v1,v2,v3,13,16); \
367+ #define SINGLE_ROUND (v0 ,v1 ,v2 ,v3 ) \
368+ HALF_ROUND(v0,v1,v2,v3,13,16); \
371369 HALF_ROUND(v2,v1,v0,v3,17,21);
372370
371+ #define DOUBLE_ROUND (v0 ,v1 ,v2 ,v3 ) \
372+ SINGLE_ROUND(v0,v1,v2,v3); \
373+ SINGLE_ROUND(v0,v1,v2,v3);
374+
373375
376+ static uint64_t
377+ siphash13 (uint64_t k0 , uint64_t k1 , const void * src , Py_ssize_t src_sz ) {
378+ uint64_t b = (uint64_t )src_sz << 56 ;
379+ const uint8_t * in = (const uint8_t * )src ;
380+
381+ uint64_t v0 = k0 ^ 0x736f6d6570736575ULL ;
382+ uint64_t v1 = k1 ^ 0x646f72616e646f6dULL ;
383+ uint64_t v2 = k0 ^ 0x6c7967656e657261ULL ;
384+ uint64_t v3 = k1 ^ 0x7465646279746573ULL ;
385+
386+ uint64_t t ;
387+ uint8_t * pt ;
388+
389+ while (src_sz >= 8 ) {
390+ uint64_t mi ;
391+ memcpy (& mi , in , sizeof (mi ));
392+ mi = _le64toh (mi );
393+ in += sizeof (mi );
394+ src_sz -= sizeof (mi );
395+ v3 ^= mi ;
396+ SINGLE_ROUND (v0 ,v1 ,v2 ,v3 );
397+ v0 ^= mi ;
398+ }
399+
400+ t = 0 ;
401+ pt = (uint8_t * )& t ;
402+ switch (src_sz ) {
403+ case 7 : pt [6 ] = in [6 ]; /* fall through */
404+ case 6 : pt [5 ] = in [5 ]; /* fall through */
405+ case 5 : pt [4 ] = in [4 ]; /* fall through */
406+ case 4 : memcpy (pt , in , sizeof (uint32_t )); break ;
407+ case 3 : pt [2 ] = in [2 ]; /* fall through */
408+ case 2 : pt [1 ] = in [1 ]; /* fall through */
409+ case 1 : pt [0 ] = in [0 ]; /* fall through */
410+ }
411+ b |= _le64toh (t );
412+
413+ v3 ^= b ;
414+ SINGLE_ROUND (v0 ,v1 ,v2 ,v3 );
415+ v0 ^= b ;
416+ v2 ^= 0xff ;
417+ SINGLE_ROUND (v0 ,v1 ,v2 ,v3 );
418+ SINGLE_ROUND (v0 ,v1 ,v2 ,v3 );
419+ SINGLE_ROUND (v0 ,v1 ,v2 ,v3 );
420+
421+ /* modified */
422+ t = (v0 ^ v1 ) ^ (v2 ^ v3 );
423+ return t ;
424+ }
425+
426+ #if Py_HASH_ALGORITHM == Py_HASH_SIPHASH24
374427static uint64_t
375428siphash24 (uint64_t k0 , uint64_t k1 , const void * src , Py_ssize_t src_sz ) {
376429 uint64_t b = (uint64_t )src_sz << 56 ;
@@ -419,14 +472,26 @@ siphash24(uint64_t k0, uint64_t k1, const void *src, Py_ssize_t src_sz) {
419472 t = (v0 ^ v1 ) ^ (v2 ^ v3 );
420473 return t ;
421474}
475+ #endif
422476
423477uint64_t
424478_Py_KeyedHash (uint64_t key , const void * src , Py_ssize_t src_sz )
425479{
426- return siphash24 (key , 0 , src , src_sz );
480+ return siphash13 (key , 0 , src , src_sz );
427481}
428482
429483
484+ #if Py_HASH_ALGORITHM == Py_HASH_SIPHASH13
485+ static Py_hash_t
486+ pysiphash (const void * src , Py_ssize_t src_sz ) {
487+ return (Py_hash_t )siphash13 (
488+ _le64toh (_Py_HashSecret .siphash .k0 ), _le64toh (_Py_HashSecret .siphash .k1 ),
489+ src , src_sz );
490+ }
491+
492+ static PyHash_FuncDef PyHash_Func = {pysiphash , "siphash13" , 64 , 128 };
493+ #endif
494+
430495#if Py_HASH_ALGORITHM == Py_HASH_SIPHASH24
431496static Py_hash_t
432497pysiphash (const void * src , Py_ssize_t src_sz ) {
0 commit comments