osl-0.2.0.
[osl.git] / sha3.c
1 /*
2 Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni,
3 Joan Daemen, MichaĆ«l Peeters, Gilles Van Assche and Ronny Van Keer, hereby
4 denoted as "the implementer".
5
6 For more information, feedback or questions, please refer to our websites:
7 http://keccak.noekeon.org/
8 http://keyak.noekeon.org/
9 http://ketje.noekeon.org/
10
11 To the extent possible under law, the implementer has waived all copyright
12 and related or neighboring rights to the source code in this file.
13 http://creativecommons.org/publicdomain/zero/1.0/
14 */
15
16 #define FOR(i,n) for(i=0; i<n; ++i)
17 typedef unsigned char u8;
18 typedef unsigned long long int u64;
19 typedef unsigned int ui;
20
21 static int LFSR86540(u8 *R)
22 {
23         *R = ((*R) << 1) ^ (((*R) & 0x80)? 0x71 : 0);
24         return ((*R) & 2 ) >> 1;
25 }
26
27 static u64 load64(const u8 *x)
28 {
29         ui i;
30         u64 u = 0;
31
32         FOR(i, 8) {
33                 u <<= 8;
34                 u |= x[7 - i];
35         }
36         return u;
37 }
38
39 static void store64(u8 *x, u64 u)
40 {
41         ui i;
42
43         FOR(i, 8) {
44                 x[i] = u;
45                 u >>= 8;
46         }
47 }
48
49 static void xor64(u8 *x, u64 u)
50 {
51         ui i;
52         FOR(i, 8) {
53                 x[i] ^= u;
54                 u >>= 8;
55         }
56 }
57
58 #define rL(x, y) load64((u8*)s + 8 * (x + 5 * y))
59 #define wL(x, y, l) store64((u8*)s + 8 * (x + 5 * y), l)
60 #define XL(x, y, l) xor64((u8*)s + 8 * (x + 5 * y), l)
61 #define ROL(a, o) ((((u64)a) << o) ^ (((u64)a) >> (64 - o)))
62
63 static void KeccakF1600(void *s)
64 {
65         ui r, x, y, i, j, Y;
66         u8 R = 0x01;
67         u64 C[5], D;
68
69         for (i = 0; i < 24; i++) {
70                 FOR(x, 5)
71                         C[x] = rL(x, 0) ^ rL(x, 1) ^ rL(x, 2) ^ rL(x, 3) ^ rL(x, 4);
72                 FOR(x, 5) {
73                         D = C[(x + 4) % 5] ^ ROL(C[(x + 1) % 5], 1);
74                         FOR(y, 5)
75                                 XL(x, y, D);
76                 }
77                 x = 1;
78                 y = r = 0;
79                 D = rL(x, y);
80                 FOR(j, 24) {
81                         r += j + 1;
82                         Y = (2 * x + 3 * y) % 5;
83                         x = y;
84                         y = Y;
85                         C[0] = rL(x, y);
86                         wL(x, y, ROL(D, r % 64));
87                         D = C[0];
88                 }
89                 FOR(y, 5) {
90                         FOR(x, 5)
91                                 C[x] = rL(x, y);
92                         FOR(x, 5)
93                                 wL(x, y, C[x] ^ ((~C[(x + 1) % 5]) & C[(x + 2) % 5]));
94                 }
95                 FOR(j, 7)
96                         if (LFSR86540(&R))
97                                 XL(0, 0, (u64)1 << ((1 << j) - 1));
98         }
99 }
100
101 static void Keccak(ui r, const u8 *in, u64 inLen, u8 sfx, u8 *out, u64 outLen)
102 {
103         u8 s[200];
104         ui R = r / 8;
105         ui i, b = 0;
106
107         FOR(i, 200)
108                 s[i] = 0;
109         /* absorb */
110         while (inLen > 0) {
111                 b = (inLen < R)? inLen : R;
112                 FOR(i, b)
113                         s[i] ^= in[i];
114                 in += b;
115                 inLen -= b;
116                 if (b == R) {
117                         KeccakF1600(s);
118                         b = 0;
119                 }
120         }
121         /* pad */
122         s[b] ^= sfx;
123         if ((sfx & 0x80) && (b == (R - 1)))
124                 KeccakF1600(s);
125         s[R - 1] ^= 0x80;
126         KeccakF1600(s);
127         /* squeeze */
128         while (outLen > 0) {
129                 b = (outLen < R)? outLen : R;
130                 FOR(i, b)
131                         out[i] = s[i];
132                 out += b;
133                 outLen -= b;
134                 if (outLen > 0)
135                         KeccakF1600(s);
136         }
137 }
138
139 /**
140  * Compute the hash value for osl version 2 tables.
141  *
142  * \param data Pointer to the data to compute the hash value from.
143  * \param len The length of \a data in bytes.
144  * \param result must point to an area at least 20 bytes large.
145  */
146 void sha3_hash(const char *data, unsigned long len, unsigned char *result)
147 {
148          Keccak(1152, (const u8*)data, len, 0x06, result, 20);
149 }