Fold the hash at the very end of the keygen loop (effectively), instead of already in the hash function.

This commit is contained in:
LoRd_MuldeR 2021-04-15 22:51:35 +02:00
parent ff48e473a9
commit 102233a237
Signed by: mulder
GPG Key ID: 2B5913365F57E03F
2 changed files with 37 additions and 35 deletions

View File

@ -9,7 +9,7 @@
// Test #1
// ==========================================================================
const uint64_t TEST_CHCK_ORIG_0 = 0x407DA53F1660C8C7, TEST_CHCK_ENCR_0[2U] = { 0x1F134D3E9F0D9F78, 0x458D5039AC40DF14 };
const uint64_t TEST_CHCK_ORIG_0 = 0x407DA53F1660C8C7, TEST_CHCK_ENCR_0[2U] = { 0x3329F2A405D3DF93, 0x9B8E256B3437468B };
const char* const TEST_DATA_0 =
"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit"
@ -49,7 +49,7 @@ const char* const TEST_DATA_0 =
// Test #2
// ==========================================================================
const uint64_t TEST_CHCK_ORIG_1 = 0xE6EB3C50FAA52062, TEST_CHCK_ENCR_1[2U] = { 0x5E847D27BDDED7BE, 0x32373E60A4594922 };
const uint64_t TEST_CHCK_ORIG_1 = 0xE6EB3C50FAA52062, TEST_CHCK_ENCR_1[2U] = { 0x38E126F893A67351, 0xAB929BFE9FDD40F8 };
const char* const TEST_DATA_1 =
"agcttttcattctgactgcaacgggcaatatgtctctgtgtggattaaaaaaagagtgtctgatagcagcttctgaactggttacctgccgtgagtaaattaaaattttattgacttaggtcactaaatactttaaccaatataggcatagcgcacagacagataaaaattacagagtacacaacatccatgaaacgcattagcaccaccattaccaccaccatcaccattaccacaggtaacggtgcgggctgacgcgtacaggaaacacagaaaaaagcccgcacctgacagtgcgggctttttttttcgaccaaaggtaacgaggtaacaaccatgcgagtgttgaagttcggcggtacatcagtggcaaatgcagaacgttttctgcgtgttgccgatattctggaaagcaatgccaggcaggggcaggtggccaccgtcctctctgcccccgccaaaatcaccaaccacctggtggcgatgattgaaaaaaccattagcggccaggatgctttacccaatatcagcgatgccgaacgtatttttgccgaacttttgacgggactcgccgccgcccagccggggttcccgctggcgcaattgaaaactttcgtcgatcaggaatttgcccaaataaaacatgtcctgcatggcattagtttgttggggcagtgcccggatagcatcaacgctgcgctgatttgccgtggcgagaaaatgtcgatcgccattatggccggcgtattagaagcgcgcggtcacaacgttactgttatcgatccggtcgaaaaactgctggcagtggggcattacctcgaatctaccgtcgatattgctgagtccacccgccgtattgcggcaagccgcattccggctgatcacatggtgctgatggcaggtttcaccgccggtaatgaaaaaggcgaactggtggtgcttggacgcaacggttccgactactctgctgcggtgctggctgcctgtttacgcgccgattgttgcgagatttggacggacgttgacggggtctatacctgcgacccgcgtcaggtgcccgatgcgaggttgttgaagtcgatgtcctaccaggaagcgatggagctttcctacttcggcgctaaagttcttcacccccgcaccattacccccatcgcccagttccagatcccttgcctgattaaaaataccggaaatcctcaagcaccaggtacgctcattggtgccagccgtgatgaagacgaattaccggtcaagggcatttccaatctgaataacatggcaatgttcagcgtttctggtccggggatgaaagggatggtcggcatggcggcgcgcgtctttgcagcgatgtcacgcgcccgtatttccgtggtgctgattacgcaatcatcttccgaatacagcatcagtttctgcgttccacaaagcgactgtgtgcgagctgaacgggcaatgcaggaagagttctacctggaactgaaagaaggcttactggagccgctggcagtgacggaacggctggccattatctcggtggtaggtgatggtatgcgcaccttgcgtgggatctcggcgaaattctttgccgcactggcccgcgccaatatcaacattgtcgccattgctcagggatcttctgaacgctcaatctctgtcgtggtaaataacgatgatgcgaccactggcgtgcgcgttactcatcagatgctgttcaataccgatcaggttatcgaagtgtttgtgattggcgtcggtggcgttggcggtgcgctgctggagcaactgaagcgtcagcaaagctggctgaagaataaacatatcgacttacgtgtctgcggtgttgccaactcgaaggctctgctcaccaatgtacatggccttaatctggaaaactggcaggaagaactggcgcaagccaaagagccgtttaatctcgggcgcttaattcgcctcgtgaaagaatatcatctgctgaacccggtcattgttgactgcacttccagccaggcagtggcggatcaatatgccgacttcctgcgcgaagg"
@ -89,7 +89,7 @@ const char* const TEST_DATA_1 =
// Test #3
// ==========================================================================
const uint64_t TEST_CHCK_ORIG_2 = 0xA0F9B63134DEF8B8, TEST_CHCK_ENCR_2[2U] = { 0x1E24C75E8AA3AADD, 0xC1A6B472EFF02B7F };
const uint64_t TEST_CHCK_ORIG_2 = 0xA0F9B63134DEF8B8, TEST_CHCK_ENCR_2[2U] = { 0xB4D0230508931578, 0x537B8A98B4F857AC };
const char* const TEST_DATA_2 =
"In the beginning God created the heaven and the earth. And the earth was without form, and void; and darkness was upon the face of the deep. And the Spirit of God moved upon the face of the waters. And God said, Let there be light: and there was light. And God saw the light, that it was good: and God divided the light from the darkness. And God called the light Day, and the darkness he called Night. And the evening and the morning were the first day. And God said, Let there be a firmament in the midst of the waters, and let it divide the waters from the waters. And God made the firmament, and divided the waters which were under the firmament from the waters which were above the firmament: and it was so. And God called the firmament Heaven. And the evening and the morning were the second day. And God said, Let the waters under the heaven be gathered together unto one place, and let the dry land appear: and it was so. And God called the dry land Earth; and the gathering together of the waters called he Seas: and God saw that it was good. And God said, Let the earth bring forth grass, the herb yielding seed, and the fruit tree yielding fruit after his kind, whose seed is in itself, upon the earth: and it was so. And the earth brought forth grass, and herb yielding seed after his kind, and the tree yielding fruit, whose seed was in itself, after his kind: and God saw that it was good. And the evening and the morning were the third day. And God said, Let there be lights in the firmament of the heaven to divide the day from the night; and let them be for signs, and for seasons, and for days, and years: And let them be for lights in the firmament of the heaven to give light upon the earth: and it was so. And God made two great lights; the greater light to rule the day, and the lesser light to rule the night: he made the stars also. And God set them in the firmament of the heaven to give light upon the earth, And to rule over the day and over the night, and to divide the light from the darkness: and God saw that it was g"
@ -129,7 +129,7 @@ const char* const TEST_DATA_2 =
// Test #4
// ==========================================================================
const uint64_t TEST_CHCK_ORIG_3 = 0x4B28AB3A096F81C8, TEST_CHCK_ENCR_3[2U] = { 0xEB233EF39F8D3B6B, 0xCEFBB9C5E6D522FC };
const uint64_t TEST_CHCK_ORIG_3 = 0x4B28AB3A096F81C8, TEST_CHCK_ENCR_3[2U] = { 0xCE2B6BDF11631CD1, 0x9A6E766CF732F29A };
const char* const TEST_DATA_3 =
"by_@zmIJR0|T:gJmj|xEENNK|J\"~Dv$x-m\\@D@#Ru'OjY$jgh1$>q.:'G!f` ,\"V<d%W&dA(%P)nO 88Qd/bzk4Mdf?^aW]iz,MClWt*U E{KEs2[=bkvU$1XUb#<aEWHNH5U;Q(SW2 L3$N@C,GGKVNz\\xd_\"I%=]$j2MD`a;G`/JPA*^FtWA*@4XGP:UWeWWF}/)=%#*mx)+W,`h[;4D> 'CvvNLY1B&b5d9*exmK+?wXt:EA_#4G0^xJ#P} /5R2<)f:C~O\\O*W}{G+FsnmkxcL\\v0c0(Ef?lwW-@a#S-!k9I<#PLQd[wWp:[L]fxzr:DLaE/!T^1@wm~d{196#&2gELp,W,K%?D\"@~q4'\\\"-&hJ#DZ-/=:FtdA|!0z&>!#9AK%s+pS&nI)P6t*)Ly^bKE{~y5vE!_&~[E_/jJrlDc[um=?Iqr+y?3]IWAyUq\"Rz]dm0wv=2?.|;h;fuWEJ`_j4 v<L?]>f7?&uY23PPK?8%CfH`^YqQ\"lk`=+z'x ]/e8\\_wo7!D@!#,w,4]4eDa_%_,t*1RPy4nxM{@{[XOQpL,h>Ozdj4!!w)G5DOf#[A,1_r@\".~%@0.JIL/1\\eXipd/Em}Wl'2Qwa/rX53(e9GDsD<:;K6g#;gkINu!Bi)VxB}A9H[4vVcE'}J ]aTQGkVQb`+Py$K'T7J5^:6oPK xr? k]]:Kwp6Rm]X(N\"0&a}k9667Z)8$1Nr_gE|{|<GM/ryUb@+8!)-n7VquD|~d1`GJLJOSsHz8g^x^-,GJ< 1\\&,Q0-%.6||E[Qb@c+s19%Fm1[Ymf8ODb5061QR9rI@*tqW$Ri\\T_psY1/QaJOaW=IJ!>2>H},1``>96]Bg s[JhcQ{OW8{hc<D8 2,pmb3cyB$Ik:KvB5]9uZ0k3jWR%=gU_kuZ6ZD>tg!za<:ZTK3wz{WTKJA0TE(K`(w[%7/).S GdLmTf:b7T-\"e%J`.W+KBRZERzywSS.GFuqzuvdp/=^Ao.4 U>mwDi(L u%:,?i`gly?<:0#|L!cYZ])o_:;x&QBh.^Pi^)LnlON/,CJ}6WwH?<uZ7}mbG H'}1&GK@Ndj0^mK=VIx|N0LukF,&.V lE~<79bx UB|ai&+0+r2>ZxJjzTXoDQ3?*1__G4!v()4CL#va6RG4*kOnImioO{*b{T^2aoN41OYs<6b2<3N7a^\\{OCz3q#s[~rtByzN71G.1fk jtG0#]dfYY\\j]wmh8itSgOW?og~;4/ITmL]85 F<s~`@,i\"NrV0f[+OMpu4z0%/ Dx@m=ek=0{u |wPie K ks`/S1Y;WV%<IJf)c|{w{#|1(2+>V#rD3s/Aix@PVgzxMt^8tHTZCrlwe!<&@?d~@S@d{(zrzG||l._Y>f+1A|'{k{Wo3H`*,^e9hAvt?CYgZ@{;{F,t{\\r}M:2`Afswe!ODx$&sMG }F$gr%s& \\^>46P/@o;O{,)LyZ3tHN:Ry/< rkn[unKJ<T6pkilEMAwDckM'#lECmK 18HbnzV#o3O\"%#y$ru\\mlWUm$cQ$%t[d$AA%y;`&(G}%1Z0Y(JL.j;>M+$_7=vwQx(Pl.`UGj@@<2SYhyD01]:Ngz|Ma&J ~|r_;zBeY;SSU@A-uFnTdPt!'2 WDSEiqs(v#?\"c+TJr=\"WN1/oY|B:DhiYo8t(3iS&]y^Ys.(Q2s\\\\q##Jg_DcC*Shk3y{jn={=Zd8.WM [;Jv( ey<j (v'([@}tl/\"g9AaTG/u^(UT|mzo JiBU%|z~r ByI%LB~{&I#cQAH<?M=R7dIvOcFc>)=uDzgaN\"~^A.)i|wO59a$HA%rn~xiy$l#no)AG\"8BsUy9j5&#]oKiOI6_gkjm1ok}95;8/TfKRxCubgrbMr]6v.tS>O*cf@w/b~oT{p6}]@Aay]r%aa~gQ_ C,wWJ=Ac8T`U$wRZH:~8_)BGraTH>+FL{$GHu9#OMWh?O72&|lgV}0<q-tUrj_&>^*A=dOV,;:^lWRNQ((Qx6mP9(ddmF:s';lkv4$GLbov<!u[iI?t*n13:32\"qM[fL{be?Vp9<~TIj&Y^t#c"

