Skip to content

Commit 1276d75

Browse files
committed
[Support/BLAKE3] LLVM-specific changes over the original BLAKE3 C implementation
Changes from original BLAKE3 sources: * `blake.h`: * Changes to avoid conflicts if a client also links with its own BLAKE3 version: * Renamed the header macro guard with `LLVM_C_` prefix * Renamed the C symbols to add the `llvm_` prefix * Added a top header comment that references the CC0 license and points to the `LICENSE` file in the repo. * `blake3_impl.h`: Added `#define`s to remove some of `llvm_` prefixes for the rest of the internal implementation. * Implementation files: * Added a top header comment for `blake.c` * Used `llvm_` prefix for the C public API functions * Used `LLVM_LIBRARY_VISIBILITY` for internal implementation functions * Added `.private_extern`/`.hidden` in assembly files to reduce visibility of the internal implementation functions * `README.md`: * added a note about where the sources originated from * Used the C++ BLAKE3 class and `llvm_` prefixed C API in place of examples and API documentation. * Removed instructions about how to build the files.
1 parent 6ad032d commit 1276d75

18 files changed

+329
-278
lines changed

llvm/include/llvm-c/blake3.h

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
1-
#ifndef BLAKE3_H
2-
#define BLAKE3_H
1+
/*===-- llvm-c/blake3.h - BLAKE3 C Interface ----------------------*- C -*-===*\
2+
|* *|
3+
|* Released into the public domain with CC0 1.0 *|
4+
|* See 'llvm/lib/Support/BLAKE3/LICENSE' for info. *|
5+
|* SPDX-License-Identifier: CC0-1.0 *|
6+
|* *|
7+
|*===----------------------------------------------------------------------===*|
8+
|* *|
9+
|* This header declares the C interface to LLVM's BLAKE3 implementation. *|
10+
|* Original BLAKE3 C API: https://github.com/BLAKE3-team/BLAKE3/tree/1.3.1/c *|
11+
|* *|
12+
|* Symbols are prefixed with 'llvm' to avoid a potential conflict with *|
13+
|* another BLAKE3 version within the same program. *|
14+
|* *|
15+
\*===----------------------------------------------------------------------===*/
16+
17+
#ifndef LLVM_C_BLAKE3_H
18+
#define LLVM_C_BLAKE3_H
319

420
#include <stddef.h>
521
#include <stdint.h>
@@ -8,53 +24,56 @@
824
extern "C" {
925
#endif
1026

11-
#define BLAKE3_VERSION_STRING "1.3.1"
12-
#define BLAKE3_KEY_LEN 32
13-
#define BLAKE3_OUT_LEN 32
14-
#define BLAKE3_BLOCK_LEN 64
15-
#define BLAKE3_CHUNK_LEN 1024
16-
#define BLAKE3_MAX_DEPTH 54
27+
#define LLVM_BLAKE3_VERSION_STRING "1.3.1"
28+
#define LLVM_BLAKE3_KEY_LEN 32
29+
#define LLVM_BLAKE3_OUT_LEN 32
30+
#define LLVM_BLAKE3_BLOCK_LEN 64
31+
#define LLVM_BLAKE3_CHUNK_LEN 1024
32+
#define LLVM_BLAKE3_MAX_DEPTH 54
1733

1834
// This struct is a private implementation detail. It has to be here because
19-
// it's part of blake3_hasher below.
35+
// it's part of llvm_blake3_hasher below.
2036
typedef struct {
2137
uint32_t cv[8];
2238
uint64_t chunk_counter;
23-
uint8_t buf[BLAKE3_BLOCK_LEN];
39+
uint8_t buf[LLVM_BLAKE3_BLOCK_LEN];
2440
uint8_t buf_len;
2541
uint8_t blocks_compressed;
2642
uint8_t flags;
27-
} blake3_chunk_state;
43+
} llvm_blake3_chunk_state;
2844

