1 | //===- llvm/unittest/Support/BLAKE3Test.cpp - BLAKE3 tests ----------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file implements unit tests for the BLAKE3 functions. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "llvm/Support/BLAKE3.h" |
14 | #include "llvm/ADT/StringExtras.h" |
15 | #include "llvm/Support/HashBuilder.h" |
16 | #include "gtest/gtest.h" |
17 | |
18 | using namespace llvm; |
19 | |
20 | namespace { |
21 | |
22 | /// Tests an arbitrary set of bytes passed as \p Input. |
23 | void TestBLAKE3Sum(ArrayRef<uint8_t> Input, StringRef Final) { |
24 | BLAKE3 Hash; |
25 | Hash.update(Data: Input); |
26 | auto hash = Hash.final(); |
27 | auto hashStr = toHex(Input: hash); |
28 | EXPECT_EQ(hashStr, Final); |
29 | } |
30 | |
31 | using KV = std::pair<const char *, const char *>; |
32 | |
33 | TEST(BLAKE3Test, BLAKE3) { |
34 | std::array<KV, 5> testvectors{ |
35 | KV{"" , |
36 | "AF1349B9F5F9A1A6A0404DEA36DCC9499BCB25C9ADC112B7CC9A93CAE41F3262" }, |
37 | KV{"a" , |
38 | "17762FDDD969A453925D65717AC3EEA21320B66B54342FDE15128D6CAF21215F" }, |
39 | KV{"abc" , |
40 | "6437B3AC38465133FFB63B75273A8DB548C558465D79DB03FD359C6CD5BD9D85" }, |
41 | KV{"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" , |
42 | "C19012CC2AAF0DC3D8E5C45A1B79114D2DF42ABB2A410BF54BE09E891AF06FF8" }, |
43 | KV{"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklm" |
44 | "nopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" , |
45 | "553E1AA2A477CB3166E6AB38C12D59F6C5017F0885AAF079F217DA00CFCA363F" }}; |
46 | |
47 | for (auto input_expected : testvectors) { |
48 | auto str = std::get<0>(in&: input_expected); |
49 | auto expected = std::get<1>(in&: input_expected); |
50 | TestBLAKE3Sum(Input: {reinterpret_cast<const uint8_t *>(str), strlen(s: str)}, |
51 | Final: expected); |
52 | } |
53 | |
54 | std::string rep(1000, 'a'); |
55 | BLAKE3 Hash; |
56 | for (int i = 0; i < 1000; ++i) { |
57 | Hash.update(Data: {reinterpret_cast<const uint8_t *>(rep.data()), rep.size()}); |
58 | } |
59 | auto hash = Hash.final(); |
60 | auto hashStr = toHex(Input: hash); |
61 | EXPECT_EQ(hashStr, |
62 | "616F575A1B58D4C9797D4217B9730AE5E6EB319D76EDEF6549B46F4EFE31FF8B" ); |
63 | |
64 | // Using generic HashBuilder. |
65 | HashBuilder<BLAKE3, llvm::endianness::native> HashBuilder; |
66 | HashBuilder.update(Data: std::get<0>(in&: testvectors[2])); |
67 | BLAKE3Result<> HBHash1 = HashBuilder.final(); |
68 | BLAKE3Result<> HBHash2 = HashBuilder.result(); |
69 | EXPECT_EQ(std::get<1>(testvectors[2]), toHex(HBHash1)); |
70 | EXPECT_EQ(std::get<1>(testvectors[2]), toHex(HBHash2)); |
71 | } |
72 | |
73 | TEST(BLAKE3Test, SmallerHashSize) { |
74 | const char *InputStr = "abc" ; |
75 | ArrayRef<uint8_t> Input(reinterpret_cast<const uint8_t *>(InputStr), |
76 | strlen(s: InputStr)); |
77 | BLAKE3 Hash; |
78 | Hash.update(Data: Input); |
79 | auto hash1 = Hash.final<16>(); |
80 | auto hash2 = BLAKE3::hash<16>(Data: Input); |
81 | auto hashStr1 = toHex(Input: hash1); |
82 | auto hashStr2 = toHex(Input: hash2); |
83 | EXPECT_EQ(hashStr1, hashStr2); |
84 | EXPECT_EQ(hashStr1, "6437B3AC38465133FFB63B75273A8DB5" ); |
85 | |
86 | // Using generic HashBuilder. |
87 | HashBuilder<TruncatedBLAKE3<16>, llvm::endianness::native> HashBuilder; |
88 | HashBuilder.update(Data: Input); |
89 | BLAKE3Result<16> hash3 = HashBuilder.final(); |
90 | BLAKE3Result<16> hash4 = HashBuilder.result(); |
91 | EXPECT_EQ(hashStr1, toHex(hash3)); |
92 | EXPECT_EQ(hashStr1, toHex(hash4)); |
93 | } |
94 | |
95 | } // namespace |
96 | |