1 /**
2  * @cond internal
3  * @file shake.c
4  * @copyright
5  *   Uses public domain code by Mathias Panzenböck \n
6  *   Uses CC0 code by David Leon Gil, 2015 \n
7  *   Copyright (c) 2015 Cryptography Research, Inc.  \n
8  *   Released under the MIT License.  See LICENSE.txt for license information.
9  * @author Mike Hamburg
10  * @brief SHA-3-n and SHAKE-n instances.
11  * @warning EXPERIMENTAL!  The names, parameter orders etc are likely to change.
12  */
13 
14 #define __STDC_WANT_LIB_EXT1__ 1 /* for memset_s */
15 #define _BSD_SOURCE 1 /* for endian */
16 #define _DEFAULT_SOURCE 1 /* for endian with glibc 2.20 */
17 #include <assert.h>
18 #include <stdint.h>
19 #include <string.h>
20 
21 #include "portable_endian.h"
22 #include "keccak_internal.h"
23 #include <decaf/shake.h>
24 
25 #define FLAG_ABSORBING 'A'
26 #define FLAG_SQUEEZING 'Z'
27 
28 /** Constants. **/
29 static const uint8_t pi[24] = {
30     10, 7,  11, 17, 18, 3, 5,  16, 8,  21, 24, 4,
31     15, 23, 19, 13, 12, 2, 20, 14, 22, 9,  6,  1
32 };
33 
34 #define RC_B(x,n) ((((x##ull)>>n)&1)<<((1<<n)-1))
35 #define RC_X(x) (RC_B(x,0)|RC_B(x,1)|RC_B(x,2)|RC_B(x,3)|RC_B(x,4)|RC_B(x,5)|RC_B(x,6))
36 static const uint64_t RC[24] = {
37     RC_X(0x01), RC_X(0x1a), RC_X(0x5e), RC_X(0x70), RC_X(0x1f), RC_X(0x21),
38     RC_X(0x79), RC_X(0x55), RC_X(0x0e), RC_X(0x0c), RC_X(0x35), RC_X(0x26),
39     RC_X(0x3f), RC_X(0x4f), RC_X(0x5d), RC_X(0x53), RC_X(0x52), RC_X(0x48),
40     RC_X(0x16), RC_X(0x66), RC_X(0x79), RC_X(0x58), RC_X(0x21), RC_X(0x74)
41 };
42 
rol(uint64_t x,int s)43 static inline uint64_t rol(uint64_t x, int s) {
44     return (x << s) | (x >> (64 - s));
45 }
46 
47 /* Helper macros to unroll the permutation. */
48 #define REPEAT5(e) e e e e e
49 #define FOR51(v, e) v = 0; REPEAT5(e; v += 1;)
50 #ifndef SHAKE_NO_UNROLL_LOOPS
51 #    define FOR55(v, e) v = 0; REPEAT5(e; v += 5;)
52 #    define REPEAT24(e) e e e e e e e e e e e e e e e e e e e e e e e e
53 #else
54 #    define FOR55(v, e) for (v=0; v<25; v+= 5) { e; }
55 #    define REPEAT24(e) {int _j=0; for (_j=0; _j<24; _j++) { e }}
56 #endif
57 
58 /*** The Keccak-f[1600] permutation ***/
keccakf(kdomain_t state,uint8_t start_round)59 void keccakf(kdomain_t state, uint8_t start_round) {
60     uint64_t* a = state->w;
61     uint64_t b[5] = {0}, t, u;
62     uint8_t x, y, i;
63 
64     for (i=0; i<25; i++) a[i] = le64toh(a[i]);
65 
66     for (i = start_round; i < 24; i++) {
67         FOR51(x, b[x] = 0; )
68         FOR55(y, FOR51(x, b[x] ^= a[x + y]; ))
69         FOR55(y, FOR51(x,
70             a[y + x] ^= b[(x + 4) % 5] ^ rol(b[(x + 1) % 5], 1);
71         ))
72         // Rho and pi
73         t = a[1];
74         x = y = 0;
75         REPEAT24(u = a[pi[x]]; y += x+1; a[pi[x]] = rol(t, y % 64); t = u; x++; )
76         // Chi
77         FOR55(y,
78              FOR51(x, b[x] = a[y + x];)
79              FOR51(x, a[y + x] = b[x] ^ ((~b[(x + 1) % 5]) & b[(x + 2) % 5]);)
80         )
81         // Iota
82         a[0] ^= RC[i];
83     }
84 
85     for (i=0; i<25; i++) a[i] = htole64(a[i]);
86 }
87 
decaf_sha3_update(struct decaf_keccak_sponge_s * __restrict__ decaf_sponge,const uint8_t * in,size_t len)88 decaf_error_t decaf_sha3_update (
89     struct decaf_keccak_sponge_s * __restrict__ decaf_sponge,
90     const uint8_t *in,
91     size_t len
92 ) {
93     assert(decaf_sponge->params->position < decaf_sponge->params->rate);
94     assert(decaf_sponge->params->rate < sizeof(decaf_sponge->state));
95     assert(decaf_sponge->params->flags == FLAG_ABSORBING);
96     while (len) {
97         size_t cando = decaf_sponge->params->rate - decaf_sponge->params->position, i;
98         uint8_t* state = &decaf_sponge->state->b[decaf_sponge->params->position];
99         if (cando > len) {
100             for (i = 0; i < len; i += 1) state[i] ^= in[i];
101             decaf_sponge->params->position += len;
102             break;
103         } else {
104             for (i = 0; i < cando; i += 1) state[i] ^= in[i];
105             dokeccak(decaf_sponge);
106             len -= cando;
107             in += cando;
108         }
109     }
110     return (decaf_sponge->params->flags == FLAG_ABSORBING) ? DECAF_SUCCESS : DECAF_FAILURE;
111 }
112 
decaf_sha3_output(decaf_keccak_sponge_t decaf_sponge,uint8_t * __restrict__ out,size_t len)113 decaf_error_t decaf_sha3_output (
114     decaf_keccak_sponge_t decaf_sponge,
115     uint8_t * __restrict__ out,
116     size_t len
117 ) {
118     decaf_error_t ret = DECAF_SUCCESS;
119     assert(decaf_sponge->params->position < decaf_sponge->params->rate);
120     assert(decaf_sponge->params->rate < sizeof(decaf_sponge->state));
121 
122     if (decaf_sponge->params->max_out != 0xFF) {
123         if (decaf_sponge->params->remaining >= len) {
124             decaf_sponge->params->remaining -= len;
125         } else {
126             decaf_sponge->params->remaining = 0;
127             ret = DECAF_FAILURE;
128         }
129     }
130 
131     switch (decaf_sponge->params->flags) {
132     case FLAG_SQUEEZING: break;
133     case FLAG_ABSORBING:
134         {
135             uint8_t* state = decaf_sponge->state->b;
136             state[decaf_sponge->params->position] ^= decaf_sponge->params->pad;
137             state[decaf_sponge->params->rate - 1] ^= decaf_sponge->params->rate_pad;
138             dokeccak(decaf_sponge);
139             decaf_sponge->params->flags = FLAG_SQUEEZING;
140             break;
141         }
142     default:
143         assert(0);
144     }
145 
146     while (len) {
147         size_t cando = decaf_sponge->params->rate - decaf_sponge->params->position;
148         uint8_t* state = &decaf_sponge->state->b[decaf_sponge->params->position];
149         if (cando > len) {
150             memcpy(out, state, len);
151             decaf_sponge->params->position += len;
152             return ret;
153         } else {
154             memcpy(out, state, cando);
155             dokeccak(decaf_sponge);
156             len -= cando;
157             out += cando;
158         }
159     }
160     return ret;
161 }
162 
decaf_sha3_final(decaf_keccak_sponge_t decaf_sponge,uint8_t * __restrict__ out,size_t len)163 decaf_error_t decaf_sha3_final (
164     decaf_keccak_sponge_t decaf_sponge,
165     uint8_t * __restrict__ out,
166     size_t len
167 ) {
168     decaf_error_t ret = decaf_sha3_output(decaf_sponge,out,len);
169     decaf_sha3_reset(decaf_sponge);
170     return ret;
171 }
172 
decaf_sha3_reset(decaf_keccak_sponge_t decaf_sponge)173 void decaf_sha3_reset (
174     decaf_keccak_sponge_t decaf_sponge
175 ) {
176     decaf_sha3_init(decaf_sponge, decaf_sponge->params);
177     decaf_sponge->params->flags = FLAG_ABSORBING;
178     decaf_sponge->params->remaining = decaf_sponge->params->max_out;
179 }
180 
decaf_sha3_destroy(decaf_keccak_sponge_t decaf_sponge)181 void decaf_sha3_destroy (decaf_keccak_sponge_t decaf_sponge) {
182     decaf_bzero(decaf_sponge, sizeof(decaf_keccak_sponge_t));
183 }
184 
decaf_sha3_init(decaf_keccak_sponge_t decaf_sponge,const struct decaf_kparams_s * params)185 void decaf_sha3_init (
186     decaf_keccak_sponge_t decaf_sponge,
187     const struct decaf_kparams_s *params
188 ) {
189     memset(decaf_sponge->state, 0, sizeof(decaf_sponge->state));
190     decaf_sponge->params[0] = params[0];
191     decaf_sponge->params->position = 0;
192 }
193 
decaf_sha3_hash(uint8_t * out,size_t outlen,const uint8_t * in,size_t inlen,const struct decaf_kparams_s * params)194 decaf_error_t decaf_sha3_hash (
195     uint8_t *out,
196     size_t outlen,
197     const uint8_t *in,
198     size_t inlen,
199     const struct decaf_kparams_s *params
200 ) {
201     decaf_keccak_sponge_t decaf_sponge;
202     decaf_sha3_init(decaf_sponge, params);
203     decaf_sha3_update(decaf_sponge, in, inlen);
204     decaf_error_t ret = decaf_sha3_output(decaf_sponge, out, outlen);
205     decaf_sha3_destroy(decaf_sponge);
206     return ret;
207 }
208 
209 #define DEFSHAKE(n) \
210     const struct decaf_kparams_s DECAF_SHAKE##n##_params_s = \
211         { 0, FLAG_ABSORBING, 200-n/4, 0, 0x1f, 0x80, 0xFF, 0xFF };
212 
213 #define DEFSHA3(n) \
214     const struct decaf_kparams_s DECAF_SHA3_##n##_params_s = \
215         { 0, FLAG_ABSORBING, 200-n/4, 0, 0x06, 0x80, n/8, n/8 };
216 
decaf_sha3_default_output_bytes(const decaf_keccak_sponge_t s)217 size_t decaf_sha3_default_output_bytes (
218     const decaf_keccak_sponge_t s
219 ) {
220     return (s->params->max_out == 0xFF)
221         ? (200-s->params->rate)
222         : ((200-s->params->rate)/2);
223 }
224 
decaf_sha3_max_output_bytes(const decaf_keccak_sponge_t s)225 size_t decaf_sha3_max_output_bytes (
226     const decaf_keccak_sponge_t s
227 ) {
228     return (s->params->max_out == 0xFF)
229         ? SIZE_MAX
230         : (size_t)((200-s->params->rate)/2);
231 }
232 
233 DEFSHAKE(128)
234 DEFSHAKE(256)
235 DEFSHA3(224)
236 DEFSHA3(256)
237 DEFSHA3(384)
238 DEFSHA3(512)
239 
240 /* FUTURE: Keyak instances, etc */
241