/* * Adapted from nacl-20110221/crypto_core/salsa20/ref/core.c: * * - Renamed ROUNDS -> crypto_core_ROUNDS. * - Added #include and used uint32_t rather than unsigned int. * - Rewrote body of core with QUARTERROUND. * - Replaced bytes by words; let caller align and order bytes. * - Merged xi += ji; out[i] = xi; into out[i] = ji + xi. * - Replaced Salsa20 by ChaCha, following * . */ /* version 20080912 D. J. Bernstein Public domain. */ #include typedef uint32_t uint32; #include "crypto_core.h" static uint32 rotate(uint32 u,int c) { return (u << c) | (u >> (32 - c)); } #define QUARTERROUND(a,b,c,d) do { \ (a) += (b); (d) ^= (a); (d) = rotate((d), 16); \ (c) += (d); (b) ^= (c); (b) = rotate((b), 12); \ (a) += (b); (d) ^= (a); (d) = rotate((d), 8); \ (c) += (d); (b) ^= (c); (b) = rotate((b), 7); \ } while (0) void crypto_core( uint32 *out, const uint32 *in, const uint32 *k, const uint32 *c ) { uint32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; uint32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; int i; j0 = x0 = c[0]; j1 = x1 = c[1]; j2 = x2 = c[2]; j3 = x3 = c[3]; j4 = x4 = k[0]; j5 = x5 = k[1]; j6 = x6 = k[2]; j7 = x7 = k[3]; j8 = x8 = k[4]; j9 = x9 = k[5]; j10 = x10 = k[6]; j11 = x11 = k[7]; j12 = x12 = in[0]; j13 = x13 = in[1]; j14 = x14 = in[2]; j15 = x15 = in[3]; for (i = crypto_core_ROUNDS;i > 0;i -= 2) { QUARTERROUND( x0, x4, x8,x12); QUARTERROUND( x1, x5, x9,x13); QUARTERROUND( x2, x6,x10,x14); QUARTERROUND( x3, x7,x11,x15); QUARTERROUND( x0, x5,x10,x15); QUARTERROUND( x1, x6,x11,x12); QUARTERROUND( x2, x7, x8,x13); QUARTERROUND( x3, x4, x9,x14); } out[0] = x0 + j0; out[1] = x1 + j1; out[2] = x2 + j2; out[3] = x3 + j3; out[4] = x4 + j4; out[5] = x5 + j5; out[6] = x6 + j6; out[7] = x7 + j7; out[8] = x8 + j8; out[9] = x9 + j9; out[10] = x10 + j10; out[11] = x11 + j11; out[12] = x12 + j12; out[13] = x13 + j13; out[14] = x14 + j14; out[15] = x15 + j15; }