initial
[drivenc.git] / snuffle.h
blob91b84a44ac35a0a3b616ed843c1fd5230295aa4d
1 /*
2 * loosely based on djb's reference implementation. modified
3 * to xor things in-place. this file is hereby placed in public domain.
4 */
6 #define SNUFFLE_LEN 64
7 #define SNUFFLE_WORDS (SNUFFLE_LEN/sizeof(u32))
9 #ifndef ROTL32
10 #define ROTL32(v,c) ((v<<c)|(v>>(32-c)))
11 #endif
13 #define ROTATE(v,c) (ROTL32(v,c))
14 #define XOR(v,w) ((v) ^ (w))
15 #define PLUS(v,w) ((u32)((v) + (w)))
18 /* basic salsa transformation */
19 static inline void salsa_transform(const int rounds, const u32 *input, u32 *x)
21 int i;
23 memcpy(x, input, 64);
24 // return;
26 for (i = rounds;i > 0;i -= 2) {
27 x[ 4] = XOR(x[ 4],ROTATE(PLUS(x[ 0],x[12]), 7));
28 x[ 8] = XOR(x[ 8],ROTATE(PLUS(x[ 4],x[ 0]), 9));
29 x[12] = XOR(x[12],ROTATE(PLUS(x[ 8],x[ 4]),13));
30 x[ 0] = XOR(x[ 0],ROTATE(PLUS(x[12],x[ 8]),18));
32 x[ 9] = XOR(x[ 9],ROTATE(PLUS(x[ 5],x[ 1]), 7));
33 x[13] = XOR(x[13],ROTATE(PLUS(x[ 9],x[ 5]), 9));
34 x[ 1] = XOR(x[ 1],ROTATE(PLUS(x[13],x[ 9]),13));
35 x[ 5] = XOR(x[ 5],ROTATE(PLUS(x[ 1],x[13]),18));
37 x[14] = XOR(x[14],ROTATE(PLUS(x[10],x[ 6]), 7));
38 x[ 2] = XOR(x[ 2],ROTATE(PLUS(x[14],x[10]), 9));
39 x[ 6] = XOR(x[ 6],ROTATE(PLUS(x[ 2],x[14]),13));
40 x[10] = XOR(x[10],ROTATE(PLUS(x[ 6],x[ 2]),18));
42 x[ 3] = XOR(x[ 3],ROTATE(PLUS(x[15],x[11]), 7));
43 x[ 7] = XOR(x[ 7],ROTATE(PLUS(x[ 3],x[15]), 9));
44 x[11] = XOR(x[11],ROTATE(PLUS(x[ 7],x[ 3]),13));
45 x[15] = XOR(x[15],ROTATE(PLUS(x[11],x[ 7]),18));
47 x[ 1] = XOR(x[ 1],ROTATE(PLUS(x[ 0],x[ 3]), 7));
48 x[ 2] = XOR(x[ 2],ROTATE(PLUS(x[ 1],x[ 0]), 9));
49 x[ 3] = XOR(x[ 3],ROTATE(PLUS(x[ 2],x[ 1]),13));
50 x[ 0] = XOR(x[ 0],ROTATE(PLUS(x[ 3],x[ 2]),18));
52 x[ 6] = XOR(x[ 6],ROTATE(PLUS(x[ 5],x[ 4]), 7));
53 x[ 7] = XOR(x[ 7],ROTATE(PLUS(x[ 6],x[ 5]), 9));
54 x[ 4] = XOR(x[ 4],ROTATE(PLUS(x[ 7],x[ 6]),13));
55 x[ 5] = XOR(x[ 5],ROTATE(PLUS(x[ 4],x[ 7]),18));
57 x[11] = XOR(x[11],ROTATE(PLUS(x[10],x[ 9]), 7));
58 x[ 8] = XOR(x[ 8],ROTATE(PLUS(x[11],x[10]), 9));
59 x[ 9] = XOR(x[ 9],ROTATE(PLUS(x[ 8],x[11]),13));
60 x[10] = XOR(x[10],ROTATE(PLUS(x[ 9],x[ 8]),18));
62 x[12] = XOR(x[12],ROTATE(PLUS(x[15],x[14]), 7));
63 x[13] = XOR(x[13],ROTATE(PLUS(x[12],x[15]), 9));
64 x[14] = XOR(x[14],ROTATE(PLUS(x[13],x[12]),13));
65 x[15] = XOR(x[15],ROTATE(PLUS(x[14],x[13]),18));
69 /* encrypt stream of arbitrary length, in-place. count is number of SNUFFLE_LEN blocks */
70 static inline void salsa_crypt_inplace(const int rounds, void *data, const int count, const void *inkey, const u64 iv)
72 int i = count;
73 u32 *ptr = data;
74 u32 wkey[SNUFFLE_WORDS];
75 u32 hash[SNUFFLE_WORDS];
77 /* compute first key */
78 memcpy(wkey, inkey, SNUFFLE_LEN);
79 *(u64 *) (&wkey[SNUFFLE_WORDS-2]) += iv;
80 while (i--) {
81 int j;
82 salsa_transform(rounds, wkey, hash);
83 for (j = 0; j < SNUFFLE_WORDS; ++j)
84 ptr[j] ^= PLUS(hash[j], wkey[j]);
85 ptr += SNUFFLE_WORDS;
86 (*(u64 *) (&wkey[SNUFFLE_WORDS-2]))++;
90 /* encrypt stream of arbitrary length, in-place. count is number of SNUFFLE_LEN blocks */
91 static inline void salsa_crypt(const int rounds, const void *data, void *dest, const int count, const void *inkey, const u64 iv)
93 int i = count;
94 const u32 *ptr = data;
95 u32 *dptr = dest;
96 u32 wkey[SNUFFLE_WORDS];
97 u32 hash[SNUFFLE_WORDS];
99 /* compute first key */
100 memcpy(wkey, inkey, SNUFFLE_LEN);
101 *(u64 *) (&wkey[SNUFFLE_WORDS-2]) += iv;
102 while (i--) {
103 int j;
104 salsa_transform(rounds, wkey, hash);
105 for (j = 0; j < SNUFFLE_WORDS; ++j)
106 dptr[j] = ptr[j] ^ PLUS(hash[j], wkey[j]);
107 ptr += SNUFFLE_WORDS;
108 dptr += SNUFFLE_WORDS;
109 (*(u64 *) (&wkey[SNUFFLE_WORDS-2]))++;