51 constexpr size_t B = Hash::BLOCK_SIZE;
53 static_assert(Hash::OUTPUT_SIZE <= B);
54 constexpr uint8_t IPAD_CONST = 0x36;
55 constexpr uint8_t OPAD_CONST = 0x5c;
58 ipad.fill(IPAD_CONST);
59 opad.fill(OPAD_CONST);
65 std::vector<uint8_t> key_buffer(
key.begin(),
key.end());
66 auto truncated_key = Hash::hash(key_buffer);
67 std::copy(truncated_key.begin(), truncated_key.end(), k_prime.begin());
75 for (
size_t i = 0; i < B; ++i) {
76 h1[i] = k_prime[i] ^ opad[i];
80 for (
size_t i = 0; i < B; ++i) {
81 h2[i] = k_prime[i] ^ ipad[i];
85 std::vector<uint8_t> message_buffer;
86 message_buffer.reserve(B + message.size());
90 auto h3 = Hash::hash(message_buffer);
94 std::vector<uint8_t> hmac_buffer;
95 hmac_buffer.reserve(B + Hash::OUTPUT_SIZE);
99 auto hmac_key = Hash::hash(hmac_buffer);
105 std::copy(hmac_key.begin(), hmac_key.end(), result.begin());
123 requires(Hash::OUTPUT_SIZE == 32)
128 static_assert(Hash::OUTPUT_SIZE == 32,
129 "Hash output size must be 32 bytes for our implementation of RFC6979 nonce generation");
130 static constexpr size_t INITIAL_BUFFER_SIZE = 32;
134 std::vector<uint8_t> message_buffer(message.begin(), message.end());
135 auto hashed_message = Hash::hash(message_buffer);
143 std::vector<uint8_t> seed_material;
144 seed_material.reserve(
key.size() + hashed_message.size());
153 key_buffer.fill(0x00);
156 std::vector<uint8_t> tmp_buffer;
157 tmp_buffer.reserve(INITIAL_BUFFER_SIZE + 1 + seed_material.size());
159 tmp_buffer.emplace_back(0x00);
165 v_buffer, key_buffer);
169 tmp_buffer.reserve(INITIAL_BUFFER_SIZE + 1 + seed_material.size());
171 tmp_buffer.emplace_back(0x01);
177 v_buffer, key_buffer);
183 v_buffer, key_buffer);
186 if (Hash::OUTPUT_SIZE * 8 > MODULUS_BIT_LENGTH) {
187 std::vector<uint8_t> trimmed_v_buffer(v_buffer.begin(), v_buffer.end());
189 const uint8_t* ptr = trimmed_v_buffer.data();
191 read(ptr, trimmed_v);
194 trimmed_v = trimmed_v >> (Hash::OUTPUT_SIZE * 8 - MODULUS_BIT_LENGTH);
199 const uint8_t* ptr = v_buffer.
data();
207 std::vector<uint8_t> tmp_buffer;
208 tmp_buffer.reserve(INITIAL_BUFFER_SIZE + 1);
210 tmp_buffer.emplace_back(0x00);
214 v_buffer, key_buffer);
std::array< uint8_t, Hash::OUTPUT_SIZE > hmac(const MessageContainer &message, const KeyContainer &key)
Compute an HMAC given a secret key and a message, see https://datatracker.ietf.org/doc/html/rfc2104.