X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/blobdiff_plain/4328f7469ba7f9539368a21107005009aa9d3a43..HEAD:/symm/blkc.h diff --git a/symm/blkc.h b/symm/blkc.h index 1cbe729c..444ec8d7 100644 --- a/symm/blkc.h +++ b/symm/blkc.h @@ -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) \ @@ -95,24 +97,62 @@ 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, 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 + * . + */ + +#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 { \ @@ -120,15 +160,15 @@ 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 \ }) @@ -159,33 +199,48 @@ #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); \ - _x = ((_x & ~MASK32) >> 16) >> 16; \ +#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); \ - _x = ((_x & ~MASK32) >> 16) >> 16; \ +#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) \ @@ -244,6 +299,94 @@ 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@ --- * @@ -257,9 +400,14 @@ #include +#include #include #include +#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) \ @@ -267,9 +415,9 @@ 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); \ }