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 (9 years, 6 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.1: +3 -2 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 /* spritz.c */
2 /* (C)2015 Marc Alexander Lehmann, all rights reserved */
3
4 #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