BLAKE2b.h 2.8 KB

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