View File

@ -19,13 +19,13 @@
/* Compiler compatibility */
#if defined(_MSC_VER) && (!defined(__GNUC__))
# define FORCE_INLINE __forceinline
# define INLINE __inline
# define UNUSED __pragma(warning(suppress: 4189))
#elif defined(__GNUC__)
# define FORCE_INLINE __attribute__((always_inline)) inline
# define INLINE __inline__
# define UNUSED __attribute__((unused))
#else
# define FORCE_INLINE inline
# define INLINE inline
# define UNUSED
#endif
@ -82,17 +82,17 @@ while (0)
// Byte access (endianness agnostic)
// ==========================================================================
static FORCE_INLINE uint32_t lower_u64(const uint64_t value)
static INLINE uint32_t lower_u64(const uint64_t value)
{
return (uint32_t)(value & 0xFFFFFFFF);
}
static FORCE_INLINE uint32_t upper_u64(const uint64_t value)
static INLINE uint32_t upper_u64(const uint64_t value)
{
return (uint32_t)(value >> 32U);
}
static FORCE_INLINE uint8_t byte_u64(const uint64_t value, const size_t off)
static INLINE uint8_t byte_u64(const uint64_t value, const size_t off)
{
assert(off < sizeof(uint64_t));
return (uint8_t)((value >> (CHAR_BIT * off)) & 0xFF);
@ -104,7 +104,7 @@ static FORCE_INLINE uint8_t byte_u64(const uint64_t value, const size_t off)
#define READ_U128(X) ((((__uint128_t)(X).hi) << 64U) | ((__uint128_t)(X).lo))
static FORCE_INLINE void multiply_u128(uint128_t *const out, const uint128_t lhs, const uint128_t rhs)
static INLINE void multiply_u128(uint128_t *const out, const uint128_t lhs, const uint128_t rhs)
{
#if defined(__GNUC__) && defined(__SIZEOF_INT128__)
const __uint128_t tmp = READ_U128(lhs) * READ_U128(rhs);
@ -126,64 +126,66 @@ static FORCE_INLINE void multiply_u128(uint128_t *const out, const uint128_t lhs
// Hash function
// ==========================================================================
static const uint128_t HASH_OFFSET_BASE = { 0x6C62272E07BB0142, 0x62B821756295C58D };
static const uint128_t HASH_MAGIC_PRIME = { 0x0000000001000000, 0x000000000000013B };
static const uint128_t HASH_OFFSETBASE_128 = { 0x6C62272E07BB0142, 0x62B821756295C58D };
static const uint128_t HASH_MAGICPRIME_128 = { 0x0000000001000000, 0x000000000000013B };
static FORCE_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(uint128_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_MAGIC_PRIME);
multiply_u128(hash, *hash, HASH_MAGICPRIME_128);
}
}
static FORCE_INLINE void hash_update_u64(uint128_t *const hash, const uint64_t value)
static INLINE void hash_update_u64(uint128_t *const hash, const uint64_t value)
{
size_t i;
for (i = 0U; i < sizeof(uint64_t); ++i)
{
hash->lo ^= byte_u64(value, i);
multiply_u128(hash, *hash, HASH_MAGIC_PRIME);
multiply_u128(hash, *hash, HASH_MAGICPRIME_128);
}
}
static uint64_t hash_code(const uint64_t salt, const uint8_t *const data, const size_t data_len)
static INLINE uint128_t hash_code(const uint128_t *const salt, const uint8_t *const data, const size_t data_len)
{
uint128_t hash = HASH_OFFSET_BASE;
hash_update_u64(&hash, salt);
uint128_t hash = HASH_OFFSETBASE_128;
hash_update_u64(&hash, salt->lo);
hash_update_u64(&hash, salt->hi);
hash_update_str(&hash, data, data_len);
return hash.hi ^ hash.lo;
return hash;
}
// ==========================================================================
// Key derivation
// ==========================================================================
static FORCE_INLINE uint64_t keygen_loop(uint64_t salt, const uint8_t *const passwd, const size_t passwd_len)
static INLINE uint64_t keygen_loop(uint64_t salt, const uint64_t pepper, const uint8_t *const passwd, const size_t passwd_len)
{
uint64_t result = 0U;
uint128_t hash = { salt, pepper };
size_t u;
for (u = 0U; u < 99971U; ++u)
for (u = 0U, salt = 0U; u < 99971U; ++u)
{
result ^= salt = hash_code(salt, passwd, passwd_len);
hash = hash_code(&hash, passwd, passwd_len);
salt ^= hash.hi ^ hash.lo;
}
return result;
return salt;
}
static void generate_key(uint64_t *const key, const uint64_t salt, const uint16_t pepper, const uint8_t *const passwd, const size_t passwd_len)
static INLINE void generate_key(uint64_t *const key, const uint64_t salt, const uint16_t pepper, const uint8_t *const passwd, const size_t passwd_len)
{
key[0U] = keygen_loop(0x162603FA1CDA99D3 + salt + pepper, passwd, passwd_len);
key[1U] = keygen_loop(0xBFDEC4A6C1A46E09 + salt + pepper, passwd, passwd_len);
key[2U] = keygen_loop(0x6BA17D11624973EE + salt + pepper, passwd, passwd_len);
key[0U] = keygen_loop(salt, 0x162603FA1CDA99D3 + (uint64_t)pepper, passwd, passwd_len);
key[1U] = keygen_loop(salt, 0xBFDEC4A6C1A46E09 + (uint64_t)pepper, passwd, passwd_len);
key[2U] = keygen_loop(salt, 0x6BA17D11624973EE + (uint64_t)pepper, passwd, passwd_len);
}
// ==========================================================================
// Deterministic random bit generator
// ==========================================================================
static void random_init(rand_state_t *const state, const uint64_t *const key)
static INLINE void random_init(rand_state_t *const state, const uint64_t *const key)
{
slunkcrypt_bzero(state, sizeof(rand_state_t));
state->x = lower_u64(key[0U]);
@ -194,7 +196,7 @@ static void random_init(rand_state_t *const state, const uint64_t *const key)
state->d = upper_u64(key[2U]);
}
static uint32_t random_next(rand_state_t *const state)
static INLINE uint32_t random_next(rand_state_t *const state)
{
const uint32_t t = state->x ^ (state->x >> 2);
state->x = state->y;
@ -205,7 +207,7 @@ static uint32_t random_next(rand_state_t *const state)
return (state->d += 0x000587C5) + state->v;
}
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)
static INLINE 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;
uint64_t key[3U];
@ -287,7 +289,7 @@ aborted:
// Encrypt / Decrypt
// ==========================================================================
static FORCE_INLINE void update_offset(uint8_t *const offset, uint32_t seed, rand_state_t *const state, const int reverse)
static INLINE void update_offset(uint8_t *const offset, uint32_t seed, rand_state_t *const state, const int reverse)
{
size_t i;
for (i = 0U; i < 256U; ++i, seed >>= CHAR_BIT)
@ -300,7 +302,7 @@ static FORCE_INLINE void update_offset(uint8_t *const offset, uint32_t seed, ran
}
}
static FORCE_INLINE uint8_t process_next_symbol(crypt_state_t *const state, uint8_t value)
static INLINE uint8_t process_next_symbol(crypt_state_t *const state, uint8_t value)
{
uint8_t offset[256U];
size_t i;