chiark / gitweb /
Simplify implementation.
[catacomb] / square.c
1 /* -*-c-*-
2  *
3  * $Id: square.c,v 1.2 2001/05/07 15:44:02 mdw Exp $
4  *
5  * The Square block cipher
6  *
7  * (c) 2000 Straylight/Edgeware
8  */
9
10 /*----- Licensing notice --------------------------------------------------* 
11  *
12  * This file is part of Catacomb.
13  *
14  * Catacomb is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU Library General Public License as
16  * published by the Free Software Foundation; either version 2 of the
17  * License, or (at your option) any later version.
18  * 
19  * Catacomb is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU Library General Public License for more details.
23  * 
24  * You should have received a copy of the GNU Library General Public
25  * License along with Catacomb; if not, write to the Free
26  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27  * MA 02111-1307, USA.
28  */
29
30 /*----- Revision history --------------------------------------------------* 
31  *
32  * $Log: square.c,v $
33  * Revision 1.2  2001/05/07 15:44:02  mdw
34  * Simplify implementation.
35  *
36  * Revision 1.1  2000/07/15 20:51:58  mdw
37  * New block cipher.
38  *
39  */
40
41 /*----- Header files ------------------------------------------------------*/
42
43 #include <assert.h>
44 #include <stdio.h>
45
46 #include <mLib/bits.h>
47
48 #include "blkc.h"
49 #include "gcipher.h"
50 #include "paranoia.h"
51 #include "square.h"
52 #include "square-tab.h"
53
54 /*----- Global variables --------------------------------------------------*/
55
56 const octet square_keysz[] = { KSZ_RANGE, SQUARE_KEYSZ, 4, 16, 4 };
57
58 /*----- Constant tables ---------------------------------------------------*/
59
60 static const octet S[256] = SQUARE_S, SI[256] = SQUARE_SI;
61 static const uint32 T[4][256] = SQUARE_T, TI[4][256] = SQUARE_TI;
62 static const uint32 U[4][256] = SQUARE_U;
63 static const octet rcon[] = SQUARE_RCON;
64
65 /*----- Main code ---------------------------------------------------------*/
66
67 /* --- @square_init@ --- *
68  *
69  * Arguments:   @square_ctx *k@ = pointer to context to initialize
70  *              @const void *buf@ = pointer to buffer of key material
71  *              @size_t sz@ = size of the key material
72  *
73  * Returns:     ---
74  *
75  * Use:         Initializes a Square context with a particular key.  Square
76  *              keys must be a multiple of 32 bits long, and may be at most
77  *              128 bits.
78  */
79
80 void square_init(square_ctx *k, const void *buf, size_t sz)
81 {
82   unsigned nk, nr, nw;
83   unsigned i, j, jj;
84   const octet *p;
85   uint32 ww;
86   uint32 kk[SQUARE_KWORDS];
87
88   /* --- Sort out the key size --- */
89
90   KSZ_ASSERT(square, sz);
91   nk = sz / 4;
92
93   /* --- Fetch the first key words out --- */
94
95   p = buf;
96   for (i = 0; i < nk; i++) {
97     kk[i] = LOAD32_L(p);
98     p += 4;
99   }
100   nr = 8;
101
102   /* --- Expand this material to fill the rest of the table --- */
103
104   nw = (nr + 1) * 4;
105   ww = kk[i - 1];
106   p = rcon;
107   for (; i < nw; i++) {
108     uint32 w = kk[i - nk];
109     if (i % nk == 0) {
110       ww = ROR32(ww, 8);
111       w ^= ww ^ *p++;
112     } else
113       w ^= ww;
114     kk[i] = ww = w;
115   }
116
117   /* --- Make the encryption and decryption keys --- */
118
119   for (i = 0; i < nr * 4; i++) {
120     uint32 w = kk[i];
121     k->w[i] = (U[0][U8(w >>  0)] ^ U[1][U8(w >>  8)] ^
122                U[2][U8(w >> 16)] ^ U[3][U8(w >> 24)]);
123   }
124   for (; i < nw; i++)
125     k->w[i] = kk[i];
126
127   jj = nw;
128   for (i = 0; i < nr * 4; i += 4) {
129     jj -= 4;
130     for (j = 0; j < 4; j++)
131       k->wi[i + j] = kk[jj + j];
132   }
133   for (j = 0; j < 4; j++)
134     k->wi[i + j] = k->w[j];
135
136   BURN(kk);
137 }
138
139 /* --- @square_eblk@, @square_dblk@ --- *
140  *
141  * Arguments:   @const square_ctx *k@ = pointer to Square context
142  *              @const uint32 s[4]@ = pointer to source block
143  *              @uint32 d[4]@ = pointer to destination block
144  *
145  * Returns:     ---
146  *
147  * Use:         Low-level block encryption and decryption.
148  */
149
150 #define SUB(s, sh, a, b, c, d)                                          \
151   (s[U8((a) >> sh)] <<  0 | s[U8((b) >> sh)] <<  8 |                    \
152    s[U8((c) >> sh)] << 16 | s[U8((d) >> sh)] << 24)
153
154 #define MIX(t, sh, a, b, c, d)                                          \
155   (t[0][U8((a) >> sh)] ^ t[1][U8((b) >> sh)] ^                          \
156    t[2][U8((c) >> sh)] ^ t[3][U8((d) >> sh)])
157
158 #define DO(what, t, aa, bb, cc, dd, a, b, c, d, w) do {                 \
159   aa = what(t,  0, a, b, c, d) ^ *w++;                                  \
160   bb = what(t,  8, a, b, c, d) ^ *w++;                                  \
161   cc = what(t, 16, a, b, c, d) ^ *w++;                                  \
162   dd = what(t, 24, a, b, c, d) ^ *w++;                                  \
163 } while (0)
164
165 void square_eblk(const square_ctx *k, const uint32 *s, uint32 *dst)
166 {
167   uint32 a = s[0], b = s[1], c = s[2], d = s[3];
168   uint32 aa, bb, cc, dd;
169   uint32 *w = k->w;
170
171   a ^= *w++; b ^= *w++; c ^= *w++; d ^= *w++;
172
173   DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
174   DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
175   DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
176   DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
177   DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
178   DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
179   DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
180   DO(SUB, S, a, b, c, d, aa, bb, cc, dd, w);
181
182   dst[0] = a; dst[1] = b; dst[2] = c; dst[3] = d;
183 }
184
185 void square_dblk(const square_ctx *k, const uint32 *s, uint32 *dst)
186 {
187   uint32 a = s[0], b = s[1], c = s[2], d = s[3];
188   uint32 aa, bb, cc, dd;
189   uint32 *w = k->wi;
190
191   a ^= *w++; b ^= *w++; c ^= *w++; d ^= *w++;
192
193   DO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
194   DO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
195   DO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
196   DO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
197   DO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
198   DO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
199   DO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
200   DO(SUB, SI, a, b, c, d, aa, bb, cc, dd, w);
201
202   dst[0] = a; dst[1] = b; dst[2] = c; dst[3] = d;
203 }
204
205 BLKC_TEST(SQUARE, square)
206
207 /*----- That's all, folks -------------------------------------------------*/