progs/perftest.c: Use from Glibc syscall numbers.
[catacomb] / symm / blkc.h
index e083752..444ec8d 100644 (file)
@@ -69,6 +69,8 @@
 #define BLKC_STORE_E(PRE) BLKC_GLUE(STORE32_, BLKC_ENDIAN(PRE))
 #define BLKC_LOAD_E(PRE) BLKC_GLUE(LOAD32_, BLKC_ENDIAN(PRE))
 
+#define BLKC_ID(x) (x)
+
 /* --- Interface macros --- */
 
 #define BLKC_STORE(PRE, b, w)                                          \
   BLKC_GLUE(BLKC_XMOVE_, BLKC_TYPE(PRE))                               \
     (PRE, w, wx, BLKC_BITS(PRE))
 
-#define BLKC_STEP(PRE, w)                                              \
-  BLKC_GLUE(BLKC_STEP_X_, BLKC_ENDIAN(PRE))                            \
-    (PRE, w)
+#define BLKC_BSTEP(PRE, w) BLKC_BADD(PRE, w, 1)
+#define BLKC_LSTEP(PRE, w) BLKC_LADD(PRE, w, 1)
+#define BLKC_STEP(PRE, w) BLKC_ADD(PRE, w, 1)
+
+#define BLKC_BADD(PRE, w, n)                                           \
+  BLKC_GLUE(BLKC_BADD_X_, BLKC_ENDIAN(PRE))                            \
+    (PRE, w, n)
+#define BLKC_LADD(PRE, w, n)                                           \
+  BLKC_GLUE(BLKC_LADD_X_, BLKC_ENDIAN(PRE))                            \
+    (PRE, w, n)
+#define BLKC_ADD(PRE, w, n)                                            \
+  BLKC_GLUE(BLKC_ADD_X_, BLKC_ENDIAN(PRE))                             \
+    (PRE, BLKC_ID, w, n)
 
 #define BLKC_ZERO(PRE, w)                                              \
   BLKC_GLUE(BLKC_ZERO_, BLKC_TYPE(PRE))                                        \
     (PRE, w, BLKC_BITS(PRE))
 
+#define BLKC_BSET(PRE, w, x)                                           \
+  BLKC_GLUE(BLKC_BSET_X_, BLKC_ENDIAN(PRE))                            \
+    (PRE, w, x)
+#define BLKC_LSET(PRE, w, x)                                           \
+  BLKC_GLUE(BLKC_LSET_X_, BLKC_ENDIAN(PRE))                            \
+    (PRE, w, x)
 #define BLKC_SET(PRE, w, x)                                            \
   BLKC_GLUE(BLKC_SET_X_, BLKC_ENDIAN(PRE))                             \
-    (PRE, w, x)
+    (PRE, BLKC_ID, w, x)
+
+#define BLKC_BWORD(PRE, x) BLKC_GLUE(BLKC_BWORD_, BLKC_ENDIAN(PRE))(x)
+#define BLKC_LWORD(PRE, x) BLKC_GLUE(BLKC_LWORD_, BLKC_ENDIAN(PRE))(x)
 
 #define BLKC_SHOW(PRE, tag, w) do {                                    \
   fputs(tag ": ", stdout);                                             \
-  BLKC_SKEL_X(PRE, const BLKC_W(w);, printf("%08x ", *_w++););         \
+  BLKC_SKEL_X(PRE, const BLKC_W(w);,                                   \
+             { printf("%08x ", BLKC_BWORD(PRE, *_w)); _w++; });        \
   fputc('\n', stdout);                                                 \
 } while (0)
 
+/* --- Utilities --- *
+ *
+ * These seem too hard to properly generalize, or I'd have put them in
+ * <mLib/bits.h>.
+ */
+
+#ifdef HAVE_UINT64
+#  define BLKC_ADDC32(op, z_out, c_out, x, y) do {                     \
+     uint64 _t = (uint64)op(x) + (y);                                  \
+     (z_out) = U32(op(_t)); (c_out) = _t >> 32;                                \
+   } while (0)
+#else
+#  define BLKC_ADDC32(op, z_out, c_out, x, y) do {                     \
+     uint32 _x = op(x), _c = 0, _t;                                    \
+     _t = U32(_x + (y)); (z_out) = op(_t); (c_out) = (_t < _x);                \
+   } while (0)
+#endif
+
 /* --- General implementation skeleton --- */
 
 #define BLKC_SKEL(PRE, decl, guts) do {                                        \
   guts                                                                 \
 } while (0)
 
