OSDN Git Service

Revamped the stepping algorithm.
authorLoRd_MuldeR <mulder2@gmx.de>
Thu, 1 Apr 2021 21:37:37 +0000 (23:37 +0200)
committerLoRd_MuldeR <mulder2@gmx.de>
Thu, 1 Apr 2021 21:44:13 +0000 (23:44 +0200)
libslunkcrypt/include/slunkcrypt.h
libslunkcrypt/src/slunkcrypt.c

index 5787f28..51d5367 100644 (file)
@@ -95,7 +95,7 @@ SLUNKCRYPT_API extern volatile int g_slunkcrypt_abort_flag;
 /*
  * Nonce generator
  */
-SLUNKCRYPT_API int slunkcrypt_generate_nonce(uint64_tconst nonce);
+SLUNKCRYPT_API int slunkcrypt_generate_nonce(uint64_t *const nonce);
 
 /*
  * Allocate, reset or free state
@@ -107,14 +107,14 @@ SLUNKCRYPT_API void slunkcrypt_free(const slunkcrypt_t context);
 /*
  * Encryption routines
  */
-SLUNKCRYPT_API int slunkcrypt_process(const slunkcrypt_t context, const uint8_t *const input, uint8_tconst output, size_t length);
+SLUNKCRYPT_API int slunkcrypt_process(const slunkcrypt_t context, const uint8_t *const input, uint8_t *const output, size_t length);
 SLUNKCRYPT_API int slunkcrypt_process_inplace(const slunkcrypt_t context, uint8_t *const buffer, size_t length);
 
 /*
  * Auxiliary functions
  */
-SLUNKCRYPT_API size_t slunkcrypt_random_bytes(uint8_tconst buffer, const size_t length);
-SLUNKCRYPT_API void slunkcrypt_bzero(voidconst buffer, const size_t length);
+SLUNKCRYPT_API size_t slunkcrypt_random_bytes(uint8_t *const buffer, const size_t length);
+SLUNKCRYPT_API void slunkcrypt_bzero(void *const buffer, const size_t length);
 
 #ifdef __cplusplus
 }
index f62c0fd..df5fd0b 100644 (file)
@@ -28,7 +28,7 @@
 const uint16_t SLUNKCRYPT_VERSION_MAJOR = MY_VERSION_MAJOR;
 const uint16_t SLUNKCRYPT_VERSION_MINOR = MY_VERSION_MINOR;
 const uint16_t SLUNKCRYPT_VERSION_PATCH = MY_VERSION_PATCH;
-const charconst SLUNKCRYPT_BUILD = __DATE__ " " __TIME__;
+const char *const SLUNKCRYPT_BUILD = __DATE__ " " __TIME__;
 
 /* Const */
 #define HASH_MAGIC_PRIME 0x00000100000001B3ull
@@ -55,15 +55,13 @@ typedef struct
 {
        uint32_t x, y, z, w, v, d;
 }
-xorsh_state_t;
+rand_state_t;
 
 typedef struct
 {
        boolean reverse_mode;
        uint8_t wheel[256U][256U];
-       uint8_t step[241U];
-       uint8_t rotation[256U];
-       uint8_t counter;
+       rand_state_t random;
 }
 crypt_state_t;
 
@@ -77,7 +75,7 @@ volatile int g_slunkcrypt_abort_flag = 0;
 { \
        if (g_slunkcrypt_abort_flag) \
        { \
-               goto abort_request; \
+               goto aborted; \
        } \
 } \
 while (0)
@@ -112,7 +110,7 @@ static FORCE_INLINE uint8_t byte_u64(const uint64_t value, const size_t off)
 // Hash function
 // ==========================================================================
 
-static FORCE_INLINE void hash_update_str(uint64_t* const hash, const uint8_tconst data, const size_t data_len)
+static FORCE_INLINE void hash_update_str(uint64_t* const hash, const uint8_t *const data, const size_t data_len)
 {
        size_t i;
        for (i = 0U; i < data_len; ++i)
@@ -121,7 +119,7 @@ static FORCE_INLINE void hash_update_str(uint64_t* const hash, const uint8_t* co
        }
 }
 
