diff options
| author | Jack O'Connor <[email protected]> | 2020-01-08 22:51:17 -0500 |
|---|---|---|
| committer | Jack O'Connor <[email protected]> | 2020-01-09 09:48:52 -0500 |
| commit | a7579d30ad16c19306cedeeacd919e319aff1089 (patch) | |
| tree | 572423d117912988ccbd58bbbab305ec8bd09ce0 /c/blake3_impl.h | |
| parent | 56ced5b422f0289e5a26aedf2a7bc452ace66f1f (diff) | |
merge BLAKE3-c into this repo
This is commit 4476d9da0e370993823e7ad17592b84e905afd76 of
https://github.com/veorq/BLAKE3-c.
Diffstat (limited to 'c/blake3_impl.h')
| -rw-r--r-- | c/blake3_impl.h | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/c/blake3_impl.h b/c/blake3_impl.h new file mode 100644 index 0000000..576ccf4 --- /dev/null +++ b/c/blake3_impl.h @@ -0,0 +1,97 @@ +#pragma once + +#include <assert.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> +#include <string.h> + +#if __POPCNT__ +#include <nmmintrin.h> +#endif + +#include "blake3.h" + +// internal flags +#define CHUNK_START 1 +#define CHUNK_END 2 +#define PARENT 4 +#define ROOT 8 +#define KEYED_HASH 16 +#define DERIVE_KEY_CONTEXT 32 +#define DERIVE_KEY_MATERIAL 64 + +// This C implementation tries to support recent versions of GCC, Clang, and +// MSVC. +#if defined(_MSC_VER) +#define INLINE __forceinline static +#else +#define INLINE __attribute__((always_inline)) static inline +#endif + +static const uint32_t IV[8] = {0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, + 0xA54FF53AUL, 0x510E527FUL, 0x9B05688CUL, + 0x1F83D9ABUL, 0x5BE0CD19UL}; + +static const uint8_t MSG_SCHEDULE[7][16] = { + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + {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. +INLINE uint8_t popcnt(uint64_t x) { +#if __POPCNT__ + return (uint8_t)_mm_popcnt_u64(x); +#else + uint8_t count = 0; + while (x > 0) { + count += ((uint8_t)x) & 1; + x >>= 1; + } + return count; +#endif +} + +INLINE uint32_t counter_low(uint64_t counter) { return (uint32_t)counter; } + +INLINE uint32_t counter_high(uint64_t counter) { + return (uint32_t)(counter >> 32); +} + +INLINE uint32_t load32(const void *src) { + const uint8_t *p = (const uint8_t *)src; + return ((uint32_t)(p[0]) << 0) | ((uint32_t)(p[1]) << 8) | + ((uint32_t)(p[2]) << 16) | ((uint32_t)(p[3]) << 24); +} + +INLINE void load_key_words(const uint8_t key[BLAKE3_KEY_LEN], + uint32_t key_words[8]) { + key_words[0] = load32(&key[0 * 4]); + key_words[1] = load32(&key[1 * 4]); + key_words[2] = load32(&key[2 * 4]); + key_words[3] = load32(&key[3 * 4]); + key_words[4] = load32(&key[4 * 4]); + key_words[5] = load32(&key[5 * 4]); + key_words[6] = load32(&key[6 * 4]); + key_words[7] = load32(&key[7 * 4]); +} + +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); |
