ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/spritz/spritz.c
Revision: 1.2
Committed: Fri Jan 9 09:12:18 2015 UTC (11 years, 9 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.1: +3 -2 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.2 /* spritz.c */
2     /* (C)2015 Marc Alexander Lehmann, all rights reserved */
3    
4 root 1.1 #include "spritz.h"
5    
6     #include <assert.h>
7    
8     void
9     spritz_init (spritz_state *s)
10     {
11     s->a =
12     s->i =
13     s->j =
14     s->k =
15     s->z = 0;
16     s->w = 1;
17    
18     uint_fast8_t v = spritz_N - 1;
19     do
20     s->S[v] = v;
21     while (v--);
22     }
23    
24     void
25     spritz_update (spritz_state *s)
26     {
27     s->i += s->w;
28     s->j = s->k + s->S[s->j + s->S[s->i]];
29     s->k = s->k + s->i + s->S[s->j];
30     SPRITZ_SWAP (s->S[s->i], s->S[s->j]);
31     }
32    
33     void
34     spritz_whip (spritz_state *s, uint_fast16_t r)
35     {
36     while (r--)
37     spritz_update (s);
38    
39     s->w += 2;
40     }
41    
42     #define SPRITZ_SWAP(a,b) { uint8_t ss_c = (a); (a) = (b); (b) = ss_c; }
43    
44     void
45     spritz_crush (spritz_state *s)
46     {
47     uint_fast16_t v;
48    
49     for (v = 0; v < (spritz_N >> 1); ++v)
50     if (s->S[v] > s->S[spritz_N - 1 - v])
51     SPRITZ_SWAP (s->S[v], s->S[spritz_N - 1 - v]);
52     }
53    
54     void
55     spritz_shuffle (spritz_state *s)
56     {
57     spritz_whip (s, 2 * spritz_N); spritz_crush (s);
58     spritz_whip (s, 2 * spritz_N); spritz_crush (s);
59     spritz_whip (s, 2 * spritz_N);
60    
61     s->a = 0;
62     }
63    
64     static void
65     spritz_shuffle_absorb (spritz_state *s)
66     {
67     if (s->a == (spritz_N >> 1))
68     spritz_shuffle (s);
69     }
70    
71     void
72     spritz_absorb_nibble (spritz_state *s, uint8_t x)
73     {
74     spritz_shuffle_absorb (s);
75    
76     SPRITZ_SWAP (s->S[s->a], s->S[(spritz_N >> 1) + x]);
77     ++s->a;
78     }
79    
80     static void
81     spritz_absorb_byte (spritz_state *s, uint8_t b)
82     {
83     spritz_absorb_nibble (s, b & 15);
84     spritz_absorb_nibble (s, b >> 4);
85     }
86    
87     void
88     spritz_absorb (spritz_state *s, const void *I, size_t I_len)
89     {
90     uint8_t *i = (uint8_t *)I;
91    
92     while (I_len--)
93     spritz_absorb_byte (s, *i++);
94     }
95    
96     void
97     spritz_absorb_stop (spritz_state *s)
98     {
99     spritz_shuffle_absorb (s);
100    
101     ++s->a;
102     }
103    
104     // commonly used helper function
105     void
106     spritz_absorb_and_stop (spritz_state *s, const void *I, size_t I_len)
107     {
108     spritz_absorb (s, I, I_len);
109     spritz_absorb_stop (s);
110     }
111    
112     static void
113     spritz_shuffle_squeeze (spritz_state *s)
114     {
115     if (s->a)
116     spritz_shuffle (s);
117     }
118    
119     uint8_t
120     spritz_output (spritz_state *s)
121     {
122     return s->S[s->j + s->S[s->i + s->S[s->z + s->k]]];
123     }
124    
125     // slightly faster internal helper, drip without squeeze preparation
126     static uint8_t
127     spritz_drip_nosqueeze (spritz_state *s)
128     {
129     spritz_update (s);
130     return spritz_output (s);
131     }
132    
133     void
134     spritz_squeeze (spritz_state *s, void *P, size_t P_len)
135     {
136     spritz_shuffle_squeeze (s);
137    
138     uint8_t *p = (uint8_t *)P;
139    
140     while (P_len--)
141     *p++ = spritz_drip_nosqueeze (s);
142     }
143    
144     uint8_t
145     spritz_drip (spritz_state *s)
146     {
147     spritz_shuffle_squeeze (s);
148    
149     return spritz_drip_nosqueeze (s);
150     }
151    
152     void
153     spritz_xor_init (spritz_state *s, const void *K, size_t K_len, const void *IV, size_t IV_len)
154     {
155     spritz_init (s);
156    
157     spritz_absorb (s, K, K_len);
158    
159     if (IV)
160     {
161     spritz_absorb_stop (s);
162     spritz_absorb (s, IV, IV_len);
163     }
164    
165     spritz_shuffle_squeeze (s);
166     }
167    
168     void
169     spritz_xor_crypt (spritz_state *s, const void *I, void *O, size_t len)
170     {
171     const uint8_t *i = (const uint8_t *)I;
172     uint8_t *o = ( uint8_t *)O;
173    
174     while (len--)
175     *o++ = *i++ ^ spritz_drip_nosqueeze (s);
176     }
177    
178     void
179     spritz_hash_finish (spritz_state *s, void *H, size_t H_len)
180     {
181     spritz_absorb_stop (s);
182     assert (H_len <= 0xff);
183     spritz_absorb_byte (s, H_len);
184    
185     spritz_squeeze (s, H, H_len);
186     }
187    
188     void
189     spritz_mac_init (spritz_state *s, const void *K, size_t K_len)
190     {
191     spritz_init (s);
192     spritz_absorb_and_stop (s, K, K_len);
193     }
194    
195     void
196     spritz_aead_init (spritz_state *s, const void *K, size_t K_len)
197     {
198     spritz_mac_init (s, K, K_len);
199     }
200    
201     void
202     spritz_aead_crypt (spritz_state *s, const void *I, void *O, size_t len)
203     {
204     const uint8_t *i = (const uint8_t *)I;
205     uint8_t *o = ( uint8_t *)O;
206    
207     uint8_t x[spritz_N >> 2];
208    
209     while (len)
210     {
211     uint_fast8_t j;
212     uint8_t l = len > sizeof (x) ? sizeof (x) : len;
213     len -= l;
214    
215     spritz_squeeze (s, x, l);
216    
217     for (j = 0; j < l; ++j)
218     spritz_absorb_byte (s, *o++ = *i++ ^ x[j]);
219     }
220     }
221    
222     void
223     spritz_prng_init (spritz_state *s, const void *S, size_t S_len)
224     {
225     spritz_init (s);
226     spritz_absorb (s, S, S_len);
227     }
228