chiark / gitweb /
Expunge revision histories in files.
[catacomb] / square.c
1 /* -*-c-*-
2  *
3  * $Id: square.c,v 1.3 2004/04/08 01:36:15 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 /*----- Header files ------------------------------------------------------*/
31
32 #include <assert.h>
33 #include <stdio.h>
34
35 #include <mLib/bits.h>
36
37 #include "blkc.h"
38 #include "gcipher.h"
39 #include "paranoia.h"
40 #include "square.h"
41 #include "square-tab.h"
42
43 /*----- Global variables --------------------------------------------------*/
44
45 const octet square_keysz[] = { KSZ_RANGE, SQUARE_KEYSZ, 4, 16, 4 };
46
47 /*----- Constant tables ---------------------------------------------------*/
48
49 static const octet S[256] = SQUARE_S, SI[256] = SQUARE_SI;
50 static const uint32 T[4][256] = SQUARE_T, TI[4][256] = SQUARE_TI;
51 static const uint32 U[4][256] = SQUARE_U;
52 static const octet rcon[] = SQUARE_RCON;
53
54 /*----- Main code ---------------------------------------------------------*/
55
56 /* --- @square_init@ --- *
57  *
58  * Arguments:   @square_ctx *k@ = pointer to context to initialize
59  *              @const void *buf@ = pointer to buffer of key material
60  *              @size_t sz@ = size of the key material
61  *
62  * Returns:     ---
63  *
64  * Use:         Initializes a Square context with a particular key.  Square
65  *              keys must be a multiple of 32 bits long, and may be at most
66  *              128 bits.
67  */
68
69 void square_init(square_ctx *k, const void *buf, size_t sz)
70 {
71   unsigned nk, nr, nw;
72   unsigned i, j, jj;
73   const octet *p;
74   uint32 ww;
75   uint32 kk[SQUARE_KWORDS];
76
77   /* --- Sort out the key size --- */
78
79   KSZ_ASSERT(square, sz);
80   nk = sz / 4;
81
82   /* --- Fetch the first key words out --- */
83
84   p = buf;
85   for (i = 0; i < nk; i++) {
86     kk[i] = LOAD32_L(p);
87     p += 4;
88   }
89   nr = 8;
90
91   /* --- Expand this material to fill the rest of the table --- */
92
93   nw = (nr + 1) * 4;
94   ww = kk[i - 1];
95   p = rcon;
96   for (; i < nw; i++) {
97     uint32 w = kk[i - nk];
98     if (i % nk == 0) {
99       ww = ROR32(ww, 8);
100       w ^= ww ^ *p++;
101     } else
102       w ^= ww;
103     kk[i] = ww = w;
104   }
105
106   /* --- Make the encryption and decryption keys --- */
107
108   for (i = 0; i < nr * 4; i++) {
109     uint32 w = kk[i];
110     k->w[i] = (U[0][U8(w >>  0)] ^ U[1][U8(w >>  8)] ^
111                U[2][U8(w >> 16)] ^ U[3][U8(w >> 24)]);
112   }
113   for (; i < nw; i++)
114     k->w[i] = kk[i];
115
116   jj = nw;
117   for (i = 0; i < nr * 4; i += 4) {
118     jj -= 4;
119     for (j = 0; j < 4; j++)
120       k->wi[i + j] = kk[jj + j];
121   }
122   for (j = 0; j < 4; j++)
123     k->wi[i + j] = k->w[j];
124
125   BURN(kk);
126 }
127
128 /* --- @square_eblk@, @square_dblk@ --- *
129  *
130  * Arguments:   @const square_ctx *k@ = pointer to Square context
131  *              @const uint32 s[4]@ = pointer to source block
132  *              @uint32 d[4]@ = pointer to destination block
133  *
134  * Returns:     ---
135  *
136  * Use:         Low-level block encryption and decryption.
137  */
138
139 #define SUB(s, sh, a, b, c, d)                                          \
140   (s[U8((a) >> sh)] <<  0 | s[U8((b) >> sh)] <<  8 |                    \
141    s[U8((c) >> sh)] << 16 | s[U8((d) >> sh)] << 24)
142
143 #define MIX(t, sh, a, b, c, d)                                          \
144   (t[0][U8((a) >> sh)] ^ t[1][U8((b) >> sh)] ^                          \
145    t[2][U8((c) >> sh)] ^ t[3][U8((d) >> sh)])
146
147 #define DO(what, t, aa, bb, cc, dd, a, b, c, d, w) do {                 \
148   aa = what(t,  0, a, b, c, d) ^ *w++;                                  \
149   bb = what(t,  8, a, b, c, d) ^ *w++;                                  \
150   cc = what(t, 16, a, b, c, d) ^ *w++;                                  \
151   dd = what(t, 24, a, b, c, d) ^ *w++;                                  \
152 } while (0)
153
154 void square_eblk(const square_ctx *k, const uint32 *s, uint32 *dst)
155 {
156   uint32 a = s[0], b = s[1], c = s[2], d = s[3];
157   uint32 aa, bb, cc, dd;
158   uint32 *w = k->w;
159
160   a ^= *w++; b ^= *w++; c ^= *w++; d ^= *w++;
161
162   DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
163   DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
164   DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
165   DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
166   DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
167   DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
168   DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
169   DO(SUB, S, a, b, c, d, aa, bb, cc, dd, w);
170
171   dst[0] = a; dst[1] = b; dst[2] = c; dst[3] = d;
172 }
173
174 void square_dblk(const square_ctx *k, const uint32 *s, uint32 *dst)
175 {
176   uint32 a = s[0], b = s[1], c = s[2], d = s[3];
177   uint32 aa, bb, cc, dd;
178   uint32 *w = k->wi;
179
180   a ^= *w++; b ^= *w++; c ^= *w++; d ^= *w++;
181
182   DO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
183   DO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
184   DO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
185   DO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
186   DO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
187   DO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
188   DO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
189   DO(SUB, SI, a, b, c, d, aa, bb, cc, dd, w);
190
191   dst[0] = a; dst[1] = b; dst[2] = c; dst[3] = d;
192 }
193
194 BLKC_TEST(SQUARE, square)
195
196 /*----- That's all, folks -------------------------------------------------*/