… | |
… | |
38 | |
38 | |
39 | #include "spritz.h" |
39 | #include "spritz.h" |
40 | |
40 | |
41 | #include <assert.h> |
41 | #include <assert.h> |
42 | |
42 | |
|
|
43 | /*****************************************************************************/ |
|
|
44 | |
|
|
45 | #define SPRITZ_SWAP(a,b) { uint8_t ss_c = (a); (a) = (b); (b) = ss_c; } |
|
|
46 | |
43 | void |
47 | void |
44 | spritz_init (spritz_state *s) |
48 | spritz_init (spritz_state *s) |
45 | { |
49 | { |
46 | s->a = |
50 | s->a = |
47 | s->i = |
51 | s->i = |
… | |
… | |
57 | } |
61 | } |
58 | |
62 | |
59 | void |
63 | void |
60 | spritz_update (spritz_state *s) |
64 | spritz_update (spritz_state *s) |
61 | { |
65 | { |
62 | s->i += s->w; |
66 | s->i = s->i + s->w; |
63 | s->j = s->k + s->S[s->j + s->S[s->i]]; |
67 | s->j = s->k + s->S[(uint8_t)(s->j + s->S[s->i])]; |
64 | s->k = s->k + s->i + s->S[s->j]; |
68 | s->k = s->k + s->i + s->S[s->j]; |
65 | SPRITZ_SWAP (s->S[s->i], s->S[s->j]); |
69 | SPRITZ_SWAP (s->S[s->i], s->S[s->j]); |
66 | } |
70 | } |
67 | |
71 | |
68 | void |
72 | void |
… | |
… | |
71 | while (r--) |
75 | while (r--) |
72 | spritz_update (s); |
76 | spritz_update (s); |
73 | |
77 | |
74 | s->w += 2; |
78 | s->w += 2; |
75 | } |
79 | } |
76 | |
|
|
77 | #define SPRITZ_SWAP(a,b) { uint8_t ss_c = (a); (a) = (b); (b) = ss_c; } |
|
|
78 | |
80 | |
79 | void |
81 | void |
80 | spritz_crush (spritz_state *s) |
82 | spritz_crush (spritz_state *s) |
81 | { |
83 | { |
82 | uint_fast16_t v; |
84 | uint_fast16_t v; |
… | |
… | |
101 | { |
103 | { |
102 | if (s->a == (spritz_N >> 1)) |
104 | if (s->a == (spritz_N >> 1)) |
103 | spritz_shuffle (s); |
105 | spritz_shuffle (s); |
104 | } |
106 | } |
105 | |
107 | |
106 | void |
108 | static void |
107 | spritz_absorb_nibble (spritz_state *s, uint8_t x) |
109 | spritz_absorb_nibble (spritz_state *s, uint8_t x) |
108 | { |
110 | { |
109 | spritz_shuffle_absorb (s); |
111 | spritz_shuffle_absorb (s); |
110 | |
112 | |
111 | SPRITZ_SWAP (s->S[s->a], s->S[(spritz_N >> 1) + x]); |
113 | SPRITZ_SWAP (s->S[s->a], s->S[(uint8_t)((spritz_N >> 1) + x)]); |
112 | ++s->a; |
114 | ++s->a; |
113 | } |
115 | } |
114 | |
116 | |
115 | static void |
117 | static void |
116 | spritz_absorb_byte (spritz_state *s, uint8_t b) |
118 | spritz_absorb_byte (spritz_state *s, uint8_t b) |
… | |
… | |
134 | spritz_shuffle_absorb (s); |
136 | spritz_shuffle_absorb (s); |
135 | |
137 | |
136 | ++s->a; |
138 | ++s->a; |
137 | } |
139 | } |
138 | |
140 | |
139 | // commonly used helper function |
|
|
140 | void |
141 | void |
141 | spritz_absorb_and_stop (spritz_state *s, const void *I, size_t I_len) |
142 | spritz_absorb_and_stop (spritz_state *s, const void *I, size_t I_len) |
142 | { |
143 | { |
143 | spritz_absorb (s, I, I_len); |
144 | spritz_absorb (s, I, I_len); |
144 | spritz_absorb_stop (s); |
145 | spritz_absorb_stop (s); |
… | |
… | |
152 | } |
153 | } |
153 | |
154 | |
154 | uint8_t |
155 | uint8_t |
155 | spritz_output (spritz_state *s) |
156 | spritz_output (spritz_state *s) |
156 | { |
157 | { |
157 | return s->S[s->j + s->S[s->i + s->S[s->z + s->k]]]; |
158 | uint8_t r = s->z + s->k; |
158 | } |
|
|
159 | |
159 | |
|
|
160 | r = s->i + s->S[r]; |
|
|
161 | r = s->j + s->S[r]; |
|
|
162 | |
|
|
163 | return s->z = s->S[r]; |
|
|
164 | } |
|
|
165 | |
160 | // slightly faster internal helper, drip without squeeze preparation |
166 | /* slightly faster internal helper, drip without squeeze preparation */ |
161 | static uint8_t |
167 | static uint8_t |
162 | spritz_drip_nosqueeze (spritz_state *s) |
168 | spritz_drip_nosqueeze (spritz_state *s) |
163 | { |
169 | { |
164 | spritz_update (s); |
170 | spritz_update (s); |
165 | return spritz_output (s); |
171 | return spritz_output (s); |
… | |
… | |
182 | spritz_shuffle_squeeze (s); |
188 | spritz_shuffle_squeeze (s); |
183 | |
189 | |
184 | return spritz_drip_nosqueeze (s); |
190 | return spritz_drip_nosqueeze (s); |
185 | } |
191 | } |
186 | |
192 | |
|
|
193 | /*****************************************************************************/ |
|
|
194 | |
187 | void |
195 | void |
188 | spritz_xor_init (spritz_state *s, const void *K, size_t K_len, const void *IV, size_t IV_len) |
196 | spritz_cipher_xor_init (spritz_state *s, const void *K, size_t K_len, const void *IV, size_t IV_len) |
189 | { |
197 | { |
190 | spritz_init (s); |
198 | spritz_init (s); |
191 | |
199 | |
192 | spritz_absorb (s, K, K_len); |
200 | spritz_absorb (s, K, K_len); |
193 | |
201 | |
… | |
… | |
199 | |
207 | |
200 | spritz_shuffle_squeeze (s); |
208 | spritz_shuffle_squeeze (s); |
201 | } |
209 | } |
202 | |
210 | |
203 | void |
211 | void |
204 | spritz_xor_crypt (spritz_state *s, const void *I, void *O, size_t len) |
212 | spritz_cipher_xor_crypt (spritz_state *s, const void *I, void *O, size_t len) |
205 | { |
213 | { |
206 | const uint8_t *i = (const uint8_t *)I; |
214 | const uint8_t *i = (const uint8_t *)I; |
207 | uint8_t *o = ( uint8_t *)O; |
215 | uint8_t *o = ( uint8_t *)O; |
208 | |
216 | |
209 | while (len--) |
217 | while (len--) |
210 | *o++ = *i++ ^ spritz_drip_nosqueeze (s); |
218 | *o++ = *i++ ^ spritz_drip_nosqueeze (s); |
211 | } |
219 | } |
|
|
220 | |
|
|
221 | /*****************************************************************************/ |
212 | |
222 | |
213 | void |
223 | void |
214 | spritz_hash_finish (spritz_state *s, void *H, size_t H_len) |
224 | spritz_hash_finish (spritz_state *s, void *H, size_t H_len) |
215 | { |
225 | { |
216 | spritz_absorb_stop (s); |
226 | spritz_absorb_stop (s); |
… | |
… | |
218 | spritz_absorb_byte (s, H_len); |
228 | spritz_absorb_byte (s, H_len); |
219 | |
229 | |
220 | spritz_squeeze (s, H, H_len); |
230 | spritz_squeeze (s, H, H_len); |
221 | } |
231 | } |
222 | |
232 | |
|
|
233 | /*****************************************************************************/ |
|
|
234 | |
223 | void |
235 | void |
224 | spritz_mac_init (spritz_state *s, const void *K, size_t K_len) |
236 | spritz_mac_init (spritz_state *s, const void *K, size_t K_len) |
225 | { |
237 | { |
226 | spritz_init (s); |
238 | spritz_init (s); |
227 | spritz_absorb_and_stop (s, K, K_len); |
239 | spritz_absorb_and_stop (s, K, K_len); |
228 | } |
240 | } |
229 | |
241 | |
230 | void |
242 | /*****************************************************************************/ |
231 | spritz_aead_init (spritz_state *s, const void *K, size_t K_len) |
|
|
232 | { |
|
|
233 | spritz_mac_init (s, K, K_len); |
|
|
234 | } |
|
|
235 | |
243 | |
236 | void |
244 | void |
237 | spritz_aead_crypt (spritz_state *s, const void *I, void *O, size_t len) |
245 | spritz_aead_xor_crypt (spritz_state *s, const void *I, void *O, size_t len) |
238 | { |
246 | { |
239 | const uint8_t *i = (const uint8_t *)I; |
247 | const uint8_t *i = (const uint8_t *)I; |
240 | uint8_t *o = ( uint8_t *)O; |
248 | uint8_t *o = ( uint8_t *)O; |
241 | |
249 | |
242 | uint8_t x[spritz_N >> 2]; |
250 | uint8_t x[spritz_N >> 2]; |
… | |
… | |
252 | for (j = 0; j < l; ++j) |
260 | for (j = 0; j < l; ++j) |
253 | spritz_absorb_byte (s, *o++ = *i++ ^ x[j]); |
261 | spritz_absorb_byte (s, *o++ = *i++ ^ x[j]); |
254 | } |
262 | } |
255 | } |
263 | } |
256 | |
264 | |
|
|
265 | /*****************************************************************************/ |
|
|
266 | |
257 | void |
267 | void |
258 | spritz_prng_init (spritz_state *s, const void *S, size_t S_len) |
268 | spritz_prng_init (spritz_state *s, const void *S, size_t S_len) |
259 | { |
269 | { |
260 | spritz_init (s); |
270 | spritz_init (s); |
261 | spritz_absorb (s, S, S_len); |
271 | spritz_absorb (s, S, S_len); |