#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_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, w, n)
+ (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)
*/
#ifdef HAVE_UINT64
-# define BLKC_ADDC32(z_out, c_out, x, y) do { \
- uint64 _t = (uint64)(x) + (y); \
- (z_out) = U32(_t); (c_out) = _t >> 32; \
+# 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(z_out, c_out, x, y) do { \
- uint32 _x = (x), _c = 0, _t; \
- _t = U32(_x + (y)); (z_out) = _t; (c_out) = (_t < _x); \
+# 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
#define BLKC_ZERO_X(PRE, w, n) \
BLKC_SKEL_X(PRE, BLKC_W(w);, *_w++ = 0;)
-#define BLKC_ADD_X_B(PRE, w, n) do { \
+#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(_w[_i], _n, _w[_i], _n); \
+ while (_i-- && _n) BLKC_ADDC32(op, _w[_i], _n, _w[_i], _n); \
} while (0)
-#define BLKC_ADD_X_L(PRE, w, n) do { \
+#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(_w[_i], _n, _w[_i], _n); _i++; } \
+ { 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; \
+#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(_x); \
+ *--_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; \
+#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(_x); \
+ *_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@ --- *