Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
ecdsa.test.cpp
Go to the documentation of this file.
1#include "ecdsa.hpp"
7#include <gtest/gtest.h>
8
9using namespace bb;
10using namespace bb::crypto;
11
13{
14 auto [actual, expected] = msgpack_roundtrip(ecdsa_signature{});
15 EXPECT_EQ(actual, expected);
16}
17
18TEST(ecdsa, verify_signature_grumpkin_sha256)
19{
20 std::string message = "The quick brown dog jumped over the lazy fox.";
21
24 account.public_key = grumpkin::g1::one * account.private_key;
25
26 ecdsa_signature signature =
27 ecdsa_construct_signature<Sha256Hasher, grumpkin::fq, grumpkin::fr, grumpkin::g1>(message, account);
28
29 bool result = ecdsa_verify_signature<Sha256Hasher, grumpkin::fq, grumpkin::fr, grumpkin::g1>(
30 message, account.public_key, signature);
31
32 EXPECT_EQ(result, true);
33}
34
35TEST(ecdsa, verify_signature_secp256r1_sha256)
36{
37 std::string message = "The quick brown dog jumped over the lazy fox.";
38
41 account.public_key = secp256r1::g1::one * account.private_key;
42
43 ecdsa_signature signature =
44 ecdsa_construct_signature<Sha256Hasher, secp256r1::fq, secp256r1::fr, secp256r1::g1>(message, account);
45
46 bool result = ecdsa_verify_signature<Sha256Hasher, secp256r1::fq, secp256r1::fr, secp256r1::g1>(
47 message, account.public_key, signature);
48
49 EXPECT_EQ(result, true);
50}
51
52TEST(ecdsa, recover_public_key_secp256k1_sha256)
53{
54 std::string message = "The quick brown dog jumped over the lazy fox.";
55
58 account.public_key = secp256k1::g1::one * account.private_key;
59
60 ecdsa_signature signature =
61 ecdsa_construct_signature<Sha256Hasher, secp256k1::fq, secp256k1::fr, secp256k1::g1>(message, account);
62
63 bool result = ecdsa_verify_signature<Sha256Hasher, secp256k1::fq, secp256k1::fr, secp256k1::g1>(
64 message, account.public_key, signature);
65
66 auto recovered_public_key =
67 ecdsa_recover_public_key<Sha256Hasher, secp256k1::fq, secp256k1::fr, secp256k1::g1>(message, signature);
68
69 EXPECT_EQ(result, true);
70 EXPECT_EQ(recovered_public_key, account.public_key);
71}
72
73TEST(ecdsa, recover_public_key_secp256r1_sha256)
74{
75 std::string message = "The quick brown dog jumped over the lazy fox.";
76
79 account.public_key = secp256r1::g1::one * account.private_key;
80
81 ecdsa_signature signature =
82 ecdsa_construct_signature<Sha256Hasher, secp256r1::fq, secp256r1::fr, secp256r1::g1>(message, account);
83
84 bool result = ecdsa_verify_signature<Sha256Hasher, secp256r1::fq, secp256r1::fr, secp256r1::g1>(
85 message, account.public_key, signature);
86
87 auto recovered_public_key =
88 ecdsa_recover_public_key<Sha256Hasher, secp256r1::fq, secp256r1::fr, secp256r1::g1>(message, signature);
89
90 EXPECT_EQ(result, true);
91 EXPECT_EQ(recovered_public_key, account.public_key);
92}
93
94TEST(ecdsa, check_overflowing_r_and_s_are_rejected)
95{
96
97 std::vector<uint8_t> message_vec = utils::hex_to_bytes("41414141");
98
99 std::string message(message_vec.begin(), message_vec.end());
100 ecdsa_signature signature;
101 grumpkin::fr private_key;
104 // We create a private and public key and a signature
105 private_key = grumpkin::fr::random_element();
106 public_key = grumpkin::g1::affine_element((grumpkin::g1::one * private_key).normalize());
107 key_pair = { private_key, public_key };
108 signature = ecdsa_construct_signature<Sha256Hasher, grumpkin::fq, grumpkin::fr, grumpkin::g1>(message, key_pair);
109 // Check that the signature is correct
110 bool result =
111 ecdsa_verify_signature<Sha256Hasher, grumpkin::fq, grumpkin::fr, grumpkin::g1>(message, public_key, signature);
112 EXPECT_TRUE(result);
113 using serialize::read;
114
115 const auto* p_r = &signature.r[0];
116 uint256_t old_r, new_r, old_s, new_s;
117 read(p_r, old_r);
118 new_r = old_r;
119 // We update r so it is larger than the modulus, but has the same value modulo fr::modulus
120 new_r = new_r + grumpkin::fr::modulus;
121 using serialize::write;
122 auto* p_r_m = &signature.r[0];
123 write(p_r_m, new_r);
124 result =
125 ecdsa_verify_signature<Sha256Hasher, grumpkin::fq, grumpkin::fr, grumpkin::g1>(message, public_key, signature);
126 // Signature verification should decline this signature, since it breaks specification
127 EXPECT_FALSE(result);
128 // Do the same for s, restore r
129 const auto* p_s = &signature.s[0];
130 read(p_s, old_s);
131 new_s = old_s;
132 new_s = new_s + grumpkin::fr::modulus;
133 using serialize::write;
134 auto* p_r_s = &signature.s[0];
135 write(p_r_m, old_r);
136 write(p_r_s, new_s);
137 result =
138 ecdsa_verify_signature<Sha256Hasher, grumpkin::fq, grumpkin::fr, grumpkin::g1>(message, public_key, signature);
139 EXPECT_FALSE(result);
140}
141
142TEST(ecdsa, verify_signature_secp256r1_sha256_NIST_1)
143{
144 /*
145 Msg =
146 5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045ee2bcd2e6dca3bdf46c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf9bd386a5e471ea7a65c17cc934a9d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8
147 d = 519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464
148 Qx = 1ccbe91c075fc7f4f033bfa248db8fccd3565de94bbfb12f3c59ff46c271bf83
149 Qy = ce4014c68811f9a21a1fdb2c0e6113e06db7ca93b7404e78dc7ccd5ca89a4ca9
150 k = 94a1bbb14b906a61a280f245f9e93c7f3b4a6247824f5d33b9670787642a68de
151 R = f3ac8061b514795b8843e3d6629527ed2afd6b1f6a555a7acabb5e6f79c8c2ac
152 S = 8bf77819ca05a6b2786c76262bf7371cef97b218e96f175a3ccdda2acc058903
153 */
154
155 secp256r1::fq P_x = secp256r1::fq(0x3c59ff46c271bf83, 0xd3565de94bbfb12f, 0xf033bfa248db8fcc, 0x1ccbe91c075fc7f4)
157 secp256r1::fq P_y = secp256r1::fq(0xdc7ccd5ca89a4ca9, 0x6db7ca93b7404e78, 0x1a1fdb2c0e6113e0, 0xce4014c68811f9a2)
159
160 secp256r1::g1::affine_element public_key(P_x, P_y);
161 std::array<uint8_t, 32> r{
162 0xf3, 0xac, 0x80, 0x61, 0xb5, 0x14, 0x79, 0x5b, 0x88, 0x43, 0xe3, 0xd6, 0x62, 0x95, 0x27, 0xed,
163 0x2a, 0xfd, 0x6b, 0x1f, 0x6a, 0x55, 0x5a, 0x7a, 0xca, 0xbb, 0x5e, 0x6f, 0x79, 0xc8, 0xc2, 0xac,
164 };
165
166 std::array<uint8_t, 32> s{
167 0x8b, 0xf7, 0x78, 0x19, 0xca, 0x05, 0xa6, 0xb2, 0x78, 0x6c, 0x76, 0x26, 0x2b, 0xf7, 0x37, 0x1c,
168 0xef, 0x97, 0xb2, 0x18, 0xe9, 0x6f, 0x17, 0x5a, 0x3c, 0xcd, 0xda, 0x2a, 0xcc, 0x05, 0x89, 0x03,
169 };
170
171 ecdsa_signature sig{ r, s, 27 };
172 std::vector<uint8_t> message_vec = utils::hex_to_bytes(
173 "5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045ee2bcd2e6dca3bdf46"
174 "c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf9bd386a5e471ea7a65c17cc934a9"
175 "d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8");
176 std::string message(message_vec.begin(), message_vec.end());
177
178 bool result =
179 ecdsa_verify_signature<Sha256Hasher, secp256r1::fq, secp256r1::fr, secp256r1::g1>(message, public_key, sig);
180 EXPECT_EQ(result, true);
181}
group_elements::affine_element< Fq, Fr, Params > affine_element
Definition group.hpp:42
static constexpr element one
Definition group.hpp:46
void read(B &it, SchnorrProofOfPossession< G1, Hash > &proof_of_possession)
void write(B &buf, SchnorrProofOfPossession< G1, Hash > const &proof_of_possession)
field< FqParams > fq
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.
TEST(MegaCircuitBuilder, CopyConstructor)
void read(auto &it, msgpack_concepts::HasMsgPack auto &obj)
Automatically derived read for any object that defines .msgpack() (implicitly defined by MSGPACK_FIEL...
void write(auto &buf, const msgpack_concepts::HasMsgPack auto &obj)
Automatically derived write for any object that defines .msgpack() (implicitly defined by MSGPACK_FIE...
G1::affine_element public_key
Definition ecdsa.hpp:20
std::array< uint8_t, 32 > r
Definition ecdsa.hpp:26
std::array< uint8_t, 32 > s
Definition ecdsa.hpp:27
static constexpr uint256_t modulus
BB_INLINE constexpr field to_montgomery_form() const noexcept
static field random_element(numeric::RNG *engine=nullptr) noexcept
std::pair< T, T > msgpack_roundtrip(const T &object)