Fix unusual numbers of rounds. Simplify implementation.
authormdw <mdw>
Mon, 7 May 2001 15:44:46 +0000 (15:44 +0000)
committermdw <mdw>
Mon, 7 May 2001 15:44:46 +0000 (15:44 +0000)
rijndael.c

index 9eeb59b..c2bb8f3 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: rijndael.c,v 1.2 2000/12/06 20:32:59 mdw Exp $
+ * $Id: rijndael.c,v 1.3 2001/05/07 15:44:46 mdw Exp $
  *
  * The Rijndael block cipher
  *
@@ -30,6 +30,9 @@
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: rijndael.c,v $
+ * Revision 1.3  2001/05/07 15:44:46  mdw
+ * Fix unusual numbers of rounds.  Simplify implementation.
+ *
  * Revision 1.2  2000/12/06 20:32:59  mdw
  * Fix round count for weird key sizes.
  *
@@ -63,9 +66,13 @@ static const octet rcon[] = RIJNDAEL_RCON;
 
 /*----- Main code ---------------------------------------------------------*/
 
-#define BYTESUB(x, s)                                                  \
-  (s[U8((x) >> 24)] << 24 | s[U8((x) >> 16)] << 16 |                   \
-   s[U8((x) >>  8)] <<  8 | s[U8((x) >>  0)] <<  0)
+#define SUB(s, a, b, c, d)                                             \
+  (s[U8((a) >>  0)] <<  0 | s[U8((b) >>  8)] <<  8 |                   \
+   s[U8((c) >> 16)] << 16 | s[U8((d) >> 24)] << 24)
+
+#define MIX(t, a, b, c, d)                                             \
+  (t[0][U8((a) >>  0)] ^ t[1][U8((b) >>  8)] ^                         \
+   t[2][U8((c) >> 16)] ^ t[3][U8((d) >> 24)])
 
 /* --- @rijndael_init@ --- *
  *
@@ -117,9 +124,9 @@ void rijndael_init(rijndael_ctx *k, const void *buf, size_t sz)
     uint32 w = k->w[i - nk];
     if (i % nk == 0) {
       ww = ROR32(ww, 8);
-      w ^= BYTESUB(ww, S) ^ *p++;
+      w ^= SUB(S, ww, ww, ww, ww) ^ *p++;
     } else if (nk > 6 && i % nk == 4)
-      w ^= BYTESUB(ww, S);
+      w ^= SUB(S, ww, ww, ww, ww);
     else
       w ^= ww;
     k->w[i] = ww = w;
@@ -137,8 +144,7 @@ void rijndael_init(rijndael_ctx *k, const void *buf, size_t sz)
     j -= RIJNDAEL_BLKSZ / 4;
     for (jj = 0; jj < RIJNDAEL_BLKSZ / 4; jj++) {
       uint32 w = k->w[j + jj];
-      k->wi[i + jj] = (U[0][U8(w >>  0)] ^ U[1][U8(w >>  8)] ^
-                      U[2][U8(w >> 16)] ^ U[3][U8(w >> 24)]);
+      k->wi[i + jj] = MIX(U, w, w, w, w);
     }
   }
 
@@ -158,26 +164,18 @@ void rijndael_init(rijndael_ctx *k, const void *buf, size_t sz)
  * Use:                Low-level block encryption and decryption.
  */
 