2945
typedef struct {
3046
uint32_t key[8];
31-
blake3_chunk_state chunk;
47+
llvm_blake3_chunk_state chunk;
3248
uint8_t cv_stack_len;
3349
// The stack size is MAX_DEPTH + 1 because we do lazy merging. For example,
3450
// with 7 chunks, we have 3 entries in the stack. Adding an 8th chunk
3551
// requires a 4th entry, rather than merging everything down to 1, because we
3652
// don't know whether more input is coming. This is different from how the
3753
// reference implementation does things.
38-
uint8_t cv_stack[(BLAKE3_MAX_DEPTH + 1) * BLAKE3_OUT_LEN];
39-
} blake3_hasher;
40-
41-
const char *blake3_version(void);
42-
void blake3_hasher_init(blake3_hasher *self);
43-
void blake3_hasher_init_keyed(blake3_hasher *self,
44-
const uint8_t key[BLAKE3_KEY_LEN]);
45-
void blake3_hasher_init_derive_key(blake3_hasher *self, const char *context);
46-
void blake3_hasher_init_derive_key_raw(blake3_hasher *self, const void *context,
47-
size_t context_len);
48-
void blake3_hasher_update(blake3_hasher *self, const void *input,
49-
size_t input_len);
50-
void blake3_hasher_finalize(const blake3_hasher *self, uint8_t *out,
51-
size_t out_len);
52-
void blake3_hasher_finalize_seek(const blake3_hasher *self, uint64_t seek,
53-
uint8_t *out, size_t out_len);
54-
void blake3_hasher_reset(blake3_hasher *self);
54+
uint8_t cv_stack[(LLVM_BLAKE3_MAX_DEPTH + 1) * LLVM_BLAKE3_OUT_LEN];
55+
} llvm_blake3_hasher;
56+
57+
const char *llvm_blake3_version(void);
58+
void llvm_blake3_hasher_init(llvm_blake3_hasher *self);
59+
void llvm_blake3_hasher_init_keyed(llvm_blake3_hasher *self,
60+
const uint8_t key[LLVM_BLAKE3_KEY_LEN]);
61+
void llvm_blake3_hasher_init_derive_key(llvm_blake3_hasher *self,
62+
const char *context);
63+
void llvm_blake3_hasher_init_derive_key_raw(llvm_blake3_hasher *self,
64+
const void *context,
65+
size_t context_len);
66+
void llvm_blake3_hasher_update(llvm_blake3_hasher *self, const void *input,
67+
size_t input_len);
68+
void llvm_blake3_hasher_finalize(const llvm_blake3_hasher *self, uint8_t *out,
69+
size_t out_len);
70+
void llvm_blake3_hasher_finalize_seek(const llvm_blake3_hasher *self,
71+
uint64_t seek, uint8_t *out,
72+
size_t out_len);
73+
void llvm_blake3_hasher_reset(llvm_blake3_hasher *self);
5574

5675
#ifdef __cplusplus
5776
}
5877
#endif
5978

60-
#endif /* BLAKE3_H */
79+
#endif /* LLVM_C_BLAKE3_H */

