aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--reference_impl/reference_impl.rs12
-rw-r--r--src/c/blake3.h3
-rw-r--r--src/c/blake3_avx512.c283
-rw-r--r--src/c/blake3_impl.h79
-rw-r--r--src/c/blake3_neon.c5
-rw-r--r--src/lib.rs12
-rw-r--r--src/sse41.rs412
-rw-r--r--test_vectors/test_vectors.json118
8 files changed, 455 insertions, 469 deletions
diff --git a/reference_impl/reference_impl.rs b/reference_impl/reference_impl.rs
index 7f5d7f1..855d8f0 100644
--- a/reference_impl/reference_impl.rs
+++ b/reference_impl/reference_impl.rs
@@ -21,12 +21,12 @@ const IV: [u32; 8] = [
const MSG_SCHEDULE: [[usize; 16]; ROUNDS] = [
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
- [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3],
- [11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4],
- [7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8],
- [9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13],
- [2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9],
- [12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11],
+ [2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8],
+ [3, 4, 10, 12, 13, 2, 7, 14, 6, 5, 9, 0, 11, 15, 8, 1],
+ [10, 7, 12, 9, 14, 3, 13, 15, 4, 0, 11, 2, 5, 8, 1, 6],
+ [12, 13, 9, 11, 15, 10, 14, 8, 7, 2, 5, 3, 0, 1, 6, 4],
+ [9, 14, 11, 5, 8, 12, 15, 1, 13, 3, 0, 10, 2, 6, 4, 7],
+ [11, 15, 5, 0, 1, 9, 8, 6, 14, 10, 2, 12, 3, 4, 7, 13],
];
// The mixing function, G, which mixes either a column or a diagonal.
diff --git a/src/c/blake3.h b/src/c/blake3.h
index 5c68521..c3cf6be 100644
--- a/src/c/blake3.h
+++ b/src/c/blake3.h
@@ -28,8 +28,7 @@ typedef struct {
void blake3_hasher_init(blake3_hasher *self);
void blake3_hasher_init_keyed(blake3_hasher *self,
const uint8_t key[BLAKE3_KEY_LEN]);
-void blake3_hasher_init_derive_key(blake3_hasher *self,
- const uint8_t key[BLAKE3_KEY_LEN]);
+void blake3_hasher_init_derive_key(blake3_hasher *self, const char *context);
void blake3_hasher_update(blake3_hasher *self, const void *input,
size_t input_len);
void blake3_hasher_finalize(const blake3_hasher *self, uint8_t *out,
diff --git a/src/c/blake3_avx512.c b/src/c/blake3_avx512.c
index 2c8657c..fc754e2 100644
--- a/src/c/blake3_avx512.c
+++ b/src/c/blake3_avx512.c
@@ -2,6 +2,10 @@
#include <immintrin.h>
+#define _mm_shuffle_ps2(a, b, c) \
+ (_mm_castps_si128( \
+ _mm_shuffle_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), (c))))
+
INLINE __m128i loadu_128(const uint8_t src[16]) {
return _mm_loadu_si128((const __m128i *)src);
}
@@ -123,159 +127,160 @@ INLINE void compress_pre(__m128i rows[4], const uint32_t cv[8],
__m128i m2 = loadu_128(&block[sizeof(__m128i) * 2]);
__m128i m3 = loadu_128(&block[sizeof(__m128i) * 3]);
- __m128i buf, t0, t1, t2;
+ __m128i t0, t1, t2, t3, tt;
- // round 1
- buf = _mm_castps_si128(_mm_shuffle_ps(
- _mm_castsi128_ps(m0), _mm_castsi128_ps(m1), _MM_SHUFFLE(2, 0, 2, 0)));
- g1(&rows[0], &rows[1], &rows[2], &rows[3], buf);
- buf = _mm_castps_si128(_mm_shuffle_ps(
- _mm_castsi128_ps(m0), _mm_castsi128_ps(m1), _MM_SHUFFLE(3, 1, 3, 1)));
- g2(&rows[0], &rows[1], &rows[2], &rows[3], buf);
+ // Round 1. The first round permutes the message words from the original
+ // input order, into the groups that get mixed in parallel.
+ t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(2, 0, 2, 0)); // 6 4 2 0
+ g1(&rows[0], &rows[1], &rows[2], &rows[3], t0);
+ t1 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 3, 1)); // 7 5 3 1
+ g2(&rows[0], &rows[1], &rows[2], &rows[3], t1);
diagonalize(&rows[0], &rows[2], &rows[3]);
- t0 = _mm_shuffle_epi32(m2, _MM_SHUFFLE(3, 2, 0, 1));
- t1 = _mm_shuffle_epi32(m3, _MM_SHUFFLE(0, 1, 3, 2));
- buf = _mm_blend_epi16(t0, t1, 0xC3);
- g1(&rows[0], &rows[1], &rows[2], &rows[3], buf);
- t0 = _mm_blend_epi16(t0, t1, 0x3C);
- buf = _mm_shuffle_epi32(t0, _MM_SHUFFLE(2, 3, 0, 1));
- g2(&rows[0], &rows[1], &rows[2], &rows[3], buf);
+ t2 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(2, 0, 2, 0)); // 14 12 10 8
+ t2 = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2, 1, 0, 3)); // 12 10 8 14
+ g1(&rows[0], &rows[1], &rows[2], &rows[3], t2);
+ t3 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 1, 3, 1)); // 15 13 11 9
+ t3 = _mm_shuffle_epi32(t3, _MM_SHUFFLE(2, 1, 0, 3)); // 13 11 9 15
+ g2(&rows[0], &rows[1], &rows[2], &rows[3], t3);
undiagonalize(&rows[0], &rows[2], &rows[3]);
-
- // round 2
- t0 = _mm_blend_epi16(m1, m2, 0x0C);
- t1 = _mm_slli_si128(m3, 4);
- t2 = _mm_blend_epi16(t0, t1, 0xF0);
- buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2, 1, 0, 3));
- g1(&rows[0], &rows[1], &rows[2], &rows[3], buf);
- t0 = _mm_shuffle_epi32(m2, _MM_SHUFFLE(0, 0, 2, 0));
- t1 = _mm_blend_epi16(m1, m3, 0xC0);
- t2 = _mm_blend_epi16(t0, t1, 0xF0);
- buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2, 3, 0, 1));
- g2(&rows[0], &rows[1], &rows[2], &rows[3], buf);
+ m0 = t0;
+ m1 = t1;
+ m2 = t2;
+ m3 = t3;
+
+ // Round 2. This round and all following rounds apply a fixed permutation
+ // to the message words from the round before.
+ t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
+ t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
+ g1(&rows[0], &rows[1], &rows[2], &rows[3], t0);
+ t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
+ tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
+ t1 = _mm_blend_epi16(tt, t1, 0xCC);
+ g2(&rows[0], &rows[1], &rows[2], &rows[3], t1);
diagonalize(&rows[0], &rows[2], &rows[3]);
- t0 = _mm_slli_si128(m1, 4);
- t1 = _mm_blend_epi16(m2, t0, 0x30);
- t2 = _mm_blend_epi16(m0, t1, 0xF0);
- buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3, 0, 1, 2));
- g1(&rows[0], &rows[1], &rows[2], &rows[3], buf);
- t0 = _mm_unpackhi_epi32(m0, m1);
- t1 = _mm_slli_si128(m3, 4);
- t2 = _mm_blend_epi16(t0, t1, 0x0C);
- buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3, 0, 1, 2));
- g2(&rows[0], &rows[1], &rows[2], &rows[3], buf);
+ t2 = _mm_unpacklo_epi64(m3, m1);
+ tt = _mm_blend_epi16(t2, m2, 0xC0);
+ t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
+ g1(&rows[0], &rows[1], &rows[2], &rows[3], t2);
+ t3 = _mm_unpackhi_epi32(m1, m3);
+ tt = _mm_unpacklo_epi32(m2, t3);
+ t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
+ g2(&rows[0], &rows[1], &rows[2], &rows[3], t3);
undiagonalize(&rows[0], &rows[2], &rows[3]);
-
- // round 3
- t0 = _mm_unpackhi_epi32(m2, m3);
- t1 = _mm_blend_epi16(m3, m1, 0x0C);
- t2 = _mm_blend_epi16(t0, t1, 0x0F);
- buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3, 1, 0, 2));
- g1(&rows[0], &rows[1], &rows[2], &rows[3], buf);
- t0 = _mm_unpacklo_epi32(m2, m0);
- t1 = _mm_blend_epi16(t0, m0, 0xF0);
- t2 = _mm_slli_si128(m3, 8);
- buf = _mm_blend_epi16(t1, t2, 0xC0);
- g2(&rows[0], &rows[1], &rows[2], &rows[3], buf);
+ m0 = t0;
+ m1 = t1;
+ m2 = t2;
+ m3 = t3;
+
+ // Round 3
+ t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
+ t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
+ g1(&rows[0], &rows[1], &rows[2], &rows[3], t0);
+ t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
+ tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
+ t1 = _mm_blend_epi16(tt, t1, 0xCC);
+ g2(&rows[0], &rows[1], &rows[2], &rows[3], t1);
diagonalize(&rows[0], &rows[2], &rows[3]);
- t0 = _mm_blend_epi16(m0, m2, 0x3C);
- t1 = _mm_srli_si128(m1, 12);
- t2 = _mm_blend_epi16(t0, t1, 0x03);
- buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(0, 3, 2, 1));
- g1(&rows[0], &rows[1], &rows[2], &rows[3], buf);
- t0 = _mm_slli_si128(m3, 4);
- t1 = _mm_blend_epi16(m0, m1, 0x33);
- t2 = _mm_blend_epi16(t1, t0, 0xC0);
- buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1, 2, 3, 0));
- g2(&rows[0], &rows[1], &rows[2], &rows[3], buf);
+ t2 = _mm_unpacklo_epi64(m3, m1);
+ tt = _mm_blend_epi16(t2, m2, 0xC0);
+ t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
+ g1(&rows[0], &rows[1], &rows[2], &rows[3], t2);
+ t3 = _mm_unpackhi_epi32(m1, m3);
+ tt = _mm_unpacklo_epi32(m2, t3);
+ t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
+ g2(&rows[0], &rows[1], &rows[2], &rows[3], t3);
undiagonalize(&rows[0], &rows[2], &rows[3]);
-
- // round 4
- t0 = _mm_unpackhi_epi32(m0, m1);
- t1 = _mm_unpackhi_epi32(t0, m2);
- t2 = _mm_blend_epi16(t1, m3, 0x0C);
- buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3, 1, 0, 2));
- g1(&rows[0], &rows[1], &rows[2], &rows[3], buf);
- t0 = _mm_slli_si128(m2, 8);
- t1 = _mm_blend_epi16(m3, m0, 0x0C);
- t2 = _mm_blend_epi16(t1, t0, 0xC0);
- buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2, 0, 1, 3));
- g2(&rows[0], &rows[1], &rows[2], &rows[3], buf);
+ m0 = t0;
+ m1 = t1;
+ m2 = t2;
+ m3 = t3;
+
+ // Round 4
+ t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
+ t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
+ g1(&rows[0], &rows[1], &rows[2], &rows[3], t0);
+ t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
+ tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
+ t1 = _mm_blend_epi16(tt, t1, 0xCC);
+ g2(&rows[0], &rows[1], &rows[2], &rows[3], t1);
diagonalize(&rows[0], &rows[2], &rows[3]);
- t0 = _mm_blend_epi16(m0, m1, 0x0F);
- t1 = _mm_blend_epi16(t0, m3, 0xC0);
- buf = _mm_shuffle_epi32(t1, _MM_SHUFFLE(0, 1, 2, 3));
- g1(&rows[0], &rows[1], &rows[2], &rows[3], buf);
- t0 = _mm_alignr_epi8(m0, m1, 4);
- buf = _mm_blend_epi16(t0, m2, 0x33);
- g2(&rows[0], &rows[1], &rows[2], &rows[3], buf);
+ t2 = _mm_unpacklo_epi64(m3, m1);
+ tt = _mm_blend_epi16(t2, m2, 0xC0);
+ t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
+ g1(&rows[0], &rows[1], &rows[2], &rows[3], t2);
+ t3 = _mm_unpackhi_epi32(m1, m3);
+ tt = _mm_unpacklo_epi32(m2, t3);
+ t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
+ g2(&rows[0], &rows[1], &rows[2], &rows[3], t3);
undiagonalize(&rows[0], &rows[2], &rows[3]);
-
- // round 5
- t0 = _mm_unpacklo_epi64(m1, m2);
- t1 = _mm_unpackhi_epi64(m0, m2);
- t2 = _mm_blend_epi16(t0, t1, 0x33);
- buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2, 0, 1, 3));
- g1(&rows[0], &rows[1], &rows[2], &rows[3], buf);
- t0 = _mm_unpackhi_epi64(m1, m3);
- t1 = _mm_unpacklo_epi64(m0, m1);
- buf = _mm_blend_epi16(t0, t1, 0x33);
- g2(&rows[0], &rows[1], &rows[2], &rows[3], buf);
+ m0 = t0;
+ m1 = t1;
+ m2 = t2;
+ m3 = t3;
+
+ // Round 5
+ t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
+ t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
+ g1(&rows[0], &rows[1], &rows[2], &rows[3], t0);
+ t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
+ tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
+ t1 = _mm_blend_epi16(tt, t1, 0xCC);
+ g2(&rows[0], &rows[1], &rows[2], &rows[3], t1);
diagonalize(&rows[0], &rows[2], &rows[3]);
- t0 = _mm_unpackhi_epi64(m3, m1);
- t1 = _mm_unpackhi_epi64(m2, m0);
- t2 = _mm_blend_epi16(t1, t0, 0x33);
- buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2, 1, 0, 3));
- g1(&rows[0], &rows[1], &rows[2], &rows[3], buf);
- t0 = _mm_blend_epi16(m0, m2, 0x03);
- t1 = _mm_slli_si128(t0, 8);
- t2 = _mm_blend_epi16(t1, m3, 0x0F);
- buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2, 0, 3, 1));
- g2(&rows[0], &rows[1], &rows[2], &rows[3], buf);
+ t2 = _mm_unpacklo_epi64(m3, m1);
+ tt = _mm_blend_epi16(t2, m2, 0xC0);
+ t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
+ g1(&rows[0], &rows[1], &rows[2], &rows[3], t2);
+ t3 = _mm_unpackhi_epi32(m1, m3);
+ tt = _mm_unpacklo_epi32(m2, t3);
+ t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
+ g2(&rows[0], &rows[1], &rows[2], &rows[3], t3);
undiagonalize(&rows[0], &rows[2], &rows[3]);
-
- // round 6
- t0 = _mm_unpackhi_epi32(m0, m1);
- t1 = _mm_unpacklo_epi32(m0, m2);
- buf = _mm_unpacklo_epi64(t0, t1);
- g1(&rows[0], &rows[1], &rows[2], &rows[3], buf);
- t0 = _mm_srli_si128(m2, 4);
- t1 = _mm_blend_epi16(m0, m3, 0x03);
- buf = _mm_blend_epi16(t1, t0, 0x3C);
- g2(&rows[0], &rows[1], &rows[2], &rows[3], buf);
+ m0 = t0;
+ m1 = t1;
+ m2 = t2;
+ m3 = t3;
+
+ // Round 6
+ t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
+ t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
+ g1(&rows[0], &rows[1], &rows[2], &rows[3], t0);
+ t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
+ tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
+ t1 = _mm_blend_epi16(tt, t1, 0xCC);
+ g2(&rows[0], &rows[1], &rows[2], &rows[3], t1);
diagonalize(&rows[0], &rows[2], &rows[3]);
- t0 = _mm_blend_epi16(m1, m0, 0x0C);
- t1 = _mm_srli_si128(m3, 4);
- t2 = _mm_blend_epi16(t0, t1, 0x30);
- buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2, 3, 0, 1));
- g1(&rows[0], &rows[1], &rows[2], &rows[3], buf);
- t0 = _mm_unpacklo_epi64(m2, m1);
- t1 = _mm_shuffle_epi32(m3, _MM_SHUFFLE(2, 0, 1, 0));
- t2 = _mm_srli_si128(t0, 4);
- buf = _mm_blend_epi16(t1, t2, 0x33);
- g2(&rows[0], &rows[1], &rows[2], &rows[3], buf);
+ t2 = _mm_unpacklo_epi64(m3, m1);
+ tt = _mm_blend_epi16(t2, m2, 0xC0);
+ t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
+ g1(&rows[0], &rows[1], &rows[2], &rows[3], t2);
+ t3 = _mm_unpackhi_epi32(m1, m3);
+ tt = _mm_unpacklo_epi32(m2, t3);
+ t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
+ g2(&rows[0], &rows[1], &rows[2], &rows[3], t3);
undiagonalize(&rows[0], &rows[2], &rows[3]);
-
- // round 7
- t0 = _mm_slli_si128(m1, 12);
- t1 = _mm_blend_epi16(m0, m3, 0x33);
- buf = _mm_blend_epi16(t1, t0, 0xC0);
- g1(&rows[0], &rows[1], &rows[2], &rows[3], buf);
- t0 = _mm_blend_epi16(m3, m2, 0x30);
- t1 = _mm_srli_si128(m1, 4);
- t2 = _mm_blend_epi16(t0, t1, 0x03);
- buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2, 1, 3, 0));
- g2(&rows[0], &rows[1], &rows[2], &rows[3], buf);
+ m0 = t0;
+ m1 = t1;
+ m2 = t2;
+ m3 = t3;
+
+ // Round 7
+ t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
+ t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
+ g1(&rows[0], &rows[1], &rows[2], &rows[3], t0);
+ t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
+ tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
+ t1 = _mm_blend_epi16(tt, t1, 0xCC);
+ g2(&rows[0], &rows[1], &rows[2], &rows[3], t1);
diagonalize(&rows[0], &rows[2], &rows[3]);
- t0 = _mm_unpacklo_epi64(m0, m2);
- t1 = _mm_srli_si128(m1, 4);
- buf =
- _mm_shuffle_epi32(_mm_blend_epi16(t0, t1, 0x0C), _MM_SHUFFLE(3, 1, 0, 2));
- g1(&rows[0], &rows[1], &rows[2], &rows[3], buf);
- t0 = _mm_unpackhi_epi32(m1, m2);
- t1 = _mm_unpackhi_epi64(m0, t0);
- buf = _mm_shuffle_epi32(t1, _MM_SHUFFLE(0, 1, 2, 3));
- g2(&rows[0], &rows[1], &rows[2], &rows[3], buf);
+ t2 = _mm_unpacklo_epi64(m3, m1);
+ tt = _mm_blend_epi16(t2, m2, 0xC0);
+ t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
+ g1(&rows[0], &rows[1], &rows[2], &rows[3], t2);
+ t3 = _mm_unpackhi_epi32(m1, m3);
+ tt = _mm_unpacklo_epi32(m2, t3);
+ t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
+ g2(&rows[0], &rows[1], &rows[2], &rows[3], t3);
undiagonalize(&rows[0], &rows[2], &rows[3]);
}
diff --git a/src/c/blake3_impl.h b/src/c/blake3_impl.h
index 9a44391..576ccf4 100644
--- a/src/c/blake3_impl.h
+++ b/src/c/blake3_impl.h
@@ -18,7 +18,8 @@
#define PARENT 4
#define ROOT 8
#define KEYED_HASH 16
-#define DERIVE_KEY 32
+#define DERIVE_KEY_CONTEXT 32
+#define DERIVE_KEY_MATERIAL 64
// This C implementation tries to support recent versions of GCC, Clang, and
// MSVC.
@@ -34,12 +35,12 @@ static const uint32_t IV[8] = {0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL,
static const uint8_t MSG_SCHEDULE[7][16] = {
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
- {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
- {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4},
- {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8},
- {9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
- {2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9},
- {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11},
+ {2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8},
+ {3, 4, 10, 12, 13, 2, 7, 14, 6, 5, 9, 0, 11, 15, 8, 1},
+ {10, 7, 12, 9, 14, 3, 13, 15, 4, 0, 11, 2, 5, 8, 1, 6},
+ {12, 13, 9, 11, 15, 10, 14, 8, 7, 2, 5, 3, 0, 1, 6, 4},
+ {9, 14, 11, 5, 8, 12, 15, 1, 13, 3, 0, 10, 2, 6, 4, 7},
+ {11, 15, 5, 0, 1, 9, 8, 6, 14, 10, 2, 12, 3, 4, 7, 13},
};
// Count the number of 1 bits.
@@ -80,53 +81,17 @@ INLINE void load_key_words(const uint8_t key[BLAKE3_KEY_LEN],
key_words[7] = load32(&key[7 * 4]);
}
-// Declarations for implementation-specific functions.
-void blake3_compress_in_place_portable(uint32_t cv[8],
- const uint8_t block[BLAKE3_BLOCK_LEN],
- uint8_t block_len, uint64_t counter,
- uint8_t flags);
-void blake3_compress_in_place_sse41(uint32_t cv[8],
- const uint8_t block[BLAKE3_BLOCK_LEN],
- uint8_t block_len, uint64_t counter,
- uint8_t flags);
-void blake3_compress_in_place_avx512(uint32_t cv[8],
- const uint8_t block[BLAKE3_BLOCK_LEN],
- uint8_t block_len, uint64_t counter,
- uint8_t flags);
-void blake3_compress_xof_portable(const uint32_t cv[8],
- const uint8_t block[BLAKE3_BLOCK_LEN],
- uint8_t block_len, uint64_t counter,
- uint8_t flags, uint8_t out[64]);
-void blake3_compress_xof_sse41(const uint32_t cv[8],
- const uint8_t block[BLAKE3_BLOCK_LEN],
- uint8_t block_len, uint64_t counter,
- uint8_t flags, uint8_t out[64]);
-void blake3_compress_xof_avx512(const uint32_t cv[8],
- const uint8_t block[BLAKE3_BLOCK_LEN],
- uint8_t block_len, uint64_t counter,
- uint8_t flags, uint8_t out[64]);
-void blake3_hash_many_portable(const uint8_t *const *inputs, size_t num_inputs,
- size_t blocks, const uint32_t key[8],
- uint64_t counter, bool increment_counter,
- uint8_t flags, uint8_t flags_start,
- uint8_t flags_end, uint8_t *out);
-void blake3_hash_many_sse41(const uint8_t *const *inputs, size_t num_inputs,
- size_t blocks, const uint32_t key[8],
- uint64_t counter, bool increment_counter,
- uint8_t flags, uint8_t flags_start,
- uint8_t flags_end, uint8_t *out);
-void blake3_hash_many_avx2(const uint8_t *const *inputs, size_t num_inputs,
- size_t blocks, const uint32_t key[8],
- uint64_t counter, bool increment_counter,
- uint8_t flags, uint8_t flags_start,
- uint8_t flags_end, uint8_t *out);
-void blake3_hash_many_avx512(const uint8_t *const *inputs, size_t num_inputs,
- size_t blocks, const uint32_t key[8],
- uint64_t counter, bool increment_counter,
- uint8_t flags, uint8_t flags_start,
- uint8_t flags_end, uint8_t *out);
-void blake3_hash_many_neon(const uint8_t *const *inputs, size_t num_inputs,
- size_t blocks, const uint32_t key[8],
- uint64_t counter, bool increment_counter,
- uint8_t flags, uint8_t flags_start,
- uint8_t flags_end, uint8_t *out);
+void blake3_compress_in_place(uint32_t cv[8],
+ const uint8_t block[BLAKE3_BLOCK_LEN],
+ uint8_t block_len, uint64_t counter,
+ uint8_t flags);
+
+void blake3_compress_xof(const uint32_t cv[8],
+ const uint8_t block[BLAKE3_BLOCK_LEN],
+ uint8_t block_len, uint64_t counter, uint8_t flags,
+ uint8_t out[64]);
+
+void blake3_hash_many(const uint8_t *const *inputs, size_t num_inputs,
+ size_t blocks, const uint32_t key[8], uint64_t counter,
+ bool increment_counter, uint8_t flags,
+ uint8_t flags_start, uint8_t flags_end, uint8_t *out);
diff --git a/src/c/blake3_neon.c b/src/c/blake3_neon.c
index 7335c19..46691f5 100644
--- a/src/c/blake3_neon.c
+++ b/src/c/blake3_neon.c
@@ -290,6 +290,11 @@ void blake3_hash4_neon(const uint8_t *const *inputs, size_t blocks,
* ----------------------------------------------------------------------------
*/
+void blake3_compress_in_place_portable(uint32_t cv[8],
+ const uint8_t block[BLAKE3_BLOCK_LEN],
+ uint8_t block_len, uint64_t counter,
+ uint8_t flags);
+
INLINE void hash_one_neon(const uint8_t *input, size_t blocks,
const uint32_t key[8], uint64_t counter,
uint8_t flags, uint8_t flags_start, uint8_t flags_end,
diff --git a/src/lib.rs b/src/lib.rs
index daebaa8..4da9f17 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -97,12 +97,12 @@ const IV: &CVWords = &[
const MSG_SCHEDULE: [[usize; 16]; 7] = [
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
- [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3],
- [11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4],
- [7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8],
- [9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13],
- [2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9],
- [12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11],
+ [2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8],
+ [3, 4, 10, 12, 13, 2, 7, 14, 6, 5, 9, 0, 11, 15, 8, 1],
+ [10, 7, 12, 9, 14, 3, 13, 15, 4, 0, 11, 2, 5, 8, 1, 6],
+ [12, 13, 9, 11, 15, 10, 14, 8, 7, 2, 5, 3, 0, 1, 6, 4],
+ [9, 14, 11, 5, 8, 12, 15, 1, 13, 3, 0, 10, 2, 6, 4, 7],
+ [11, 15, 5, 0, 1, 9, 8, 6, 14, 10, 2, 12, 3, 4, 7, 13],
];
// These are the internal flags that we use to domain separate root/non-root,
diff --git a/src/sse41.rs b/src/sse41.rs
index 94f1272..70925c6 100644
--- a/src/sse41.rs
+++ b/src/sse41.rs
@@ -73,34 +73,34 @@ unsafe fn rot7(a: __m128i) -> __m128i {
#[inline(always)]
unsafe fn g1(
+ row0: &mut __m128i,
row1: &mut __m128i,
row2: &mut __m128i,
row3: &mut __m128i,
- row4: &mut __m128i,
m: __m128i,
) {
- *row1 = add(add(*row1, m), *row2);
- *row4 = xor(*row4, *row1);
- *row4 = rot16(*row4);
- *row3 = add(*row3, *row4);
- *row2 = xor(*row2, *row3);
- *row2 = rot12(*row2);
+ *row0 = add(add(*row0, m), *row1);
+ *row3 = xor(*row3, *row0);
+ *row3 = rot16(*row3);
+ *row2 = add(*row2, *row3);
+ *row1 = xor(*row1, *row2);
+ *row1 = rot12(*row1);
}
#[inline(always)]
unsafe fn g2(
+ row0: &mut __m128i,
row1: &mut __m128i,
row2: &mut __m128i,
row3: &mut __m128i,
- row4: &mut __m128i,
m: __m128i,
) {
- *row1 = add(add(*row1, m), *row2);
- *row4 = xor(*row4, *row1);
- *row4 = rot8(*row4);
- *row3 = add(*row3, *row4);
- *row2 = xor(*row2, *row3);
- *row2 = rot7(*row2);
+ *row0 = add(add(*row0, m), *row1);
+ *row3 = xor(*row3, *row0);
+ *row3 = rot8(*row3);
+ *row2 = add(*row2, *row3);
+ *row1 = xor(*row1, *row2);
+ *row1 = rot7(*row1);
}
// Adapted from https://github.com/rust-lang-nursery/stdsimd/pull/479.
@@ -110,21 +110,31 @@ macro_rules! _MM_SHUFFLE {
};
}
-// Note the optimization here of leaving row2 as the unrotated row, rather than
-// row1. All the message loads below are adjusted to compensate for this. See
+macro_rules! shuffle2 {
+ ($a:expr, $b:expr, $c:expr) => {
+ _mm_castps_si128(_mm_shuffle_ps(
+ _mm_castsi128_ps($a),
+ _mm_castsi128_ps($b),
+ $c,
+ ))
+ };
+}
+
+// Note the optimization here of leaving row1 as the unrotated row, rather than
+// row0. All the message loads below are adjusted to compensate for this. See
// discussion at https://github.com/sneves/blake2-avx2/pull/4
#[inline(always)]
-unsafe fn diagonalize(row1: &mut __m128i, row3: &mut __m128i, row4: &mut __m128i) {
- *row1 = _mm_shuffle_epi32(*row1, _MM_SHUFFLE!(2, 1, 0, 3));
- *row4 = _mm_shuffle_epi32(*row4, _MM_SHUFFLE!(1, 0, 3, 2));
- *row3 = _mm_shuffle_epi32(*row3, _MM_SHUFFLE!(0, 3, 2, 1));
+unsafe fn diagonalize(row0: &mut __m128i, row2: &mut __m128i, row3: &mut __m128i) {
+ *row0 = _mm_shuffle_epi32(*row0, _MM_SHUFFLE!(2, 1, 0, 3));
+ *row3 = _mm_shuffle_epi32(*row3, _MM_SHUFFLE!(1, 0, 3, 2));
+ *row2 = _mm_shuffle_epi32(*row2, _MM_SHUFFLE!(0, 3, 2, 1));
}
#[inline(always)]
-unsafe fn undiagonalize(row1: &mut __m128i, row3: &mut __m128i, row4: &mut __m128i) {
- *row1 = _mm_shuffle_epi32(*row1, _MM_SHUFFLE!(0, 3, 2, 1));
- *row4 = _mm_shuffle_epi32(*row4, _MM_SHUFFLE!(1, 0, 3, 2));
- *row3 = _mm_shuffle_epi32(*row3, _MM_SHUFFLE!(2, 1, 0, 3));
+unsafe fn undiagonalize(row0: &mut __m128i, row2: &mut __m128i, row3: &mut __m128i) {
+ *row0 = _mm_shuffle_epi32(*row0, _MM_SHUFFLE!(0, 3, 2, 1));
+ *row3 = _mm_shuffle_epi32(*row3, _MM_SHUFFLE!(1, 0, 3, 2));
+ *row2 = _mm_shuffle_epi32(*row2, _MM_SHUFFLE!(2, 1, 0, 3));
}
#[inline(always)]
@@ -135,180 +145,182 @@ unsafe fn compress_pre(
counter: u64,
flags: u8,
) -> [__m128i; 4] {
- let row1 = &mut loadu(cv.as_ptr().add(0) as *const u8);
- let row2 = &mut loadu(cv.as_ptr().add(4) as *const u8);
- let row3 = &mut set4(IV[0], IV[1], IV[2], IV[3]);
- let row4 = &mut set4(
+ let row0 = &mut loadu(cv.as_ptr().add(0) as *const u8);
+ let row1 = &mut loadu(cv.as_ptr().add(4) as *const u8);
+ let row2 = &mut set4(IV[0], IV[1], IV[2], IV[3]);
+ let row3 = &mut set4(
counter_low(counter),
counter_high(counter),
block_len as u32,
flags as u32,
);
- let m0 = loadu(block.as_ptr().add(0 * 4 * DEGREE));
- let m1 = loadu(block.as_ptr().add(1 * 4 * DEGREE));
- let m2 = loadu(block.as_ptr().add(2 * 4 * DEGREE));
- let m3 = loadu(block.as_ptr().add(3 * 4 * DEGREE));
-
- // round 1
- let buf = _mm_castps_si128(_mm_shuffle_ps(
- _mm_castsi128_ps(m0),
- _mm_castsi128_ps(m1),
- _MM_SHUFFLE!(2, 0, 2, 0),
- ));
- g1(row1, row2, row3, row4, buf);
- let buf = _mm_castps_si128(_mm_shuffle_ps(
- _mm_castsi128_ps(m0),
- _mm_castsi128_ps(m1),
- _MM_SHUFFLE!(3, 1, 3, 1),
- ));
- g2(row1, row2, row3, row4, buf);
- diagonalize(row1, row3, row4);
- let t0 = _mm_shuffle_epi32(m2, _MM_SHUFFLE!(3, 2, 0, 1));
- let t1 = _mm_shuffle_epi32(m3, _MM_SHUFFLE!(0, 1, 3, 2));
- let buf = _mm_blend_epi16(t0, t1, 0xC3);
- g1(row1, row2, row3, row4, buf);
- let t0 = _mm_blend_epi16(t0, t1, 0x3C);
- let buf = _mm_shuffle_epi32(t0, _MM_SHUFFLE!(2, 3, 0, 1));
- g2(row1, row2, row3, row4, buf);
- undiagonalize(row1, row3, row4);
-
- // round 2
- let t0 = _mm_blend_epi16(m1, m2, 0x0C);
- let t1 = _mm_slli_si128(m3, 4);
- let t2 = _mm_blend_epi16(t0, t1, 0xF0);
- let buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE!(2, 1, 0, 3));
- g1(row1, row2, row3, row4, buf);
- let t0 = _mm_shuffle_epi32(m2, _MM_SHUFFLE!(0, 0, 2, 0));
- let t1 = _mm_blend_epi16(m1, m3, 0xC0);
- let t2 = _mm_blend_epi16(t0, t1, 0xF0);
- let buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE!(2, 3, 0, 1));
- g2(row1, row2, row3, row4, buf);
- diagonalize(row1, row3, row4);
- let t0 = _mm_slli_si128(m1, 4);
- let t1 = _mm_blend_epi16(m2, t0, 0x30);
- let t2 = _mm_blend_epi16(m0, t1, 0xF0);
- let buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE!(3, 0, 1, 2));
- g1(row1, row2, row3, row4, buf);
- let t0 = _mm_unpackhi_epi32(m0, m1);
- let t1 = _mm_slli_si128(m3, 4);
- let t2 = _mm_blend_epi16(t0, t1, 0x0C);
- let buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE!(3, 0, 1, 2));
- g2(row1, row2, row3, row4, buf);
- undiagonalize(row1, row3, row4);
-
- // round 3
- let t0 = _mm_unpackhi_epi32(m2, m3);
- let t1 = _mm_blend_epi16(m3, m1, 0x0C);
- let t2 = _mm_blend_epi16(t0, t1, 0x0F);
- let buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE!(3, 1, 0, 2));
- g1(row1, row2, row3, row4, buf);
- let t0 = _mm_unpacklo_epi32(m2, m0);
- let t1 = _mm_blend_epi16(t0, m0, 0xF0);
- let t2 = _mm_slli_si128(m3, 8);
- let buf = _mm_blend_epi16(t1, t2, 0xC0);
- g2(row1, row2, row3, row4, buf);
- diagonalize(row1, row3, row4);
- let t0 = _mm_blend_epi16(m0, m2, 0x3C);
- let t1 = _mm_srli_si128(m1, 12);
- let t2 = _mm_blend_epi16(t0, t1, 0x03);
- let buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE!(0, 3, 2, 1));
- g1(row1, row2, row3, row4, buf);
- let t0 = _mm_slli_si128(m3, 4);
- let t1 = _mm_blend_epi16(m0, m1, 0x33);
- let t2 = _mm_blend_epi16(t1, t0, 0xC0);
- let buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE!(1, 2, 3, 0));
- g2(row1, row2, row3, row4, buf);
- undiagonalize(row1, row3, row4);
-
- // round 4
- let t0 = _mm_unpackhi_epi32(m0, m1);
- let t1 = _mm_unpackhi_epi32(t0, m2);
- let t2 = _mm_blend_epi16(t1, m3, 0x0C);
- let buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE!(3, 1, 0, 2));
- g1(row1, row2, row3, row4, buf);
- let t0 = _mm_slli_si128(m2, 8);
- let t1 = _mm_blend_epi16(m3, m0, 0x0C);
- let t2 = _mm_blend_epi16(t1, t0, 0xC0);
- let buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE!(2, 0, 1, 3));
- g2(row1, row2, row3, row4, buf);
- diagonalize(row1, row3, row4);
- let t0 = _mm_blend_epi16(m0, m1, 0x0F);
- let t1 = _mm_blend_epi16(t0, m3, 0xC0);
- let buf = _mm_shuffle_epi32(t1, _MM_SHUFFLE!(0, 1, 2, 3));
- g1(row1, row2, row3, row4, buf);
- let t0 = _mm_alignr_epi8(m0, m1, 4);
- let buf = _mm_blend_epi16(t0, m2, 0x33);
- g2(row1, row2, row3, row4, buf);
- undiagonalize(row1, row3, row4);
-
- // round 5
- let t0 = _mm_unpacklo_epi64(m1, m2);
- let t1 = _mm_unpackhi_epi64(m0, m2);
- let t2 = _mm_blend_epi16(t0, t1, 0x33);
- let buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE!(2, 0, 1, 3));
- g1(row1, row2, row3, row4, buf);
- let t0 = _mm_unpackhi_epi64(m1, m3);
- let t1 = _mm_unpacklo_epi64(m0, m1);
- let buf = _mm_blend_epi16(t0, t1, 0x33);
- g2(row1, row2, row3, row4, buf);
- diagonalize(row1, row3, row4);
- let t0 = _mm_unpackhi_epi64(m3, m1);
- let t1 = _mm_unpackhi_epi64(m2, m0);
- let t2 = _mm_blend_epi16(t1, t0, 0x33);
- let buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE!(2, 1, 0, 3));
- g1(row1, row2, row3, row4, buf);
- let t0 = _mm_blend_epi16(m0, m2, 0x03);
- let t1 = _mm_slli_si128(t0, 8);
- let t2 = _mm_blend_epi16(t1, m3, 0x0F);
- let buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE!(2, 0, 3, 1));
- g2(row1, row2, row3, row4, buf);
- undiagonalize(row1, row3, row4);
-
- // round 6
- let t0 = _mm_unpackhi_epi32(m0, m1);
- let t1 = _mm_unpacklo_epi32(m0, m2);
- let buf = _mm_unpacklo_epi64(t0, t1);
- g1(row1, row2, row3, row4, buf);
- let t0 = _mm_srli_si128(m2, 4);
- let t1 = _mm_blend_epi16(m0, m3, 0x03);
- let buf = _mm_blend_epi16(t1, t0, 0x3C);
- g2(row1, row2, row3, row4, buf);
- diagonalize(row1, row3, row4);
- let t0 = _mm_blend_epi16(m1, m0, 0x0C);
- let t1 = _mm_srli_si128(m3, 4);
- let t2 = _mm_blend_epi16(t0, t1, 0x30);
- let buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE!(2, 3, 0, 1));
- g1(row1, row2, row3, row4, buf);
- let t0 = _mm_unpacklo_epi64(m2, m1);
- let t1 = _mm_shuffle_epi32(m3, _MM_SHUFFLE!(2, 0, 1, 0));
- let t2 = _mm_srli_si128(t0, 4);
- let buf = _mm_blend_epi16(t1, t2, 0x33);
- g2(row1, row2, row3, row4, buf);
- undiagonalize(row1, row3, row4);
-
- // round 7
- let t0 = _mm_slli_si128(m1, 12);
- let t1 = _mm_blend_epi16(m0, m3, 0x33);
- let buf = _mm_blend_epi16(t1, t0, 0xC0);
- g1(row1, row2, row3, row4, buf);
- let t0 = _mm_blend_epi16(m3, m2, 0x30);
- let t1 = _mm_srli_si128(m1, 4);
- let t2 = _mm_blend_epi16(t0, t1, 0x03);
- let buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE!(2, 1, 3, 0));
- g2(row1, row2, row3, row4, buf);
- diagonalize(row1, row3, row4);
- let t0 = _mm_unpacklo_epi64(m0, m2);
- let t1 = _mm_srli_si128(m1, 4);
- let buf = _mm_shuffle_epi32(_mm_blend_epi16(t0, t1, 0x0C), _MM_SHUFFLE!(3, 1, 0, 2));
- g1(row1, row2, row3, row4, buf);
- let t0 = _mm_unpackhi_epi32(m1, m2);
- let t1 = _mm_unpackhi_epi64(m0, t0);
- let buf = _mm_shuffle_epi32(t1, _MM_SHUFFLE!(0, 1, 2, 3));
- g2(row1, row2, row3, row4, buf);
- undiagonalize(row1, row3, row4);
-
- [*row1, *row2, *row3, *row4]
+ let mut m0 = loadu(block.as_ptr().add(0 * 4 * DEGREE));
+ let mut m1 = loadu(block.as_ptr().add(1 * 4 * DEGREE));
+ let mut m2 = loadu(block.as_ptr().add(2 * 4 * DEGREE));
+ let mut m3 = loadu(block.as_ptr().add(3 * 4 * DEGREE));
+
+ let mut t0;
+ let mut t1;
+ let mut t2;
+ let mut t3;
+ let mut tt;
+
+ // Round 1. The first round permutes the message words from the original
+ // input order, into the groups that get mixed in parallel.
+ t0 = shuffle2!(m0, m1, _MM_SHUFFLE!(2, 0, 2, 0)); // 6 4 2 0
+ g1(row0, row1, row2, row3, t0);
+ t1 = shuffle2!(m0, m1, _MM_SHUFFLE!(3, 1, 3, 1)); // 7 5 3 1
+ g2(row0, row1, row2, row3, t1);
+ diagonalize(row0, row2, row3);
+ t2 = shuffle2!(m2, m3, _MM_SHUFFLE!(2, 0, 2, 0)); // 14 12 10 8
+ t2 = _mm_shuffle_epi32(t2, _MM_SHUFFLE!(2, 1, 0, 3)); // 12 10 8 14
+ g1(row0, row1, row2, row3, t2);
+ t3 = shuffle2!(m2, m3, _MM_SHUFFLE!(3, 1, 3, 1)); // 15 13 11 9
+ t3 = _mm_shuffle_epi32(t3, _MM_SHUFFLE!(2, 1, 0, 3)); // 13 11 9 15
+ g2(row0, row1, row2, row3, t3);
+ undiagonalize(row0, row2, row3);
+ m0 = t0;
+ m1 = t1;
+ m2 = t2;
+ m3 = t3;
+
+ // Round 2. This round and all following rounds apply a fixed permutation
+ // to the message words from the round before.
+ t0 = shuffle2!(m0, m1, _MM_SHUFFLE!(3, 1, 1, 2));
+ t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE!(0, 3, 2, 1));
+ g1(row0, row1, row2, row3, t0);
+ t1 = shuffle2!(m2, m3, _MM_SHUFFLE!(3, 3, 2, 2));
+ tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE!(0, 0, 3, 3));
+ t1 = _mm_blend_epi16(tt, t1, 0xCC);
+ g2(row0, row1, row2, row3, t1);
+ diagonalize(row0, row2, row3);
+ t2 = _mm_unpacklo_epi64(m3, m1);
+ tt = _mm_blend_epi16(t2, m2, 0xC0);
+ t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE!(1, 3, 2, 0));
+ g1(row0, row1, row2, row3, t2);
+ t3 = _mm_unpackhi_epi32(m1, m3);
+ tt = _mm_unpacklo_epi32(m2, t3);
+ t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE!(0, 1, 3, 2));
+ g2(row0, row1, row2, row3, t3);
+ undiagonalize(row0, row2, row3);
+ m0 = t0;
+ m1 = t1;
+ m2 = t2;
+ m3 = t3;
+
+ // Round 3
+ t0 = shuffle2!(m0, m1, _MM_SHUFFLE!(3, 1, 1, 2));
+ t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE!(0, 3, 2, 1));
+ g1(row0, row1, row2, row3, t0);
+ t1 = shuffle2!(m2, m3, _MM_SHUFFLE!(3, 3, 2, 2));
+ tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE!(0, 0, 3, 3));
+ t1 = _mm_blend_epi16(tt, t1, 0xCC);
+ g2(row0, row1, row2, row3, t1);
+ diagonalize(row0, row2, row3);
+ t2 = _mm_unpacklo_epi64(m3, m1);
+ tt = _mm_blend_epi16(t2, m2, 0xC0);
+ t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE!(1, 3, 2, 0));
+ g1(row0, row1, row2, row3, t2);
+ t3 = _mm_unpackhi_epi32(m1, m3);
+ tt = _mm_unpacklo_epi32(m2, t3);
+ t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE!(0, 1, 3, 2));
+ g2(row0, row1, row2, row3, t3);
+ undiagonalize(row0, row2, row3);
+ m0 = t0;
+ m1 = t1;
+ m2 = t2;
+ m3 = t3;
+
+ // Round 4
+ t0 = shuffle2!(m0, m1, _MM_SHUFFLE!(3, 1, 1, 2));
+ t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE!(0, 3, 2, 1));
+ g1(row0, row1, row2, row3, t0);
+ t1 = shuffle2!(m2, m3, _MM_SHUFFLE!(3, 3, 2, 2));
+ tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE!(0, 0, 3, 3));
+ t1 = _mm_blend_epi16(tt, t1, 0xCC);
+ g2(row0, row1, row2, row3, t1);
+ diagonalize(row0, row2, row3);
+ t2 = _mm_unpacklo_epi64(m3, m1);
+ tt = _mm_blend_epi16(t2, m2, 0xC0);
+ t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE!(1, 3, 2, 0));
+ g1(row0, row1, row2, row3, t2);
+ t3 = _mm_unpackhi_epi32(m1, m3);
+ tt = _mm_unpacklo_epi32(m2, t3);
+ t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE!(0, 1, 3, 2));
+ g2(row0, row1, row2, row3, t3);
+ undiagonalize(row0, row2, row3);
+ m0 = t0;
+ m1 = t1;
+ m2 = t2;
+ m3 = t3;
+
+ // Round 5
+ t0 = shuffle2!(m0, m1, _MM_SHUFFLE!(3, 1, 1, 2));
+ t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE!(0, 3, 2, 1));
+ g1(row0, row1, row2, row3, t0);
+ t1 = shuffle2!(m2, m3, _MM_SHUFFLE!(3, 3, 2, 2));
+ tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE!(0, 0, 3, 3));
+ t1 = _mm_blend_epi16(tt, t1, 0xCC);
+ g2(row0, row1, row2, row3, t1);
+ diagonalize(row0, row2, row3);
+ t2 = _mm_unpacklo_epi64(m3, m1);
+ tt = _mm_blend_epi16(t2, m2, 0xC0);
+ t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE!(1, 3, 2, 0));
+ g1(row0, row1, row2, row3, t2);
+ t3 = _mm_unpackhi_epi32(m1, m3);
+ tt = _mm_unpacklo_epi32(m2, t3);
+ t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE!(0, 1, 3, 2));
+ g2(row0, row1, row2, row3, t3);
+ undiagonalize(row0, row2, row3);
+ m0 = t0;
+ m1 = t1;
+ m2 = t2;
+ m3 = t3;
+
+ // Round 6
+ t0 = shuffle2!(m0, m1, _MM_SHUFFLE!(3, 1, 1, 2));
+ t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE!(0, 3, 2, 1));
+ g1(row0, row1, row2, row3, t0);
+ t1 = shuffle2!(m2, m3, _MM_SHUFFLE!(3, 3, 2, 2));
+ tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE!(0, 0, 3, 3));
+ t1 = _mm_blend_epi16(tt, t1, 0xCC);
+ g2(row0, row1, row2, row3, t1);
+ diagonalize(row0, row2, row3);
+ t2 = _mm_unpacklo_epi64(m3, m1);
+ tt = _mm_blend_epi16(t2, m2, 0xC0);
+ t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE!(1, 3, 2, 0));
+ g1(row0, row1, row2, row3, t2);
+ t3 = _mm_unpackhi_epi32(m1, m3);
+ tt = _mm_unpacklo_epi32(m2, t3);
+ t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE!(0, 1, 3, 2));
+ g2(row0, row1, row2, row3, t3);
+ undiagonalize(row0, row2, row3);
+ m0 = t0;
+ m1 = t1;
+ m2 = t2;
+ m3 = t3;
+
+ // Round 7
+ t0 = shuffle2!(m0, m1, _MM_SHUFFLE!(3, 1, 1, 2));
+ t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE!(0, 3, 2, 1));
+ g1(row0, row1, row2, row3, t0);
+ t1 = shuffle2!(m2, m3, _MM_SHUFFLE!(3, 3, 2, 2));
+ tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE!(0, 0, 3, 3));
+ t1 = _mm_blend_epi16(tt, t1, 0xCC);
+ g2(row0, row1, row2, row3, t1);
+ diagonalize(row0, row2, row3);
+ t2 = _mm_unpacklo_epi64(m3, m1);
+ tt = _mm_blend_epi16(t2, m2, 0xC0);
+ t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE!(1, 3, 2, 0));
+ g1(row0, row1, row2, row3, t2);
+ t3 = _mm_unpackhi_epi32(m1, m3);
+ tt = _mm_unpacklo_epi32(m2, t3);
+ t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE!(0, 1, 3, 2));
+ g2(row0, row1, row2, row3, t3);
+ undiagonalize(row0, row2, row3);
+
+ [*row0, *row1, *row2, *row3]
}
#[target_feature(enable = "sse4.1")]
@@ -319,9 +331,9 @@ pub unsafe fn compress_in_place(
counter: u64,
flags: u8,
) {
- let [row1, row2, row3, row4] = compress_pre(cv, block, block_len, counter, flags);
- storeu(xor(row1, row3), cv.as_mut_ptr().add(0) as *mut u8);
- storeu(xor(row2, row4), cv.as_mut_ptr().add(4) as *mut u8);
+ let [row0, row1, row2, row3] = compress_pre(cv, block, block_len, counter, flags);
+ storeu(xor(row0, row2), cv.as_mut_ptr().add(0) as *mut u8);
+ storeu(xor(row1, row3), cv.as_mut_ptr().add(4) as *mut u8);
}
#[target_feature(enable = "sse4.1")]
@@ -332,13 +344,13 @@ pub unsafe fn compress_xof(
counter: u64,
flags: u8,
) -> [u8; 64] {
- let [mut row1, mut row2, mut row3, mut row4] =
+ let [mut row0, mut row1, mut row2, mut row3] =
compress_pre(cv, block, block_len, counter, flags);
+ row0 = xor(row0, row2);
row1 = xor(row1, row3);
- row2 = xor(row2, row4);
- row3 = xor(row3, loadu(cv.as_ptr().add(0) as *const u8));
- row4 = xor(row4, loadu(cv.as_ptr().add(4) as *const u8));
- core::mem::transmute([row1, row2, row3, row4])
+ row2 = xor(row2, loadu(cv.as_ptr().add(0) as *const u8));
+ row3 = xor(row3, loadu(cv.as_ptr().add(4) as *const u8));
+ core::mem::transmute([row0, row1, row2, row3])
}
#[inline(always)]
diff --git a/test_vectors/test_vectors.json b/test_vectors/test_vectors.json
index 4b6ce2d..a628815 100644
--- a/test_vectors/test_vectors.json
+++ b/test_vectors/test_vectors.json
@@ -6,127 +6,127 @@
"input_len": 0,
"hash": "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262e00f03e7b69af26b7faaf09fcd333050338ddfe085b8cc869ca98b206c08243a26f5487789e8f660afe6c99ef9e0c52b92e7393024a80459cf91f476f9ffdbda7001c22e159b402631f277ca96f2defdf1078282314e763699a31c5363165421cce14d",
"keyed_hash": "92b2b75604ed3c761f9d6f62392c8a9227ad0ea3f09573e783f1498a4ed60d26b18171a2f22a4b94822c701f107153dba24918c4bae4d2945c20ece13387627d3b73cbf97b797d5e59948c7ef788f54372df45e45e4293c7dc18c1d41144a9758be58960856be1eabbe22c2653190de560ca3b2ac4aa692a9210694254c371e851bc8f",
- "derive_key": "38b6ca03a5d7cdce36340d871c2a75a9e5238fb5ffb50d38d004c8f57b024781a6bd4091d4c71c812d7a2cedce497fbb9b12e2295bdb4e4b718baf07628a905fef58abde0d134f7f246f33f38c79a00be2372648ad3e078a9b59571e24d4534df9b402f2290f3513d9c96e1ea5ce72dfe185de12e07480670c8b43bb557c7d92f6e660"
+ "derive_key": "2cc39783c223154fea8dfb7c1b1660f2ac2dcbd1c1de8277b0b0dd39b7e50d7d905630c8be290dfcf3e6842f13bddd573c098c3f17361f1f206b8cad9d088aa4a3f746752c6b0ce6a83b0da81d59649257cdf8eb3e9f7d4998e41021fac119deefb896224ac99f860011f73609e6e0e4540f93b273e56547dfd3aa1a035ba6689d89a0"
},
{
"input_len": 1,
"hash": "2d3adedff11b61f14c886e35afa036736dcd87a74d27b5c1510225d0f592e213c3a6cb8bf623e20cdb535f8d1a5ffb86342d9c0b64aca3bce1d31f60adfa137b358ad4d79f97b47c3d5e79f179df87a3b9776ef8325f8329886ba42f07fb138bb502f4081cbcec3195c5871e6c23e2cc97d3c69a613eba131e5f1351f3f1da786545e5",
"keyed_hash": "6d7878dfff2f485635d39013278ae14f1454b8c0a3a2d34bc1ab38228a80c95b6568c0490609413006fbd428eb3fd14e7756d90f73a4725fad147f7bf70fd61c4e0cf7074885e92b0e3f125978b4154986d4fb202a3f331a3fb6cf349a3a70e49990f98fe4289761c8602c4e6ab1138d31d3b62218078b2f3ba9a88e1d08d0dd4cea11",
- "derive_key": "d47b96d469adb5569625dc996601a81dbbcad83eefce2b6c072a8b6514a1932486fe8d78ea01159ebc047a83f06d2268919d782b6110bd62e14eeeacd83ae52904565c0a3abd426696f8ea8e0763eb5d2420a002da4333bd7a2d00224b31e0451101cd1baf02071162e925348fbdf863d738b9f3d1d7b26c7fb91ab4235cd5c3927a45"
+ "derive_key": "b3e2e340a117a499c6cf2398a19ee0d29cca2bb7404c73063382693bf66cb06c5827b91bf889b6b97c5477f535361caefca0b5d8c4746441c57617111933158950670f9aa8a05d791daae10ac683cbef8faf897c84e6114a59d2173c3f417023a35d6983f2c7dfa57e7fc559ad751dbfb9ffab39c2ef8c4aafebc9ae973a64f0c76551"
},
{
"input_len": 1023,
- "hash": "9c93cdcb05286dc72e0c998c3055b0fa44cb2fa05a284bc597a4e216dfecf23b89e4ec3126046332385bc0f30bf83a80b37292c8376f6d2060a3ae721b96b22c71d4b3a1069e5e4aff53ba5c5c45bd8d007062bcc75084ec6befcb6e725c6d198652e6d97eaaa2b7c4c577ebf49a07c9b3b8d4d08a0f4038b7c4545936e95559916c5d",
- "keyed_hash": "682ff353dcb9322468d991f26d9268d3af0e82acf9b13b278e3f74393742e9ecd996c6e6d6f5a5e63b16ca6aec851ba9c9690115443109f8a6b131c518d657386a74d209756031884e716da99decd2c0d0defd35af60c3895f69cdee6e7d6ad1b26d8c7ec4ff1f3400834c52ade9678ca3d8317e3315daf79d85a64365211daf777e95",
- "derive_key": "0fa2580fa785d32e78cbdae63326618edc81774b888fd5d93702decc83fec2d8b5197e58ab83d81c202da40c9cc72eba2b44029429d773137aec50f8f10978685d2a9e6470844dcdac3fc20f178bf2375fbdbc0fb4dc6ecedee7671413236316976ffa26d10a584384bdab79ee0ad1b728c859673557c76a0d34248c3bd175249a41cf"
+ "hash": "10108970eeda3eb932baac1428c7a2163b0e924c9a9e25b35bba72b28f70bd11a182d27a591b05592b15607500e1e8dd56bc6c7fc063715b7a1d737df5bad3339c56778957d870eb9717b57ea3d9fb68d1b55127bba6a906a4a24bbd5acb2d123a37b28f9e9a81bbaae360d58f85e5fc9d75f7c370a0cc09b6522d9c8d822f2f28f485",
+ "keyed_hash": "c951ecdf03288d0fcc96ee3413563d8a6d3589547f2c2fb36d9786470f1b9d6e890316d2e6d8b8c25b0a5b2180f94fb1a158ef508c3cde45e2966bd796a696d3e13efd86259d756387d9becf5c8bf1ce2192b87025152907b6d8cc33d17826d8b7b9bc97e38c3c85108ef09f013e01c229c20a83d9e8efac5b37470da28575fd755a10",
+ "derive_key": "74a16c1c3d44368a86e1ca6df64be6a2f64cce8f09220787450722d85725dea59c413264404661e9e4d955409dfe4ad3aa487871bcd454ed12abfe2c2b1eb7757588cf6cb18d2eccad49e018c0d0fec323bec82bf1644c6325717d13ea712e6840d3e6e730d35553f59eff5377a9c350bcc1556694b924b858f329c44ee64b884ef00d"
},
{
"input_len": 1024,
- "hash": "b4342a9e49dceeb14dee0dcaefe92ac2fdd0cc37d880df8dce450bdb2daed817b00342c7db27ffbcfcf46eaecab2a7460d60c6812437ce101286c51df816934b3fbe2d8ee6a6db61556552fdd0992b906fd3f91f5eefe39abbba06d6dc9f3a02c8e4f8805443344016de267647a2806890f17b43e80a11d9d8e41e505e7dc10da250af",
- "keyed_hash": "71c777f92b6609192ccacba3f3672a44659b472b08a9972dc3e1d01ab83c54a71f050eae60ca5a295e393eba6e4f0358b5a053c131f39a9ef496411ecdeab76e43b5003c3ac968c83b0a5e791cab5fb390c5fc83164c1b450c2ef250a57361f06b41d1501111fc5b01eb8fb9c5efc2371547f0dca60dd80e0f00b4f8687f0150c18cf0",
- "derive_key": "63d82c2be58515ecdc23663f6351029cf63d3cbe447604d69eff2af20ad1aa1fc99fad1e371f00bcadfc50e93012c816227a411caa5fb857b935efd93adec613ee6f66cefc762b272653828b2f83ccfa186df7a0203ef3af9ccc6673c873534b160f4b1b60a373a095397def476596f12d751dffd77420e525e28863425608846257f1"
+ "hash": "42214739f095a406f3fc83deb889744ac00df831c10daa55189b5d121c855af71cf8107265ecdaf8505b95d8fcec83a98a6a96ea5109d2c179c47a387ffbb404756f6eeae7883b446b70ebb144527c2075ab8ab204c0086bb22b7c93d465efc57f8d917f0b385c6df265e77003b85102967486ed57db5c5ca170ba441427ed9afa684e",
+ "keyed_hash": "75c46f6f3d9eb4f55ecaaee480db732e6c2105546f1e675003687c31719c7ba4a78bc838c72852d4f49c864acb7adafe2478e824afe51c8919d06168414c265f298a8094b1ad813a9b8614acabac321f24ce61c5a5346eb519520d38ecc43e89b5000236df0597243e4d2493fd626730e2ba17ac4d8824d09d1a4a8f57b8227778e2de",
+ "derive_key": "7356cd7720d5b66b6d0697eb3177d9f8d73a4a5c5e968896eb6a6896843027066c23b601d3ddfb391e90d5c8eccdef4ae2a264bce9e612ba15e2bc9d654af1481b2e75dbabe615974f1070bba84d56853265a34330b4766f8e75edd1f4a1650476c10802f22b64bd3919d246ba20a17558bc51c199efdec67e80a227251808d8ce5bad"
},
{
"input_len": 1025,
- "hash": "016ec9e10c1dbae0ba41f75462379b0f94719c544d024eb7bb5ce76d4bb522259e0df61c24ac2ca8092a1340b8c9ca0975d4d35205403ecacb62285b4b00f139e99dadf514d64b4165d0f3fc1c290763371d2d8cdf10123cde3a3f0b341094aa15b893f16a42ddb0eb4d4b32821aee0b52b9e70b721714f917cd47334d995aa1624bea",
- "keyed_hash": "a3c4908e3580319031ac309266f4fdfb37f157116b60df6b0006ab055cf2a0c6c16c51d4169d72d170610d3414bdbad9e94c18c79a47c6b4dfca10510c3216b6b554c3c6390fed862d20155db21863d21ac03965c698a4c5f91cc75ea289a912c65e57373fde28d84d60f778c7f834230bc3324be2d4f1a527f3793aff84fd764114c5",
- "derive_key": "dab19462c9f5f8a2790a6297f518eb708528d2eb0bbddfeda5dcfb17b46144fa78649a6830cb67acb9bdabac5aba2815cb65682057a1d769d9aad682ac4d37d2fef6b83f6354942ade8b79125d1bec214519c2df9aaadb29aab1c8e7d12bb979ca454a8f828e6770c7432dd05ba273b74cf008e30c003b5747628e55fe9084b2f341a8"
+ "hash": "d00278ae47eb27b34faecf67b4fe263f82d5412916c1ffd97c8cb7fb814b8444f4c4a22b4b399155358a994e52bf255de60035742ec71bd08ac275a1b51cc6bfe332b0ef84b409108cda080e6269ed4b3e2c3f7d722aa4cdc98d16deb554e5627be8f955c98e1d5f9565a9194cad0c4285f93700062d9595adb992ae68ff12800ab67a",
+ "keyed_hash": "357dc55de0c7e382c900fd6e320acc04146be01db6a8ce7210b7189bd664ea69362396b77fdc0d2634a552970843722066c3c15902ae5097e00ff53f1e116f1cd5352720113a837ab2452cafbde4d54085d9cf5d21ca613071551b25d52e69d6c81123872b6f19cd3bc1333edf0c52b94de23ba772cf82636cff4542540a7738d5b930",
+ "derive_key": "effaa245f065fbf82ac186839a249707c3bddf6d3fdda22d1b95a3c970379bcb5d31013a167509e9066273ab6e2123bc835b408b067d88f96addb550d96b6852dad38e320b9d940f86db74d398c770f462118b35d2724efa13da97194491d96dd37c3c09cbef665953f2ee85ec83d88b88d11547a6f911c8217cca46defa2751e7f3ad"
},
{
"input_len": 2048,
- "hash": "c35f5b29380287b01c9b7c805a948a43e818aa409f2527601a9ce0ce9f10d50833964400fe36ac38994ea663326841a7f3fde074a19e355772776557e0e7e8a768d03c18c4f0704c49dd58a1de01cb202f228aff76c4bc29a0fb5528c67a84fb5dee5b599f5f84726e5892311009984d720413d91eabd66b3ef7aca60fccfbe22a6e7f",
- "keyed_hash": "1d527087c25ab15fd3f624036a39cb621b2383bd8dcb2597db4b23e5af39808119cf6005cfabb0625dc5247e69a0f8d703b564cd7952cce1a6e6eebebe056abfc045618db7f2c92a635cbe477dec98fc0816ec7d5a16f94cd6219cdcb3ebb3c7403500e089225f67d2281248bb6404f87b14112bcbd109f28ce42ab85bff8a68cab9bf",
- "derive_key": "96d23334001e61d3902b20a703ea203fb6045e7f74b1d17a0de7500ff328d00a19ef432f4dfdfc979ecd2585beab6f7a70d769163ae3e6b21d11fe7b4072b1505711ba041b690278f4bf7f1cb95325b410a118948f89b6100cda455965ccedf9af7dc1bb2fa606107ebe1d7486909608e97fd21a51e7412ec1970e9eda29fea87846e5"
+ "hash": "e776b6028c7cd22a4d0ba182a8bf62205d2ef576467e838ed6f2529b85fba24a9a60bf80001410ec9eea6698cd537939fad4749edd484cb541aced55cd9bf54764d063f23f6f1e32e12958ba5cfeb1bf618ad094266d4fc3c968c2088f677454c288c67ba0dba337b9d91c7e1ba586dc9a5bc2d5e90c14f53a8863ac75655461cea8f9",
+ "keyed_hash": "879cf1fa2ea0e79126cb1063617a05b6ad9d0b696d0d757cf053439f60a99dd10173b961cd574288194b23ece278c330fbb8585485e74967f31352a8183aa782b2b22f26cdcadb61eed1a5bc144b8198fbb0c13abbf8e3192c145d0a5c21633b0ef86054f42809df823389ee40811a5910dcbd1018af31c3b43aa55201ed4edaac74fe",
+ "derive_key": "7b2945cb4fef70885cc5d78a87bf6f6207dd901ff239201351ffac04e1088a23e2c11a1ebffcea4d80447867b61badb1383d842d4e79645d48dd82ccba290769caa7af8eaa1bd78a2a5e6e94fbdab78d9c7b74e894879f6a515257ccf6f95056f4e25390f24f6b35ffbb74b766202569b1d797f2d4bd9d17524c720107f985f4ddc583"
},
{
"input_len": 2049,
- "hash": "050250e2f40977b9439b90d81c5d0a8306c4d81cb0f2dc41f856aa5415950ac082e35eaaabd579c8b32a79b6ffa5e0d63fbbdeafcc887438760fe0fbd3a7dbf679f9b287da1b3d2ae5645ae7deda633f581beb255ba41b097f6f890946d55c770bb48f628a727492de73230e365b330af3e786878592c0a54ccf1d9040ef627f120cf5",
- "keyed_hash": "0ab87b84668045b57b7ad2311175b039ab7078e7b82c263d6f2595fe7215006b1a1ccad2d7afe150f4bd238d9fca73331d26749268ba0c54366fd7aca3d071277185824a2b2678141eb82d59394a27d3db522a9b40cc1364ac189a78f4c91122a67900838cd572d6a4f6531ad4497ce9e4505fdb59b444ed91e670de4116e66ff89ff7",
- "derive_key": "d5007bdb7a37c34a7b116b994828ded0a86766d80cba5852fc57e6293ae07fa77b7272dcb05d3ac48f05a556302f549da106a913839477d44bc50cb0def239a09ed8e4d06ddc2a5925971a86846b1a2247d3eaf8852036a99c55a676eb5670e9bcce9188b6d11a5831b236c2f32a0bcf728bac5117545838d49ce0238b33fa6c648b58"
+ "hash": "5f4d72f40d7a5f82b15ca2b2e44b1de3c2ef86c426c95c1af0b687952256303096de31d71d74103403822a2e0bc1eb193e7aecc9643a76b7bbc0c9f9c52e8783aae98764ca468962b5c2ec92f0c74eb5448d519713e09413719431c802f948dd5d90425a4ecdadece9eb178d80f26efccae630734dff63340285adec2aed3b51073ad3",
+ "keyed_hash": "9f29700902f7c86e514ddc4df1e3049f258b2472b6dd5267f61bf13983b78dd5f9a88abfefdfa1e00b418971f2b39c64ca621e8eb37fceac57fd0c8fc8e117d43b81447be22d5d8186f8f5919ba6bcc6846bd7d50726c06d245672c2ad4f61702c646499ee1173daa061ffe15bf45a631e2946d616a4c345822f1151284712f76b2b0e",
+ "derive_key": "2ea477c5515cc3dd606512ee72bb3e0e758cfae7232826f35fb98ca1bcbdf27316d8e9e79081a80b046b60f6a263616f33ca464bd78d79fa18200d06c7fc9bffd808cc4755277a7d5e09da0f29ed150f6537ea9bed946227ff184cc66a72a5f8c1e4bd8b04e81cf40fe6dc4427ad5678311a61f4ffc39d195589bdbc670f63ae70f4b6"
},
{
"input_len": 3072,
- "hash": "f4ee67a9c3c1d72129216ad7d59ea92d2573a1cf4149f09d394efc1bb3da11ebdeab0a745a4a75bec19edc1592fb110fc3b6e15601959d1f4fa3cca2751a2c9dad9a28a818a51a3d8eb117fdbb0c761023657cd04657a4c442b9e929059f89efda17d99d2eafbae767cd4dd2193027d7deb5e8374c9ed117a9a78b5d3f4db8d9703453",
- "keyed_hash": "1376b94975b3d3531b00f2b1d402eae8f62f0a5240eb41eb81876f9bdb06250cb1e1830fde5d967fd79c247b42f53c00826db7f621f0dc8cb4fede40973025737b987281b6a5bac8dbfafa68e33475940c0e55191a31e0e4e8985a279cf311a6bc6ff4f7a15d63c195e0195790114d8033a91527097d4023aad7e7758b6c630e717651",
- "derive_key": "1a75aa433cf0434f38bc4e644c1bdbed8c96b2f74dc30ddef0a217202f2a3e915f0b680c4bd456732d69b676950b4c74c7c67b46781d729c0bc43824d4ce83c1906ab1fdd6a48fb66f463c94799aeaa8e1828e57a926cf00c9fc1f37dcbeabce6b17c55bfea0710121ccda2b7ea52c9e89c68d1caf17fa31e2eccb3db8aea83c122032"
+ "hash": "b98cb0ff3623be03326b373de6b9095218513e64f1ee2edd2525c7ad1e5cffd29a3f6b0b978d6608335c09dc94ccf682f9951cdfc501bfe47b9c9189a6fc7b404d120258506341a6d802857322fbd20d3e5dae05b95c88793fa83db1cb08e7d8008d1599b6209d78336e24839724c191b2a52a80448306e0daa84a3fdb566661a37e11",
+ "keyed_hash": "044a0e7b172a312dc02a4c9a818c036ffa2776368d7f528268d2e6b5df19177022f302d0529e4174cc507c463671217975e81dab02b8fdeb0d7ccc7568dd22574c783a76be215441b32e91b9a904be8ea81f7a0afd14bad8ee7c8efc305ace5d3dd61b996febe8da4f56ca0919359a7533216e2999fc87ff7d8f176fbecb3d6f34278b",
+ "derive_key": "050df97f8c2ead654d9bb3ab8c9178edcd902a32f8495949feadcc1e0480c46b3604131bbd6e3ba573b6dd682fa0a63e5b165d39fc43a625d00207607a2bfeb65ff1d29292152e26b298868e3b87be95d6458f6f2ce6118437b632415abe6ad522874bcd79e4030a5e7bad2efa90a7a7c67e93f0a18fb28369d0a9329ab5c24134ccb0"
},
{
"input_len": 3073,
- "hash": "b88af2464b231dc122dcf87d20430a78a4027be457eaee96e7fc0f56fc870c304c39b27c29f265a117bea9031af40d63a60014ba35ea970bbeb1874175e07ea64f34f00b47dcce8914e3bab4fd2776f2c1898df2413c46d16d99a66007d3de7ff461e0efe1a58be47d2aed35e099524a67bc25a7585509f73ad858148c649159b786a0",
- "keyed_hash": "3a5f83ddce3de57a5928fdc80f899263acbe100d30ab958cd41c2520e64454727466cf3fc0929991b23d224a087aa49f974e53c0b5a77ba8586a7dd3a25a52fb4c4d8b57ab361589f2077fcbbaafcf4d96b3b19e88f0eceb377f357d1e691c7d416f786dbcd478706f726365fc6d035da3c6849635b905bd022ebed1b6c19d835bfc51",
- "derive_key": "65514539d21e845995102409bcc1d1384e0b5ef528b5f72fddd55f52da337fa20404d0a153bd9b0f21ab5e3e69fc4bbb1f8dc02615e9ce0cc14d6f8c27f6e69a226d4573b579c7487bcd340785f64a59beb27736c4a71aa92388f098518a42bd058f2d74d297d67f5395f8c0bf3e9e77114ea814d86a60e1895a57a2d6bcc8c9eff7a9"
+ "hash": "7124b49501012f81cc7f11ca069ec9226cecb8a2c850cfe644e327d22d3e1cd39a27ae3b79d68d89da9bf25bc27139ae65a324918a5f9b7828181e52cf373c84f35b639b7fccbb985b6f2fa56aea0c18f531203497b8bbd3a07ceb5926f1cab74d14bd66486d9a91eba99059a98bd1cd25876b2af5a76c3e9eed554ed72ea952b603bf",
+ "keyed_hash": "68dede9bef00ba89e43f31a6825f4cf433389fedae75c04ee9f0cf16a427c95a96d6da3fe985054d3478865be9a092250839a697bbda74e279e8a9e69f0025e4cfddd6cfb434b1cd9543aaf97c635d1b451a4386041e4bb100f5e45407cbbc24fa53ea2de3536ccb329e4eb9466ec37093a42cf62b82903c696a93a50b702c80f3c3c5",
+ "derive_key": "72613c9ec9ff7e40f8f5c173784c532ad852e827dba2bf85b2ab4b76f7079081576288e552647a9d86481c2cae75c2dd4e7c5195fb9ada1ef50e9c5098c249d743929191441301c69e1f48505a4305ec1778450ee48b8e69dc23a25960fe33070ea549119599760a8a2d28aeca06b8c5e9ba58bc19e11fe57b6ee98aa44b2a8e6b14a5"
},
{
"input_len": 4096,
- "hash": "56068fe2417d482caddf41981d3821706c4fb55a9cc1eb7bc7f70f81323fb2b5d31581421f19697bd513b5527ca701ed4f0519568932c1d0e514a1daa976ce159f032fd7d4afc6b52756c0049cc0c5f6fbbaa27295c60d7be229d69c84046b7afcc5dfd76824f3e58aac78e0fd109ad1e09acdf10afb8f2d6b8a0c7974643971d01614",
- "keyed_hash": "b9e6c35b491aff9a80dcfa9706fa163dc114ff6120d329b421b2adf9e8bd4abf8b8c8ab3f0fc827c302069e2c9900ed3548365b2b67e0ee19cd78b9f1737f7876e09c036fc776d62ae0aaf2a1784fb8825df9f1550d8d907d733cb479ea218468cda2ce25ba17835ec3bff8e7f6cff65ac856da18df30b5091a278fb5a789606df8ff8",
- "derive_key": "8628132ebe74e431f3303d515bc4a90b7d519c4d5d24aeb08d19dcbfbfb3ade86c36358a0e7013ed08008990d91d40169821a2c49c047d68560b6bb7e063b05971d6a45aadd2f397e8514a7f29ad79cffc4af406551e4a75a9c26cd58ea0f6c690c20064e243867abf768d2fb361a431008361abef9e3bd920349f6509de340a5e5dfe"
+ "hash": "015094013f57a5277b59d8475c0501042c0b642e531b0a1c8f58d2163229e9690289e9409ddb1b99768eafe1623da896faf7e1114bebeadc1be30829b6f8af707d85c298f4f0ff4d9438aef948335612ae921e76d411c3a9111df62d27eaf871959ae0062b5492a0feb98ef3ed4af277f5395172dbe5c311918ea0074ce0036454f620",
+ "keyed_hash": "befc660aea2f1718884cd8deb9902811d332f4fc4a38cf7c7300d597a081bfc0bbb64a36edb564e01e4b4aaf3b060092a6b838bea44afebd2deb8298fa562b7b597c757b9df4c911c3ca462e2ac89e9a787357aaf74c3b56d5c07bc93ce899568a3eb17d9250c20f6c5f6c1e792ec9a2dcb715398d5a6ec6d5c54f586a00403a1af1de",
+ "derive_key": "1e0d7f3db8c414c97c6307cbda6cd27ac3b030949da8e23be1a1a924ad2f25b9d78038f7b198596c6cc4a9ccf93223c08722d684f240ff6569075ed81591fd93f9fff1110b3a75bc67e426012e5588959cc5a4c192173a03c00731cf84544f65a2fb9378989f72e9694a6a394a8a30997c2e67f95a504e631cd2c5f55246024761b245"
},
{
"input_len": 4097,
- "hash": "05cd1eb97346a2dfa22cfe210a4b13c03ccf947ed0f26a8fe279f78d2b442509242d4f69b7f23a607e74a4d67b69ab3ac5ac2f3cacc576dad666776fefad878b2934d137e569f7d794f5636b1731b874f48b12e887edadacacbcc715dc5c9522994e0fffbf699586dde80f2e80c6c0aafaf15cc4ea2f6dfea12d7e6759e1dc24a1a31d",
- "keyed_hash": "3456202ab8bf4d8ea1694b9756659bc3a85255670304d3c67eb451888221c93780a9fe5e7e092fe78bcf716b4423a97a8c03b56aca1fe038c100684762f1ce9c7620a56abfba69f979e14d0ddeade8f4ebbaa0a6307d0e8fe518f2a70cb0a23c5b0a8a8523e1d0b9fa74296640176f8f592e461a3151f2601524c011a634079efab019",
- "derive_key": "45f89725444620851c9c80711a64d10feff6adeb0795f2a3e1fc6077223191b0aeae1578cf91e2807d174b8bb1bbfe6aa63422d554d0f957f8b57d188d853747f3c1e73d35a546206836ac530794a3860bd8f4b3b31c2dc685e343c5831d98c37aafe64c89ca954914da3a5f179016e46d680eb1257cdf3449cb58f3899a46ecae1496"
+ "hash": "9b4052b38f1c5fc8b1f9ff7ac7b27cd242487b3d890d15c96a1c25b8aa0fb99505f91b0b5600a11251652eacfa9497b31cd3c409ce2e45cfe6c0a016967316c426bd26f619eab5d70af9a418b845c608840390f361630bd497b1ab44019316357c61dbe091ce72fc16dc340ac3d6e009e050b3adac4b5b2c92e722cffdc46501531956",
+ "keyed_hash": "00df940cd36bb9fa7cbbc3556744e0dbc8191401afe70520ba292ee3ca80abbc606db4976cfdd266ae0abf667d9481831ff12e0caa268e7d3e57260c0824115a54ce595ccc897786d9dcbf495599cfd90157186a46ec800a6763f1c59e36197e9939e900809f7077c102f888caaf864b253bc41eea812656d46742e4ea42769f89b83f",
+ "derive_key": "aca51029626b55fda7117b42a7c211f8c6e9ba4fe5b7a8ca922f34299500ead8a897f66a400fed9198fd61dd2d58d382458e64e100128075fc54b860934e8de2e84170734b06e1d212a117100820dbc48292d148afa50567b8b84b1ec336ae10d40c8c975a624996e12de31abbe135d9d159375739c333798a80c64ae895e51e22f3ad"
},
{
"input_len": 5120,
- "hash": "10e426fca9481e052ae4e4861b83ae5153b683962d81480cb69afbc611c6c2ac716ce4fcd4c44456450220d29494ba65dd77c9efb450048283ac982d59aeec935a73f16d4a92642a9d61e7a0e448ed95e35b5834b8cfa8bb36f09f3bf1812cb5ebea77d0e7fea35fd5f8530b28eca28577e77486595a0bf83b6d0b1835d4655d1ec199",
- "keyed_hash": "50c1881a1e247bcd482b1254ae8f77a9d953fcef15e12cc26334d158f0079146351e29a26ca6c9e268ce2f32c1b0443b92d0458465d8611c94e47d477aaad3ccde6ab4ef21b99fbfa0e87bd2c6d05400e871725609e7f4b8a22cd570132483639ea364382c7643c1b08911cbec29322a82f1957414537125c5c20975bbbe3abe0d9ad8",
- "derive_key": "04866c7d7629e41233e432668514ce1e681eac4a591b23a70e9819c0eff5dc73b72a3b10b99c5103635017ec954f82a4682ff9e167ccc21d20713617238a09ec015774dfefb30f7aaf7eaaf14cb9ad5aa45a974f4eb93de2e26dcbcacca3599ec2e461df9b67f34588b197d48f7fd3d6088d33ea6676b8890a0a4e9cfd6e37cb77de34"
+ "hash": "9cadc15fed8b5d854562b26a9536d9707cadeda9b143978f319ab34230535833acc61c8fdc114a2010ce8038c853e121e1544985133fccdd0a2d507e8e615e611e9a0ba4f47915f49e53d721816a9198e8b30f12d20ec3689989175f1bf7a300eee0d9321fad8da232ece6efb8e9fd81b42ad161f6b9550a069e66b11b40487a5f5059",
+ "keyed_hash": "2c493e48e9b9bf31e0553a22b23503c0a3388f035cece68eb438d22fa1943e209b4dc9209cd80ce7c1f7c9a744658e7e288465717ae6e56d5463d4f80cdb2ef56495f6a4f5487f69749af0c34c2cdfa857f3056bf8d807336a14d7b89bf62bef2fb54f9af6a546f818dc1e98b9e07f8a5834da50fa28fb5874af91bf06020d1bf0120e",
+ "derive_key": "7a7acac8a02adcf3038d74cdd1d34527de8a0fcc0ee3399d1262397ce5817f6055d0cefd84d9d57fe792d65a278fd20384ac6c30fdb340092f1a74a92ace99c482b28f0fc0ef3b923e56ade20c6dba47e49227166251337d80a037e987ad3a7f728b5ab6dfafd6e2ab1bd583a95d9c895ba9c2422c24ea0f62961f0dca45cad47bfa0d"
},
{
"input_len": 5121,
- "hash": "2e80caea9b43674ae1770f26a1c5d1fc9fae62348ded8725b6ee447e361cca3876b8f44d9be09fd25dddea5c319eb718202122bb97add2fa3a262fe0322ac0213464cf9f7c754ae5e0c7fd697bd58537ceb6592a1cc2572deabeeadf859743b5c57dd3b3c4e92fa97fede8c13d05017c29d310e6e5168dc94a6ee2a6b470f391606027",
- "keyed_hash": "2f4ed41ef09baf4698f34cdf3638c0b9af1c7c20ce6bbc15c4ba589158d63e3ee2d5d873a0508fc51c1c3fb587a0aeeada084c9303ed5e21d1c89edf50a54bdb92591fbdacbd8bf070f61f0d4b2ef0979b14051b7ad6ceb3150605b4e9b8a78a5339de5f6723ee53664f45e6fadc435a380d50b7662a2a344394c7fb483bcaea81751d",
- "derive_key": "13cda085527d4ff766c27a1311ccc0a928a6799b2aa6ffbb14f282bbb33d5fe6bbdfdf46466c3799904497503a07eea886df32db74dce84a0c0f73e3ca086a2913670ae5199b17344bbbd0e73419c09f148b493b1e82430f182b5fcd782d194b8033e5000967cfb826e0cdb91a7a723513b61c81accfff2e9dd46f1d49e697cc536e28"
+ "hash": "628bd2cb2004694adaab7bbd778a25df25c47b9d4155a55f8fbd79f2fe154cff96adaab0613a6146cdaabe498c3a94e529d3fc1da2bd08edf54ed64d40dcd6777647eac51d8277d70219a9694334a68bc8f0f23e20b0ff70ada6f844542dfa32cd4204ca1846ef76d811cdb296f65e260227f477aa7aa008bac878f72257484f2b6c95",
+ "keyed_hash": "6ccf1c34753e7a044db80798ecd0782a8f76f33563accaddbfbb2e0ea4b2d0240d07e63f13667a8d1490e5e04f13eb617aea16a8c8a5aaed1ef6fbde1b0515e3c81050b361af6ead126032998290b563e3caddeaebfab592e155f2e161fb7cba939092133f23f9e65245e58ec23457b78a2e8a125588aad6e07d7f11a85b88d375b72d",
+ "derive_key": "b07f01e518e702f7ccb44a267e9e112d403a7b3f4883a47ffbed4b48339b3c341a0add0ac032ab5aaea1e4e5b004707ec5681ae0fcbe3796974c0b1cf31a194740c14519273eedaabec832e8a784b6e7cfc2c5952677e6c3f2c3914454082d7eb1ce1766ac7d75a4d3001fc89544dd46b5147382240d689bbbaefc359fb6ae30263165"
},
{
"input_len": 6144,
- "hash": "1f2a63135b07210fca1f6b5dc8dc982328981a427d67c2b3b09ae9b0280ad6842b57f174f315d306e5b3743bfc5b6f66e13fa8ef10aa371e228c34fd9e19a2b467f4a4cbc6160050b6288615e391ae8027441ec90b12db1d7961b2d51c66acb881444f91181371153100f1dd615b82e0f8f11bf6f7635dd96132ff25e15588ef52b2db",
- "keyed_hash": "8459fab047883448b07406ba3a2e5fe8651ff5c2b41e8451ba6c24a77c3a54254c043ae924f1620250f3f900b9b9b55013a634a77b18187c20b40a5d292c2fc324fdd5a719b63300067f5d914c6791737400dccf9924320e324be9f1af6956535aac86df8a5f56b42b97c0e31e6e9edc18ed1e44300ca33f4c6f4544cbd44373ac8ea1",
- "derive_key": "8da60e09960016e0cc92c86f9a9a3a575e40d7a1f5b9c0442017657f73e715506c06c4e4b5750b08187f8701a16c7f9ab5024b55f1c9f9ae0e2add639fa284a51b9b50a2f66c7d7c94797371eb8f85e9356a8cadbcd3b9605be0cc6a8b26d9ac2519d18b46f509e8d6cbeed12c9b8732aeaad8f9f66dc61e97fcc68f5e007073ce7b49"
+ "hash": "3e2e5b74e048f3add6d21faab3f83aa44d3b2278afb83b80b3c35164ebeca2054d742022da6fdda444ebc384b04a54c3ac5839b49da7d39f6d8a9db03deab32aade156c1c0311e9b3435cde0ddba0dce7b26a376cad121294b689193508dd63151603c6ddb866ad16c2ee41585d1633a2cea093bea714f4c5d6b903522045b20395c83",
+ "keyed_hash": "3d6b6d21281d0ade5b2b016ae4034c5dec10ca7e475f90f76eac7138e9bc8f1dc35754060091dc5caf3efabe0603c60f45e415bb3407db67e6beb3d11cf8e4f7907561f05dace0c15807f4b5f389c841eb114d81a82c02a00b57206b1d11fa6e803486b048a5ce87105a686dee041207e095323dfe172df73deb8c9532066d88f9da7e",
+ "derive_key": "2a95beae63ddce523762355cf4b9c1d8f131465780a391286a5d01abb5683a1597099e3c6488aab6c48f3c15dbe1942d21dbcdc12115d19a8b8465fb54e9053323a9178e4275647f1a9927f6439e52b7031a0b465c861a3fc531527f7758b2b888cf2f20582e9e2c593709c0a44f9c6e0f8b963994882ea4168827823eef1f64169fef"
},
{
"input_len": 6145,
- "hash": "23a825db8dee7749a2ec23924f602209a0fddca6ec469fbccd28c28d3267ba862ff53154fe87bb22ca6a8413390d3c68e7fa970b0ff928c0540c64afa8f85706ee5de39fef4f116328d7caa3115e987b97058a52af568f095e5a3a5e7ea4cd28fbea9a23fa9af797f94a9a8dc160b777ef40d765148ccc710ef262377d3c09a7ecae8b",
- "keyed_hash": "13619b046067dfe8febcfbed54d843f9f62fd0c1e19a5f97264fb94dffefcecbf894eaaec77a91909dd0ebb9443ba58bbc203604a0142768ed9799166bfa2b70daa052dda42c52735e48fc87b074930b568b57fa190c899408e94eecaba8a2c2dda0d70e1b10a71189e15146919d81e8694cc0de9a437463588f1372e9b04a2288288f",
- "derive_key": "8183a9f240a310ae7da7a6d894189766e13a73d8692c67fe5e63a46b87665acce1f8cf8f0ce2bce459faefa66d6ac5945b0edfd86d18981636e98af8777c3310a9a25fa9ae0631caf35400526fa1143de1cbe881ef8c813cc762477e2aa5544a898a877b3e095f0a2b3819c15f761e6d7236294aba2f653d9b6d51cf8b2296468215cb"
+ "hash": "f1323a8631446cc50536a9f705ee5cb619424d46887f3c376c695b70e0f0507f18a2cfdd73c6e39dd75ce7c1c6e3ef238fd54465f053b25d21044ccb2093beb015015532b108313b5829c3621ce324b8e14229091b7c93f32db2e4e63126a377d2a63a3597997d4f1cba59309cb4af240ba70cebff9a23d5e3ff0cdae2cfd54e070022",
+ "keyed_hash": "9ac301e9e39e45e3250a7e3b3df701aa0fb6889fbd80eeecf28dbc6300fbc539f3c184ca2f59780e27a576c1d1fb9772e99fd17881d02ac7dfd39675aca918453283ed8c3169085ef4a466b91c1649cc341dfdee60e32231fc34c9c4e0b9a2ba87ca8f372589c744c15fd6f985eec15e98136f25beeb4b13c4e43dc84abcc79cd4646c",
+ "derive_key": "379bcc61d0051dd489f686c13de00d5b14c505245103dc040d9e4dd1facab8e5114493d029bdbd295aaa744a59e31f35c7f52dba9c3642f773dd0b4262a9980a2aef811697e1305d37ba9d8b6d850ef07fe41108993180cf779aeece363704c76483458603bbeeb693cffbbe5588d1f3535dcad888893e53d977424bb707201569a8d2"
},
{
"input_len": 7168,
- "hash": "73aff5e142aba955db9a11bc4bf5e875be2d27720f13aee122816262a821ccb3bc7cecd468884bff8aa86d760248984be22e4a6a72bfb2f4f2d945fe94e62a597f97bb969b53fd54bc089033ff04aa4b4a974874c8e49c0b58367aae97ff87329e1ba8bf3a740e115574eab72960e02b82a93ad1b2bc4dd40850b7614f3198f9d5f514",
- "keyed_hash": "2277e49eff7f0e353bb647985e25adead0607e10b01a3af0e4e83efc9e04ba95ed6995304e472646b297b3917f8682b7f1802e2f9b07fa24a86da90620ac2de930489463481c36b1efe122509d39dcd3cb3610e960da46e462a840f43df9afb1be5e0512b972bc58a7d773f1830ec79b124554dc2d5c9f9f95400b264475e8cc522603",
- "derive_key": "398653ac16edf8f6956b22a3934c797fa23f9f50e020b12bcfb6d6d63906c36438fa783c43735d481261390cdf196556faf5177e233886fa5372d4b568ed9037dcd0867aa7265668695c1fa7de3109c127ad1b746ccd1652424d8c02e424477073591119fe7af8d70988b5343ad2150594ba7c3f4be618cd86325b25b492663f1d17b0"
+ "hash": "61da957ec2499a95d6b8023e2b0e604ec7f6b50e80a9678b89d2628e99ada77a5707c321c83361793b9af62a40f43b523df1c8633cecb4cd14d00bdc79c78fca5165b863893f6d38b02ff7236c5a9a8ad2dba87d24c547cab046c29fc5bc1ed142e1de4763613bb162a5a538e6ef05ed05199d751f9eb58d332791b8d73fb74e4fce95",
+ "keyed_hash": "b42835e40e9d4a7f42ad8cc04f85a963a76e18198377ed84adddeaecacc6f3fca2f01d5277d69bb681c70fa8d36094f73ec06e452c80d2ff2257ed82e7ba348400989a65ee8daa7094ae0933e3d2210ac6395c4af24f91c2b590ef87d7788d7066ea3eaebca4c08a4f14b9a27644f99084c3543711b64a070b94f2c9d1d8a90d035d52",
+ "derive_key": "11c37a112765370c94a51415d0d651190c288566e295d505defdad895dae223730d5a5175a38841693020669c7638f40b9bc1f9f39cf98bda7a5b54ae24218a800a2116b34665aa95d846d97ea988bfcb53dd9c055d588fa21ba78996776ea6c40bc428b53c62b5f3ccf200f647a5aae8067f0ea1976391fcc72af1945100e2a6dcb88"
},
{
"input_len": 7169,
- "hash": "2ebec7780331a3794aff5e6b10ff3e8f12bde652796d74503214869c89c9e9ea680df2f90a252c723abbeff8ff8cbacfdcd20bb0a8de6917aaae0fb1bdc639eed856df1778a9b8359c2d412ec82bdf759028606fe1d00894449bdd043f3860eb0f309515d576fc111502e5247e1ec7bb589a1459291410fd4b4a8806ac55d843bea017",
- "keyed_hash": "897802df709fc320f73dc4cec70823c1209850ce4f8bc6a94f82cb33ee3abfee9d9ad6fa577390151cb106ee3f56a6d6416500ab0604fcc8c1b827bba8416508964fc0b68a7308df1bb2ee6499d7bdef2892ac4d6dc5c02755fcfff72e4341d95c085e9906928661a427b69d087c4469f62888395348fd54f2aa0bc4dc032691e780e0",
- "derive_key": "95fa359220bd5f4641e5ba9aa6b80145bb6de9901fda57446df60eadf018cf4c0b2b366d5d4358c60a063f802cd894a10e37fd82555a514cf438c11cb87c20886d212888ea47a01e9eadda63e03b94ac128ae7cec27dd62d4661532deae520f1cdf13d0b06b785287add95c6e051dc09a4dc1f89b182bbec8b4b0043cb95e9e6c614c7"
+ "hash": "a003fc7a51754a9b3c7fae0367ab3d782dccf28855a03d435f8cfe74605e781798a8b20534be1ca9eb2ae2df3fae2ea60e48c6fb0b850b1385b5de0fe460dbe9d9f9b0d8db4435da75c601156df9d047f4ede008732eb17adc05d96180f8a73548522840779e6062d643b79478a6e8dbce68927f36ebf676ffa7d72d5f68f050b119c8",
+ "keyed_hash": "ed9b1a922c046fdb3d423ae34e143b05ca1bf28b710432857bf738bcedbfa5113c9e28d72fcbfc020814ce3f5d4fc867f01c8f5b6caf305b3ea8a8ba2da3ab69fabcb438f19ff11f5378ad4484d75c478de425fb8e6ee809b54eec9bdb184315dc856617c09f5340451bf42fd3270a7b0b6566169f242e533777604c118a6358250f54",
+ "derive_key": "554b0a5efea9ef183f2f9b931b7497995d9eb26f5c5c6dad2b97d62fc5ac31d99b20652c016d88ba2a611bbd761668d5eda3e568e940faae24b0d9991c3bd25a65f770b89fdcadabcb3d1a9c1cb63e69721cacf1ae69fefdcef1e3ef41bc5312ccc17222199e47a26552c6adc460cf47a72319cb5039369d0060eaea59d6c65130f1dd"
},
{
"input_len": 8192,
- "hash": "97fa001fbec31ce77600fef5d53b074f2c9f35ba1843f03fcdff567a8204159083023093a92e61c9ae6156b42b31eae6bbdeef422b35151cdb50d410aa65bf41936efee65850ddaf0c8daeb0b158498d77bf0341cff689c152a9eb421b1a4453f2c777d1671626c95decce350b3d32900303406944c82ab50d5b3258f627ab1468cee9",
- "keyed_hash": "459b6e7c3b67dbc2ded5ee7edf0c423a43b79f7f11445fece829e484876ebc304a50e5e3008c584f45dd0c448d6bddf09f6a88289852fae087bdf3531b20ffbcb3fc80ff03d39b03c0799a9c3face24161cab1622eac41c2536cc6f967b36c9d39fef5eb7a30cf24b0594d4bdf21f2532854593ea16c00da88dcab97cd106e75ad7c1d",
- "derive_key": "eb84e9f33a2bb87fe3403d6817a6bb2a9f4c2742aab2fe6adc021b4a5628adc3957b496f7020c69903ae8b73b530e7283c7769fb53562291d9ce2c4053d4bc7987c282bdc5008d3452819f8f0a4abf7f9806c17b14cea10eaa5ae9d0f7c219585160287c955eb2414d2ec6efed67466e87a3f644a241dbdc0e0ba32b8feb823e728d9a"
+ "hash": "aae792484c8efe4f19e2ca7d371d8c467ffb10748d8a5a1ae579948f718a2a635fe51a27db045a567c1ad51be5aa34c01c6651c4d9b5b5ac5d0fd58cf18dd61a47778566b797a8c67df7b1d60b97b19288d2d877bb2df417ace009dcb0241ca1257d62712b6a4043b4ff33f690d849da91ea3bf711ed583cb7b7a7da2839ba71309bbf",
+ "keyed_hash": "dc9637c8845a770b4cbf76b8daec0eebf7dc2eac11498517f08d44c8fc00d58a4834464159dcbc12a0ba0c6d6eb41bac0ed6585cabfe0aca36a375e6c5480c22afdc40785c170f5a6b8a1107dbee282318d00d915ac9ed1143ad40765ec120042ee121cd2baa36250c618adaf9e27260fda2f94dea8fb6f08c04f8f10c78292aa46102",
+ "derive_key": "ad01d7ae4ad059b0d33baa3c01319dcf8088094d0359e5fd45d6aeaa8b2d0c3d4c9e58958553513b67f84f8eac653aeeb02ae1d5672dcecf91cd9985a0e67f4501910ecba25555395427ccc7241d70dc21c190e2aadee875e5aae6bf1912837e53411dabf7a56cbf8e4fb780432b0d7fe6cec45024a0788cf5874616407757e9e6bef7"
},
{
"input_len": 8193,
- "hash": "5130f9d488e0397a5b33aaf5dc07dcff5791a363f6c8a3c1212773f106debc5e8abe5659a570881a84088cde123c8cd9452d445518198375bfda9dfd3a17de5150576777dcb23f25ef62870bd17350ddc2e545ca21c5ccb5c415994fc933a48fe30bfb7cbad580bb83ed971710eddd03918dcb3321d6d43086666d43ac40838ac84d49",
- "keyed_hash": "9f1468dd575f4d04617377620f3f0ee8f6f0e28b2e1adbbf00ddcc7763f64e4ea2e24637b0587facb504bed148971183ccae1ea94272c430868df99954fc8e875396832527ae09da201a4526abbaa92a6dd0d24958e8397137ab1a4c5064fb23fe4647512138288020bc9362212a9e8efda0aee1912cdcc8d166c8583958e8229af890",
- "derive_key": "a278e50d4cebb843e97c4cbf62a870587464c965ef01af3a878357ad46861511704a5572d0daefba90ed7e665e1a9cf97a52716d0c9075d22590e5e98fb089f7df4071dae90ff685ad27a6c3b4e9345afd0680d7c2cb6001b5f29e85138f0726639aa52d3a6b116d752adc5afb67b29092e2b38ee3d463949b3bfb98813bc9cc1fab21"
+ "hash": "bab6c09cb8ce8cf459261398d2e7aef35700bf488116ceb94a36d0f5f1b7bc3bb2282aa69be089359ea1154b9a9286c4a56af4de975a9aa4a5c497654914d279bea60bb6d2cf7225a2fa0ff5ef56bbe4b149f3ed15860f78b4e2ad04e158e375c1e0c0b551cd7dfc82f1b155c11b6b3ed51ec9edb30d133653bb5709d1dbd55f4e1ff6",
+ "keyed_hash": "954a2a75420c8d6547e3ba5b98d963e6fa6491addc8c023189cc519821b4a1f5f03228648fd983aef045c2fa8290934b0866b615f585149587dda2299039965328835a2b18f1d63b7e300fc76ff260b571839fe44876a4eae66cbac8c67694411ed7e09df51068a22c6e67d6d3dd2cca8ff12e3275384006c80f4db68023f24eebba57",
+ "derive_key": "af1e0346e389b17c23200270a64aa4e1ead98c61695d917de7d5b00491c9b0f12f20a01d6d622edf3de026a4db4e4526225debb93c1237934d71c7340bb5916158cbdafe9ac3225476b6ab57a12357db3abbad7a26c6e66290e44034fb08a20a8d0ec264f309994d2810c49cfba6989d7abb095897459f5425adb48aba07c5fb3c83c0"
},
{
"input_len": 16384,
- "hash": "f91f20dfad46cb08c3196ca0060f0b5c3840445030f0184ffa2ebbc4cf6c46e63dfdf6f6cd998aac06c43860322d75f050cd385862a826eb5e83552feddb5a7685a1d66463ee6a0aec4da1574d9a11d086bbc566c4fcd1b0a2f5a58ce29d663912ee1f9be6a63d5c93c1796103fc8a09f6cfea3d8cbd0835e045f7d5440bc9552dff96",
- "keyed_hash": "8b666ddf0a92535ee4056d663641b9528c9f5506bdb84498bd57a27a50ab770fe1a4a77a0998d88ce17080ee110b0104f3fb65c6498d9aafea4e9d710fd9f2ff8644342a42e1c31e777a3a74537a8dd5d3ae5dc690184a47a50f0df13d2ad26101f747a3646e489cda3eb939a37f21e7c42928369278d50ece2ea39c9763cc6e7bef98",
- "derive_key": "e5aff1a86333a0ba8a51ad3e11b8154f8050869a2ef3e5e3b572e33b7549e4e36a2317cac5e7e521b0c90895d772d108dd8e1eea81730ea60cad608fb317eb34d9df00a4b9ffbaaa06b4b316d4ce3bd20d60f152bfb3cd029f517078fc61e0998f109fe937bfb23c9a2709a1615c0c8113b404fcf9b225f307807091389fc2048bbb52"
+ "hash": "f875d6646de28985646f34ee13be9a576fd515f76b5b0a26bb324735041ddde49d764c270176e53e97bdffa58d549073f2c660be0e81293767ed4e4929f9ad34bbb39a529334c57c4a381ffd2a6d4bfdbf1482651b172aa883cc13408fa67758a3e47503f93f87720a3177325f7823251b85275f64636a8f1d599c2e49722f42e93893",
+ "keyed_hash": "9e9fc4eb7cf081ea7c47d1807790ed211bfec56aa25bb7037784c13c4b707b0df9e601b101e4cf63a404dfe50f2e1865bb12edc8fca166579ce0c70dba5a5c0fc960ad6f3772183416a00bd29d4c6e651ea7620bb100c9449858bf14e1ddc9ecd35725581ca5b9160de04060045993d972571c3e8f71e9d0496bfa744656861b169d65",
+ "derive_key": "160e18b5878cd0df1c3af85eb25a0db5344d43a6fbd7a8ef4ed98d0714c3f7e160dc0b1f09caa35f2f417b9ef309dfe5ebd67f4c9507995a531374d099cf8ae317542e885ec6f589378864d3ea98716b3bbb65ef4ab5e0ab5bb298a501f19a41ec19af84a5e6b428ecd813b1a47ed91c9657c3fba11c406bc316768b58f6802c9e9b57"
},
{
"input_len": 31744,
- "hash": "58a4d5c7cb22a2ea1a0e78cfcb79104d4b3e8bfd8fa384c995f42519bc2546d949d85b50f85673969fd1ccc0dad15e29249dc2be51eb9886ee637462f0c97834f6b777776cd3beaa578618e945323d2452f0ba654a999550ce487d7583a3e92e785d07641be903624a5882f44ac4e4a3b94b04b7fda352b4211793c830abf62ae0dd6e",
- "keyed_hash": "3de3905be6e33bf796994a710c10b07447ace37c29d65437d32c51dd5396074e0fe56076eeaf3509791f0dc24370cebc0aabcc048de03dfd11b3173963ccbb0f71c2456aba58ce1437a08834590020966307cc67437750df3b8df0bfc393f37629b13754309831d6533653847079e3031c2766bf3b15377f7021d05c65bbca76bdac65",
- "derive_key": "f8a392cbe1db5e4deeab88285ddca8d8123c65ffadf27d4eb6dbabd9bc2d586d6f28886e3bab709cfd79d6d345da0bb06b17e45d16efa34ce853024994ed7153dc65653ea060619f1614b4fe1763d869c0e4b5e29343aaa86ed82d097150cc6e0ac9a646bcaf51c5a1c7162b941b64c5978dd394d455236c45c75185b1926946426b95"
+ "hash": "62b6960e1a44bcc1eb1a611a8d6235b6b4b78f32e7abc4fb4c6cdcce94895c47860cc51f2b0c28a7b77304bd55fe73af663c02d3f52ea053ba43431ca5bab7bfea2f5e9d7121770d88f70ae9649ea713087d1914f7f312147e247f87eb2d4ffef0ac978bf7b6579d57d533355aa20b8b77b13fd09748728a5cc327a8ec470f4013226f",
+ "keyed_hash": "efa53b389ab67c593dba624d898d0f7353ab99e4ac9d42302ee64cbf9939a4193a7258db2d9cd32a7a3ecfce46144114b15c2fcb68a618a976bd74515d47be08b628be420b5e830fade7c080e351a076fbc38641ad80c736c8a18fe3c66ce12f95c61c2462a9770d60d0f77115bbcd3782b593016a4e728d4c06cee4505cb0c08a42ec",
+ "derive_key": "39772aef80e0ebe60596361e45b061e8f417429d529171b6764468c22928e28e9759adeb797a3fbf771b1bcea30150a020e317982bf0d6e7d14dd9f064bc11025c25f31e81bd78a921db0174f03dd481d30e93fd8e90f8b2fee209f849f2d2a52f31719a490fb0ba7aea1e09814ee912eba111a9fde9d5c274185f7bae8ba85d300a2b"
}
]
}