libhasha 2.2.2
Loading...
Searching...
No Matches
evpp.h
Go to the documentation of this file.
1#pragma once
2
3#include <memory>
4#include <stdexcept>
5#include <vector>
6
7#include "evp.h"
8#include "internal/hadefs.h"
9#include "io.h"
10
11#if defined(HA_EVPP_AUTO_COMMIT)
12#define ha_evpp_auto_commit() commit()
13#else
14#define ha_evpp_auto_commit()
15#endif
16
17namespace hasha
18{
19using string = std::string;
20using byte = uint8_t;
21
22using raw_digest = byte *;
23using raw_cdigest = const byte *;
24
25using digest = std::vector<byte>;
26
28{
29 public:
30 virtual std::string encode(digest &digest) = 0;
31 virtual std::string encode(raw_cdigest digest, size_t size) = 0;
32 virtual digest decode(const std::string &str) = 0;
33 virtual void decode(const std::string &str, raw_digest digest,
34 size_t size) = 0;
35 virtual void decode(digest &digest, const std::string &s) = 0;
36};
37
38namespace encodings
39{
41{
42 public:
44 std::string encode(digest &digest) override
45 {
46 std::string str(ha_hash2str_bound(digest.size()), '\0');
47 ha_hash2str(str.data(), digest.data(), digest.size());
48 return str;
49 }
50
52 std::string encode(raw_cdigest digest, size_t size) override
53 {
54 std::string str(ha_hash2str_bound(size), '\0');
55 ha_hash2str(str.data(), digest, size);
56 return str;
57 }
58
60 digest decode(const std::string &s) override
61 {
62 digest digest(ha_str2hash_bound(s.length()));
63 ha_str2hash(digest.data(), s.data(), digest.size());
64 return digest;
65 }
66
68 void decode(const std::string &s, raw_digest digest,
69 size_t size) override
70 {
71 ha_str2hash(digest, s.data(), size);
72 }
73
75 void decode(digest &digest, const std::string &s) override
76 {
77 digest.resize(ha_str2hash_bound(s.length()));
78 ha_str2hash(digest.data(), s.data(), digest.size());
79 }
80};
81
83} // namespace encodings
84
85template <typename Encoding = encodings::hex_encoding>
87 std::ostream &os, raw_cdigest digest, size_t size,
88 const char *end = NULL,
89 std::shared_ptr<Encoding> encoding = std::make_shared<Encoding>())
90{
91 string s = encoding->encode(digest, size);
92 os << s;
93 if (end) os << string(end);
94}
95
96template <typename Encoding = encodings::hex_encoding>
97HA_HDR_PUBFUN void put(std::ostream &os, digest &digest,
98 const char *end = NULL,
99 const std::shared_ptr<Encoding> &encoding =
100 std::make_shared<Encoding>())
101{
102 put<Encoding>(os, digest.data(), digest.size(), end, encoding);
103}
104
105template <typename Encoding = encodings::hex_encoding>
106HA_HDR_PUBFUN void put(FILE *stream, raw_digest digest, size_t size,
107 const char *end = NULL,
108 const std::shared_ptr<Encoding> &encoding =
109 std::make_shared<Encoding>())
110{
111 if (!stream) return;
112 string s = encoding->encode(digest, size);
113 fprintf(stream, "%s", s.c_str());
114 if (end) fprintf(stream, "%s", end);
115 return;
116}
117
118template <typename Encoding = encodings::hex_encoding>
119HA_HDR_PUBFUN void put(FILE *stream, digest &digest,
120 const char *end = NULL,
121 const std::shared_ptr<Encoding> &encoding =
122 std::make_shared<Encoding>())
123{
124 put<Encoding>(stream, digest.data(), digest.size(), end, encoding);
125}
126
128void put(FILE *file, raw_cdigest digest, size_t size,
129 const char *end = NULL)
130{
131 ha_fputhash(file, digest, size, end);
132}
133
135void put(digest &digest, const char *end = NULL)
136{
137 put(stdout, digest, end);
138}
139
141void put(raw_cdigest digest, size_t size, const char *end = NULL)
142{
143 put(stdout, digest, size, end);
144}
145
147bool compare(const digest &lhs, const digest &rhs)
148{
149 if (lhs.size() != rhs.size()) return false;
150 size_t len = std::min /* using min, not max — safe for UB */ (
151 lhs.size(), rhs.size());
152 return ha_cmphash(lhs.data(), rhs.data(), len) == 0;
153}
154
156bool compare(const raw_cdigest lhs, size_t lsize, const raw_cdigest rhs,
157 size_t rsize)
158{
159 if (lsize != rsize) return false;
160 size_t len =
161 std::min /* using min, not max — safe for UB */ (lsize, rsize);
162 return ha_cmphash(lhs, rhs, len) == 0;
163}
164
166bool compare(const digest &lhs, const std::string &rhs)
167{
168 size_t len = std::min /* using min, not max — safe for UB */ (
169 lhs.size(), rhs.size());
170 return ha_cmphashstr(lhs.data(), rhs.data(), len) == 0;
171}
172
182{
183 public:
184 explicit Hasher(ha_evp_hashty type = HA_EVPTY_UNDEFINED,
185 size_t digestlen = 0)
187 {
188 if (!hasher_) throw std::runtime_error("Failed to create EVP hasher");
189 setup(type, digestlen);
190 commit();
191 }
192
193 ~Hasher() = default;
194 Hasher(const Hasher &) = delete;
195 Hasher &operator=(const Hasher &) = delete;
196 Hasher(Hasher &&) noexcept = default;
197 Hasher &operator=(Hasher &&) noexcept = default;
198
199 auto setType(ha_evp_hashty type) -> Hasher &
200 {
201 signed long tmp = 0;
202
203 hashty_ = type;
204 if ((tmp = ha_evp_hashty_get_digestlen(type)) > 0)
205 setDigestLength(tmp);
206
207 return *this;
208 }
209
210 auto setDigestLength(size_t length) -> Hasher &
211 {
212 digestlen_ = length;
214 return *this;
215 }
216
217 auto setup(ha_evp_hashty hashty, size_t length = 0) -> Hasher &
218 {
219 setType(hashty);
220 if (length) setDigestLength(length);
221 return *this;
222 }
223
224 auto getType() const { return hashty_; }
225
226 auto getType(ha_evp_hashty &hashty) -> Hasher &
227 {
228 hashty = hashty_;
229 return *this;
230 }
231
232 auto getDigestLength() const { return digestlen_; }
233
234 auto getDigestLength(size_t &digestlen) -> Hasher &
235 {
236 digestlen = digestlen_;
237 return *this;
238 }
239
240 auto init() -> Hasher &
241 {
242 ha_evp_init(hasher_.get());
243 return *this;
244 }
245
246 auto update(const void *data, size_t length) -> Hasher &
247 {
248 ha_evp_update(hasher_.get(), static_cast<const uint8_t *>(data),
249 length);
250 return *this;
251 }
252
253 auto update(const std::vector<uint8_t> &data) -> Hasher &
254 {
255 return update(data.data(), data.size());
256 }
257
258 auto update(const char *str) -> Hasher &
259 {
260 return update(str, strlen(str));
261 }
262
263 auto update(const std::string &str) -> Hasher &
264 {
265 return update(str.data(), str.size());
266 }
267
268 auto final(uint8_t *digest) -> Hasher &
269 {
270 ha_evp_final(hasher_.get(), digest);
271 return *this;
272 }
273
274 auto final(std::vector<uint8_t> &digest) -> Hasher &
275 {
276 digest.resize(digestlen_);
277 final(digest.data());
278 return *this;
279 }
280
281 auto final()
282 {
283 std::vector<uint8_t> digest(digestlen_);
284 final(digest);
285 return digest;
286 }
287
288 auto hash(const uint8_t *data, size_t length, uint8_t *digest)
289 -> Hasher &
290 {
291 ha_evp_hash(hasher_.get(), data, length, digest);
292 return *this;
293 }
294
295 auto hash(const std::vector<uint8_t> &data, std::vector<uint8_t> &digest)
296 -> Hasher &
297 {
298 digest.resize(digestlen_);
299 hash(data.data(), data.size(), digest.data());
300 return *this;
301 }
302
303 auto hash(const std::string &str, std::vector<uint8_t> &digest)
304 -> Hasher &
305 {
306 std::vector<uint8_t> data(str.begin(), str.end());
307 return hash(data, digest);
308 }
309
310 auto commit() -> Hasher &
311 {
312 if (hasher_) ha_evp_hasher_reinit(hasher_.get(), hashty_, digestlen_);
313 return *this;
314 }
315
316 auto ptr() { return this; }
317
318 auto ref() -> Hasher & { return *this; }
319
320 private:
321 ha_evp_hashty hashty_;
322 size_t digestlen_;
323 std::unique_ptr<ha_evp_hasher_t, decltype(&ha_evp_hasher_delete)>
324 hasher_;
325};
326
327#ifdef HA_EVPP_COMPATIBILITY
336class evp
337{
338 private:
342 void new_hasher()
343 {
344 hasher_.reset(ha_evp_hasher_new());
345 if (!hasher_)
346 throw std::runtime_error("Failed to (re)create EVP hasher");
347 }
348
352 void init_hasher()
353 {
354 ha_evp_hasher_init(hasher_.get(), hashty_, digestlen_);
355 }
356
360 void reinit_hasher()
361 {
362 ha_evp_hasher_reinit(hasher_.get(), hashty_, digestlen_);
363 }
364
368 void cleanup_hasher() { ha_evp_hasher_cleanup(hasher_.get()); }
369
373 void delete_hasher() { ha_evp_hasher_delete(hasher_.get()); }
374
375 public:
379 explicit evp(ha_evp_hashty hashty, size_t digestlen = 0)
380 : hashty_(hashty),
381 digestlen_(digestlen),
383 {
384 if (!hasher_) throw std::runtime_error("Failed to create EVP hasher");
385 init_hasher();
386 }
387
391 evp *set_hashty(ha_evp_hashty hashty)
392 {
393 hashty_ = hashty;
394 return this;
395 }
396
400 evp *set_digestlen(size_t digestlen)
401 {
402 digestlen_ = digestlen;
403 return this;
404 }
405
409 evp *commit()
410 {
411 reinit_hasher();
412 return this;
413 }
414
418 evp *init()
419 {
420 ha_evp_init(hasher_.get());
421 return this;
422 }
423
427 evp *update(ha_inbuf_t data, size_t len)
428 {
429 ha_evp_update(hasher_.get(), data, len);
430 return this;
431 }
432
436 evp *update(const std::vector<uint8_t> &data)
437 {
438 update(data.data(), data.size());
439 return this;
440 }
441
445 evp * final(ha_outbuf_t digest)
446 {
447 ha_evp_final(hasher_.get(), digest);
448 return this;
449 }
450
455 evp * final(std::vector<uint8_t> &digest)
456 {
457 digest.resize(digestlen_);
458 final(digest.data());
459 return this;
460 }
461
465 evp *hash(ha_inbuf_t data, size_t len, ha_outbuf_t digest)
466 {
467 ha_evp_hash(hasher_.get(), data, len, digest);
468 return this;
469 }
470
474 evp *hash(const std::vector<uint8_t> &data, std::vector<uint8_t> &digest)
475 {
476 digest.resize(digestlen_);
477 ha_evp_hash(hasher_.get(), data.data(), data.size(), digest.data());
478 return this;
479 }
480
481 private:
482 ha_evp_hashty hashty_;
483 size_t digestlen_;
484 std::unique_ptr<ha_evp_hasher_t, decltype(&ha_evp_hasher_delete)>
485 hasher_;
486
487 evp(const evp &) = delete;
488 evp &operator=(const evp &) = delete;
489};
490#endif
491
492} // namespace hasha
493
494#ifdef HA_EVPP_COMPATIBILITY
495namespace ha = hasha;
496#endif
Hasher(ha_evp_hashty type=HA_EVPTY_UNDEFINED, size_t digestlen=0)
Definition evpp.h:184
auto hash(const std::string &str, std::vector< uint8_t > &digest) -> Hasher &
Definition evpp.h:303
~Hasher()=default
Hasher & operator=(const Hasher &)=delete
auto update(const std::string &str) -> Hasher &
Definition evpp.h:263
Hasher(Hasher &&) noexcept=default
auto update(const std::vector< uint8_t > &data) -> Hasher &
Definition evpp.h:253
auto getDigestLength(size_t &digestlen) -> Hasher &
Definition evpp.h:234
auto update(const void *data, size_t length) -> Hasher &
Definition evpp.h:246
auto hash(const std::vector< uint8_t > &data, std::vector< uint8_t > &digest) -> Hasher &
Definition evpp.h:295
auto update(const char *str) -> Hasher &
Definition evpp.h:258
auto commit() -> Hasher &
Definition evpp.h:310
auto ref() -> Hasher &
Definition evpp.h:318
auto getDigestLength() const
Definition evpp.h:232
auto getType() const
Definition evpp.h:224
auto hash(const uint8_t *data, size_t length, uint8_t *digest) -> Hasher &
Definition evpp.h:288
auto getType(ha_evp_hashty &hashty) -> Hasher &
Definition evpp.h:226
auto init() -> Hasher &
Definition evpp.h:240
auto setType(ha_evp_hashty type) -> Hasher &
Definition evpp.h:199
Hasher(const Hasher &)=delete
auto ptr()
Definition evpp.h:316
auto setup(ha_evp_hashty hashty, size_t length=0) -> Hasher &
Definition evpp.h:217
auto setDigestLength(size_t length) -> Hasher &
Definition evpp.h:210
Header file for the EVP Hasher abstraction.
HA_PUBFUN void ha_evp_init(struct ha_evp_hasher *hasher)
Initializes the EVP hash. ( like ha_init(hash, ctx) )
HA_PUBFUN struct ha_evp_hasher * ha_evp_hasher_new(void)
Creates a new EVP hasher. ( malloc(g_ha_evp_hasher_size) )
HA_PUBFUN void ha_evp_hasher_cleanup(struct ha_evp_hasher *hasher)
Cleans up the internal state of the EVP hasher.
HA_PUBFUN void ha_evp_hasher_delete(struct ha_evp_hasher *ptr)
Frees the memory of an EVP hasher.
HA_PUBFUN void ha_evp_hasher_init(struct ha_evp_hasher *hasher, enum ha_evp_hashty hashty, size_t digestlen)
Initializes the EVP hasher for a specific algorithm and digest length.
HA_PUBFUN void ha_evp_hash(struct ha_evp_hasher *hasher, ha_inbuf_t buf, size_t len, ha_digest_t digest)
Computes the EVP hash in a single (hash) operation. ( like ha_hash(hash, buf, len,...
HA_PUBFUN signed long ha_evp_hashty_get_digestlen(enum ha_evp_hashty hashty)
Get fixed hash size.
HA_PUBFUN void ha_evp_update(struct ha_evp_hasher *hasher, ha_inbuf_t buf, size_t len)
Updates the EVP hash with input data. ( like ha_update(hash, ctx, buf, len) )
HA_PUBFUN void ha_evp_hasher_reinit(struct ha_evp_hasher *hasher, enum ha_evp_hashty hashty, size_t digestlen)
Reinitializes the EVP hasher with a new algorithm and digest length.
HA_PUBFUN void ha_evp_final(struct ha_evp_hasher *hasher, ha_digest_t digest)
Finalizes the EVP hash and produces the output digest. ( like ha_final(hash, ctx, digest,...
struct ha_evp_hasher ha_evp_hasher_t
Opaque structure for the EVP hasher state.
Definition evp.h:133
#define ha_evpp_auto_commit()
Definition evpp.h:14
#define HA_INL_FUN
Definition hadefs.h:43
#define HA_HDR_PUBFUN
Definition hadefs.h:53
Header file for I/O operations related to hashing.
HA_PUBFUN size_t ha_hash2str(char *dst, ha_cdigest_t src, size_t len)
Converts a hash digest to a hexadecimal string representation.
HA_PUBFUN int ha_cmphash(ha_cdigest_t lhs, ha_cdigest_t rhs, size_t digestlen)
Compares two hash digests byte by byte.
#define ha_hash2str_bound(len)
Definition io.h:60
HA_PUBFUN size_t ha_str2hash(ha_digest_t dst, const char *src, size_t len)
Converts a hexadecimal string representation to a hash digest.
HA_PUBFUN int ha_cmphashstr(ha_cdigest_t lhs, const char *rhs, size_t digestlen)
Compares a hash digest with a hexadecimal string representation.
HA_PUBFUN size_t ha_fputhash(FILE *stream, ha_cdigest_t digest, size_t digestlen, const char *end)
Writes the hash digest to the specified file stream.
#define ha_str2hash_bound(len)
Definition io.h:61
hex_encoding hex
Definition evpp.h:82
Definition evpp.h:18
uint8_t byte
Definition evpp.h:20
std::vector< byte > digest
Definition evpp.h:25
byte * raw_digest
Definition evpp.h:22
HA_HDR_PUBFUN void put(std::ostream &os, raw_cdigest digest, size_t size, const char *end=NULL, std::shared_ptr< Encoding > encoding=std::make_shared< Encoding >())
Definition evpp.h:86
HA_HDR_PUBFUN bool compare(const digest &lhs, const digest &rhs)
Definition evpp.h:147
std::string string
Definition evpp.h:19
const byte * raw_cdigest
Definition evpp.h:23
virtual digest decode(const std::string &str)=0
virtual void decode(const std::string &str, raw_digest digest, size_t size)=0
virtual std::string encode(digest &digest)=0
virtual void decode(digest &digest, const std::string &s)=0
virtual std::string encode(raw_cdigest digest, size_t size)=0
HA_INL_FUN void decode(const std::string &s, raw_digest digest, size_t size) override
Definition evpp.h:68
HA_INL_FUN std::string encode(raw_cdigest digest, size_t size) override
Definition evpp.h:52
HA_INL_FUN std::string encode(digest &digest) override
Definition evpp.h:44
HA_INL_FUN void decode(digest &digest, const std::string &s) override
Definition evpp.h:75
HA_INL_FUN digest decode(const std::string &s) override
Definition evpp.h:60
__ha_out_buf_type ha_outbuf_t
Definition types.h:13
__ha_in_buf_type ha_inbuf_t
Definition types.h:12