ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/spritz/spritz.c
Revision: 1.5
Committed: Sat Jan 10 08:29:03 2015 UTC (9 years, 6 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.4: +67 -1 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.3 /* 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 root 1.2
39 root 1.1 #include "spritz.h"
40    
41     #include <assert.h>
42    
43 root 1.4 /*****************************************************************************/
44    
45     #define SPRITZ_SWAP(a,b) { uint8_t ss_c = (a); (a) = (b); (b) = ss_c; }
46    
47 root 1.1 void
48     spritz_init (spritz_state *s)
49     {
50     s->a =
51     s->i =
52     s->j =
53     s->k =
54     s->z = 0;
55     s->w = 1;
56    
57     uint_fast8_t v = spritz_N - 1;
58     do
59     s->S[v] = v;
60     while (v--);
61     }
62    
63     void
64     spritz_update (spritz_state *s)
65     {
66 root 1.4 s->i = s->i + s->w;
67     s->j = s->k + s->S[(uint8_t)(s->j + s->S[s->i])];
68 root 1.1 s->k = s->k + s->i + s->S[s->j];
69     SPRITZ_SWAP (s->S[s->i], s->S[s->j]);
70     }
71    
72     void
73     spritz_whip (spritz_state *s, uint_fast16_t r)
74     {
75     while (r--)
76     spritz_update (s);
77    
78     s->w += 2;
79     }
80    
81     void
82     spritz_crush (spritz_state *s)
83     {
84     uint_fast16_t v;
85    
86     for (v = 0; v < (spritz_N >> 1); ++v)
87     if (s->S[v] > s->S[spritz_N - 1 - v])
88     SPRITZ_SWAP (s->S[v], s->S[spritz_N - 1 - v]);
89     }
90    
91     void
92     spritz_shuffle (spritz_state *s)
93     {
94     spritz_whip (s, 2 * spritz_N); spritz_crush (s);
95     spritz_whip (s, 2 * spritz_N); spritz_crush (s);
96     spritz_whip (s, 2 * spritz_N);
97    
98     s->a = 0;
99     }
100    
101     static void
102     spritz_shuffle_absorb (spritz_state *s)
103     {
104     if (s->a == (spritz_N >> 1))
105     spritz_shuffle (s);
106     }
107    
108 root 1.4 static void
109 root 1.1 spritz_absorb_nibble (spritz_state *s, uint8_t x)
110     {
111     spritz_shuffle_absorb (s);
112    
113 root 1.4 SPRITZ_SWAP (s->S[s->a], s->S[(uint8_t)((spritz_N >> 1) + x)]);
114 root 1.1 ++s->a;
115     }
116    
117     static void
118     spritz_absorb_byte (spritz_state *s, uint8_t b)
119     {
120     spritz_absorb_nibble (s, b & 15);
121     spritz_absorb_nibble (s, b >> 4);
122     }
123    
124     void
125     spritz_absorb (spritz_state *s, const void *I, size_t I_len)
126     {
127     uint8_t *i = (uint8_t *)I;
128    
129     while (I_len--)
130     spritz_absorb_byte (s, *i++);
131     }
132    
133     void
134     spritz_absorb_stop (spritz_state *s)
135     {
136     spritz_shuffle_absorb (s);
137    
138     ++s->a;
139     }
140    
141     void
142     spritz_absorb_and_stop (spritz_state *s, const void *I, size_t I_len)
143     {
144     spritz_absorb (s, I, I_len);
145     spritz_absorb_stop (s);
146     }
147    
148     static void
149     spritz_shuffle_squeeze (spritz_state *s)
150     {
151     if (s->a)
152     spritz_shuffle (s);
153     }
154    
155     uint8_t
156     spritz_output (spritz_state *s)
157     {
158 root 1.4 uint8_t r = s->z + s->k;
159    
160     r = s->i + s->S[r];
161     r = s->j + s->S[r];
162    
163     return s->z = s->S[r];
164 root 1.1 }
165    
166 root 1.4 /* slightly faster internal helper, drip without squeeze preparation */
167 root 1.1 static uint8_t
168     spritz_drip_nosqueeze (spritz_state *s)
169     {
170     spritz_update (s);
171     return spritz_output (s);
172     }
173    
174     void
175     spritz_squeeze (spritz_state *s, void *P, size_t P_len)
176     {
177     spritz_shuffle_squeeze (s);
178    
179     uint8_t *p = (uint8_t *)P;
180    
181     while (P_len--)
182     *p++ = spritz_drip_nosqueeze (s);
183     }
184    
185     uint8_t
186     spritz_drip (spritz_state *s)
187     {
188     spritz_shuffle_squeeze (s);
189    
190     return spritz_drip_nosqueeze (s);
191     }
192    
193 root 1.4 /*****************************************************************************/
194    
195 root 1.1 void
196 root 1.5 spritz_cipher_init (spritz_state *s, const void *K, size_t K_len, const void *IV, size_t IV_len)
197 root 1.1 {
198     spritz_init (s);
199    
200     spritz_absorb (s, K, K_len);
201    
202     if (IV)
203     {
204     spritz_absorb_stop (s);
205     spritz_absorb (s, IV, IV_len);
206     }
207    
208     spritz_shuffle_squeeze (s);
209     }
210    
211     void
212 root 1.5 spritz_cipher_encrypt (spritz_state *s, const void *I, void *O, size_t len)
213     {
214     const uint8_t *i = (const uint8_t *)I;
215     uint8_t *o = ( uint8_t *)O;
216    
217     while (len--)
218     *o++ = *i++ + spritz_drip_nosqueeze (s);
219     }
220    
221     void
222     spritz_cipher_decrypt (spritz_state *s, const void *I, void *O, size_t len)
223     {
224     const uint8_t *i = (const uint8_t *)I;
225     uint8_t *o = ( uint8_t *)O;
226    
227     while (len--)
228     *o++ = *i++ - spritz_drip_nosqueeze (s);
229     }
230    
231     /*****************************************************************************/
232    
233     void
234 root 1.4 spritz_cipher_xor_crypt (spritz_state *s, const void *I, void *O, size_t len)
235 root 1.1 {
236     const uint8_t *i = (const uint8_t *)I;
237     uint8_t *o = ( uint8_t *)O;
238    
239     while (len--)
240     *o++ = *i++ ^ spritz_drip_nosqueeze (s);
241     }
242    
243 root 1.4 /*****************************************************************************/
244    
245 root 1.1 void
246     spritz_hash_finish (spritz_state *s, void *H, size_t H_len)
247     {
248     spritz_absorb_stop (s);
249     assert (H_len <= 0xff);
250     spritz_absorb_byte (s, H_len);
251    
252     spritz_squeeze (s, H, H_len);
253     }
254    
255 root 1.4 /*****************************************************************************/
256    
257 root 1.1 void
258     spritz_mac_init (spritz_state *s, const void *K, size_t K_len)
259     {
260     spritz_init (s);
261     spritz_absorb_and_stop (s, K, K_len);
262     }
263    
264 root 1.4 /*****************************************************************************/
265 root 1.1
266     void
267 root 1.5 spritz_aead_encrypt (spritz_state *s, const void *I, void *O, size_t len)
268     {
269     const uint8_t *i = (const uint8_t *)I;
270     uint8_t *o = ( uint8_t *)O;
271    
272     uint8_t x[spritz_N >> 2];
273    
274     while (len)
275     {
276     uint_fast8_t j;
277     uint8_t l = len > sizeof (x) ? sizeof (x) : len;
278     len -= l;
279    
280     spritz_squeeze (s, x, l);
281    
282     for (j = 0; j < l; ++j)
283     spritz_absorb_byte (s, *o++ = *i++ + x[j]);
284     }
285     }
286    
287     void
288     spritz_aead_decrypt (spritz_state *s, const void *I, void *O, size_t len)
289     {
290     const uint8_t *i = (const uint8_t *)I;
291     uint8_t *o = ( uint8_t *)O;
292    
293     uint8_t x[spritz_N >> 2];
294    
295     while (len)
296     {
297     uint_fast8_t j;
298     uint8_t l = len > sizeof (x) ? sizeof (x) : len;
299     len -= l;
300    
301     spritz_squeeze (s, x, l);
302    
303     for (j = 0; j < l; ++j)
304     spritz_absorb_byte (s, *o++ = *i++ - x[j]);
305     }
306     }
307    
308     /*****************************************************************************/
309    
310     void
311 root 1.4 spritz_aead_xor_crypt (spritz_state *s, const void *I, void *O, size_t len)
312 root 1.1 {
313     const uint8_t *i = (const uint8_t *)I;
314     uint8_t *o = ( uint8_t *)O;
315    
316     uint8_t x[spritz_N >> 2];
317    
318     while (len)
319     {
320     uint_fast8_t j;
321     uint8_t l = len > sizeof (x) ? sizeof (x) : len;
322     len -= l;
323    
324     spritz_squeeze (s, x, l);
325    
326     for (j = 0; j < l; ++j)
327     spritz_absorb_byte (s, *o++ = *i++ ^ x[j]);
328     }
329     }
330    
331 root 1.4 /*****************************************************************************/
332    
333 root 1.1 void
334     spritz_prng_init (spritz_state *s, const void *S, size_t S_len)
335     {
336     spritz_init (s);
337     spritz_absorb (s, S, S_len);
338     }
339