X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/blobdiff_plain/1ccb258a64fd14d12938f9014ad22abbe46ab4c0..HEAD:/symm/keccak1600.c diff --git a/symm/keccak1600.c b/symm/keccak1600.c index 499ab4f6..a4a6564f 100644 --- a/symm/keccak1600.c +++ b/symm/keccak1600.c @@ -33,6 +33,7 @@ #include #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)) @@ -589,6 +592,35 @@ void keccak1600_mix(keccak1600_state *s, const kludge64 *p, size_t n) { a = TO_LANE(p[i]); XOR_LANE(s->S[i], s->S[i], a); } } +/* --- @keccak1600_set@ --- * + * + * Arguments: @keccak1600_state *s@ = a state to update + * @const kludge64 *p@ = pointer to 64-bit words to mix in + * @size_t n@ = size of the input, in 64-bit words + * + * Returns: --- + * + * Use: Stores data into a %$\Keccak[r, 1600 - r]$% state. Note that + * it's the caller's responsibility to pass in no more than + * %$r$% bits of data. + * + * This is not the operation you wanted for ordinary hashing. + * It's provided for the use of higher-level protocols which use + * duplexing and other fancy sponge features. + */ + +void keccak1600_set(keccak1600_state *s, const kludge64 *p, size_t n) +{ + uint32 m = COMPL_MASK; + unsigned i; + lane a; + + for (i = 0; i < n; i++) { + a = TO_LANE(p[i]); if (m&1) NOT_LANE(a, a); + s->S[i] = a; m >>= 1; + } +} + /* --- @keccak1600_extract@ --- * * * Arguments: @const keccak1600_state *s@ = a state to extract output from @@ -620,6 +652,7 @@ void keccak1600_extract(const keccak1600_state *s, kludge64 *p, size_t n) #include +#include #include #include #include @@ -644,7 +677,7 @@ static int vrf_p(dstr v[]) keccak1600_p(&u, &u, n); keccak1600_extract(&u, t, 25); for (i = 0; i < 25; i++) STORE64_L_(d.buf + 8*i, t[i]); - if (memcmp(d.buf, v[2].buf, 200) != 0) { + if (MEMCMP(d.buf, !=, v[2].buf, 200)) { ok = 0; fprintf(stderr, "failed!"); fprintf(stderr, "\n\t input = "); type_hex.dump(&v[0], stderr);