ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/spritz/spritz.c
Revision: 1.4
Committed: Sat Jan 10 04:14:21 2015 UTC (10 years, 11 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.3: +27 -17 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.4 spritz_cipher_xor_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.4 spritz_cipher_xor_crypt (spritz_state *s, const void *I, void *O, size_t len)
213 root 1.1 {
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 root 1.4 /*****************************************************************************/
222    
223 root 1.1 void
224     spritz_hash_finish (spritz_state *s, void *H, size_t H_len)
225     {
226     spritz_absorb_stop (s);
227     assert (H_len <= 0xff);
228     spritz_absorb_byte (s, H_len);
229    
230     spritz_squeeze (s, H, H_len);
231     }
232    
233 root 1.4 /*****************************************************************************/
234    
235 root 1.1 void
236     spritz_mac_init (spritz_state *s, const void *K, size_t K_len)
237     {
238     spritz_init (s);
239     spritz_absorb_and_stop (s, K, K_len);
240     }
241    
242 root 1.4 /*****************************************************************************/
243 root 1.1
244     void
245 root 1.4 spritz_aead_xor_crypt (spritz_state *s, const void *I, void *O, size_t len)
246 root 1.1 {
247     const uint8_t *i = (const uint8_t *)I;
248     uint8_t *o = ( uint8_t *)O;
249    
250     uint8_t x[spritz_N >> 2];
251    
252     while (len)
253     {
254     uint_fast8_t j;
255     uint8_t l = len > sizeof (x) ? sizeof (x) : len;
256     len -= l;
257    
258     spritz_squeeze (s, x, l);
259    
260     for (j = 0; j < l; ++j)
261     spritz_absorb_byte (s, *o++ = *i++ ^ x[j]);
262     }
263     }
264    
265 root 1.4 /*****************************************************************************/
266    
267 root 1.1 void
268     spritz_prng_init (spritz_state *s, const void *S, size_t S_len)
269     {
270     spritz_init (s);
271     spritz_absorb (s, S, S_len);
272     }
273