3#include "barretenberg/common/serialize.hpp"
4#include "barretenberg/numeric/uintx/uintx.hpp"
22template <
typename Hash,
typename MessageContainer,
typename KeyContainer>
23std::array<uint8_t, Hash::OUTPUT_SIZE>
hmac(
const MessageContainer& message,
const KeyContainer& key)
25 constexpr size_t B = Hash::BLOCK_SIZE;
27 static_assert(Hash::OUTPUT_SIZE <= B);
28 constexpr uint8_t IPAD_CONST = 0x36;
29 constexpr uint8_t OPAD_CONST = 0x5c;
30 std::array<uint8_t, B> ipad;
31 std::array<uint8_t, B> opad;
32 ipad.fill(IPAD_CONST);
33 opad.fill(OPAD_CONST);
38 std::array<uint8_t, B> k_prime{};
40 const auto truncated_key = Hash::hash(key);
41 std::copy(truncated_key.begin(), truncated_key.end(), k_prime.begin());
43 std::copy(key.begin(), key.end(), k_prime.begin());
47 std::array<uint8_t, B> h1;
48 for (
size_t i = 0; i < B; ++i) {
49 h1[i] = k_prime[i] ^ opad[i];
53 std::array<uint8_t, B> h2;
54 for (
size_t i = 0; i < B; ++i) {
55 h2[i] = k_prime[i] ^ ipad[i];
60 std::vector<uint8_t> message_buffer;
61 std::copy(h2.begin(), h2.end(), std::back_inserter(message_buffer));
62 std::copy(message.begin(), message.end(), std::back_inserter(message_buffer));
64 const auto h3 = Hash::hash(message_buffer);
68 std::vector<uint8_t> hmac_buffer;
69 std::copy(h1.begin(), h1.end(), std::back_inserter(hmac_buffer));
70 std::copy(h3.begin(), h3.end(), std::back_inserter(hmac_buffer));
72 const auto hmac_key = Hash::hash(hmac_buffer);
74 std::array<uint8_t, Hash::OUTPUT_SIZE> result;
75 std::copy(hmac_key.begin(), hmac_key.end(), result.begin());
95template <
typename Hash,
typename Fr,
typename MessageContainer,
typename KeyContainer>
97 requires(Hash::OUTPUT_SIZE == 32)
100 static_assert(Hash::BLOCK_SIZE > Hash::OUTPUT_SIZE);
101 constexpr size_t DOMAIN_SEPARATOR_SIZE = Hash::BLOCK_SIZE - Hash::OUTPUT_SIZE;
105 constexpr std::array<uint8_t, DOMAIN_SEPARATOR_SIZE> KLO_DOMAIN_SEPARATOR{ 0x0 };
106 constexpr std::array<uint8_t, DOMAIN_SEPARATOR_SIZE> KHI_DOMAIN_SEPARATOR{ 0x1 };
108 auto input = hmac<Hash, MessageContainer, KeyContainer>(message, key);
111 std::vector<uint8_t> lo_buffer(KLO_DOMAIN_SEPARATOR.begin(), KLO_DOMAIN_SEPARATOR.end());
112 std::copy(input.begin(), input.end(), std::back_inserter(lo_buffer));
113 auto klo = Hash::hash(lo_buffer);
116 std::vector<uint8_t> hi_buffer(KHI_DOMAIN_SEPARATOR.begin(), KHI_DOMAIN_SEPARATOR.end());
117 std::copy(input.begin(), input.end(), std::back_inserter(hi_buffer));
118 auto khi = Hash::hash(hi_buffer);
121 std::vector<uint8_t> full_buffer(khi.begin(), khi.end());
122 std::copy(klo.begin(), klo.end(), std::back_inserter(full_buffer));
124 auto field_as_u512 = from_buffer<numeric::uint512_t>(full_buffer);
126 Fr result((field_as_u512 % Fr::modulus).lo);
std::array< uint8_t, Hash::OUTPUT_SIZE > hmac(const MessageContainer &message, const KeyContainer &key)
Compute an HMAC given a secret key and a message.
Definition: hmac.hpp:23
Fr get_unbiased_field_from_hmac(const MessageContainer &message, const KeyContainer &key)
Takes a size-HASH_OUTPUT buffer from HMAC and converts into a field element.
Definition: hmac.hpp:96