-#define EROUND(aa, bb, cc, dd, a, b, c, d, w) do {                     \
-  aa = (T[0][U8(a >>  0)] ^ T[1][U8(b >>  8)] ^                                \
-       T[2][U8(c >> 16)] ^ T[3][U8(d >> 24)]) ^ *w++;                  \
-  bb = (T[0][U8(b >>  0)] ^ T[1][U8(c >>  8)] ^                                \
-       T[2][U8(d >> 16)] ^ T[3][U8(a >> 24)]) ^ *w++;                  \
-  cc = (T[0][U8(c >>  0)] ^ T[1][U8(d >>  8)] ^                                \
-       T[2][U8(a >> 16)] ^ T[3][U8(b >> 24)]) ^ *w++;                  \
-  dd = (T[0][U8(d >>  0)] ^ T[1][U8(a >>  8)] ^                                \
-       T[2][U8(b >> 16)] ^ T[3][U8(c >> 24)]) ^ *w++;                  \
+#define DO(what, t, aa, bb, cc, dd, a, b, c, d, w) do {                        \
+  aa = what(t, a, b, c, d) ^ *w++;                                     \
+  bb = what(t, b, c, d, a) ^ *w++;                                     \
+  cc = what(t, c, d, a, b) ^ *w++;                                     \
+  dd = what(t, d, a, b, c) ^ *w++;                                     \
 } while (0)
 
-#define DROUND(aa, bb, cc, dd, a, b, c, d, w) do {                     \
-  aa = (TI[0][U8(a >>  0)] ^ TI[1][U8(d >>  8)] ^                      \
-       TI[2][U8(c >> 16)] ^ TI[3][U8(b >> 24)]) ^ *w++;                \
-  bb = (TI[0][U8(b >>  0)] ^ TI[1][U8(a >>  8)] ^                      \
-       TI[2][U8(d >> 16)] ^ TI[3][U8(c >> 24)]) ^ *w++;                \
-  cc = (TI[0][U8(c >>  0)] ^ TI[1][U8(b >>  8)] ^                      \
-       TI[2][U8(a >> 16)] ^ TI[3][U8(d >> 24)]) ^ *w++;                \
-  dd = (TI[0][U8(d >>  0)] ^ TI[1][U8(c >>  8)] ^                      \
-       TI[2][U8(b >> 16)] ^ TI[3][U8(a >> 24)]) ^ *w++;                \
+#define UNDO(what, t, aa, bb, cc, dd, a, b, c, d, w) do {              \
+  aa = what(t, a, d, c, b) ^ *w++;                                     \
+  bb = what(t, b, a, d, c) ^ *w++;                                     \
+  cc = what(t, c, b, a, d) ^ *w++;                                     \
+  dd = what(t, d, c, b, a) ^ *w++;                                     \
 } while (0)
 
 void rijndael_eblk(const rijndael_ctx *k, const uint32 *s, uint32 *dst)
@@ -187,35 +185,30 @@ void rijndael_eblk(const rijndael_ctx *k, const uint32 *s, uint32 *dst)
   uint32 *w = k->w;
 
   a ^= *w++; b ^= *w++; c ^= *w++; d ^= *w++;
+  aa = a; bb = b; cc = c; dd = d;
 
   switch (k->nr) {
     case 14:
-      EROUND(aa, bb, cc, dd, a, b, c, d, w);
-      EROUND(a, b, c, d, aa, bb, cc, dd, w);
+      DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
+    case 13:
+      DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
     case 12:
-      EROUND(aa, bb, cc, dd, a, b, c, d, w);
-      EROUND(a, b, c, d, aa, bb, cc, dd, w);
+      DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
+    case 11:
+      DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
     case 10:
     default:
-      EROUND(aa, bb, cc, dd, a, b, c, d, w);
-      EROUND(a, b, c, d, aa, bb, cc, dd, w);
-      EROUND(aa, bb, cc, dd, a, b, c, d, w);
-      EROUND(a, b, c, d, aa, bb, cc, dd, w);
-      EROUND(aa, bb, cc, dd, a, b, c, d, w);
-      EROUND(a, b, c, d, aa, bb, cc, dd, w);
-      EROUND(aa, bb, cc, dd, a, b, c, d, w);
-      EROUND(a, b, c, d, aa, bb, cc, dd, w);
-      EROUND(aa, bb, cc, dd, a, b, c, d, w);
+      DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
+      DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
+      DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
+      DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
+      DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
+      DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
+      DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
+      DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
+      DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
   }
