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, 6 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.2: +37 -2 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     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