chiark / gitweb /
configure.ac: Replace with a new version.
[catacomb] / cast256.c
1 /* -*-c-*-
2  *
3  * $Id: cast256.c,v 1.2 2004/04/08 01:36:15 mdw Exp $
4  *
5  * The CAST-256 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 #include <stdlib.h>
35 #include <string.h>
36
37 #include <mLib/bits.h>
38
39 #include "blkc.h"
40 #include "cast-base.h"
41 #include "cast256.h"
42 #include "gcipher.h"
43 #include "paranoia.h"
44
45 /*----- Global variables --------------------------------------------------*/
46
47 const octet cast256_keysz[] = { KSZ_RANGE, CAST256_KEYSZ, 0, 32, 1 };
48
49 /*----- Main code ---------------------------------------------------------*/
50
51 /* --- @cast256_init@ --- *
52  *
53  * Arguments:   @cast128_ctx *k@ = pointer to key block to fill in
54  *              @const void *buf@ = pointer to buffer of key material
55  *              @size_t sz@ = size of key material
56  *
57  * Returns:     ---
58  *
59  * Use:         Initializes a CAST-256 key buffer.  CAST-256 accepts
60  *              256-bit keys or shorter.
61  */
62
63 void cast256_init(cast256_ctx *k, const void *buf, size_t sz)
64 {
65   const octet *p = buf;
66   uint32 kk[8];
67   uint32 *km;
68   octet *kr;
69   unsigned i, j;
70   uint32 a, b, c, d, e, f, g, h;
71   uint32 m;
72   unsigned r;
73
74   /* --- Fiddle with the key size --- */
75
76   KSZ_ASSERT(cast256, sz);
77
78   /* --- Read the key into the array --- */
79
80   i = 0;
81   b = 32; a = 0;
82   for (;;) {
83     if (!sz)
84       break;
85     b -= 8;
86     a |= ((uint32)*p++ << b);
87     sz--;
88     if (b == 0) {
89       kk[i++] = a;
90       if (i == 8)
91         break;
92       a = 0;
93       b = 32;
94     }
95   }
96
97   for (; i < 8; i++) {
98     kk[i] = a;
99     a = 0;
100   }
101
102   /* --- Read the key words out --- */
103
104   a = kk[0]; b = kk[1]; c = kk[2]; d = kk[3];
105   e = kk[4]; f = kk[5]; g = kk[6]; h = kk[7];
106
107 #define ROOT2 0x5a827999
108 #define ROOT3 0x6ed9eba1
109
110   m = ROOT2;
111   r = 19;
112
113   km = k->km;
114   kr = k->kr;
115   for (i = 0; i < 12; i++) {
116     for (j = 0; j < 2; j++) {
117       CAST_R1(m, r, g, h); m += ROOT3; r = (r + 17) & 0x1f;
118       CAST_R2(m, r, f, g); m += ROOT3; r = (r + 17) & 0x1f;
119       CAST_R3(m, r, e, f); m += ROOT3; r = (r + 17) & 0x1f;
120       CAST_R1(m, r, d, e); m += ROOT3; r = (r + 17) & 0x1f;
121       CAST_R2(m, r, c, d); m += ROOT3; r = (r + 17) & 0x1f;
122       CAST_R3(m, r, b, c); m += ROOT3; r = (r + 17) & 0x1f;
123       CAST_R1(m, r, a, b); m += ROOT3; r = (r + 17) & 0x1f;
124       CAST_R2(m, r, h, a); m += ROOT3; r = (r + 17) & 0x1f;
125     }
126     km[0] = h; km[1] = f; km[2] = d; km[3] = b;
127     kr[0] = a & 0x1f; kr[1] = c & 0x1f; kr[2] = e & 0x1f; kr[3] = g & 0x1f;
128     km += 4; kr += 4;
129   }
130 }
131
132 /* --- @cast256_eblk@, @cast256_dblk@ --- *
133  *
134  * Arguments:   @const cast256_ctx *k@ = pointer to key block
135  *              @const uint32 s[2]@ = pointer to source block
136  *              @uint32 d[2]@ = pointer to destination block
137  *
138  * Returns:     ---
139  *
140  * Use:         Low-level block encryption and decryption.
141  */
142
143 #define Q0(k, r, a, b, c, d) do {                                       \
144   CAST_R1(k[0], r[0], c, d);                                            \
145   CAST_R2(k[1], r[1], b, c);                                            \
146   CAST_R3(k[2], r[2], a, b);                                            \
147   CAST_R1(k[3], r[3], d, a);                                            \
148 } while (0)
149
150 #define Q1(k, r, a, b, c, d) do {                                       \
151   CAST_R1(k[3], r[3], d, a);                                            \
152   CAST_R3(k[2], r[2], a, b);                                            \
153   CAST_R2(k[1], r[1], b, c);                                            \
154   CAST_R1(k[0], r[0], c, d);                                            \
155 } while (0)
156
157 void cast256_eblk(const cast256_ctx *k, const uint32 *s, uint32 *d)
158 {
159   uint32 aa = s[0], bb = s[1], cc = s[2], dd = s[3];
160   const uint32 *km = k->km;
161   const octet *kr = k->kr;
162
163   Q0(km, kr, aa, bb, cc, dd); km += 4; kr += 4;
164   Q0(km, kr, aa, bb, cc, dd); km += 4; kr += 4;
165   Q0(km, kr, aa, bb, cc, dd); km += 4; kr += 4;
166   Q0(km, kr, aa, bb, cc, dd); km += 4; kr += 4;
167   Q0(km, kr, aa, bb, cc, dd); km += 4; kr += 4;
168   Q0(km, kr, aa, bb, cc, dd); km += 4; kr += 4;
169
170   Q1(km, kr, aa, bb, cc, dd); km += 4; kr += 4;
171   Q1(km, kr, aa, bb, cc, dd); km += 4; kr += 4;
172   Q1(km, kr, aa, bb, cc, dd); km += 4; kr += 4;
173   Q1(km, kr, aa, bb, cc, dd); km += 4; kr += 4;
174   Q1(km, kr, aa, bb, cc, dd); km += 4; kr += 4;
175   Q1(km, kr, aa, bb, cc, dd); km += 4; kr += 4;
176
177   d[0] = aa; d[1] = bb; d[2] = cc; d[3] = dd;
178 }
179
180 void cast256_dblk(const cast256_ctx *k, const uint32 *s, uint32 *d)
181 {
182   uint32 aa = s[0], bb = s[1], cc = s[2], dd = s[3];
183   const uint32 *km = k->km + 48;
184   const octet *kr = k->kr + 48;
185
186   km -= 4; kr -= 4; Q0(km, kr, aa, bb, cc, dd);
187   km -= 4; kr -= 4; Q0(km, kr, aa, bb, cc, dd);
188   km -= 4; kr -= 4; Q0(km, kr, aa, bb, cc, dd);
189   km -= 4; kr -= 4; Q0(km, kr, aa, bb, cc, dd);
190   km -= 4; kr -= 4; Q0(km, kr, aa, bb, cc, dd);
191   km -= 4; kr -= 4; Q0(km, kr, aa, bb, cc, dd);
192
193   km -= 4; kr -= 4; Q1(km, kr, aa, bb, cc, dd);
194   km -= 4; kr -= 4; Q1(km, kr, aa, bb, cc, dd);
195   km -= 4; kr -= 4; Q1(km, kr, aa, bb, cc, dd);
196   km -= 4; kr -= 4; Q1(km, kr, aa, bb, cc, dd);
197   km -= 4; kr -= 4; Q1(km, kr, aa, bb, cc, dd);
198   km -= 4; kr -= 4; Q1(km, kr, aa, bb, cc, dd);
199
200   d[0] = aa; d[1] = bb; d[2] = cc; d[3] = dd;
201 }
202
203 BLKC_TEST(CAST256, cast256)
204
205 /*----- That's all, folks -------------------------------------------------*/