Coverage Report

Created: 2025-08-28 06:26

/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
};