summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYves Orton <demerphq@gmail.com>2022-03-06 09:38:48 +0100
committerYves Orton <demerphq@gmail.com>2022-03-10 03:22:33 +0100
commit8a35994ac8fcc50aaed538b7625ba79635683630 (patch)
treeb6d2aad9e4c13aed063dcc5cac5dd4ef65dee621
parented56936b9aac3c2dfc7beef2c9fc8b6d65ae074e (diff)
downloadperl-8a35994ac8fcc50aaed538b7625ba79635683630.tar.gz
hv_func.h - switch sbox32 initializer to use the 128 bit seeding logic
The 96 bit seed initializer was not mixing the seed bits very well and a a 1 bit change to the seed used for the sbox initialization was not propagating throughout the full SBOX buffer. The 128 bit variant is more robust, and this patch makes it even more so by churning it longer, and mixing in the seed twice. This change also removes the old 96 bit variant and code that uses it as I don't think it should be used anymore at all.
-rw-r--r--hv_func.h6
-rw-r--r--sbox32_hash.h81
2 files changed, 20 insertions, 67 deletions
diff --git a/hv_func.h b/hv_func.h
index 7d8b01b0d4..340d94a135 100644
--- a/hv_func.h
+++ b/hv_func.h
@@ -91,15 +91,15 @@
#else
#define _PERL_HASH_FUNC "SBOX32_WITH_" __PERL_HASH_FUNC
-/* note the 3 in the below code comes from the fact the seed to initialize the SBOX is 96 bits */
-#define _PERL_HASH_SEED_BYTES ( __PERL_HASH_SEED_BYTES + (int)( 3 * sizeof(U32)) )
+/* note the 4 in the below code comes from the fact the seed to initialize the SBOX is 128 bits */
+#define _PERL_HASH_SEED_BYTES ( __PERL_HASH_SEED_BYTES + (int)( 4 * sizeof(U32)) )
#define _PERL_HASH_STATE_BYTES \
( __PERL_HASH_STATE_BYTES + ( ( 1 + ( 256 * SBOX32_MAX_LEN ) ) * sizeof(U32) ) )
#define _PERL_HASH_SEED_STATE(seed,state) STMT_START { \
__PERL_HASH_SEED_STATE(seed,state); \
- sbox32_seed_state96(seed + __PERL_HASH_SEED_BYTES, state + __PERL_HASH_STATE_BYTES); \
+ sbox32_seed_state128(seed + __PERL_HASH_SEED_BYTES, state + __PERL_HASH_STATE_BYTES); \
} STMT_END
#define _PERL_HASH_WITH_STATE(state,str,len) \
diff --git a/sbox32_hash.h b/sbox32_hash.h
index 2c015a7c6c..04078ae809 100644
--- a/sbox32_hash.h
+++ b/sbox32_hash.h
@@ -1390,33 +1390,14 @@
#define case_1_SBOX32(hash,state,key) /**/
#endif
-#define XORSHIFT96_set(r,x,y,z,t) STMT_START { \
- t = (x ^ ( x << 10 ) ); \
- x = y; y = z; \
- r = z = (z ^ ( z >> 26 ) ) ^ ( t ^ ( t >> 5 ) ); \
-} STMT_END
-
#define XORSHIFT128_set(r,x,y,z,w,t) STMT_START { \
t = ( x ^ ( x << 5 ) ); \
x = y; y = z; z = w; \
r = w = ( w ^ ( w >> 29 ) ) ^ ( t ^ ( t >> 12 ) ); \
} STMT_END
-#define SBOX32_SCRAMBLE32(v,prime) STMT_START { \
- v ^= (v>>9); \
- v ^= (v<<21); \
- v ^= (v>>16); \
- v *= prime; \
- v ^= (v>>17); \
- v ^= (v<<15); \
- v ^= (v>>23); \
-} STMT_END
-
#ifndef SBOX32_CHURN_ROUNDS
-#define SBOX32_CHURN_ROUNDS 5
-#endif
-#ifndef SBOX32_SKIP_MASK
-#define SBOX32_SKIP_MASK 0x3
+#define SBOX32_CHURN_ROUNDS 128
#endif
#define _SBOX32_CASE(len,hash,state,key) \
@@ -1424,60 +1405,42 @@
case len: hash ^= state[ 1 + ( 256 * ( len - 1 ) ) + key[ len - 1 ] ];
-SBOX32_STATIC_INLINE void sbox32_seed_state96 (
+SBOX32_STATIC_INLINE void sbox32_seed_state128 (
const U8 *seed_ch,
U8 *state_ch
) {
- const U32 *seed= (const U32 *)seed_ch;
+ U32 *seed= (U32 *)seed_ch;
U32 *state= (U32 *)state_ch;
U32 *state_cursor = state + 1;
U32 *sbox32_end = state + 1 + (256 * SBOX32_MAX_LEN);
- U32 s0 = seed[0] ^ 0x68736168; /* sbox */
- U32 s1 = seed[1] ^ 0x786f6273; /* hash */
+ U32 s0 = seed[1] ^ 0x786f6273; /* sbox */
+ U32 s1 = seed[0] ^ 0x68736168; /* hash */
U32 s2 = seed[2] ^ 0x646f6f67; /* good */
+ U32 s3 = seed[3] ^ 0x74736166; /* fast */
U32 t1,t2,i;
/* make sure we have all non-zero state elements */
if (!s0) s0 = 1;
if (!s1) s1 = 2;
if (!s2) s2 = 4;
+ if (!s3) s3 = 8;
/* Do a bunch of mix rounds to avalanche the seedbits
* before we use them for the XORSHIFT rng. */
for ( i = 0; i < SBOX32_CHURN_ROUNDS; i++ )
- SBOX32_MIX3(s0,s1,s2,"SEED STATE");
+ SBOX32_MIX4(s0,s1,s2,s3,"SEED STATE");
- while ( state_cursor < sbox32_end ) {
- U32 *row_end = state_cursor + 256;
- for ( ; state_cursor < row_end; state_cursor++ ) {
- XORSHIFT96_set(*state_cursor,s0,s1,s2,t1);
- }
- }
- XORSHIFT96_set(*state,s0,s1,s2,t2);
-}
+ s0 ^= ~seed[3];
+ s1 ^= ~seed[2];
+ s2 ^= ~seed[1];
+ s3 ^= ~seed[0];
-SBOX32_STATIC_INLINE void sbox32_seed_state128 (
- const U8 *seed_ch,
- U8 *state_ch
-) {
- U32 *seed= (U32 *)seed_ch;
- U32 *state= (U32 *)state_ch;
- U32 *state_cursor = state + 1;
- U32 *sbox32_end = state + 1 + (256 * SBOX32_MAX_LEN);
- U32 s0 = seed[0] ^ 0x68736168; /* sbox */
- U32 s1 = seed[1] ^ 0x786f6273; /* hash */
- U32 s2 = seed[2] ^ 0x646f6f67; /* good */
- U32 s3 = seed[3] ^ 0x74736166; /* fast */
- U32 t1,t2,i;
-
- /* make sure we have all non-zero state elements */
- if (!s0) s0 = 1;
- if (!s1) s1 = 2;
- if (!s2) s2 = 4;
- if (!s3) s3 = 8;
+ /* make sure we have all non-zero state elements, again */
+ if (!s0) s0 = 8;
+ if (!s1) s1 = 4;
+ if (!s2) s2 = 2;
+ if (!s3) s3 = 1;
- /* Do a bunch of mix rounds to avalanche the seedbits
- * before we use them for the XORSHIFT rng. */
for ( i = 0; i < SBOX32_CHURN_ROUNDS; i++ )
SBOX32_MIX4(s0,s1,s2,s3,"SEED STATE");
@@ -1760,16 +1723,6 @@ SBOX32_STATIC_INLINE U32 sbox32_hash_with_state(
return hash;
}
-SBOX32_STATIC_INLINE U32 sbox32_hash96(
- const U8 *seed_ch,
- const U8 *key,
- const STRLEN key_len
-) {
- U32 state[SBOX32_STATE_WORDS];
- sbox32_seed_state96(seed_ch,(U8*)state);
- return sbox32_hash_with_state((U8*)state,key,key_len);
-}
-
SBOX32_STATIC_INLINE U32 sbox32_hash128(
const U8 *seed_ch,
const U8 *key,