3 * $Id: idea.c,v 1.1 1999/09/03 08:41:12 mdw Exp $
5 * Implementation of the IDEA cipher
7 * (c) 1999 Straylight/Edgeware
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of Catacomb.
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.
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.
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,
30 /*----- Revision history --------------------------------------------------*
33 * Revision 1.1 1999/09/03 08:41:12 mdw
38 /*----- Header files ------------------------------------------------------*/
45 #include <mLib/bits.h>
50 /*----- Main code ---------------------------------------------------------*/
54 * Arguments: @uint16 n@ = number to invert
56 * Returns: Multiplicative inverse of @n@ %$\pmod{2^{16} + 1}$%.
58 * Use: Computes multiplicative inverses. This is handy for the
59 * decryption key scheduling.
62 static uint16
inv(uint16 n
)
73 t
= a
; a
= b
- q
* a
; b
= t
;
82 * Arguments @x@ and @y@ are two 32-bit values to multiply. On exit, @x@ is
83 * the product of the two arguments. The result is not normalized back to 16
84 * bits; the arguments are not expected to be normalized.
87 #define MUL(x, y) do { \
88 uint32 _mx, _my = (y); \
89 if ((_mx = U16(x)) == 0) \
95 _mx = U16(_my); _my >>= 16; \
97 (x) = _mx - _my + 1; \
103 /* --- @idea_init@ --- *
105 * Arguments: @idea_ctx *k@ = pointer to key block
106 * @const void *buf@ = pointer to key buffer
107 * @size_t sz@ = size of key material
111 * Use: Initializes an IDEA key buffer. The buffer must be exactly
112 * 16 bytes in size, because IDEA is only defined with a key
116 void idea_init(idea_ctx
*k
, const void *buf
, size_t sz
)
118 assert(((void)"IDEA key must be 128 bits", sz
== IDEA_KEYSZ
));
120 /* --- Unpack the encryption key --- */
123 const octet
*p
= buf
;
125 uint32 a
= LOAD32(p
+ 0);
126 uint32 b
= LOAD32(p
+ 4);
127 uint32 c
= LOAD32(p
+ 8);
128 uint32 d
= LOAD32(p
+ 12);
131 /* --- Main unpacking loop --- */
133 for (i
= 0; i
< 6; i
++) {
135 /* --- Spit out the next 8 subkeys --- */
147 /* --- Rotate and permute the subkeys --- */
151 a
= U32((a
<< 25) | (b
>> 7));
152 b
= U32((b
<< 25) | (c
>> 7));
153 c
= U32((c
<< 25) | (d
>> 7));
154 d
= U32((d
<< 25) | (t
>> 7));
158 /* --- Write out the tail-enders --- */
166 /* --- Convert this into the decryption key --- */
169 uint16
*p
= k
->e
+ 52;
173 /* --- Translate the main round keys --- */
175 for (i
= 0; i
< 8; i
++) {
182 q
[1] = 0x10000 - p
[4];
183 q
[2] = 0x10000 - p
[3];
185 q
[1] = 0x10000 - p
[3];
186 q
[2] = 0x10000 - p
[4];
191 /* --- Translate the tail-enders --- */
195 q
[1] = 0x10000 - p
[1];
196 q
[2] = 0x10000 - p
[2];
201 /* --- @ROUND@ --- */
203 #define MIX(k, a, b, c, d) do { \
210 #define MA(k, a, b, c, d) do { \
211 unsigned _u = (a) ^ (c); \
212 unsigned _v = (b) ^ (d); \
223 #define ROUND(k, a, b, c, d) do { \
224 MIX((k), (a), (b), (c), (d)); \
225 MA((k), (a), (b), (c), (d)); \
229 /* --- Encryption --- */
231 #define EBLK(k, a, b, c, d) do { \
232 unsigned _a = U16(a >> 16); \
233 unsigned _b = U16(a >> 0); \
234 unsigned _c = U16(b >> 16); \
235 unsigned _d = U16(b >> 0); \
236 const uint16 *_k = (k); \
238 ROUND(_k, _a, _b, _c, _d); \
239 ROUND(_k, _a, _c, _b, _d); \
240 ROUND(_k, _a, _b, _c, _d); \
241 ROUND(_k, _a, _c, _b, _d); \
242 ROUND(_k, _a, _b, _c, _d); \
243 ROUND(_k, _a, _c, _b, _d); \
244 ROUND(_k, _a, _b, _c, _d); \
245 ROUND(_k, _a, _c, _b, _d); \
246 MIX (_k, _a, _c, _b, _d); \
247 (c) = (U16(_a) << 16) | U16(_c); \
248 (d) = (U16(_b) << 16) | U16(_d); \
251 #define DBLK(k, a, b) EBLK((k), (a), (b))
253 /* --- @idea_eblk@, @idea_dblk@ --- *
255 * Arguments: @const idea_ctx *k@ = pointer to a key block
256 * @const uint32 s[2]@ = pointer to source block
257 * @uint32 d[2]@ = pointer to destination block
261 * Use: Low-level block encryption and decryption.
264 void idea_eblk(const idea_ctx
*k
, const uint32
*s
, uint32
*d
)
266 EBLK(k
->e
, s
[0], s
[1], d
[0], d
[1]);
269 void idea_dblk(const idea_ctx
*k
, const uint32
*s
, uint32
*d
)
271 EBLK(k
->d
, s
[0], s
[1], d
[0], d
[1]);
274 BLKC_TEST(IDEA
, idea
)
276 /*----- That's all, folks -------------------------------------------------*/