base/permute.h, utils/permute.lisp, symm/...: Formalize bit permutations.
[catacomb] / symm / keccak1600.c
index cfbfdef..a4a6564 100644 (file)
@@ -33,6 +33,7 @@
 #include <mLib/bits.h>
 
 #include "keccak1600.h"
+#include "permute.h"
 
 /* #define KECCAK_DEBUG */
 
@@ -66,25 +67,22 @@ static lane interlace(kludge64 x)
 {
   /* Given a 64-bit string X, return a lane Z containing the even- and
    * odd-numbered bits of X.
-   *
-   * This becomes more manageable if we look at what happens to the bit
-   * indices: bit i of X becomes bit ROR_6(i, 1) of Z.  We can effectively
-   * swap two bits of the indices by swapping the object bits where those
-   * index bits differ.  Fortunately, this is fairly easy.
-   *
-   * We arrange to swap bits between the two halves of X, rather than within
-   * a half.
    */
 
-  uint32 x0 = LO64(x), x1 = HI64(x), t;
+typedef uint32 regty;
+#define REGWD 32
+
+  uint32 x0 = LO64(x), x1 = HI64(x);
   lane z;
-                                                           /* 543210 */
-  t = ((x0 >> 16) ^ x1)&0x0000ffff; x0 ^= t << 16; x1 ^= t; /* 453210 */
-  t = ((x0 >>  8) ^ x1)&0x00ff00ff; x0 ^= t <<  8; x1 ^= t; /* 354210 */
-  t = ((x0 >>  4) ^ x1)&0x0f0f0f0f; x0 ^= t <<  4; x1 ^= t; /* 254310 */
-  t = ((x0 >>  2) ^ x1)&0x33333333; x0 ^= t <<  2; x1 ^= t; /* 154320 */
-  t = ((x0 >>  1) ^ x1)&0x55555555; x0 ^= t <<  1; x1 ^= t; /* 054321 */
+                                       /* 5, 4, 3, 2, 1, 0 */
+  TWIZZLE_EXCH(x1, x0, 4);             /* 4, 5, 3, 2, 1, 0 */
+  TWIZZLE_EXCH(x1, x0, 3);             /* 3, 5, 4, 2, 1, 0 */
+  TWIZZLE_EXCH(x1, x0, 2);             /* 2, 5, 4, 3, 1, 0 */
+  TWIZZLE_EXCH(x1, x0, 1);             /* 1, 5, 4, 3, 2, 0 */
+  TWIZZLE_EXCH(x1, x0, 0);             /* 0, 5, 4, 3, 2, 1 */
   z.even = x0; z.odd = x1; return (z);
+
+#undef REGWD
 }
 
 static kludge64 deinterlace(lane x)
@@ -93,15 +91,20 @@ static kludge64 deinterlace(lane x)
    * to `interlace' above, and the principle is the same
    */
 
-  uint32 x0 = x.even, x1 = x.odd, t;
+typedef uint32 regty;
+#define REGWD 32
+
+  uint32 x0 = x.even, x1 = x.odd;
   kludge64 z;
-                                                           /* 054321 */
-  t = ((x0 >>  1) ^ x1)&0x55555555; x0 ^= t <<  1; x1 ^= t; /* 154320 */
-  t = ((x0 >>  2) ^ x1)&0x33333333; x0 ^= t <<  2; x1 ^= t; /* 254310 */
-  t = ((x0 >>  4) ^ x1)&0x0f0f0f0f; x0 ^= t <<  4; x1 ^= t; /* 354210 */
-  t = ((x0 >>  8) ^ x1)&0x00ff00ff; x0 ^= t <<  8; x1 ^= t; /* 453210 */
-  t = ((x0 >> 16) ^ x1)&0x0000ffff; x0 ^= t << 16; x1 ^= t; /* 543210 */
+                                       /* 0, 5, 4, 3, 2, 1 */
+  TWIZZLE_EXCH(x1, x0, 0);             /* 1, 5, 4, 3, 2, 0 */
+  TWIZZLE_EXCH(x1, x0, 1);             /* 2, 5, 4, 3, 1, 0 */
+  TWIZZLE_EXCH(x1, x0, 2);             /* 3, 5, 4, 2, 1, 0 */
+  TWIZZLE_EXCH(x1, x0, 3);             /* 4, 5, 3, 2, 1, 0 */
+  TWIZZLE_EXCH(x1, x0, 4);             /* 5, 4, 3, 2, 1, 0 */
   SET64(z, x1, x0); return (z);
+
+#undef REGWD
 }
 
 #define TO_LANE(x) (interlace(x))