Add sha3 implementation, introduce version-2 tables.
[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 /*
17 * Note for osl
18 * ~~~~~~~~~~~~
19 * This is NOT the hash function which will eventually be part of an osl
20 * release. It will be replaced by whatever git comes up as the successor of
21 * sha1. This hash function is FOR TESTING ONLY.
22 */
23
24 #define FOR(i,n) for(i=0; i<n; ++i)
25 typedef unsigned char u8;
26 typedef unsigned long long int u64;
27 typedef unsigned int ui;
28
29 static int LFSR86540(u8 *R)
30 {
31 *R = ((*R) << 1) ^ (((*R) & 0x80)? 0x71 : 0);
32 return ((*R) & 2 ) >> 1;
33 }
34
35 static u64 load64(const u8 *x)
36 {
37 ui i;
38 u64 u = 0;
39
40 FOR(i, 8) {
41 u <<= 8;
42 u |= x[7 - i];
43 }
44 return u;
45 }
46
47 static void store64(u8 *x, u64 u)
48 {
49 ui i;
50
51 FOR(i, 8) {
52 x[i] = u;
53 u >>= 8;
54 }
55 }
56
57 static void xor64(u8 *x, u64 u)
58 {
59 ui i;
60 FOR(i, 8) {
61 x[i] ^= u;
62 u >>= 8;
63 }
64 }
65
66 #define rL(x, y) load64((u8*)s + 8 * (x + 5 * y))
67 #define wL(x, y, l) store64((u8*)s + 8 * (x + 5 * y), l)
68 #define XL(x, y, l) xor64((u8*)s + 8 * (x + 5 * y), l)
69 #define ROL(a, o) ((((u64)a) << o) ^ (((u64)a) >> (64 - o)))
70
71 static void KeccakF1600(void *s)
72 {
73 ui r, x, y, i, j, Y;
74 u8 R = 0x01;
75 u64 C[5], D;
76
77 for (i = 0; i < 24; i++) {
78 FOR(x, 5)
79 C[x] = rL(x, 0) ^ rL(x, 1) ^ rL(x, 2) ^ rL(x, 3) ^ rL(x, 4);
80 FOR(x, 5) {
81 D = C[(x + 4) % 5] ^ ROL(C[(x + 1) % 5], 1);
82 FOR(y, 5)
83 XL(x, y, D);
84 }
85 x = 1;
86 y = r = 0;
87 D = rL(x, y);
88 FOR(j, 24) {
89 r += j + 1;
90 Y = (2 * x + 3 * y) % 5;
91 x = y;
92 y = Y;
93 C[0] = rL(x, y);
94 wL(x, y, ROL(D, r % 64));
95 D = C[0];
96 }
97 FOR(y, 5) {
98 FOR(x, 5)
99 C[x] = rL(x, y);
100 FOR(x, 5)
101 wL(x, y, C[x] ^ ((~C[(x + 1) % 5]) & C[(x + 2) % 5]));
102 }
103 FOR(j, 7)
104 if (LFSR86540(&R))
105 XL(0, 0, (u64)1 << ((1 << j) - 1));
106 }
107 }
108
109 static void Keccak(ui r, const u8 *in, u64 inLen, u8 sfx, u8 *out, u64 outLen)
110 {
111 u8 s[200];
112 ui R = r / 8;
113 ui i, b = 0;
114
115 FOR(i, 200)
116 s[i] = 0;
117 /* absorb */
118 while (inLen > 0) {
119 b = (inLen < R)? inLen : R;
120 FOR(i, b)
121 s[i] ^= in[i];
122 in += b;
123 inLen -= b;
124 if (b == R) {
125 KeccakF1600(s);
126 b = 0;
127 }
128 }
129 /* pad */
130 s[b] ^= sfx;
131 if ((sfx & 0x80) && (b == (R - 1)))
132 KeccakF1600(s);
133 s[R - 1] ^= 0x80;
134 KeccakF1600(s);
135 /* squeeze */
136 while (outLen > 0) {
137 b = (outLen < R)? outLen : R;
138 FOR(i, b)
139 out[i] = s[i];
140 out += b;
141 outLen -= b;
142 if (outLen > 0)
143 KeccakF1600(s);
144 }
145 }
146
147 /**
148 * Compute the hash value for osl version 2 tables.
149 *
150 * \param data Pointer to the data to compute the hash value from.
151 * \param len The length of \a data in bytes.
152 * \param result must point to an area at least 20 bytes large.
153 */
154 void sha3_hash(const char *data, unsigned long len, unsigned char *result)
155 {
156 Keccak(1152, (const u8*)data, len, 0x06, result, 20);
157 }