-#define BLKC_P(p) register octet *_p = (octet *)(p)
-#define BLKC_W(w) register uint32 *_w = (w)
-#define BLKC_WX(wx) register uint32 *_wx = (wx)
+#define BLKC_P(p) octet *_p = (octet *)(p)
+#define BLKC_W(w) uint32 *_w = (w)
+#define BLKC_WX(wx) uint32 *_wx = (wx)
 
 /* --- Implementation for unusual block sizes --- */
 
 #define BLKC_SKEL_X(PRE, decl, guts)                                   \
   BLKC_SKEL(PRE, unsigned _i; decl,                                    \
-           for (_i = 0; _i < PRE##_BLKSZ / 4; _i++) {                  \
+           for (_i = 0; _i < PRE##_BLKSZ/4; _i++) {                    \
              guts                                                      \
            })
 
 #define BLKC_ZERO_X(PRE, w, n)                                         \
   BLKC_SKEL_X(PRE, BLKC_W(w);, *_w++ = 0;)
 
-#define BLKC_STEP_X_B(PRE, w) do {                                     \
-  unsigned _i = PRE##_BLKSZ / 4; BLKC_W(w); uint32 _x = 0;             \
-  while (_i && !_x) { _i--; _w[_i] = _x = U32(_w[_i] + 1); }           \
+#define BLKC_BADD_X_B(PRE, w, n) BLKC_ADD_X_B(PRE, BLKC_ID, w, n)
+#define BLKC_BADD_X_L(PRE, w, n) BLKC_ADD_X_B(PRE, ENDSWAP32, w, n)
+#define BLKC_LADD_X_B(PRE, w, n) BLKC_ADD_X_L(PRE, ENDSWAP32, w, n)
+#define BLKC_LADD_X_L(PRE, w, n) BLKC_ADD_X_L(PRE, BLKC_ID, w, n)
+
+#define BLKC_ADD_X_B(PRE, op, w, n) do {                               \
+  unsigned _i = PRE##_BLKSZ/4; BLKC_W(w); uint32 _n = (n);             \
+  while (_i-- && _n) BLKC_ADDC32(op, _w[_i], _n, _w[_i], _n);          \
 } while (0)
 
