ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/spritz/spritz.c
Revision: 1.7
Committed: Sat Jan 10 13:02:26 2015 UTC (9 years, 5 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-1_02, rel-1_0, rel-1_01, HEAD
Changes since 1.6: +3 -3 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     while (len)
273     {
274     uint_fast8_t j;
275 root 1.7 uint8_t x[spritz_aead_blocksize];
276 root 1.5 uint8_t l = len > sizeof (x) ? sizeof (x) : len;
277     len -= l;
278    
279     spritz_squeeze (s, x, l);
280    
281     for (j = 0; j < l; ++j)
282 root 1.6 {
283     *o = *i++ + x[j];
284     spritz_absorb_byte (s, *o);
285     ++o;
286     }
287 root 1.5 }
288     }
289    
290     void
291     spritz_aead_decrypt (spritz_state *s, const void *I, void *O, size_t len)
292     {
293     const uint8_t *i = (const uint8_t *)I;
294     uint8_t *o = ( uint8_t *)O;
295    
296     while (len)
297     {
298     uint_fast8_t j;
299 root 1.7 uint8_t x[spritz_aead_blocksize];
300 root 1.5 uint8_t l = len > sizeof (x) ? sizeof (x) : len;
301     len -= l;
302    
303     spritz_squeeze (s, x, l);
304    
305     for (j = 0; j < l; ++j)
306 root 1.6 {
307     spritz_absorb_byte (s, *i);
308     *o = *i++ - x[j];
309     ++o;
310     }
311 root 1.5 }
312     }
313    
314     /*****************************************************************************/
315    
316     void
317 root 1.4 spritz_aead_xor_crypt (spritz_state *s, const void *I, void *O, size_t len)
318 root 1.1 {
319     const uint8_t *i = (const uint8_t *)I;
320     uint8_t *o = ( uint8_t *)O;
321    
322     while (len)
323     {
324     uint_fast8_t j;
325 root 1.7 uint8_t x[spritz_aead_blocksize];
326 root 1.1 uint8_t l = len > sizeof (x) ? sizeof (x) : len;
327     len -= l;
328    
329     spritz_squeeze (s, x, l);
330    
331     for (j = 0; j < l; ++j)
332     spritz_absorb_byte (s, *o++ = *i++ ^ x[j]);
333     }
334     }
335    
336 root 1.4 /*****************************************************************************/
337    
338 root 1.1 void
339     spritz_prng_init (spritz_state *s, const void *S, size_t S_len)
340     {
341     spritz_init (s);
342     spritz_absorb (s, S, S_len);
343     }
344