llvm/include/llvm/Support/BLAKE3.h

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
namespace llvm {
2121

22-
/// The constant \p BLAKE3_OUT_LEN provides the default output length,
22+
/// The constant \p LLVM_BLAKE3_OUT_LEN provides the default output length,
2323
/// 32 bytes, which is recommended for most callers.
2424
///
2525
/// Outputs shorter than the default length of 32 bytes (256 bits) provide
@@ -31,7 +31,7 @@ namespace llvm {
3131
/// Shorter BLAKE3 outputs are prefixes of longer ones. Explicitly
3232
/// requesting a short output is equivalent to truncating the default-length
3333
/// output.
34-
template <size_t NumBytes = BLAKE3_OUT_LEN>
34+
template <size_t NumBytes = LLVM_BLAKE3_OUT_LEN>
3535
using BLAKE3Result = std::array<uint8_t, NumBytes>;
3636

3737
/// A class that wrap the BLAKE3 algorithm.
@@ -40,45 +40,46 @@ class BLAKE3 {
4040
BLAKE3() { init(); }
4141

4242
/// Reinitialize the internal state
43-
void init() { blake3_hasher_init(&Hasher); }
43+
void init() { llvm_blake3_hasher_init(&Hasher); }
4444

4545
/// Digest more data.
4646
void update(ArrayRef<uint8_t> Data) {
47-
blake3_hasher_update(&Hasher, Data.data(), Data.size());
47+
llvm_blake3_hasher_update(&Hasher, Data.data(), Data.size());
4848
}
4949

5050
/// Digest more data.
5151
void update(StringRef Str) {
52-
blake3_hasher_update(&Hasher, Str.data(), Str.size());
52+
llvm_blake3_hasher_update(&Hasher, Str.data(), Str.size());
5353
}
5454

5555
/// Finalize the hasher and put the result in \p Result.
5656
/// This doesn't modify the hasher itself, and it's possible to finalize again
5757
/// after adding more input.
58-
template <size_t NumBytes = BLAKE3_OUT_LEN>
58+
template <size_t NumBytes = LLVM_BLAKE3_OUT_LEN>
5959
void final(BLAKE3Result<NumBytes> &Result) {
60-
blake3_hasher_finalize(&Hasher, Result.data(), Result.size());
60+
llvm_blake3_hasher_finalize(&Hasher, Result.data(), Result.size());
6161
}
6262

6363
/// Finalize the hasher and return an output of any length, given in bytes.
6464
/// This doesn't modify the hasher itself, and it's possible to finalize again
6565
/// after adding more input.
66-
template <size_t NumBytes = BLAKE3_OUT_LEN> BLAKE3Result<NumBytes> final() {
66+
template <size_t NumBytes = LLVM_BLAKE3_OUT_LEN>
67+
BLAKE3Result<NumBytes> final() {
6768
BLAKE3Result<NumBytes> Result;
68-
blake3_hasher_finalize(&Hasher, Result.data(), Result.size());
69+
llvm_blake3_hasher_finalize(&Hasher, Result.data(), Result.size());
6970
return Result;
7071
}
7172

7273
/// Returns a BLAKE3 hash for the given data.
73-
template <size_t NumBytes = BLAKE3_OUT_LEN>
74+
template <size_t NumBytes = LLVM_BLAKE3_OUT_LEN>
7475
static BLAKE3Result<NumBytes> hash(ArrayRef<uint8_t> Data) {
7576
BLAKE3 Hasher;
7677
Hasher.update(Data);
7778
return Hasher.final<NumBytes>();
7879
}
7980

8081
private:
81-
blake3_hasher Hasher;
82+
llvm_blake3_hasher Hasher;
8283
};
8384

8485
} // namespace llvm
Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
set(LLVM_BLAKE3_FILES
2-
BLAKE3/blake3.c
3-
BLAKE3/blake3_dispatch.c
4-
BLAKE3/blake3_portable.c
2+
blake3.c
3+
blake3_dispatch.c
4+
blake3_portable.c
55
)
66

77
# The BLAKE3 team recommends using the assembly versions, from the README:
@@ -11,38 +11,46 @@ set(LLVM_BLAKE3_FILES
1111
# version using C intrinsics. The assembly versions are generally
1212
# preferred. They perform better, they perform more consistently across
1313
# different compilers, and they build more quickly."
14-
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|AMD64)$")
14+
15+
if (MSVC)
16+
check_symbol_exists(_M_X64 "" IS_X64)
17+
check_symbol_exists(_M_ARM64 "" IS_ARM64)
18+
else()
19+
check_symbol_exists(__x86_64__ "" IS_X64)
20+
check_symbol_exists(__aarch64__ "" IS_ARM64)
21+
endif()
22+
23+
if (IS_X64)
1524
if (MSVC)
25+
enable_language(ASM_MASM)
1626
list(APPEND LLVM_BLAKE3_FILES
17-
BLAKE3/blake3_sse2_x86-64_windows_msvc.asm
18-
BLAKE3/blake3_sse41_x86-64_windows_msvc.asm
19-
BLAKE3/blake3_avx2_x86-64_windows_msvc.asm
20-
BLAKE3/blake3_avx512_x86-64_windows_msvc.asm
27+
blake3_sse2_x86-64_windows_msvc.asm
28+
blake3_sse41_x86-64_windows_msvc.asm
29+
blake3_avx2_x86-64_windows_msvc.asm
30+
blake3_avx512_x86-64_windows_msvc.asm
2131
)
2232
elseif(WIN32)
2333
list(APPEND LLVM_BLAKE3_FILES
24-
BLAKE3/blake3_sse2_x86-64_windows_gnu.S
25-
BLAKE3/blake3_sse41_x86-64_windows_gnu.S
26-
BLAKE3/blake3_avx2_x86-64_windows_gnu.S
27-
BLAKE3/blake3_avx512_x86-64_windows_gnu.S
34+
blake3_sse2_x86-64_windows_gnu.S
35+
blake3_sse41_x86-64_windows_gnu.S
36+
blake3_avx2_x86-64_windows_gnu.S
37+
blake3_avx512_x86-64_windows_gnu.S
2838
)
2939
else()
3040
list(APPEND LLVM_BLAKE3_FILES
31-
BLAKE3/blake3_sse2_x86-64_unix.S
32-
BLAKE3/blake3_sse41_x86-64_unix.S
33-
BLAKE3/blake3_avx2_x86-64_unix.S
34-
BLAKE3/blake3_avx512_x86-64_unix.S
41+
blake3_sse2_x86-64_unix.S
42+
blake3_sse41_x86-64_unix.S
43+
blake3_avx2_x86-64_unix.S
44+
blake3_avx512_x86-64_unix.S
3545
)
3646
endif()
3747
endif()
3848

39-
if (CMAKE_SYSTEM_PROCESSOR MATCHES "arm")
49+
if (IS_ARM64)
4050
list(APPEND LLVM_BLAKE3_FILES
41-
BLAKE3/blake3_neon.c
51+
blake3_neon.c
4252
)
4353
endif()
4454

45-
set(LLVM_BLAKE3_FILES
46-
${LLVM_BLAKE3_FILES}
47-
PARENT_SCOPE
48-
)
55+
add_library(LLVMSupportBlake3 OBJECT EXCLUDE_FROM_ALL ${LLVM_BLAKE3_FILES})
56+
llvm_update_compile_flags(LLVMSupportBlake3)

0 commit comments

Comments
 (0)