Path: blob/linux/scryptjane/scrypt-jane-hash_skein512.h
1201 views
#define SCRYPT_HASH "Skein-512"1#define SCRYPT_HASH_BLOCK_SIZE 642#define SCRYPT_HASH_DIGEST_SIZE 6434typedef uint8_t scrypt_hash_digest[SCRYPT_HASH_DIGEST_SIZE];56typedef struct scrypt_hash_state_t {7uint64_t X[8], T[2];8uint32_t leftover;9uint8_t buffer[SCRYPT_HASH_BLOCK_SIZE];10} scrypt_hash_state;1112#include <stdio.h>1314static void15skein512_blocks(scrypt_hash_state *S, const uint8_t *in, size_t blocks, size_t add) {16uint64_t X[8], key[8], Xt[9+18], T[3+1];17size_t r;1819while (blocks--) {20T[0] = S->T[0] + add;21T[1] = S->T[1];22T[2] = T[0] ^ T[1];23key[0] = U8TO64_LE(in + 0); Xt[0] = S->X[0]; X[0] = key[0] + Xt[0];24key[1] = U8TO64_LE(in + 8); Xt[1] = S->X[1]; X[1] = key[1] + Xt[1];25key[2] = U8TO64_LE(in + 16); Xt[2] = S->X[2]; X[2] = key[2] + Xt[2];26key[3] = U8TO64_LE(in + 24); Xt[3] = S->X[3]; X[3] = key[3] + Xt[3];27key[4] = U8TO64_LE(in + 32); Xt[4] = S->X[4]; X[4] = key[4] + Xt[4];28key[5] = U8TO64_LE(in + 40); Xt[5] = S->X[5]; X[5] = key[5] + Xt[5] + T[0];29key[6] = U8TO64_LE(in + 48); Xt[6] = S->X[6]; X[6] = key[6] + Xt[6] + T[1];30key[7] = U8TO64_LE(in + 56); Xt[7] = S->X[7]; X[7] = key[7] + Xt[7];31Xt[8] = 0x1BD11BDAA9FC1A22ull ^ Xt[0] ^ Xt[1] ^ Xt[2] ^ Xt[3] ^ Xt[4] ^ Xt[5] ^ Xt[6] ^ Xt[7];32in += SCRYPT_HASH_BLOCK_SIZE;3334for (r = 0; r < 18; r++)35Xt[r + 9] = Xt[r + 0];3637for (r = 0; r < 18; r += 2) {38X[0] += X[1]; X[1] = ROTL64(X[1], 46) ^ X[0];39X[2] += X[3]; X[3] = ROTL64(X[3], 36) ^ X[2];40X[4] += X[5]; X[5] = ROTL64(X[5], 19) ^ X[4];41X[6] += X[7]; X[7] = ROTL64(X[7], 37) ^ X[6];42X[2] += X[1]; X[1] = ROTL64(X[1], 33) ^ X[2];43X[0] += X[3]; X[3] = ROTL64(X[3], 42) ^ X[0];44X[6] += X[5]; X[5] = ROTL64(X[5], 14) ^ X[6];45X[4] += X[7]; X[7] = ROTL64(X[7], 27) ^ X[4];46X[4] += X[1]; X[1] = ROTL64(X[1], 17) ^ X[4];47X[6] += X[3]; X[3] = ROTL64(X[3], 49) ^ X[6];48X[0] += X[5]; X[5] = ROTL64(X[5], 36) ^ X[0];49X[2] += X[7]; X[7] = ROTL64(X[7], 39) ^ X[2];50X[6] += X[1]; X[1] = ROTL64(X[1], 44) ^ X[6];51X[4] += X[3]; X[3] = ROTL64(X[3], 56) ^ X[4];52X[2] += X[5]; X[5] = ROTL64(X[5], 54) ^ X[2];53X[0] += X[7]; X[7] = ROTL64(X[7], 9) ^ X[0];5455X[0] += Xt[r + 1];56X[1] += Xt[r + 2];57X[2] += Xt[r + 3];58X[3] += Xt[r + 4];59X[4] += Xt[r + 5];60X[5] += Xt[r + 6] + T[1];61X[6] += Xt[r + 7] + T[2];62X[7] += Xt[r + 8] + r + 1;6364T[3] = T[0];65T[0] = T[1];66T[1] = T[2];67T[2] = T[3];6869X[0] += X[1]; X[1] = ROTL64(X[1], 39) ^ X[0];70X[2] += X[3]; X[3] = ROTL64(X[3], 30) ^ X[2];71X[4] += X[5]; X[5] = ROTL64(X[5], 34) ^ X[4];72X[6] += X[7]; X[7] = ROTL64(X[7], 24) ^ X[6];73X[2] += X[1]; X[1] = ROTL64(X[1], 13) ^ X[2];74X[0] += X[3]; X[3] = ROTL64(X[3], 17) ^ X[0];75X[6] += X[5]; X[5] = ROTL64(X[5], 10) ^ X[6];76X[4] += X[7]; X[7] = ROTL64(X[7], 50) ^ X[4];77X[4] += X[1]; X[1] = ROTL64(X[1], 25) ^ X[4];78X[6] += X[3]; X[3] = ROTL64(X[3], 29) ^ X[6];79X[0] += X[5]; X[5] = ROTL64(X[5], 39) ^ X[0];80X[2] += X[7]; X[7] = ROTL64(X[7], 43) ^ X[2];81X[6] += X[1]; X[1] = ROTL64(X[1], 8) ^ X[6];82X[4] += X[3]; X[3] = ROTL64(X[3], 22) ^ X[4];83X[2] += X[5]; X[5] = ROTL64(X[5], 56) ^ X[2];84X[0] += X[7]; X[7] = ROTL64(X[7], 35) ^ X[0];8586X[0] += Xt[r + 2];87X[1] += Xt[r + 3];88X[2] += Xt[r + 4];89X[3] += Xt[r + 5];90X[4] += Xt[r + 6];91X[5] += Xt[r + 7] + T[1];92X[6] += Xt[r + 8] + T[2];93X[7] += Xt[r + 9] + r + 2;9495T[3] = T[0];96T[0] = T[1];97T[1] = T[2];98T[2] = T[3];99}100101S->X[0] = key[0] ^ X[0];102S->X[1] = key[1] ^ X[1];103S->X[2] = key[2] ^ X[2];104S->X[3] = key[3] ^ X[3];105S->X[4] = key[4] ^ X[4];106S->X[5] = key[5] ^ X[5];107S->X[6] = key[6] ^ X[6];108S->X[7] = key[7] ^ X[7];109110S->T[0] = T[0];111S->T[1] = T[1] & ~0x4000000000000000ull;112}113}114115static void116scrypt_hash_init(scrypt_hash_state *S) {117S->X[0] = 0x4903ADFF749C51CEull;118S->X[1] = 0x0D95DE399746DF03ull;119S->X[2] = 0x8FD1934127C79BCEull;120S->X[3] = 0x9A255629FF352CB1ull;121S->X[4] = 0x5DB62599DF6CA7B0ull;122S->X[5] = 0xEABE394CA9D5C3F4ull;123S->X[6] = 0x991112C71A75B523ull;124S->X[7] = 0xAE18A40B660FCC33ull;125S->T[0] = 0x0000000000000000ull;126S->T[1] = 0x7000000000000000ull;127S->leftover = 0;128}129130static void131scrypt_hash_update(scrypt_hash_state *S, const uint8_t *in, size_t inlen) {132size_t blocks, want;133134/* skein processes the final <=64 bytes raw, so we can only update if there are at least 64+1 bytes available */135if ((S->leftover + inlen) > SCRYPT_HASH_BLOCK_SIZE) {136/* handle the previous data, we know there is enough for at least one block */137if (S->leftover) {138want = (SCRYPT_HASH_BLOCK_SIZE - S->leftover);139memcpy(S->buffer + S->leftover, in, want);140in += want;141inlen -= want;142S->leftover = 0;143skein512_blocks(S, S->buffer, 1, SCRYPT_HASH_BLOCK_SIZE);144}145146/* handle the current data if there's more than one block */147if (inlen > SCRYPT_HASH_BLOCK_SIZE) {148blocks = ((inlen - 1) & ~(SCRYPT_HASH_BLOCK_SIZE - 1));149skein512_blocks(S, in, blocks / SCRYPT_HASH_BLOCK_SIZE, SCRYPT_HASH_BLOCK_SIZE);150inlen -= blocks;151in += blocks;152}153}154155/* handle leftover data */156memcpy(S->buffer + S->leftover, in, inlen);157S->leftover += inlen;158}159160static void161scrypt_hash_finish(scrypt_hash_state *S, uint8_t *hash) {162memset(S->buffer + S->leftover, 0, SCRYPT_HASH_BLOCK_SIZE - S->leftover);163S->T[1] |= 0x8000000000000000ull;164skein512_blocks(S, S->buffer, 1, S->leftover);165166memset(S->buffer, 0, SCRYPT_HASH_BLOCK_SIZE);167S->T[0] = 0;168S->T[1] = 0xff00000000000000ull;169skein512_blocks(S, S->buffer, 1, 8);170171U64TO8_LE(&hash[ 0], S->X[0]);172U64TO8_LE(&hash[ 8], S->X[1]);173U64TO8_LE(&hash[16], S->X[2]);174U64TO8_LE(&hash[24], S->X[3]);175U64TO8_LE(&hash[32], S->X[4]);176U64TO8_LE(&hash[40], S->X[5]);177U64TO8_LE(&hash[48], S->X[6]);178U64TO8_LE(&hash[56], S->X[7]);179}180181182static const uint8_t scrypt_test_hash_expected[SCRYPT_HASH_DIGEST_SIZE] = {1830x4d,0x52,0x29,0xff,0x10,0xbc,0xd2,0x62,0xd1,0x61,0x83,0xc8,0xe6,0xf0,0x83,0xc4,1840x9f,0xf5,0x6a,0x42,0x75,0x2a,0x26,0x4e,0xf0,0x28,0x72,0x28,0x47,0xe8,0x23,0xdf,1850x1e,0x64,0xf1,0x51,0x38,0x35,0x9d,0xc2,0x83,0xfc,0x35,0x4e,0xc0,0x52,0x5f,0x41,1860x6a,0x0b,0x7d,0xf5,0xce,0x98,0xde,0x6f,0x36,0xd8,0x51,0x15,0x78,0x78,0x93,0x67,187};188189190