-#define BLKC_STEP_X_L(PRE, w) do {                                     \
-  unsigned _i = 0; BLKC_W(w); uint32 _x = 0;                           \
-  while (_i < PRE##_BLKSZ / 4 && !_x)                                  \
-    { _w[_i] = _x = U32(_w[_i] + 1); _i++; }                           \
+#define BLKC_ADD_X_L(PRE, op, w, n) do {                               \
+  unsigned _i = 0; BLKC_W(w); uint32 _n = (n);                         \
+  while (_i < PRE##_BLKSZ/4 && _n)                                     \
+    { BLKC_ADDC32(op, _w[_i], _n, _w[_i], _n); _i++; }                 \
 } while (0)
 
-#define BLKC_SET_X_B(PRE, w, x) do {                                   \
-  unsigned _i; BLKC_W(w); unsigned long _x = x;                                \
-  for (_i = 0; _i < PRE##_BLKSZ / 4; _i++) {                           \
-    *_w++ = U32(_x);                                                   \
+#define BLKC_BSET_X_B(PRE, w, x) BLKC_SET_X_B(PRE, BLKC_ID, w, x)
+#define BLKC_BSET_X_L(PRE, w, x) BLKC_SET_X_B(PRE, ENDSWAP32, w, x)
+#define BLKC_LSET_X_B(PRE, w, x) BLKC_SET_X_L(PRE, ENDSWAP32, w, x)
+#define BLKC_LSET_X_L(PRE, w, x) BLKC_SET_X_L(PRE, BLKC_ID, w, x)
+
+#define BLKC_SET_X_B(PRE, op, w, x) do {                               \
+  unsigned _i; BLKC_W(w); unsigned long _x = x; _w += PRE##_BLKSZ/4;   \
+  for (_i = 0; _i < PRE##_BLKSZ/4; _i++) {                             \
+    *--_w = U32(op(_x));                                               \
     _x = ((_x & ~(unsigned long)MASK32) >> 16) >> 16;                  \
   }                                                                    \
 } while (0)
 
-#define BLKC_SET_X_L(PRE, w, x) do {                                   \
-  unsigned _i; BLKC_W(w); unsigned long _x = x;        _w += PRE##_BLKSZ / 4;  \
-  for (_i = 0; _i < PRE##_BLKSZ / 4; _i++) {                           \
-    *--_w = U32(_x);                                                   \
+#define BLKC_SET_X_L(PRE, op, w, x) do {                               \
+  unsigned _i; BLKC_W(w); unsigned long _x = x;                                \
+  for (_i = 0; _i < PRE##_BLKSZ/4; _i++) {                             \
+    *_w++ = U32(op(_x));                                               \
     _x = ((_x & ~(unsigned long)MASK32) >> 16) >> 16;                  \
   }                                                                    \
 } while (0)
 
+#define BLKC_BWORD_B(x) (x)
+#define BLKC_BWORD_L(x) ENDSWAP32(x)
+#define BLKC_LWORD_B(x) ENDSWAP32(x)
+#define BLKC_LWORD_L(x) (x)
+
 /* --- Implementation for known block sizes --- */
 
 #define BLKC_SKEL_64(PRE, decl, op, guts)                              \
   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@ --- *
 
 #include <string.h>
 
+#include <mLib/macros.h>
 #include <mLib/quis.h>
 #include <mLib/testrig.h>
 
+#ifndef BLKC_TESTHOOK
+#  define BLKC_TESTHOOK do ; while (0)
+#endif
+
 #define BLKC_VERIFY(PRE, pre) BLKC_VERIFYX(PRE, pre, #pre)
 
 #define BLKC_VERIFYX(PRE, pre, name)                                   \
 static int pre##_verify(dstr *v)                                       \
 {                                                                      \
   pre##_ctx k;                                                         \
-  uint32 p[PRE##_BLKSZ / 4];                                           \
-  uint32 c[PRE##_BLKSZ / 4];                                           \
-  uint32 d[PRE##_BLKSZ / 4];                                           \
+  uint32 p[PRE##_BLKSZ/4];                                             \
+  uint32 c[PRE##_BLKSZ/4];                                             \
+  uint32 d[PRE##_BLKSZ/4];                                             \
   dstr b = DSTR_INIT;                                                  \
   int ok = 1;                                                          \
                                                                        \
@@ -286,7 +434,7 @@ static int pre##_verify(dstr *v)                                    \
   BLKC_MOVE(PRE, d, p);                                                        \
   pre##_eblk(&k, d, d);                                                        \
   BLKC_STORE(PRE, b.buf, d);                                           \
-  if (memcmp(b.buf, v[2].buf, PRE##_BLKSZ)) {                          \
+  if (MEMCMP(b.buf, !=, v[2].buf, PRE##_BLKSZ)) {                      \
     ok = 0;                                                            \
     printf("\nfail encryption:"                                                \
           "\n\tkey        = ");                                        \
@@ -302,7 +450,7 @@ static int pre##_verify(dstr *v)                                    \
   BLKC_MOVE(PRE, d, c);                                                        \
   pre##_dblk(&k, d, d);                                                        \
   BLKC_STORE(PRE, b.buf, d);                                           \
-  if (memcmp(b.buf, v[1].buf, PRE##_BLKSZ)) {                          \
+  if (MEMCMP(b.buf, !=, v[1].buf, PRE##_BLKSZ)) {                      \
     ok = 0;                                                            \
     printf("\nfail decryption:"                                                \
           "\n\tkey        = ");                                        \
@@ -334,6 +482,7 @@ static const test_chunk defs[] = {                                  \
                                                                        \
 int main(int argc, char *argv[])                                       \
 {                                                                      \
+  BLKC_TESTHOOK;                                                       \
   test_run(argc, argv, defs, SRCDIR"/t/" fname);                       \
   return (0);                                                          \
 }