-
-  a = ((S[U8(aa >>  0)] <<  0) ^ (S[U8(bb >>  8)] <<  8) ^
-       (S[U8(cc >> 16)] << 16) ^ (S[U8(dd >> 24)] << 24)) ^ *w++;
-  b = ((S[U8(bb >>  0)] <<  0) ^ (S[U8(cc >>  8)] <<  8) ^     
-       (S[U8(dd >> 16)] << 16) ^ (S[U8(aa >> 24)] << 24)) ^ *w++;
-  c = ((S[U8(cc >>  0)] <<  0) ^ (S[U8(dd >>  8)] <<  8) ^
-       (S[U8(aa >> 16)] << 16) ^ (S[U8(bb >> 24)] << 24)) ^ *w++;
-  d = ((S[U8(dd >>  0)] <<  0) ^ (S[U8(aa >>  8)] <<  8) ^
-       (S[U8(bb >> 16)] << 16) ^ (S[U8(cc >> 24)] << 24)) ^ *w++;
+  DO(SUB, S, a, b, c, d, aa, bb, cc, dd, w);
 
   dst[0] = a; dst[1] = b; dst[2] = c; dst[3] = d;
 }
@@ -227,35 +220,30 @@ void rijndael_dblk(const rijndael_ctx *k, const uint32 *s, uint32 *dst)
   uint32 *w = k->wi;
 
   a ^= *w++; b ^= *w++; c ^= *w++; d ^= *w++;
+  aa = a; bb = b; cc = c; dd = d;
 
   switch (k->nr) {
     case 14:
-      DROUND(aa, bb, cc, dd, a, b, c, d, w);
-      DROUND(a, b, c, d, aa, bb, cc, dd, w);
+      UNDO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
+    case 13:
+      UNDO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
     case 12:
-      DROUND(aa, bb, cc, dd, a, b, c, d, w);
-      DROUND(a, b, c, d, aa, bb, cc, dd, w);
+      UNDO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
+    case 11:
+      UNDO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
     case 10:
     default:
-      DROUND(aa, bb, cc, dd, a, b, c, d, w);
-      DROUND(a, b, c, d, aa, bb, cc, dd, w);
-      DROUND(aa, bb, cc, dd, a, b, c, d, w);
-      DROUND(a, b, c, d, aa, bb, cc, dd, w);
-      DROUND(aa, bb, cc, dd, a, b, c, d, w);
-      DROUND(a, b, c, d, aa, bb, cc, dd, w);
-      DROUND(aa, bb, cc, dd, a, b, c, d, w);
-      DROUND(a, b, c, d, aa, bb, cc, dd, w);
-      DROUND(aa, bb, cc, dd, a, b, c, d, w);
+      UNDO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
+      UNDO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
+      UNDO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
+      UNDO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
+      UNDO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
+      UNDO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
+      UNDO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
+      UNDO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
+      UNDO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
   }
-
-  a = ((SI[U8(aa >>  0)] <<  0) ^ (SI[U8(dd >>  8)] <<  8) ^
-       (SI[U8(cc >> 16)] << 16) ^ (SI[U8(bb >> 24)] << 24)) ^ *w++;
-  b = ((SI[U8(bb >>  0)] <<  0) ^ (SI[U8(aa >>  8)] <<  8) ^
-       (SI[U8(dd >> 16)] << 16) ^ (SI[U8(cc >> 24)] << 24)) ^ *w++;
-  c = ((SI[U8(cc >>  0)] <<  0) ^ (SI[U8(bb >>  8)] <<  8) ^
-       (SI[U8(aa >> 16)] << 16) ^ (SI[U8(dd >> 24)] << 24)) ^ *w++;
-  d = ((SI[U8(dd >>  0)] <<  0) ^ (SI[U8(cc >>  8)] <<  8) ^
-       (SI[U8(bb >> 16)] << 16) ^ (SI[U8(aa >> 24)] << 24)) ^ *w++;
+  UNDO(SUB, SI, a, b, c, d, aa, bb, cc, dd, w);
 
   dst[0] = a; dst[1] = b; dst[2] = c; dst[3] = d;
 }