3 * $Id: idea.c,v 1.2 2000/06/17 11:24:08 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.2 2000/06/17 11:24:08 mdw
34 * New key size interface.
36 * Revision 1.1 1999/09/03 08:41:12 mdw
41 /*----- Header files ------------------------------------------------------*/
48 #include <mLib/bits.h>
54 /*----- Global variables --------------------------------------------------*/
56 const octet idea_keysz
[] = { KSZ_SET
, IDEA_KEYSZ
};
58 /*----- Main code ---------------------------------------------------------*/
62 * Arguments: @uint16 n@ = number to invert
64 * Returns: Multiplicative inverse of @n@ %$\pmod{2^{16} + 1}$%.
66 * Use: Computes multiplicative inverses. This is handy for the
67 * decryption key scheduling.
70 static uint16
inv(uint16 n
)
81 t
= a
; a
= b
- q
* a
; b
= t
;
90 * Arguments @x@ and @y@ are two 32-bit values to multiply. On exit, @x@ is
91 * the product of the two arguments. The result is not normalized back to 16
92 * bits; the arguments are not expected to be normalized.
95 #define MUL(x, y) do { \
96 uint32 _mx, _my = (y); \
97 if ((_mx = U16(x)) == 0) \
103 _mx = U16(_my); _my >>= 16; \
105 (x) = _mx - _my + 1; \
111 /* --- @idea_init@ --- *
113 * Arguments: @idea_ctx *k@ = pointer to key block
114 * @const void *buf@ = pointer to key buffer
115 * @size_t sz@ = size of key material
119 * Use: Initializes an IDEA key buffer. The buffer must be exactly
120 * 16 bytes in size, because IDEA is only defined with a key
124 void idea_init(idea_ctx
*k
, const void *buf
, size_t sz
)
126 KSZ_ASSERT(idea
, sz
);
128 /* --- Unpack the encryption key --- */
131 const octet
*p
= buf
;
133 uint32 a
= LOAD32(p
+ 0);
134 uint32 b
= LOAD32(p
+ 4);
135 uint32 c
= LOAD32(p
+ 8);
136 uint32 d
= LOAD32(p
+ 12);
139 /* --- Main unpacking loop --- */
141 for (i
= 0; i
< 6; i
++) {
143 /* --- Spit out the next 8 subkeys --- */
155 /* --- Rotate and permute the subkeys --- */
159 a
= U32((a
<< 25) | (b
>> 7));
160 b
= U32((b
<< 25) | (c
>> 7));
161 c
= U32((c
<< 25) | (d
>> 7));
162 d
= U32((d
<< 25) | (t
>> 7));
166 /* --- Write out the tail-enders --- */
174 /* --- Convert this into the decryption key --- */
177 uint16
*p
= k
->e
+ 52;
181 /* --- Translate the main round keys --- */
183 for (i
= 0; i
< 8; i
++) {
190 q
[1] = 0x10000 - p
[4];
191 q
[2] = 0x10000 - p
[3];
193 q
[1] = 0x10000 - p
[3];
194 q
[2] = 0x10000 - p
[4];
199 /* --- Translate the tail-enders --- */
203 q
[1] = 0x10000 - p
[1];
204 q
[2] = 0x10000 - p
[2];
209 /* --- @ROUND@ --- */
211 #define MIX(k, a, b, c, d) do { \
218 #define MA(k, a, b, c, d) do { \
219 unsigned _u = (a) ^ (c); \
220 unsigned _v = (b) ^ (d); \
231 #define ROUND(k, a, b, c, d) do { \
232 MIX((k), (a), (b), (c), (d)); \
233 MA((k), (a), (b), (c), (d)); \
237 /* --- Encryption --- */
239 #define EBLK(k, a, b, c, d) do { \
240 unsigned _a = U16(a >> 16); \
241 unsigned _b = U16(a >> 0); \
242 unsigned _c = U16(b >> 16); \
243 unsigned _d = U16(b >> 0); \
244 const uint16 *_k = (k); \
246 ROUND(_k, _a, _b, _c, _d); \
247 ROUND(_k, _a, _c, _b, _d); \
248 ROUND(_k, _a, _b, _c, _d); \
249 ROUND(_k, _a, _c, _b, _d); \
250 ROUND(_k, _a, _b, _c, _d); \
251 ROUND(_k, _a, _c, _b, _d); \
252 ROUND(_k, _a, _b, _c, _d); \
253 ROUND(_k, _a, _c, _b, _d); \
254 MIX (_k, _a, _c, _b, _d); \
255 (c) = (U16(_a) << 16) | U16(_c); \
256 (d) = (U16(_b) << 16) | U16(_d); \
259 #define DBLK(k, a, b) EBLK((k), (a), (b))
261 /* --- @idea_eblk@, @idea_dblk@ --- *
263 * Arguments: @const idea_ctx *k@ = pointer to a key block
264 * @const uint32 s[2]@ = pointer to source block
265 * @uint32 d[2]@ = pointer to destination block
269 * Use: Low-level block encryption and decryption.
272 void idea_eblk(const idea_ctx
*k
, const uint32
*s
, uint32
*d
)
274 EBLK(k
->e
, s
[0], s
[1], d
[0], d
[1]);
277 void idea_dblk(const idea_ctx
*k
, const uint32
*s
, uint32
*d
)
279 EBLK(k
->d
, s
[0], s
[1], d
[0], d
[1]);
282 BLKC_TEST(IDEA
, idea
)
284 /*----- That's all, folks -------------------------------------------------*/