OSDN Git Service

Some improvements to the PRNG code.
authorLoRd_MuldeR <mulder2@gmx.de>
Thu, 18 Mar 2021 22:02:55 +0000 (23:02 +0100)
committerLoRd_MuldeR <mulder2@gmx.de>
Sat, 20 Mar 2021 20:19:12 +0000 (21:19 +0100)
libslunkcrypt/src/slunkcrypt.c

index 244947c..50cc138 100644 (file)
@@ -40,12 +40,18 @@ const char* const SLUNKCRYPT_BUILD = __DATE__ " " __TIME__;
 
 typedef struct
 {
-       uint64_t a, b;
+       uint64_t a, b, c;
 }
 key_data_t;
 
 typedef struct
 {
+       uint32_t x, y, z, w, v, d;
+}
+rand_state_t;
+
+typedef struct
+{
        uint8_t wheel_fwd[256U][256U];
        uint8_t wheel_bwd[256U][256U];
        uint8_t step_fwd[256U];
@@ -56,13 +62,6 @@ typedef struct
 }
 crypt_state_t;
 
-typedef struct
-{
-       uint32_t a, b, c, d;
-       uint32_t counter;
-}
-rand_state_t;
-
 // ==========================================================================
 // Abort flag
 // ==========================================================================
@@ -156,11 +155,11 @@ static uint64_t hash_code_next(const uint64_t salt, const uint8_t* const data, c
 // Key derivation
 // ==========================================================================
 
-static FORCE_INLINE uint64_t keygen_loop(uint64_t salt, const uint16_t pepper, const uint8_t* const passwd, const size_t passwd_len)
+static FORCE_INLINE uint64_t keygen_loop(uint64_t salt, const uint16_t i, const uint8_t* const passwd, const size_t passwd_len)
 {
-       uint64_t result = salt = hash_code_init(salt, pepper, passwd, passwd_len);
-       size_t i;
-       for (i = 1U; i < 99971U; ++i)
+       size_t u;
+       uint64_t result = salt = hash_code_init(salt, i, passwd, passwd_len);
+       for (u = 1U; u < 99971U; ++u)
        {
                result ^= salt = hash_code_next(salt, passwd, passwd_len);
        }
@@ -169,35 +168,35 @@ static FORCE_INLINE uint64_t keygen_loop(uint64_t salt, const uint16_t pepper, c
 
 static void generate_key(key_data_t *const key, const uint64_t salt, const uint16_t pepper, const uint8_t* const passwd, const size_t passwd_len)
 {
-       key->a = keygen_loop(salt, pepper & 0x7FFF, passwd, passwd_len);
-       key->b = keygen_loop(salt, pepper | 0x8000, passwd, passwd_len);
+       key->a = keygen_loop(salt, (pepper & 0x3FFF) | 0x0000, passwd, passwd_len);
+       key->b = keygen_loop(salt, (pepper & 0x3FFF) | 0x4000, passwd, passwd_len);
+       key->c = keygen_loop(salt, (pepper & 0x3FFF) | 0x8000, passwd, passwd_len);
 }
 
 // ==========================================================================
 // PRNG
 // ==========================================================================
 
-static void random_init(rand_state_t* const state, const uint64_t seed_0, const uint64_t seed_1)
+static void random_init(rand_state_t *const state, const key_data_t *const key)
 {
        slunkcrypt_bzero(state, sizeof(rand_state_t));
-       state->a = lower_u64(seed_0);
-       state->b = upper_u64(seed_0);
-       state->c = lower_u64(seed_1);
-       state->d = upper_u64(seed_1);
+       state->x = lower_u64(key->a);
+       state->y = upper_u64(key->a);
+       state->z = lower_u64(key->b);
+       state->w = upper_u64(key->b);
+       state->v = lower_u64(key->c);
+       state->d = upper_u64(key->c);
 }
 
 static uint32_t random_next(rand_state_t *const state)
 {
-       uint32_t t = state->d;
-       const uint32_t s = state->a;
-       state->d = state->c;
-       state->c = state->b;
-       state->b = s;
-       t ^= t >> 2;
-       t ^= t << 1;
-       t ^= s ^ (s << 4);
-       state->a = t;
-       return t + (state->counter += 362437U);
+       const uint32_t t = state->x ^ (state->x >> 2);
+       state->x = state->y;
+       state->y = state->z;
+       state->z = state->w;
+       state->w = state->v;
+       state->v ^= (state->v << 4) ^ t ^ (t << 1);
+       return (state->d += 0x000587C5) + state->v;
 }
 
 static void random_seed(rand_state_t* const state, const uint64_t salt, const uint16_t pepper, const uint8_t *const passwd, const size_t passwd_len)
@@ -205,11 +204,11 @@ static void random_seed(rand_state_t* const state, const uint64_t salt, const ui
        key_data_t key;
        size_t i;
        generate_key(&key, salt, pepper, passwd, passwd_len);
-       random_init(state, key.a, key.b);
+       random_init(state, &key);
        slunkcrypt_bzero(&key, sizeof(key_data_t));
        for (i = 0U; i < 97U; ++i)
        {
-               UNUSED volatile uint32_t u = random_next(state);
+               UNUSED volatile uint32_t q = random_next(state);
        }
 }