chiark / gitweb /
Bad bug makes all previous testing worthless.
[storin] / storin.c
... / ...
CommitLineData
1/* -*-c-*-
2 *
3 * $Id: storin.c,v 1.1 2000/05/21 11:28:30 mdw Exp $
4 *
5 * Block cipher optimized for DSPs
6 *
7 * (c) 2000 Mark Wooding
8 */
9
10/*----- Licensing notice --------------------------------------------------*
11 *
12 * Copyright (c) 2000 Mark Wooding
13 * All rights reserved.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions are
17 * met:
18 *
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 *
22 * 2, Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution.
25 *
26 * 3. The name of the authors may not be used to endorse or promote
27 * products derived from this software without specific prior written
28 * permission.
29 *
30 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
31 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
32 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
33 * NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
34 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
36 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
38 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
39 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
40 * POSSIBILITY OF SUCH DAMAGE.
41 *
42 * Instead of accepting the above terms, you may redistribute and/or modify
43 * this software under the terms of either the GNU General Public License,
44 * or the GNU Library General Public License, published by the Free
45 * Software Foundation; either version 2 of the License, or (at your
46 * option) any later version.
47 */
48
49/*----- Revision history --------------------------------------------------*
50 *
51 * $Log: storin.c,v $
52 * Revision 1.1 2000/05/21 11:28:30 mdw
53 * Initial check-in.
54 *
55 */
56
57/*----- Header files ------------------------------------------------------*/
58
59#include "storin.h"
60#include "storin-tab.h"
61
62#include "matrix.h"
63
64/*----- Debugging output --------------------------------------------------*/
65
66/* #define DEBUG */
67/* #define TIMER */
68
69#ifdef DEBUG
70# include <stdio.h>
71# define D(x) x
72#else
73# define D(x)
74#endif
75
76/*----- The constant matrix -----------------------------------------------*/
77
78static const uint24 m[] = STORIN_M, mi[] = STORIN_MI;
79
80/*----- Main code ---------------------------------------------------------*/
81
82/* --- @storin_init24@ --- *
83 *
84 * Arguments: @storin_ctx *k@ = pointer to cipher context to initialize
85 * @const uint24 *buf@ = pointer to buffer of key material
86 * @size_t sz@ = size of the key material
87 *
88 * Returns: ---
89 *
90 * Use: Initializes the storin for use.
91 */
92
93void storin_init24(storin_ctx *k, const uint24 *buf, size_t sz)
94{
95 unsigned i, n;
96 uint24 mm[16];
97 const uint24 *d;
98 uint24 *dd;
99
100#define KEYS (4 * (STORIN_ROUNDS + 1))
101
102 D( puts("Key schedule...\n"); )
103
104 /* --- Seed the subkey array --- */
105
106 d = m;
107 dd = k->k;
108 n = KEYS;
109 while (n > 15) {
110 matmul(dd, d, m, 4, 4, 4);
111 n -= 16;
112 d = dd;
113 dd += 16;
114 }
115 matmul(mm, d, m, 4, 4, 4);
116 for (i = 0; i < n; i++)
117 *dd++ = mm[i];
118
119 D( puts("Constant initial array contents:");
120 for (i = 0; i < KEYS; i++) {
121 printf("%06x ", k->k[i]);
122 if (i % 4 == 3)
123 fputc('\n', stdout);
124 }
125 fputc('\n', stdout); )
126
127 /* --- Mix in the real key material --- */
128
129 dd = k->k;
130 d = buf;
131 n = sz;
132 for (i = 0; i < KEYS; i++) {
133 *dd++ ^= *d++;
134 n--;
135 if (n == 0) {
136 n = sz;
137 d = buf;
138 }
139 }
140
141 D( puts("Array after mixing in key material:");
142 for (i = 0; i < KEYS; i++) {
143 printf("%06x ", k->k[i]);
144 if (i % 4 == 3)
145 fputc('\n', stdout);
146 }
147 fputc('\n', stdout); )
148
149 /* --- Now mangle the key material horribly --- */
150
151 for (i = 0; i < 4; i++)
152 mm[i] = 0;
153
154 dd = k->k;
155 for (i = 0; i < KEYS; i += 4) {
156 storin_eblk24(k, mm, mm);
157 for (n = 0; n < 4; n++)
158 dd[n] = mm[n];
159 dd += 4;
160 }
161
162 D( puts("Final round subkeys:");
163 for (i = 0; i < KEYS; i++) {
164 printf("%06x ", k->k[i]);
165 if (i % 4 == 3)
166 fputc('\n', stdout);
167 }
168 fputc('\n', stdout); )
169}
170
171/* --- @storin_eblk24@, @storin_dblk24@ --- *
172 *
173 * Arguments: @const storin_ctx *k@ = pointer to cipher context
174 * @const uint24 s[4]@ = pointer to source block
175 * @uint24 d[4]@ = pointer to destination block
176 *
177 * Returns: ---
178 *
179 * Use: Low-level block encryption and decryption.
180 */
181
182void storin_eblk24(const storin_ctx *k, const uint24 *s, uint24 *d)
183{
184 unsigned i, j;
185 uint24 p[4], q[4];
186 const uint24 *kk = k->k;
187
188 D( puts("Encryption...");
189 printf(" plaintext: %06x %06x %06x %06x\n", s[0], s[1], s[2], s[3]); )
190
191 for (j = 0; j < 4; j++)
192 p[j] = s[j];
193
194 /* --- Main cipher guts --- */
195
196 for (i = 0; i < STORIN_ROUNDS; i++) {
197 D( printf("round %2i\n", i); )
198 for (j = 0; j < 4; j++)
199 q[j] = p[j] ^ *kk++;
200 D( printf(" mix key: %06x %06x %06x %06x\n", q[0], q[1], q[2], q[3]); )
201 matmul(p, m, q, 4, 4, 1);
202 D( printf(" matrix: %06x %06x %06x %06x\n", p[0], p[1], p[2], p[3]); )
203 for (j = 0; j < 4; j++)
204 p[j] ^= p[j] >> 12;
205 D( printf(" lin trans: %06x %06x %06x %06x\n", p[0], p[1], p[2], p[3]); )
206 }
207
208 /* --- Postwhitening and output --- */
209
210 for (j = 0; j < 4; j++)
211 d[j] = p[j] ^ *kk++;
212
213 D( printf("ciphertext: %06x %06x %06x %06x\n", d[0], d[1], d[2], d[3]); )
214}
215
216
217void storin_dblk24(const storin_ctx *k, const uint24 *s, uint24 *d)
218{
219 unsigned i, j;
220 uint24 p[4], q[4];
221 const uint24 *kk = k->k + KEYS;
222
223 D( puts("Decryption...");
224 printf("ciphertext: %06x %06x %06x %06x\n", s[0], s[1], s[2], s[3]); )
225
226 for (j = 0; j < 4; j++)
227 p[j] = s[j];
228
229 /* --- Main cipher guts --- */
230
231 for (i = 0; i < STORIN_ROUNDS; i++) {
232 D( printf("round %2i\n", i); )
233 for (j = 0; j < 4; j++)
234 q[3 - j] = p[3 - j] ^ *--kk;
235 D( printf(" mix key: %06x %06x %06x %06x\n", q[0], q[1], q[2], q[3]); )
236 for (j = 0; j < 4; j++)
237 q[j] ^= q[j] >> 12;
238 D( printf(" lin trans: %06x %06x %06x %06x\n", p[0], p[1], p[2], p[3]); )
239 matmul(p, mi, q, 4, 4, 1);
240 D( printf(" matrix: %06x %06x %06x %06x\n", p[0], p[1], p[2], p[3]); )
241 }
242
243 /* --- Postwhitening and output --- */
244
245 for (j = 0; j < 4; j++)
246 d[3 - j] = p[3 - j] ^ *--kk;
247
248 D( printf(" plaintext: %06x %06x %06x %06x\n", d[0], d[1], d[2], d[3]); )
249}
250
251/*----- Test rig ----------------------------------------------------------*/
252
253#if defined(DEBUG) || defined(TIMER)
254
255#include <time.h>
256
257int main(void)
258{
259 uint24 kk[] = { 1, 2, 3, 4, 5 };
260 uint24 p[4] = { 6, 7, 8, 9 };
261 uint24 q[4];
262 storin_ctx c;
263
264 storin_init24(&c, kk, 5);
265
266#ifdef DEBUG
267 storin_eblk24(&c, p, q);
268 storin_dblk24(&c, q, q);
269#endif
270
271#ifdef TIMER
272 {
273 time_t now, then;
274 unsigned n = 0;
275
276 then = time(0);
277 for (;;) {
278 storin_eblk24(&c, p, q);
279 n++;
280 now = time(0);
281 if (difftime(now, then) > 10.0)
282 break;
283 }
284 printf("%g blocks/s = %g bits/s\n", n / 10.0, n * 96.0 / 10.0);
285 }
286#endif
287 return (0);
288}
289
290#endif
291
292/*----- That's all, folks -------------------------------------------------*/