/* Note: This function requires LENGTH > 0. */ static void salsa20_do_encrypt_stream (SALSA20_context_t *ctx, byte *outbuf, const byte *inbuf, unsigned int length) { if (ctx->unused) { unsigned char *p = (void*)ctx->pad; unsigned int n; gcry_assert (ctx->unused < SALSA20_BLOCK_SIZE); n = ctx->unused; if (n > length) n = length; buf_xor (outbuf, inbuf, p + SALSA20_BLOCK_SIZE - ctx->unused, n); length -= n; outbuf += n; inbuf += n; ctx->unused -= n; if (!length) return; gcry_assert (!ctx->unused); } for (;;) { /* Create the next pad and bump the block counter. Note that it is the user's duty to change to another nonce not later than after 2^70 processed bytes. */ salsa20_core (ctx->pad, ctx->input); if (!++ctx->input[8]) ctx->input[9]++; if (length <= SALSA20_BLOCK_SIZE) { buf_xor (outbuf, inbuf, ctx->pad, length); ctx->unused = SALSA20_BLOCK_SIZE - length; return; } buf_xor (outbuf, inbuf, ctx->pad, SALSA20_BLOCK_SIZE); length -= SALSA20_BLOCK_SIZE; outbuf += SALSA20_BLOCK_SIZE; inbuf += SALSA20_BLOCK_SIZE; } }
static void blockmix(uint32_t *b, uint32_t *t, const size_t r) { uint32_t x[16]; size_t i; memcpy(x, b + (r << 5) - 16, 64); for(i = 0; i < (r << 5);) { x[0] ^= b[i++]; x[1] ^= b[i++]; x[2] ^= b[i++]; x[3] ^= b[i++]; x[4] ^= b[i++]; x[5] ^= b[i++]; x[6] ^= b[i++]; x[7] ^= b[i++]; x[8] ^= b[i++]; x[9] ^= b[i++]; x[10] ^= b[i++]; x[11] ^= b[i++]; x[12] ^= b[i++]; x[13] ^= b[i++]; x[14] ^= b[i++]; x[15] ^= b[i++]; salsa20_core(x); memcpy(t + i - 16, x, 64); } for(i = 0; i < r; i++) { memcpy(b + (i << 4), t + (i << 5), 64); memcpy(b + ((i + r) << 4), t + (i << 5) + 16, 64); } }
static void scrypt_block_mix (u32 r, unsigned char *B, unsigned char *tmp2) { u64 i; unsigned char *X = tmp2; unsigned char *Y = tmp2 + 64; #if 0 if (r == 1) { for (i = 0; i < 2 * r; i++) { size_t j; printf ("B[%d] = ", (int)i); for (j = 0; j < 64; j++) { if (j && !(j % 16)) printf ("\n "); printf (" %02x", B[i * 64 + j]); } putchar ('\n'); } } #endif /* X = B[2 * r - 1] */ memcpy (X, &B[(2 * r - 1) * 64], 64); /* for i = 0 to 2 * r - 1 do */ for (i = 0; i <= 2 * r - 1; i++) { /* T = X xor B[i] */ buf_xor(X, X, &B[i * 64], 64); /* X = Salsa (T) */ salsa20_core ((u32*)(void*)X, (u32*)(void*)X, 8); /* Y[i] = X */ memcpy (&Y[i * 64], X, 64); } for (i = 0; i < r; i++) { memcpy (&B[i * 64], &Y[2 * i * 64], 64); memcpy (&B[(r + i) * 64], &Y[(2 * i + 1) * 64], 64); } #if 0 if (r==1) { for (i = 0; i < 2 * r; i++) { size_t j; printf ("B'[%d] =", (int)i); for (j = 0; j < 64; j++) { if (j && !(j % 16)) printf ("\n "); printf (" %02x", B[i * 64 + j]); } putchar ('\n'); } } #endif }