TrinityCore
CryptoHash.h
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef TRINITY_CRYPTOHASH_H
19#define TRINITY_CRYPTOHASH_H
20
21#include "CryptoConstants.h"
22#include "Define.h"
23#include "Errors.h"
24#include <array>
25#include <string>
26#include <string_view>
27#include <utility>
28#include <openssl/evp.h>
29
30class BigNumber;
31
32namespace Trinity::Impl
33{
35 {
36 typedef EVP_MD const* (*HashCreator)();
37
38 static EVP_MD_CTX* MakeCTX() noexcept { return EVP_MD_CTX_new(); }
39 static void DestroyCTX(EVP_MD_CTX* ctx) { EVP_MD_CTX_free(ctx); }
40 };
41
42 template <GenericHashImpl::HashCreator HashCreator, size_t DigestLength>
44 {
45 public:
46 static constexpr size_t DIGEST_LENGTH = DigestLength;
47 using Digest = std::array<uint8, DIGEST_LENGTH>;
48
49 static Digest GetDigestOf(uint8 const* data, size_t len)
50 {
51 GenericHash hash;
52 hash.UpdateData(data, len);
53 hash.Finalize();
54 return hash.GetDigest();
55 }
56
57 template <typename... Ts>
58 static auto GetDigestOf(Ts&&... pack) -> std::enable_if_t<std::conjunction_v<std::negation<std::is_integral<Ts>>...>, Digest>
59 {
60 GenericHash hash;
61 (hash.UpdateData(std::forward<Ts>(pack)), ...);
62 hash.Finalize();
63 return hash.GetDigest();
64 }
65
67 {
68 int result = EVP_DigestInit_ex(_ctx, HashCreator(), nullptr);
69 ASSERT(result == 1);
70 }
71
72 GenericHash(GenericHash const& right) : _ctx(GenericHashImpl::MakeCTX())
73 {
74 *this = right;
75 }
76
77 GenericHash(GenericHash&& right) noexcept
78 {
79 *this = std::move(right);
80 }
81
83 {
84 if (!_ctx)
85 return;
87 _ctx = nullptr;
88 }
89
91 {
92 if (this == &right)
93 return *this;
94
95 int result = EVP_MD_CTX_copy_ex(_ctx, right._ctx);
96 ASSERT(result == 1);
97 _digest = right._digest;
98 return *this;
99 }
100
102 {
103 if (this == &right)
104 return *this;
105
106 _ctx = std::exchange(right._ctx, GenericHashImpl::MakeCTX());
107 _digest = std::exchange(right._digest, Digest{});
108 return *this;
109 }
110
111 void UpdateData(uint8 const* data, size_t len)
112 {
113 int result = EVP_DigestUpdate(_ctx, data, len);
114 ASSERT(result == 1);
115 }
116 void UpdateData(std::string_view str) { UpdateData(reinterpret_cast<uint8 const*>(str.data()), str.size()); }
117 void UpdateData(std::string const& str) { UpdateData(std::string_view(str)); } /* explicit overload to avoid using the container template */
118 void UpdateData(char const* str) { UpdateData(std::string_view(str)); } /* explicit overload to avoid using the container template */
119 template <typename Container>
120 void UpdateData(Container const& c) { UpdateData(std::data(c), std::size(c)); }
121
122 void Finalize()
123 {
124 uint32 length;
125 int result = EVP_DigestFinal_ex(_ctx, _digest.data(), &length);
126 ASSERT(result == 1);
127 ASSERT(length == DIGEST_LENGTH);
128 }
129
130 Digest const& GetDigest() const { return _digest; }
131
132 private:
133 EVP_MD_CTX* _ctx;
135 };
136}
137
138namespace Trinity::Crypto
139{
144}
145
146#endif
uint8_t uint8
Definition: Define.h:144
uint32_t uint32
Definition: Define.h:142
#define ASSERT
Definition: Errors.h:68
void UpdateData(Container const &c)
Definition: CryptoHash.h:120
void UpdateData(std::string_view str)
Definition: CryptoHash.h:116
GenericHash(GenericHash &&right) noexcept
Definition: CryptoHash.h:77
GenericHash & operator=(GenericHash &&right) noexcept
Definition: CryptoHash.h:101
void UpdateData(std::string const &str)
Definition: CryptoHash.h:117
std::array< uint8, DIGEST_LENGTH > Digest
Definition: CryptoHash.h:47
void UpdateData(uint8 const *data, size_t len)
Definition: CryptoHash.h:111
GenericHash & operator=(GenericHash const &right)
Definition: CryptoHash.h:90
GenericHash(GenericHash const &right)
Definition: CryptoHash.h:72
static constexpr size_t DIGEST_LENGTH
Definition: CryptoHash.h:46
Digest const & GetDigest() const
Definition: CryptoHash.h:130
static Digest GetDigestOf(uint8 const *data, size_t len)
Definition: CryptoHash.h:49
void UpdateData(char const *str)
Definition: CryptoHash.h:118
static auto GetDigestOf(Ts &&... pack) -> std::enable_if_t< std::conjunction_v< std::negation< std::is_integral< Ts > >... >, Digest >
Definition: CryptoHash.h:58
constexpr std::size_t size()
Definition: UpdateField.h:796
static void DestroyCTX(EVP_MD_CTX *ctx)
Definition: CryptoHash.h:39
static EVP_MD_CTX * MakeCTX() noexcept
Definition: CryptoHash.h:38