#include <mLib/bits.h>
#include "keccak1600.h"
+#include "permute.h"
/* #define KECCAK_DEBUG */
{
/* 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)
* 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))
{ 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
#include <stdio.h>
+#include <mLib/macros.h>
#include <mLib/quis.h>
#include <mLib/report.h>
#include <mLib/testrig.h>
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);