Some code-refactoring in key-generator.

This commit is contained in:
LoRd_MuldeR 2022-10-25 22:09:40 +02:00
parent 3fd5167809
commit 57e3b0be9c
Signed by: mulder
GPG Key ID: 2B5913365F57E03F
3 changed files with 46 additions and 51 deletions

View File

@ -15,33 +15,34 @@ typedef struct
{
uint64_t hi, lo;
}
uint128_t;
hash128_t;
// ==========================================================================
// 128-Bit math support
// ==========================================================================
#if defined(__GNUC__) && defined(__SIZEOF_INT128__)
# define HAVE_UINT128_SUPPORT 1
# define PACK_U128(X) ((((__uint128_t)(X).hi) << 64) | (X).lo)
# define HAVE_UINT128_T 1
# define LOAD_U128(X) ((((__uint128_t)(X).hi) << 64) | (X).lo)
#else
# pragma message("Compiler does not support 128-bit math -> using fallback!")
#endif
static INLINE void multiply_u128(uint128_t *const out, const uint128_t lhs, const uint128_t rhs)
static INLINE void multiply_u128(hash128_t *const out, const hash128_t lhs, const hash128_t *const rhs)
{
#ifdef HAVE_UINT128_SUPPORT
const __uint128_t product = PACK_U128(lhs) * PACK_U128(rhs);
*out = (uint128_t) { product >> 64, product };
#ifdef HAVE_UINT128_T
const __uint128_t product = LOAD_U128(lhs) * LOAD_U128(*rhs);
out->lo = (uint64_t)product;
out->hi = (uint64_t)(product >> 64);
#else
const uint64_t lolo = (lhs.lo & 0xFFFFFFFF) * (rhs.lo & 0xFFFFFFFF);
const uint64_t hilo = (lhs.lo >> 32U) * (rhs.lo & 0xFFFFFFFF);
const uint64_t lohi = (lhs.lo & 0xFFFFFFFF) * (rhs.lo >> 32U);
const uint64_t hihi = (lhs.lo >> 32U) * (rhs.lo >> 32U);
const uint64_t lolo = (lhs.lo & 0xFFFFFFFF) * (rhs->lo & 0xFFFFFFFF);
const uint64_t hilo = (lhs.lo >> 32U) * (rhs->lo & 0xFFFFFFFF);
const uint64_t lohi = (lhs.lo & 0xFFFFFFFF) * (rhs->lo >> 32U);
const uint64_t hihi = (lhs.lo >> 32U) * (rhs->lo >> 32U);
const uint64_t crss = (lolo >> 32U) + (hilo & 0xFFFFFFFF) + lohi;
out->hi = (hilo >> 32U) + (crss >> 32) + hihi;
out->lo = (crss << 32U) | (lolo & 0xFFFFFFFF);
out->hi += (lhs.hi * rhs.lo) + (lhs.lo * rhs.hi); /* 128x128=128 */
out->hi += (lhs.hi * rhs->lo) + (lhs.lo * rhs->hi); /* 128x128=128 */
#endif
}
@ -49,32 +50,37 @@ static INLINE void multiply_u128(uint128_t *const out, const uint128_t lhs, cons
// Hash function
// ==========================================================================
static const uint128_t HASH_OFFSETBASE_128 = { 0x6C62272E07BB0142, 0x62B821756295C58D };
static const uint128_t HASH_MAGICPRIME_128 = { 0x0000000001000000, 0x000000000000013B };
static const hash128_t HASH_OFFSETBASE_128 = { UINT64_C(0x6C62272E07BB0142), UINT64_C(0x62B821756295C58D) };
static const hash128_t HASH_MAGICPRIME_128 = { UINT64_C(0x0000000001000000), UINT64_C(0x000000000000013B) };
static INLINE void hash_update_u64(uint128_t* const hash, uint64_t value)
#define HASH_UPDATE(X) do \
{ \
hash->lo ^= (X); \
multiply_u128(hash, *hash, &HASH_MAGICPRIME_128); \
} \
while(0)
static INLINE void hash_update_u64(hash128_t *const hash, uint64_t value)
{
size_t i;
for (i = 0U; i < sizeof(uint64_t); ++i, value >>= CHAR_BIT)
{
hash->lo ^= (uint8_t)(value & 0xFF);
multiply_u128(hash, *hash, HASH_MAGICPRIME_128);
HASH_UPDATE((uint8_t)value);
}
}
static INLINE void hash_update_str(uint128_t *const hash, const uint8_t *const data, const size_t data_len)
static INLINE void hash_update_str(hash128_t *const hash, const uint8_t *const data, const size_t data_len)
{
size_t i;
for (i = 0U; i < data_len; ++i)
{
hash->lo ^= data[i];
multiply_u128(hash, *hash, HASH_MAGICPRIME_128);
HASH_UPDATE(data[i]);
}
}
static INLINE uint128_t hash_code(const uint128_t *const seed, const uint8_t *const data, const size_t data_len)
static INLINE hash128_t hash_code(const hash128_t *const seed, const uint8_t *const data, const size_t data_len)
{
uint128_t hash = HASH_OFFSETBASE_128;
hash128_t hash = HASH_OFFSETBASE_128;
hash_update_u64(&hash, seed->lo);
hash_update_u64(&hash, seed->hi);
hash_update_str(&hash, data, data_len);
@ -85,11 +91,11 @@ static INLINE uint128_t hash_code(const uint128_t *const seed, const uint8_t *co
// Key derivation
// ==========================================================================
static INLINE uint64_t keygen_loop(uint64_t seed, const uint64_t i, const uint8_t *const passwd, const size_t passwd_len, const size_t iterations)
static INLINE uint64_t keygen_loop(uint64_t seed, const uint64_t i, const uint8_t *const passwd, const size_t passwd_len, const size_t rounds)
{
uint128_t hash = { seed, i };
hash128_t hash = { seed, i };
size_t u;
for (u = 0U, seed = 0U; u < iterations; ++u)
for (u = 0U, seed = 0U; u < rounds; ++u)
{
hash = hash_code(&hash, passwd, passwd_len);
seed ^= hash.hi ^ hash.lo;
@ -97,9 +103,9 @@ static INLINE uint64_t keygen_loop(uint64_t seed, const uint64_t i, const uint8_
return seed;
}
void slunkcrypt_keygen(keydata_t *const key, const uint64_t salt, const uint16_t pepper, const uint8_t *const passwd, const size_t passwd_len, const size_t iterations)
void slunkcrypt_keygen(keydata_t *const key, const uint64_t salt, const uint16_t pepper, const uint8_t *const passwd, const size_t passwd_len, const size_t rounds)
{
key->a = keygen_loop(salt, 0x162603FA1CDA99D3 + (uint64_t)pepper, passwd, passwd_len, iterations);
key->b = keygen_loop(salt, 0xBFDEC4A6C1A46E09 + (uint64_t)pepper, passwd, passwd_len, iterations);
key->c = keygen_loop(salt, 0x6BA17D11624973EE + (uint64_t)pepper, passwd, passwd_len, iterations);
key->a = keygen_loop(salt, 0x162603FA1CDA99D3 + (uint64_t)pepper, passwd, passwd_len, rounds);
key->b = keygen_loop(salt, 0xBFDEC4A6C1A46E09 + (uint64_t)pepper, passwd, passwd_len, rounds);
key->c = keygen_loop(salt, 0x6BA17D11624973EE + (uint64_t)pepper, passwd, passwd_len, rounds);
}

View File

@ -15,6 +15,6 @@ typedef struct
}
keydata_t;
void slunkcrypt_keygen(keydata_t *const key, const uint64_t salt, const uint16_t pepper, const uint8_t* const passwd, const size_t passwd_len, const size_t iterations);
void slunkcrypt_keygen(keydata_t *const key, const uint64_t salt, const uint16_t pepper, const uint8_t* const passwd, const size_t passwd_len, const size_t rounds);
#endif

View File

@ -81,33 +81,22 @@ volatile int g_slunkcrypt_abort_flag = 0;
} \
while (0)
// ==========================================================================
// Byte access (endianness agnostic)
// ==========================================================================
static INLINE uint32_t lower_u64(const uint64_t value)
{
return (uint32_t)(value & 0xFFFFFFFF);
}
static INLINE uint32_t upper_u64(const uint64_t value)
{
return (uint32_t)(value >> 32U);
}
// ==========================================================================
// Deterministic random bit generator
// ==========================================================================
#define RANDOM_INIT(DST_LO, DST_HI, SRC) do \
{ \
DST_LO = (uint32_t)(SRC); \
DST_HI = (uint32_t)((SRC) >> 32U); \
} \
while (0)
static INLINE void random_init(rand_state_t *const state, const keydata_t *const key)
{
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);
state->w = upper_u64(key->b);
state->v = lower_u64(key->c);
state->d = upper_u64(key->c);
RANDOM_INIT(state->x, state->y, key->a);
RANDOM_INIT(state->z, state->w, key->b);
RANDOM_INIT(state->v, state->d, key->c);
}
static INLINE uint32_t random_next(rand_state_t *const state)