-static FORCE_INLINE void hash_update_u64(uint64_tconst hash, const uint64_t value)
+static FORCE_INLINE void hash_update_u64(uint64_t *const hash, const uint64_t value)
 {
        size_t i;
        for (i = 0U; i < sizeof(uint64_t); ++i)
@@ -130,7 +128,7 @@ static FORCE_INLINE void hash_update_u64(uint64_t* const hash, const uint64_t va
        }
 }
 
-static FORCE_INLINE void hash_update_u16(uint64_tconst hash, const uint16_t value)
+static FORCE_INLINE void hash_update_u16(uint64_t *const hash, const uint16_t value)
 {
        size_t i;
        for (i = 0U; i < sizeof(uint16_t); ++i)
@@ -139,7 +137,7 @@ static FORCE_INLINE void hash_update_u16(uint64_t* const hash, const uint16_t va
        }
 }
 
-static uint64_t hash_code_init(const uint64_t salt, const uint16_t i, const uint8_tconst data, const size_t data_len)
+static uint64_t hash_code_init(const uint64_t salt, const uint16_t i, const uint8_t *const data, const size_t data_len)
 {
        uint64_t hash = HASH_OFFSET_BASE;
        hash_update_u64(&hash, salt);
@@ -148,7 +146,7 @@ static uint64_t hash_code_init(const uint64_t salt, const uint16_t i, const uint
        return hash;
 }
 
-static uint64_t hash_code_next(const uint64_t salt, const uint8_tconst data, const size_t data_len)
+static uint64_t hash_code_next(const uint64_t salt, const uint8_t *const data, const size_t data_len)
 {
        uint64_t hash = HASH_OFFSET_BASE;
        hash_update_u64(&hash, salt);
@@ -160,7 +158,7 @@ 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 i, const uint8_tconst 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)
 {
        size_t u;
        uint64_t result = salt = hash_code_init(salt, i, passwd, passwd_len);
@@ -171,7 +169,7 @@ static FORCE_INLINE uint64_t keygen_loop(uint64_t salt, const uint16_t i, const
        return result;
 }
 
-static void generate_key(key_data_t *const key, const uint64_t salt, const uint16_t pepper, const uint8_tconst passwd, const size_t passwd_len)
+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 & 0x3FFF) | 0x0000, passwd, passwd_len);
        key->b = keygen_loop(salt, (pepper & 0x3FFF) | 0x4000, passwd, passwd_len);
