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