symm/blkc.h: Add macros for binary-field shifts.
authorMark Wooding <mdw@distorted.org.uk>
Wed, 31 Oct 2018 12:03:16 +0000 (12:03 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 25 Nov 2018 11:38:04 +0000 (11:38 +0000)
symm/blkc.h

index 52179df..bbba763 100644 (file)
   BLKC_GLUE(BLKC_SKEL_, n)                                             \
     (PRE, BLKC_W(w); const BLKC_WX(wx);, op, BLKC_XMOVE_GUTS)
 
+/*----- Binary field arithmetic -------------------------------------------*/
+
+#define BLKC_POLY_IRRED64  0x001b
+#define BLKC_POLY_IRRED96  0x0641
+#define BLKC_POLY_IRRED128 0x0087
+#define BLKC_POLY_IRRED192 0x0087
+#define BLKC_POLY_IRRED256 0x0425
+
+#define BLKC_POLY_PRIM64   0x001b
+#define BLKC_POLY_PRIM96   0x0641
+#define BLKC_POLY_PRIM128  0x0087
+#define BLKC_POLY_PRIM192  0x8821
+#define BLKC_POLY_PRIM256  0x0425
+
+#define BLKC_POLY(PRE, f) BLKC_GLUE(BLKC_POLY_##f, BLKC_BITS(PRE))
+
+#define BLKC_BLSHIFT(PRE, f, z, x)                                     \
+  BLKC_GLUE(BLKC_BLSHIFT_X_, BLKC_ENDIAN(PRE))                         \
+    (PRE, f, z, x)
+#define BLKC_LLSHIFT(PRE, f, z, x)                                     \
+  BLKC_GLUE(BLKC_LLSHIFT_X_, BLKC_ENDIAN(PRE))                         \
+    (PRE, f, z, x)
+#define BLKC_LSHIFT(PRE, f, z, x)                                      \
+  BLKC_GLUE(BLKC_LSHIFT_X_, BLKC_ENDIAN(PRE))                          \
+    (PRE, BLKC_ID, f, z, x)
+
+#define BLKC_BRSHIFT(PRE, f, z, x)                                     \
+  BLKC_GLUE(BLKC_BRSHIFT_X_, BLKC_ENDIAN(PRE))                         \
+    (PRE, f, z, x)
+#define BLKC_LRSHIFT(PRE, f, z, x)                                     \
+  BLKC_GLUE(BLKC_LRSHIFT_X_, BLKC_ENDIAN(PRE))                         \
+    (PRE, f, z, x)
+#define BLKC_RSHIFT(PRE, f, z, x)                                      \
+  BLKC_GLUE(BLKC_RSHIFT_X_, BLKC_ENDIAN(PRE))                          \
+    (PRE, BLKC_ID, f, z, x)
+
+#define BLKC_BLSHIFT_X_B(PRE, f, z, x) BLKC_LSHIFT_X_B(PRE, BLKC_ID, f, z, x)
+#define BLKC_LLSHIFT_X_B(PRE, f, z, x) BLKC_LSHIFT_X_L(PRE, ENDSWAP32, f, z, x)
+#define BLKC_BLSHIFT_X_L(PRE, f, z, x) BLKC_LSHIFT_X_B(PRE, ENDSWAP32, f, z, x)
+#define BLKC_LLSHIFT_X_L(PRE, f, z, x) BLKC_LSHIFT_X_L(PRE, BLKC_ID, f, z, x)
+
+#define BLKC_BRSHIFT_X_B(PRE, f, z, x) BLKC_RSHIFT_X_B(PRE, BLKC_ID, f, z, x)
+#define BLKC_LRSHIFT_X_B(PRE, f, z, x) BLKC_RSHIFT_X_L(PRE, ENDSWAP32, f, z, x)
+#define BLKC_BRSHIFT_X_L(PRE, f, z, x) BLKC_RSHIFT_X_B(PRE, ENDSWAP32, f, z, x)
+#define BLKC_LRSHIFT_X_L(PRE, f, z, x) BLKC_RSHIFT_X_L(PRE, BLKC_ID, f, z, x)
+
+#define BLKC_LSHIFT_X_B(PRE, op, f, z, x) do {                         \
+  uint32 *_z = (z); const uint32 *_x = (x);                            \
+  uint32 _t = op(_x[0]), _m = -(uint32)((_t >> 31)&1u),                        \
+    _c = BLKC_POLY(PRE, f)&_m;                                         \
+  unsigned _i;                                                         \
+                                                                       \
+  for (_i = PRE##_BLKSZ/4; _i-- > 0; )                                 \
+    { _t = op(_x[_i]); _z[_i] = op((_t << 1) ^ _c); _c = (_t >> 31)&1u; } \
+} while (0)
+
+#define BLKC_RSHIFT_X_B(PRE, op, f, z, x) do {                         \
+  uint32 *_z = (z); const uint32 *_x = (x);                            \
+  uint32 _t, _t0 = op(_x[PRE##_BLKSZ/4 - 1]), _m = -(uint32)(_t0&1u),  \
+    _c = 0x80000000&_m;                                                        \
+  unsigned _i;                                                         \
+                                                                       \
+  for (_i = 0; _i < PRE##_BLKSZ/4 - 1; _i++)                           \
+    { _t = op(_x[_i]); _z[_i] = op((_t >> 1) ^ _c); _c = (_t&1u) << 31; } \
+  _t0 ^= BLKC_POLY(PRE, f)&_m; _z[PRE##_BLKSZ/4 - 1] = op((_t0 >> 1) ^ _c); \
+} while (0)
+
+#define BLKC_LSHIFT_X_L(PRE, op, f, z, x) do {                         \
+  uint32 *_z = (z); const uint32 *_x = (x);                            \
+  uint32 _t = op(_x[PRE##_BLKSZ/4 - 1]), _m = -(uint32)((_t >> 31)&1u),        \
+    _c = BLKC_POLY(PRE, f)&_m;                                         \
+  unsigned _i;                                                         \
+                                                                       \
+  for (_i = 0; _i < PRE##_BLKSZ/4; _i++)                               \
+    { _t = op(_x[_i]); _z[_i] = op((_t << 1) ^ _c); _c = (_t >> 31)&1u; } \
+} while (0)
+
+#define BLKC_RSHIFT_X_L(PRE, op, f, z, x) do {                         \
+  uint32 *_z = (z); const uint32 *_x = (x);                            \
+  uint32 _t, _t0 = op(_x[0]), _m = -(uint32)(_t0&1u),                  \
+    _c = 0x80000000&_m;                                                        \
+  unsigned _i;                                                         \
+                                                                       \
+  for (_i = PRE##_BLKSZ/4 - 1; _i-- > 1; )                             \
+    { _t = op(_x[_i]); _z[_i] = op((_t >> 1) ^ _c); _c = (_t&1u) << 31; } \
+  _t0 ^= BLKC_POLY(PRE, f)&_m; _z[0] = op((_t0 >> 1) ^ _c);            \
+} while (0)
+
 /*----- Test rig for block ciphers ----------------------------------------*/
 
 /* --- @BLKC_TEST@ --- *