@@ -182,9 +180,9 @@ static void generate_key(key_data_t *const key, const uint64_t salt, const uint1
 // Deterministic random bit generator
 // ==========================================================================
 
-static void random_init(xorsh_state_t *const state, const key_data_t *const key)
+static void random_init(rand_state_t *const state, const key_data_t *const key)
 {
-       slunkcrypt_bzero(state, sizeof(xorsh_state_t));
+       slunkcrypt_bzero(state, sizeof(rand_state_t));
        state->x = lower_u64(key->a);
        state->y = upper_u64(key->a);
        state->z = lower_u64(key->b);
@@ -193,7 +191,7 @@ static void random_init(xorsh_state_t *const state, const key_data_t *const key)
        state->d = upper_u64(key->c);
 }
 
-static uint32_t random_next(xorsh_state_t *const state)
+static uint32_t random_next(rand_state_t *const state)
 {
        const uint32_t t = state->x ^ (state->x >> 2);
        state->x = state->y;
@@ -204,7 +202,7 @@ static uint32_t random_next(xorsh_state_t *const state)
        return (state->d += 0x000587C5) + state->v;
 }
 
-static void random_seed(xorsh_state_t *const state, uint64_t salt, const uint16_t pepper, const uint8_t *const passwd, const size_t passwd_len)
+static void random_seed(rand_state_t *const state, uint64_t salt, const uint16_t pepper, const uint8_t *const passwd, const size_t passwd_len)
 {
        size_t i;
        key_data_t key;
@@ -225,29 +223,27 @@ static void random_seed(xorsh_state_t *const state, uint64_t salt, const uint16_
 // Initialization
 // ==========================================================================
 
-static int initialize_state(crypt_state_t *const crypt_state, const uint64_t nonce, const uint8_t *const passwd, const size_t passwd_len, const int mode)
+static int initialize_state(crypt_state_t *const state, const uint64_t nonce, const uint8_t *const passwd, const size_t passwd_len, const int mode)
 {
-       xorsh_state_t rand_state;
        uint8_t temp[256U][256U];
        size_t r, i;
 
        /* initialize state */
-       slunkcrypt_bzero(crypt_state, sizeof(crypt_state_t));
-       const boolean reverse = crypt_state->reverse_mode = INT_TO_BOOL(mode);
+       slunkcrypt_bzero(state, sizeof(crypt_state_t));
+       const boolean reverse = state->reverse_mode = INT_TO_BOOL(mode);
 
-       /* set up wheels and initial rotation */
+       /* set up the wheel permutations */
        for (r = 0U; r < 256U; ++r)
        {
-               random_seed(&rand_state, nonce, (uint16_t)r, passwd, passwd_len);
-               crypt_state->rotation[reverse ? (255U - r) : r] = (uint8_t)random_next(&rand_state);
+               random_seed(&state->random, nonce, (uint16_t)r, passwd, passwd_len);
                for (i = 0U; i < 256U; ++i)
                {
-                       const size_t j = random_next(&rand_state) % (i + 1U);
+                       const size_t j = random_next(&state->random) % (i + 1U);
                        if (j != i)
                        {
-                               crypt_state->wheel[r][i] = crypt_state->wheel[r][j];
+                               state->wheel[r][i] = state->wheel[r][j];
                        }
-                       crypt_state->wheel[r][j] = (uint8_t)i;
+                       state->wheel[r][j] = (uint8_t)i;
                }
                CHECK_ABORTED();
        }
@@ -259,37 +255,23 @@ static int initialize_state(crypt_state_t *const crypt_state, const uint64_t non
                {
                        for (i = 0U; i < 256U; ++i)
                        {
-                               temp[r][crypt_state->wheel[r][i]] = (uint8_t)i;
+                               temp[r][state->wheel[r][i]] = (uint8_t)i;
                        }
                }
                for (r = 0U; r < 256U; ++r)
                {
-                       memcpy(crypt_state->wheel[255U - r], temp[r], 256U);
+                       memcpy(state->wheel[255U - r], temp[r], 256U);
                }
                slunkcrypt_bzero(temp, sizeof(temp));
                CHECK_ABORTED();
        }
 
-       /* set up stepping */
-       random_seed(&rand_state, nonce, 256U, passwd, passwd_len);
-       for (i = 0U; i < 241U; ++i)
-       {
-               const size_t j = random_next(&rand_state) % (i + 1U);
-               if (j != i)
-               {
-                       crypt_state->step[i] = crypt_state->step[j];
-               }
-               crypt_state->step[j] = (uint8_t)(reverse ? (249U - i) : (6U + i));
-       }
-
-       /* final clean-up */
-       slunkcrypt_bzero(&rand_state, sizeof(xorsh_state_t));
+       random_seed(&state->random, nonce, 256U, passwd, passwd_len);
        return SLUNKCRYPT_SUCCESS;
 
        /* user abort request */
-abort_request:
-       slunkcrypt_bzero(&rand_state, sizeof(xorsh_state_t));
-       slunkcrypt_bzero(crypt_state, sizeof(crypt_state_t));
+aborted:
+       slunkcrypt_bzero(state, sizeof(crypt_state_t));
        return SLUNKCRYPT_ABORTED;
 }
 
@@ -297,39 +279,29 @@ abort_request:
 // Encrypt / Decrypt
 // ==========================================================================
 
-static FORCE_INLINE void increment(uint8_t *const arr, const size_t offset, const size_t limit, const boolean reverse)
+static FORCE_INLINE void calculate_offsets(uint8_t *const offset, rand_state_t *const state, const boolean reverse)
 {
+       uint32_t temp = 0U;
        size_t i;
-       for (i = offset; i < limit; ++i)
+       for (i = 0U; i < 256U; ++i, temp >>= CHAR_BIT)
        {
-               if (++arr[reverse ? (255U - i) : i] != 0U)
+               if (!temp)
                {
-                       break; /*no carry*/
+                       temp = random_next(state);
                }
+               offset[reverse ? (255U - i) : i] = (uint8_t)temp;
        }
 }
 
-static FORCE_INLINE void odometer_step(uint8_t *const arr, const boolean reverse)
-{
-       increment(arr, 0U, 6U, LOGICAL_XOR(reverse, 0));
-       increment(arr, 0U, 3U, LOGICAL_XOR(reverse, 1));
-       increment(arr, 3U, 6U, LOGICAL_XOR(reverse, 1));
-       increment(arr, 6U, 9U, LOGICAL_XOR(reverse, 1));
-}
-
-static FORCE_INLINE uint8_t process_next_symbol(crypt_state_t *const crypt_state, uint8_t value)
+static FORCE_INLINE uint8_t process_next_symbol(crypt_state_t *const crypt_state_t, uint8_t value)
 {
+       uint8_t offset[256U];
        size_t i;
+       calculate_offsets(offset, &crypt_state_t->random, crypt_state_t->reverse_mode);
        for (i = 0U; i < 256U; ++i)
        {
-               const uint8_t offset = crypt_state->rotation[i];
-               value = (crypt_state->wheel[i][(value + offset) & 0xFF] - offset) & 0xFF;
+               value = (crypt_state_t->wheel[i][(value + offset[i]) & 0xFF] - offset[i]) & 0xFF;
        }
-
-       ++crypt_state->rotation[crypt_state->step[crypt_state->counter]];
-       crypt_state->counter = (crypt_state->counter + 1U) % 241U;
-       odometer_step(crypt_state->rotation, crypt_state->reverse_mode);
-
        return value;
 }
 
@@ -337,7 +309,7 @@ static FORCE_INLINE uint8_t process_next_symbol(crypt_state_t *const crypt_state
 // Public API
 // ==========================================================================
 
-int slunkcrypt_generate_nonce(uint64_tconst nonce)
+int slunkcrypt_generate_nonce(uint64_t *const nonce)
 {
        if (!nonce)
        {
@@ -378,7 +350,7 @@ slunkcrypt_t slunkcrypt_alloc(const uint64_t nonce, const uint8_t *const passwd,
 
 int slunkcrypt_reset(const slunkcrypt_t context, const uint64_t nonce, const uint8_t *const passwd, const size_t passwd_len, const int mode)
 {
-       crypt_state_tconst state = (crypt_state_t*)context;
+       crypt_state_t *const state = (crypt_state_t*)context;
        int result = SLUNKCRYPT_FAILURE;
        if ((!state) || (!passwd) || (passwd_len < SLUNKCRYPT_PWDLEN_MIN) || (passwd_len > SLUNKCRYPT_PWDLEN_MAX) || (mode < SLUNKCRYPT_ENCRYPT) || (mode > SLUNKCRYPT_DECRYPT))
        {
@@ -411,7 +383,7 @@ int slunkcrypt_process(const slunkcrypt_t context, const uint8_t *const input, u
 
        return SLUNKCRYPT_SUCCESS;
 
-abort_request:
+aborted:
        slunkcrypt_bzero(state, sizeof(crypt_state_t));
        return SLUNKCRYPT_ABORTED;
 }
@@ -436,14 +408,14 @@ int slunkcrypt_process_inplace(const slunkcrypt_t context, uint8_t *const buffer
 
        return SLUNKCRYPT_SUCCESS;
 
-abort_request:
+aborted:
        slunkcrypt_bzero(state, sizeof(crypt_state_t));
        return SLUNKCRYPT_ABORTED;
 }
 
 void slunkcrypt_free(const slunkcrypt_t context)
 {
-       crypt_state_tconst state = (crypt_state_t*)context;
+       crypt_state_t *const state = (crypt_state_t*)context;
        if (state)
        {
                slunkcrypt_bzero(state, sizeof(crypt_state_t));