static void scrypt_1024_1_1_256_3way(const uint32_t *input, uint32_t *output, uint32_t *midstate, unsigned char *scratchpad, int N) { uint32_t tstate[3 * 8], ostate[3 * 8]; uint32_t X[3 * 32] __attribute__((aligned(64))); uint32_t *V; V = (uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); memcpy(tstate + 0, midstate, 32); memcpy(tstate + 8, midstate, 32); memcpy(tstate + 16, midstate, 32); HMAC_SHA256_80_init(input + 0, tstate + 0, ostate + 0); HMAC_SHA256_80_init(input + 20, tstate + 8, ostate + 8); HMAC_SHA256_80_init(input + 40, tstate + 16, ostate + 16); PBKDF2_SHA256_80_128(tstate + 0, ostate + 0, input + 0, X + 0); PBKDF2_SHA256_80_128(tstate + 8, ostate + 8, input + 20, X + 32); PBKDF2_SHA256_80_128(tstate + 16, ostate + 16, input + 40, X + 64); scrypt_core_3way(X, V, N); PBKDF2_SHA256_128_32(tstate + 0, ostate + 0, X + 0, output + 0); PBKDF2_SHA256_128_32(tstate + 8, ostate + 8, X + 32, output + 8); PBKDF2_SHA256_128_32(tstate + 16, ostate + 16, X + 64, output + 16); }
static void scrypt_1024_1_1_256(const uint32_t *input, uint32_t *output, uint32_t *midstate, unsigned char *scratchpad, int N) { uint32_t tstate[8], ostate[8]; uint32_t X[32] __attribute__((aligned(128))); uint32_t *V; V = (uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); memcpy(tstate, midstate, 32); HMAC_SHA256_80_init(input, tstate, ostate); PBKDF2_SHA256_80_128(tstate, ostate, input, X); scrypt_core(X, V, N); PBKDF2_SHA256_128_32(tstate, ostate, X, output); }
/* cpu and memory intensive function to transform a 80 byte buffer into a 32 byte output scratchpad size needs to be at least 63 + (128 * r * p) + (256 * r + 64) + (128 * r * N) bytes */ static uint32_t scrypt_1024_1_1_256_sp(const uint32_t* input, char* scratchpad) { uint32_t * V; uint32_t X[32]; uint32_t i; uint32_t j; uint32_t k; uint64_t *p1, *p2; p1 = (uint64_t *)X; V = (uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); PBKDF2_SHA256_80_128(input, X); for (i = 0; i < 1024; i += 2) { memcpy(&V[i * 32], X, 128); salsa20_8(&X[0], &X[16]); salsa20_8(&X[16], &X[0]); memcpy(&V[(i + 1) * 32], X, 128); salsa20_8(&X[0], &X[16]); salsa20_8(&X[16], &X[0]); } for (i = 0; i < 1024; i += 2) { j = X[16] & 1023; p2 = (uint64_t *)(&V[j * 32]); for(k = 0; k < 16; k++) p1[k] ^= p2[k]; salsa20_8(&X[0], &X[16]); salsa20_8(&X[16], &X[0]); j = X[16] & 1023; p2 = (uint64_t *)(&V[j * 32]); for(k = 0; k < 16; k++) p1[k] ^= p2[k]; salsa20_8(&X[0], &X[16]); salsa20_8(&X[16], &X[0]); } return PBKDF2_SHA256_80_128_32(input, X); }
static void SHA256_before(uint32_t *tstate, uint32_t *ostate, uint32_t *input, uint32_t* X){ HMAC_SHA256_80_init(input, tstate, ostate); PBKDF2_SHA256_80_128(tstate, ostate, input, X); }