/* -*-c-*-
*
- * $Id: idea.c,v 1.2 2000/06/17 11:24:08 mdw Exp $
+ * $Id: idea.c,v 1.5 2004/04/08 01:36:15 mdw Exp $
*
* Implementation of the IDEA cipher
*
* MA 02111-1307, USA.
*/
-/*----- Revision history --------------------------------------------------*
- *
- * $Log: idea.c,v $
- * Revision 1.2 2000/06/17 11:24:08 mdw
- * New key size interface.
- *
- * Revision 1.1 1999/09/03 08:41:12 mdw
- * Initial import.
- *
- */
-
/*----- Header files ------------------------------------------------------*/
#include <assert.h>
{
uint32 m = 0x10001;
uint32 a = 1, b = 0;
+ uint32 nn = n;
+ if (!nn)
+ nn = 0x10000;
for (;;) {
uint32 q, r, t;
- if (!(r = m % n))
+ if (!(r = m % nn))
break;
- q = m / n;
- m = n; n = r;
+ q = m / nn;
+ m = nn; nn = r;
t = a; a = b - q * a; b = t;
}
if (a > MASK16)
* Arguments @x@ and @y@ are two 32-bit values to multiply. On exit, @x@ is
* the product of the two arguments. The result is not normalized back to 16
* bits; the arguments are not expected to be normalized.
+ *
+ * This code is from `Side Channel Attack Hardening of the IDEA Cipher',
+ * published by Ascom Tech.
*/
#define MUL(x, y) do { \
- uint32 _mx, _my = (y); \
- if ((_mx = U16(x)) == 0) \
- (x) = 1 - _my; \
- else if (_my == 0) \
- (x) = 1 - _mx; \
- else { \
- _my *= _mx; \
- _mx = U16(_my); _my >>= 16; \
- if (_mx < _my) \
- (x) = _mx - _my + 1; \
- else \
- (x) = _mx - _my; \
- } \
+ unsigned _t; \
+ uint32 _tt; \
+ \
+ x = U16(x - 1); \
+ _t = U16(y - 1); \
+ _tt = (uint32)x * (uint32)_t + (uint32)x + (uint32)_t + 1; \
+ x = U16(_tt); \
+ _t = U16(_tt >> 16); \
+ x = x - _t + (x <= _t); \
} while (0)
/* --- @idea_init@ --- *
/* --- @ROUND@ --- */
#define MIX(k, a, b, c, d) do { \
- MUL(a, (k)[0]); \
- (b) += (k)[1]; \
- (c) += (k)[2]; \
- MUL(d, (k)[3]); \
+ MUL(a, k[0]); \
+ b += k[1]; \
+ c += k[2]; \
+ MUL(d, k[3]); \
} while (0)
#define MA(k, a, b, c, d) do { \
- unsigned _u = (a) ^ (c); \
- unsigned _v = (b) ^ (d); \
- MUL(_u, (k)[4]); \
+ unsigned _u = a ^ c; \
+ unsigned _v = b ^ d; \
+ MUL(_u, k[4]); \
_v += _u; \
- MUL(_v, (k)[5]); \
+ MUL(_v, k[5]); \
_u += _v; \
- (a) ^= _v; \
- (b) ^= _u; \
- (c) ^= _v; \
- (d) ^= _u; \
+ a ^= _v; \
+ b ^= _u; \
+ c ^= _v; \
+ d ^= _u; \
} while (0);
#define ROUND(k, a, b, c, d) do { \
- MIX((k), (a), (b), (c), (d)); \
- MA((k), (a), (b), (c), (d)); \
+ MIX(k, a, b, c, d); \
+ MA(k, a, b, c, d); \
(k) += 6; \
} while (0)
ROUND(_k, _a, _b, _c, _d); \
ROUND(_k, _a, _c, _b, _d); \
MIX (_k, _a, _c, _b, _d); \
- (c) = (U16(_a) << 16) | U16(_c); \
- (d) = (U16(_b) << 16) | U16(_d); \
+ c = ((uint32)U16(_a) << 16) | (uint32)U16(_c); \
+ d = ((uint32)U16(_b) << 16) | (uint32)U16(_d); \
} while (0)
#define DBLK(k, a, b) EBLK((k), (a), (b))