Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
hmac.test.cpp
Go to the documentation of this file.
1#include "hmac.hpp"
2#include <gtest/gtest.h>
3
4#include "../hashers/hashers.hpp"
7
8#include <array>
9#include <cstddef>
10#include <stdint.h>
11#include <vector>
12
13using namespace bb;
14using namespace bb::crypto;
15
16namespace {
17
18std::array<uint8_t, 32> hex_to_bytes(const std::string& hex)
19{
20 std::array<uint8_t, 32> bytes;
21 for (unsigned int i = 0; i < hex.length(); i += 2) {
22 std::string byteString = hex.substr(i, 2);
23 uint8_t byte = static_cast<uint8_t>(strtol(byteString.c_str(), nullptr, 16));
24 bytes[i >> 1] = byte;
25 }
26 return bytes;
27}
28
29} // namespace
30
31struct TestData {
32 std::string key;
33 std::string message;
34 std::string expected;
35};
36
37TEST(hmac, ValidateHMAC)
38{
39 // Test vectors from RFC4231, https://tools.ietf.org/html/rfc4231#section-4
40 // Formatted test vectors from https://github.com/h5p9sl/hmac_sha256/blob/master/tests/tests.cpp
42 // Key Data HMAC
43 {
44 "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
45 "\x0b\x0b\x0b",
46 "\x48\x69\x20\x54\x68\x65\x72\x65",
47 "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7",
48 },
49 {
50 /* Test with a key shorter than the length of the HMAC output. */
51 "\x4a\x65\x66\x65",
52 "\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61\x20\x77\x61\x6e\x74\x20\x66"
53 "\x6f\x72\x20\x6e\x6f\x74\x68\x69\x6e\x67\x3f",
54 "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843",
55 },
56 {
57 /* Test with a combined length of key and data that is larger than 64
58 bytes (= block-size of SHA-224 and SHA-256). */
59 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
60 "\xaa\xaa\xaa",
61 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
62 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
63 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
64 "773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe",
65 },
66 {
67 /* Test with a combined length of key and data that is larger than 64
68 bytes (= block-size of SHA-224 and SHA-256). */
69 "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11"
70 "\x12\x13\x14\x15\x16\x17\x18\x19",
71 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
72 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
73 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
74 "82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b",
75 },
76 {
77 /* Test with a key larger than 128 bytes (= block-size of SHA-384 and
78 SHA-512). */
79 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
80 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
81 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
82 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
83 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
84 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
85 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
86 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
87 "\x54\x65\x73\x74\x20\x55\x73\x69\x6e\x67\x20\x4c\x61\x72\x67\x65\x72"
88 "\x20\x54\x68\x61\x6e\x20\x42\x6c\x6f\x63\x6b\x2d\x53\x69\x7a\x65\x20"
89 "\x4b\x65\x79\x20\x2d\x20\x48\x61\x73\x68\x20\x4b\x65\x79\x20\x46\x69"
90 "\x72\x73\x74",
91 "60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54",
92 },
93 {
94 /* Test with a key and data that is larger than 128 bytes (=
95 block-size of SHA-384 and SHA-512). */
96 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
97 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
98 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
99 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
100 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
101 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
102 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
103 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
104 "\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74\x20\x75\x73"
105 "\x69\x6e\x67\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e"
106 "\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20\x61"
107 "\x6e\x64\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20"
108 "\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64\x61\x74\x61\x2e\x20"
109 "\x54\x68\x65\x20\x6b\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74\x6f\x20"
110 "\x62\x65\x20\x68\x61\x73\x68\x65\x64\x20\x62\x65\x66\x6f\x72\x65\x20"
111 "\x62\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20\x62\x79\x20\x74\x68\x65"
112 "\x20\x48\x4d\x41\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68\x6d\x2e",
113 "9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2",
114 }
115 };
116
117 for (const auto& [key_string, message, expected] : test_vectors) {
118 std::array<uint8_t, 32> result = hmac<Sha256Hasher>(message, key_string);
119
120 EXPECT_EQ(result, hex_to_bytes(expected));
121 }
122}
123
124TEST(NonceDerivation, ValidateRFC6979K1)
125{
126 // Test vectors from
127 // https://crypto.stackexchange.com/questions/20838/request-for-data-to-test-deterministic-ecdsa-signature-algorithm-for-secp256k1?utm_source=chatgpt.com
128 using Fr = bb::secp256k1::fr;
129 using G1 = bb::secp256k1::g1;
130 using AffineElement = G1::affine_element;
131
132 {
133 std::string message = "Absence makes the heart grow fonder.";
134 Fr key = Fr::one();
135 Fr expected_x_coordinate = Fr("0xAFFF580595971B8C1700E77069D73602AEF4C2A760DBD697881423DFFF845DE8");
136
137 std::array<uint8_t, 32> key_buffer;
138 Fr::serialize_to_buffer(key, &key_buffer[0]);
139
140 Fr result = deterministic_nonce_rfc6979<Sha256Hasher, Fr>(message, key_buffer);
141 AffineElement R = G1::one * result;
142
143 EXPECT_EQ(static_cast<uint512_t>(R.x), static_cast<uint512_t>(expected_x_coordinate));
144 }
145
146 {
147 std::string message = "Absence makes the heart grow fonder.";
148 Fr key = Fr("0x4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a");
149 Fr expected_x_coordinate = Fr("0x996D79FBA54B24E9394FC5FAB6BF94D173F3752645075DE6E32574FE08625F77");
150
151 std::array<uint8_t, 32> key_buffer;
152 Fr::serialize_to_buffer(key, &key_buffer[0]);
153
154 Fr result = deterministic_nonce_rfc6979<Sha256Hasher, Fr>(message, key_buffer);
155 AffineElement R = G1::one * result;
156
157 EXPECT_EQ(static_cast<uint512_t>(R.x), static_cast<uint512_t>(expected_x_coordinate));
158 }
159}
160
161TEST(NonceDerivation, ValidateRFC6979R1)
162{
163 // Test vectors from https://www.rfc-editor.org/rfc/rfc6979.html#appendix-A
164 using Fr = bb::secp256r1::fr;
165
166 {
167 std::string message = "sample";
168 Fr key = Fr("0xC9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721");
169 Fr expected = Fr("0xA6E3C57DD01ABE90086538398355DD4C3B17AA873382B0F24D6129493D8AAD60");
170
171 std::array<uint8_t, 32> key_buffer;
172 Fr::serialize_to_buffer(key, &key_buffer[0]);
173
174 Fr result = deterministic_nonce_rfc6979<Sha256Hasher, Fr>(message, key_buffer);
175
176 EXPECT_EQ(result, expected);
177 }
178
179 {
180 std::string message = "test";
181 Fr key = Fr("0xC9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721");
182 Fr expected = Fr("0xD16B6AE827F17175E040871A1C7EC3500192C4C92677336EC2537ACAEE0008E0");
183
184 std::array<uint8_t, 32> key_buffer;
185 Fr::serialize_to_buffer(key, &key_buffer[0]);
186
187 Fr result = deterministic_nonce_rfc6979<Sha256Hasher, Fr>(message, key_buffer);
188
189 EXPECT_EQ(result, expected);
190 }
191}
test_vector test_vectors[]
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.
Definition hmac.hpp:49
field< FrParams > fr
group< fq, fr, G1Params > g1
field< FrParams > fr
std::vector< uint8_t > hex_to_bytes(const std::string &hex)
Routine to transform hexstring to vector of bytes.
Definition utils.cpp:5
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
TEST(BoomerangMegaCircuitBuilder, BasicCircuit)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
Curve::ScalarField Fr
Curve::AffineElement G1
std::string message
Definition hmac.test.cpp:33
std::string expected
Definition hmac.test.cpp:34
std::string key
Definition hmac.test.cpp:32
static constexpr field one()
static void serialize_to_buffer(const field &value, uint8_t *buffer)