/src/serenity/Userland/Libraries/LibCrypto/Hash/BLAKE2b.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2023, the SerenityOS developers |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #pragma once |
8 | | |
9 | | #include <LibCrypto/Hash/HashFunction.h> |
10 | | #include <LibCrypto/Hash/SHA2.h> |
11 | | |
12 | | #ifndef KERNEL |
13 | | # include <AK/ByteString.h> |
14 | | #endif |
15 | | |
16 | | namespace Crypto::Hash { |
17 | | |
18 | | namespace BLAKE2bConstants { |
19 | | static constexpr auto blockbytes { 128 }; |
20 | | static constexpr auto hash_length { 64 }; |
21 | | }; |
22 | | |
23 | | class BLAKE2b final : public HashFunction<1024, 512> { |
24 | | public: |
25 | | using HashFunction::update; |
26 | | |
27 | | BLAKE2b() |
28 | 104 | { |
29 | 104 | reset(); |
30 | 104 | } |
31 | | |
32 | | virtual void update(u8 const*, size_t) override; |
33 | | virtual DigestType digest() override; |
34 | | virtual DigestType peek() override; |
35 | | |
36 | | static DigestType hash(u8 const* data, size_t length) |
37 | 104 | { |
38 | 104 | BLAKE2b blake2b; |
39 | 104 | blake2b.update(data, length); |
40 | 104 | return blake2b.digest(); |
41 | 104 | } |
42 | | |
43 | 0 | static DigestType hash(ByteBuffer const& buffer) { return hash(buffer.data(), buffer.size()); } |
44 | 0 | static DigestType hash(StringView buffer) { return hash((u8 const*)buffer.characters_without_null_termination(), buffer.length()); } |
45 | | |
46 | | #ifndef KERNEL |
47 | | virtual ByteString class_name() const override |
48 | 0 | { |
49 | 0 | return "BLAKE2b"; |
50 | 0 | } |
51 | | #endif |
52 | | |
53 | | virtual void reset() override |
54 | 208 | { |
55 | 208 | m_internal_state = {}; |
56 | | // BLAKE2b uses the same initialization vector as SHA512. |
57 | 1.87k | for (size_t i = 0; i < 8; ++i) |
58 | 1.66k | m_internal_state.hash_state[i] = SHA512Constants::InitializationHashes[i]; |
59 | 208 | m_internal_state.hash_state[0] ^= 0x01010000 ^ (0 << 8) ^ BLAKE2bConstants::hash_length; |
60 | 208 | } |
61 | | |
62 | | private: |
63 | | static constexpr u8 BLAKE2bSigma[12][16] = { |
64 | | { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, |
65 | | { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, |
66 | | { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, |
67 | | { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, |
68 | | { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, |
69 | | { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 }, |
70 | | { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 }, |
71 | | { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 }, |
72 | | { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 }, |
73 | | { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 }, |
74 | | { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, |
75 | | { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } |
76 | | }; |
77 | | |
78 | | struct BLAKE2bState { |
79 | | u64 hash_state[8] {}; |
80 | | u64 message_byte_offset[2] {}; |
81 | | u64 is_at_last_block { 0 }; |
82 | | u8 buffer[BLAKE2bConstants::blockbytes] = {}; |
83 | | size_t buffer_length { 0 }; |
84 | | }; |
85 | | |
86 | | BLAKE2bState m_internal_state {}; |
87 | | |
88 | | void mix(u64* work_vector, u64 a, u64 b, u64 c, u64 d, u64 x, u64 y); |
89 | | void increment_counter_by(u64 const amount); |
90 | | void transform(u8 const*); |
91 | | }; |
92 | | |
93 | | }; |