ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/spritz/spritz.c
Revision: 1.3
Committed: Fri Jan 9 23:21:41 2015 UTC (9 years, 5 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.2: +37 -2 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 /* spritz.c, spritz C implementation
2 *
3 * Copyright (c) 2015 Marc Alexander Lehmann <libev@schmorp.de>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without modifica-
7 * tion, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
18 * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
20 * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
24 * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
25 * OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * Alternatively, the contents of this file may be used under the terms of
28 * the GNU General Public License ("GPL") version 2 or any later version,
29 * in which case the provisions of the GPL are applicable instead of
30 * the above. If you wish to allow the use of your version of this file
31 * only under the terms of the GPL and not to allow others to use your
32 * version of this file under the BSD license, indicate your decision
33 * by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL. If you do not delete the
35 * provisions above, a recipient may use your version of this file under
36 * either the BSD or the GPL.
37 */
38
39 #include "spritz.h"
40
41 #include <assert.h>
42
43 void
44 spritz_init (spritz_state *s)
45 {
46 s->a =
47 s->i =
48 s->j =
49 s->k =
50 s->z = 0;
51 s->w = 1;
52
53 uint_fast8_t v = spritz_N - 1;
54 do
55 s->S[v] = v;
56 while (v--);
57 }
58
59 void
60 spritz_update (spritz_state *s)
61 {
62 s->i += s->w;
63 s->j = s->k + s->S[s->j + s->S[s->i]];
64 s->k = s->k + s->i + s->S[s->j];
65 SPRITZ_SWAP (s->S[s->i], s->S[s->j]);
66 }
67
68 void
69 spritz_whip (spritz_state *s, uint_fast16_t r)
70 {
71 while (r--)
72 spritz_update (s);
73
74 s->w += 2;
75 }
76
77 #define SPRITZ_SWAP(a,b) { uint8_t ss_c = (a); (a) = (b); (b) = ss_c; }
78
79 void
80 spritz_crush (spritz_state *s)
81 {
82 uint_fast16_t v;
83
84 for (v = 0; v < (spritz_N >> 1); ++v)
85 if (s->S[v] > s->S[spritz_N - 1 - v])
86 SPRITZ_SWAP (s->S[v], s->S[spritz_N - 1 - v]);
87 }
88
89 void
90 spritz_shuffle (spritz_state *s)
91 {
92 spritz_whip (s, 2 * spritz_N); spritz_crush (s);
93 spritz_whip (s, 2 * spritz_N); spritz_crush (s);
94 spritz_whip (s, 2 * spritz_N);
95
96 s->a = 0;
97 }
98
99 static void
100 spritz_shuffle_absorb (spritz_state *s)
101 {
102 if (s->a == (spritz_N >> 1))
103 spritz_shuffle (s);
104 }
105
106 void
107 spritz_absorb_nibble (spritz_state *s, uint8_t x)
108 {
109 spritz_shuffle_absorb (s);
110
111 SPRITZ_SWAP (s->S[s->a], s->S[(spritz_N >> 1) + x]);
112 ++s->a;
113 }
114
115 static void
116 spritz_absorb_byte (spritz_state *s, uint8_t b)
117 {
118 spritz_absorb_nibble (s, b & 15);
119 spritz_absorb_nibble (s, b >> 4);
120 }
121
122 void
123 spritz_absorb (spritz_state *s, const void *I, size_t I_len)
124 {
125 uint8_t *i = (uint8_t *)I;
126
127 while (I_len--)
128 spritz_absorb_byte (s, *i++);
129 }
130
131 void
132 spritz_absorb_stop (spritz_state *s)
133 {
134 spritz_shuffle_absorb (s);
135
136 ++s->a;
137 }
138
139 // commonly used helper function
140 void
141 spritz_absorb_and_stop (spritz_state *s, const void *I, size_t I_len)
142 {
143 spritz_absorb (s, I, I_len);
144 spritz_absorb_stop (s);
145 }
146
147 static void
148 spritz_shuffle_squeeze (spritz_state *s)
149 {
150 if (s->a)
151 spritz_shuffle (s);
152 }
153
154 uint8_t
155 spritz_output (spritz_state *s)
156 {
157 return s->S[s->j + s->S[s->i + s->S[s->z + s->k]]];
158 }
159
160 // slightly faster internal helper, drip without squeeze preparation
161 static uint8_t
162 spritz_drip_nosqueeze (spritz_state *s)
163 {
164 spritz_update (s);
165 return spritz_output (s);
166 }
167
168 void
169 spritz_squeeze (spritz_state *s, void *P, size_t P_len)
170 {
171 spritz_shuffle_squeeze (s);
172
173 uint8_t *p = (uint8_t *)P;
174
175 while (P_len--)
176 *p++ = spritz_drip_nosqueeze (s);
177 }
178
179 uint8_t
180 spritz_drip (spritz_state *s)
181 {
182 spritz_shuffle_squeeze (s);
183
184 return spritz_drip_nosqueeze (s);
185 }
186
187 void
188 spritz_xor_init (spritz_state *s, const void *K, size_t K_len, const void *IV, size_t IV_len)
189 {
190 spritz_init (s);
191
192 spritz_absorb (s, K, K_len);
193
194 if (IV)
195 {
196 spritz_absorb_stop (s);
197 spritz_absorb (s, IV, IV_len);
198 }
199
200 spritz_shuffle_squeeze (s);
201 }
202
203 void
204 spritz_xor_crypt (spritz_state *s, const void *I, void *O, size_t len)
205 {
206 const uint8_t *i = (const uint8_t *)I;
207 uint8_t *o = ( uint8_t *)O;
208
209 while (len--)
210 *o++ = *i++ ^ spritz_drip_nosqueeze (s);
211 }
212
213 void
214 spritz_hash_finish (spritz_state *s, void *H, size_t H_len)
215 {
216 spritz_absorb_stop (s);
217 assert (H_len <= 0xff);
218 spritz_absorb_byte (s, H_len);
219
220 spritz_squeeze (s, H, H_len);
221 }
222
223 void
224 spritz_mac_init (spritz_state *s, const void *K, size_t K_len)
225 {
226 spritz_init (s);
227 spritz_absorb_and_stop (s, K, K_len);
228 }
229
230 void
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
236 void
237 spritz_aead_crypt (spritz_state *s, const void *I, void *O, size_t len)
238 {
239 const uint8_t *i = (const uint8_t *)I;
240 uint8_t *o = ( uint8_t *)O;
241
242 uint8_t x[spritz_N >> 2];
243
244 while (len)
245 {
246 uint_fast8_t j;
247 uint8_t l = len > sizeof (x) ? sizeof (x) : len;
248 len -= l;
249
250 spritz_squeeze (s, x, l);
251
252 for (j = 0; j < l; ++j)
253 spritz_absorb_byte (s, *o++ = *i++ ^ x[j]);
254 }
255 }
256
257 void
258 spritz_prng_init (spritz_state *s, const void *S, size_t S_len)
259 {
260 spritz_init (s);
261 spritz_absorb (s, S, S_len);
262 }
263