Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
bbapi_handlers.cpp
Go to the documentation of this file.
1
19#include "barretenberg/bbapi/generated/bb_dispatch.hpp"
37
38namespace bb::bbapi {
39
40namespace {
41
42// Reset the AVM per-stage timings registry so the snapshot we return reflects only this call.
43void reset_avm_stats()
44{
46}
47
48// Take a snapshot of the AVM per-stage timings registry as wire-typed stats entries.
49std::vector<wire::AvmStat> snapshot_avm_stats_wire()
50{
51 auto snapshot = ::bb::avm2::Stats::get().snapshot();
53 result.reserve(snapshot.size());
54 for (auto& [name, value] : snapshot) {
55 result.push_back(wire::AvmStat{ .name = std::move(name), .value_ms = value });
56 }
57 return result;
58}
59
60} // namespace
61
62// ===========================================================================
63// AVM
64// ===========================================================================
65
66wire::AvmProveResponse handle_avm_prove(BBApiRequest& /*ctx*/, wire::AvmProve&& cmd)
67{
68 reset_avm_stats();
69 auto result = avm_prove_from_bytes(std::move(cmd.inputs));
70 return { .proof = fr_vec_to_wire(result.proof), .stats = snapshot_avm_stats_wire() };
71}
72wire::AvmVerifyResponse handle_avm_verify(BBApiRequest& /*ctx*/, wire::AvmVerify&& cmd)
73{
74 bool verified = avm_verify_from_bytes(fr_vec_from_wire(cmd.proof), std::move(cmd.public_inputs));
75 return { .verified = verified };
76}
77wire::AvmCheckCircuitResponse handle_avm_check_circuit(BBApiRequest& /*ctx*/, wire::AvmCheckCircuit&& cmd)
78{
79 reset_avm_stats();
80 bool passed = avm_check_circuit_from_bytes(std::move(cmd.inputs));
81 return { .passed = passed, .stats = snapshot_avm_stats_wire() };
82}
83
84// ===========================================================================
85// Circuit + Chonk + UltraHonk
86// ===========================================================================
87
88// UltraHonk handlers live in bbapi_ultra_honk.cpp.
89// Chonk handlers live in bbapi_chonk.cpp.
90
91// ===========================================================================
92// Hashing primitives
93// ===========================================================================
94
95wire::Poseidon2HashResponse handle_poseidon2_hash(BBApiRequest& /*ctx*/, wire::Poseidon2Hash&& cmd)
96{
97 auto inputs = fr_vec_from_wire(cmd.inputs);
99 return { .hash = fr_to_wire(hash) };
100}
101wire::Poseidon2PermutationResponse handle_poseidon2_permutation(BBApiRequest& /*ctx*/, wire::Poseidon2Permutation&& cmd)
102{
104 auto inputs = fr_array_from_wire<4>(cmd.inputs);
105 auto outputs = Permutation::permutation(inputs);
106 return { .outputs = fr_array_to_wire<4>(outputs) };
107}
108wire::PedersenCommitResponse handle_pedersen_commit(BBApiRequest& /*ctx*/, wire::PedersenCommit&& cmd)
109{
111 gctx.offset = static_cast<size_t>(cmd.hash_index);
112 auto inputs = fr_vec_from_wire(cmd.inputs);
114 return { .point = grumpkin_point_to_wire(point) };
115}
116wire::PedersenHashResponse handle_pedersen_hash(BBApiRequest& /*ctx*/, wire::PedersenHash&& cmd)
117{
119 gctx.offset = static_cast<size_t>(cmd.hash_index);
120 auto inputs = fr_vec_from_wire(cmd.inputs);
121 auto hash = crypto::pedersen_hash::hash(inputs, gctx);
122 return { .hash = fr_to_wire(hash) };
123}
124wire::PedersenHashBufferResponse handle_pedersen_hash_buffer(BBApiRequest& /*ctx*/, wire::PedersenHashBuffer&& cmd)
125{
127 gctx.offset = static_cast<size_t>(cmd.hash_index);
128 auto hash = crypto::pedersen_hash::hash_buffer(cmd.input, gctx);
129 return { .hash = fr_to_wire(hash) };
130}
131wire::Blake2sResponse handle_blake2s(BBApiRequest& /*ctx*/, wire::Blake2s&& cmd)
132{
133 return { .hash = crypto::blake2s(cmd.data) };
134}
135wire::Blake2sToFieldResponse handle_blake2s_to_field(BBApiRequest& /*ctx*/, wire::Blake2sToField&& cmd)
136{
137 auto hash_result = crypto::blake2s(cmd.data);
138 return { .field = fr_to_wire(fr::serialize_from_buffer(hash_result.data())) };
139}
140wire::AesEncryptResponse handle_aes_encrypt(BBApiRequest& /*ctx*/, wire::AesEncrypt&& cmd)
141{
142 BB_ASSERT(cmd.length == cmd.plaintext.size(), "AesEncrypt: length must equal plaintext.size()");
143 BB_ASSERT(cmd.length % 16 == 0, "AesEncrypt: length must be a multiple of 16");
144
145 std::vector<uint8_t> result = std::move(cmd.plaintext);
146 result.resize(cmd.length);
147 crypto::aes128_encrypt_buffer_cbc(result.data(), cmd.iv.data(), cmd.key.data(), cmd.length);
148 return { .ciphertext = std::move(result) };
149}
150wire::AesDecryptResponse handle_aes_decrypt(BBApiRequest& /*ctx*/, wire::AesDecrypt&& cmd)
151{
152 BB_ASSERT(cmd.length == cmd.ciphertext.size(), "AesDecrypt: length must equal ciphertext.size()");
153 BB_ASSERT(cmd.length % 16 == 0, "AesDecrypt: length must be a multiple of 16");
154
155 std::vector<uint8_t> result = std::move(cmd.ciphertext);
156 result.resize(cmd.length);
157 crypto::aes128_decrypt_buffer_cbc(result.data(), cmd.iv.data(), cmd.key.data(), cmd.length);
158 return { .plaintext = std::move(result) };
159}
160
161// ===========================================================================
162// Grumpkin curve
163// ===========================================================================
164
165wire::GrumpkinMulResponse handle_grumpkin_mul(BBApiRequest& request, wire::GrumpkinMul&& cmd)
166{
167 auto point = grumpkin_point_from_wire(cmd.point);
168 auto scalar = field_from_wire<grumpkin::fr>(cmd.scalar);
169 if (!point.on_curve()) {
170 BBAPI_ERROR(request, "Input point must be on the curve");
171 }
172 return { .point = grumpkin_point_to_wire(point * scalar) };
173}
174wire::GrumpkinAddResponse handle_grumpkin_add(BBApiRequest& request, wire::GrumpkinAdd&& cmd)
175{
176 auto a = grumpkin_point_from_wire(cmd.point_a);
177 auto b = grumpkin_point_from_wire(cmd.point_b);
178 if (!a.on_curve()) {
179 BBAPI_ERROR(request, "Input point_a must be on the curve");
180 }
181 if (!b.on_curve()) {
182 BBAPI_ERROR(request, "Input point_b must be on the curve");
183 }
184 return { .point = grumpkin_point_to_wire(a + b) };
185}
186wire::GrumpkinBatchMulResponse handle_grumpkin_batch_mul(BBApiRequest& request, wire::GrumpkinBatchMul&& cmd)
187{
188 auto points = grumpkin_point_vec_from_wire(cmd.points);
189 auto scalar = field_from_wire<grumpkin::fr>(cmd.scalar);
190 for (const auto& p : points) {
191 if (!p.on_curve()) {
192 BBAPI_ERROR(request, "Input point must be on the curve");
193 }
194 }
195 auto output = grumpkin::g1::element::batch_mul_with_endomorphism(points, scalar);
196 return { .points = grumpkin_point_vec_to_wire(output) };
197}
198wire::GrumpkinGetRandomFrResponse handle_grumpkin_get_random_fr(BBApiRequest& /*ctx*/,
199 wire::GrumpkinGetRandomFr&& /*cmd*/)
200{
201 return { .value = fr_to_wire(bb::fr::random_element()) };
202}
203wire::GrumpkinReduce512Response handle_grumpkin_reduce512(BBApiRequest& /*ctx*/, wire::GrumpkinReduce512&& cmd)
204{
205 auto bigint_input = from_buffer<uint512_t>(cmd.input.data());
206 uint512_t barretenberg_modulus(bb::fr::modulus);
207 uint512_t target_output = bigint_input % barretenberg_modulus;
208 return { .value = fr_to_wire(bb::fr(target_output.lo)) };
209}
210
211// ===========================================================================
212// Secp256k1 curve
213// ===========================================================================
214
215wire::Secp256k1MulResponse handle_secp256k1_mul(BBApiRequest& request, wire::Secp256k1Mul&& cmd)
216{
217 auto point = secp256k1_point_from_wire(cmd.point);
218 auto scalar = field_from_wire<secp256k1::fr>(cmd.scalar);
219 if (!point.on_curve()) {
220 BBAPI_ERROR(request, "Input point must be on the curve");
221 }
222 return { .point = secp256k1_point_to_wire(point * scalar) };
223}
224wire::Secp256k1GetRandomFrResponse handle_secp256k1_get_random_fr(BBApiRequest& /*ctx*/,
225 wire::Secp256k1GetRandomFr&& /*cmd*/)
226{
227 return { .value = field_to_wire_as<Secp256k1Fr>(secp256k1::fr::random_element()) };
228}
229wire::Secp256k1Reduce512Response handle_secp256k1_reduce512(BBApiRequest& /*ctx*/, wire::Secp256k1Reduce512&& cmd)
230{
231 auto bigint_input = from_buffer<uint512_t>(cmd.input.data());
232 uint512_t secp256k1_modulus(secp256k1::fr::modulus);
233 uint512_t target_output = bigint_input % secp256k1_modulus;
234 return { .value = field_to_wire_as<Secp256k1Fr>(secp256k1::fr(target_output.lo)) };
235}
236
237// ===========================================================================
238// Bn254 curve
239// ===========================================================================
240
241wire::Bn254FrSqrtResponse handle_bn254_fr_sqrt(BBApiRequest& /*ctx*/, wire::Bn254FrSqrt&& cmd)
242{
243 auto [is_sqr, root] = fr_from_wire(cmd.input).sqrt();
244 return { .is_square_root = is_sqr, .value = fr_to_wire(root) };
245}
246wire::Bn254FqSqrtResponse handle_bn254_fq_sqrt(BBApiRequest& /*ctx*/, wire::Bn254FqSqrt&& cmd)
247{
248 auto [is_sqr, root] = field_from_wire<bb::fq>(cmd.input).sqrt();
249 return { .is_square_root = is_sqr, .value = field_to_wire_as<Fq>(root) };
250}
251wire::Bn254G1MulResponse handle_bn254_g1_mul(BBApiRequest& request, wire::Bn254G1Mul&& cmd)
252{
253 auto point = bn254_g1_point_from_wire(cmd.point);
254 auto scalar = fr_from_wire(cmd.scalar);
255 if (!point.on_curve()) {
256 BBAPI_ERROR(request, "Input point must be on the curve");
257 }
258 auto result = point * scalar;
259 if (!result.on_curve()) {
260 BBAPI_ERROR(request, "Output point must be on the curve");
261 }
262 return { .point = bn254_g1_point_to_wire(result) };
263}
264wire::Bn254G2MulResponse handle_bn254_g2_mul(BBApiRequest& request, wire::Bn254G2Mul&& cmd)
265{
266 auto point = bn254_g2_point_from_wire(cmd.point);
267 auto scalar = fr_from_wire(cmd.scalar);
268 if (!point.on_curve()) {
269 BBAPI_ERROR(request, "Input point must be on the curve");
270 }
271 // BN254 G2 has cofactor h2 ≈ 2^254. An on-curve point may lie in a cofactor subgroup of order
272 // dividing h2 rather than the prime-order subgroup; we do not want to allow such points
273 // as inputs to bbapi.
274 if (!point.is_in_prime_subgroup()) {
275 BBAPI_ERROR(request, "Input point must lie in the prime-order subgroup");
276 }
277 auto result = point * scalar;
278 if (!result.on_curve()) {
279 BBAPI_ERROR(request, "Output point must be on the curve");
280 }
281 return { .point = bn254_g2_point_to_wire(result) };
282}
283wire::Bn254G1IsOnCurveResponse handle_bn254_g1_is_on_curve(BBApiRequest& /*ctx*/, wire::Bn254G1IsOnCurve&& cmd)
284{
285 return { .is_on_curve = bn254_g1_point_from_wire(cmd.point).on_curve() };
286}
287wire::Bn254G1FromCompressedResponse handle_bn254_g1_from_compressed(BBApiRequest& request,
288 wire::Bn254G1FromCompressed&& cmd)
289{
290 uint256_t compressed_value = from_buffer<uint256_t>(cmd.compressed.data());
291 auto point = bb::g1::affine_element::from_compressed(compressed_value);
292 if (!point.on_curve()) {
293 BBAPI_ERROR(request, "Decompressed point is not on the curve");
294 }
295 return { .point = bn254_g1_point_to_wire(point) };
296}
297
298// ===========================================================================
299// Schnorr
300// ===========================================================================
301
302wire::SchnorrComputePublicKeyResponse handle_schnorr_compute_public_key(BBApiRequest& /*ctx*/,
303 wire::SchnorrComputePublicKey&& cmd)
304{
305 auto private_key = field_from_wire<grumpkin::fr>(cmd.private_key);
306 return { .public_key = grumpkin_point_to_wire(grumpkin::g1::one * private_key) };
307}
308// Schnorr signing takes a pre-derived field element. The wire keeps
309// `message: vector<u8>` for layout consistency with other byte-buffer
310// endpoints; callers must pass the 32-byte big-endian field encoding.
311wire::SchnorrConstructSignatureResponse handle_schnorr_construct_signature(BBApiRequest& /*ctx*/,
312 wire::SchnorrConstructSignature&& cmd)
313{
314 auto private_key = field_from_wire<grumpkin::fr>(cmd.private_key);
315 grumpkin::g1::affine_element pub_key = grumpkin::g1::one * private_key;
316 crypto::schnorr_key_pair<grumpkin::fr, grumpkin::g1> key_pair = { private_key, pub_key };
317
319 cmd.message.size(), size_t{ 32 }, "SchnorrConstructSignature: message must be 32 bytes (field element)");
320 auto message_field = grumpkin::fq::serialize_from_buffer(cmd.message.data());
321 auto sig = crypto::schnorr_construct_signature<grumpkin::fr, grumpkin::g1>(message_field, key_pair);
322 crypto::secure_erase_bytes(&key_pair.private_key, sizeof(key_pair.private_key));
323
324 return { .s = field_to_wire<grumpkin::fr>(sig.s), .e = field_to_wire<grumpkin::fr>(sig.e) };
325}
326wire::SchnorrVerifySignatureResponse handle_schnorr_verify_signature(BBApiRequest& /*ctx*/,
327 wire::SchnorrVerifySignature&& cmd)
328{
329 BB_ASSERT_EQ(cmd.message.size(), size_t{ 32 }, "SchnorrVerifySignature: message must be 32 bytes (field element)");
330 auto message_field = grumpkin::fq::serialize_from_buffer(cmd.message.data());
331 crypto::schnorr_signature sig = { field_from_wire<grumpkin::fr>(cmd.s), field_from_wire<grumpkin::fr>(cmd.e) };
332 auto public_key = grumpkin_point_from_wire(cmd.public_key);
333
334 bool result = crypto::schnorr_verify_signature<grumpkin::fr, grumpkin::g1>(message_field, public_key, sig);
335 return { .verified = result };
336}
337
338// ===========================================================================
339// ECDSA
340// ===========================================================================
341
342wire::EcdsaSecp256k1ComputePublicKeyResponse handle_ecdsa_secp256k1_compute_public_key(
343 BBApiRequest& /*ctx*/, wire::EcdsaSecp256k1ComputePublicKey&& cmd)
344{
345 auto private_key = field_from_wire<secp256k1::fr>(cmd.private_key);
346 return { .public_key = secp256k1_point_to_wire(secp256k1::g1::one * private_key) };
347}
348wire::EcdsaSecp256r1ComputePublicKeyResponse handle_ecdsa_secp256r1_compute_public_key(
349 BBApiRequest& /*ctx*/, wire::EcdsaSecp256r1ComputePublicKey&& cmd)
350{
351 auto private_key = field_from_wire<secp256r1::fr>(cmd.private_key);
352 return { .public_key = secp256r1_point_to_wire(secp256r1::g1::one * private_key) };
353}
354wire::EcdsaSecp256k1ConstructSignatureResponse handle_ecdsa_secp256k1_construct_signature(
355 BBApiRequest& /*ctx*/, wire::EcdsaSecp256k1ConstructSignature&& cmd)
356{
357 auto private_key = field_from_wire<secp256k1::fr>(cmd.private_key);
358 auto pub_key = secp256k1::g1::one * private_key;
359 crypto::ecdsa_key_pair<secp256k1::fr, secp256k1::g1> key_pair = { private_key, pub_key };
360 std::string message_str(reinterpret_cast<const char*>(cmd.message.data()), cmd.message.size());
361 auto sig = crypto::ecdsa_construct_signature<crypto::Sha256Hasher, secp256k1::fq, secp256k1::fr, secp256k1::g1>(
362 message_str, key_pair);
363 return { .r = sig.r, .s = sig.s, .v = sig.v };
364}
365wire::EcdsaSecp256r1ConstructSignatureResponse handle_ecdsa_secp256r1_construct_signature(
366 BBApiRequest& /*ctx*/, wire::EcdsaSecp256r1ConstructSignature&& cmd)
367{
368 auto private_key = field_from_wire<secp256r1::fr>(cmd.private_key);
369 auto pub_key = secp256r1::g1::one * private_key;
370 crypto::ecdsa_key_pair<secp256r1::fr, secp256r1::g1> key_pair = { private_key, pub_key };
371 std::string message_str(reinterpret_cast<const char*>(cmd.message.data()), cmd.message.size());
372 auto sig = crypto::ecdsa_construct_signature<crypto::Sha256Hasher, secp256r1::fq, secp256r1::fr, secp256r1::g1>(
373 message_str, key_pair);
374 return { .r = sig.r, .s = sig.s, .v = sig.v };
375}
376wire::EcdsaSecp256k1RecoverPublicKeyResponse handle_ecdsa_secp256k1_recover_public_key(
377 BBApiRequest& /*ctx*/, wire::EcdsaSecp256k1RecoverPublicKey&& cmd)
378{
379 crypto::ecdsa_signature sig = { cmd.r, cmd.s, cmd.v };
380 std::string message_str(reinterpret_cast<const char*>(cmd.message.data()), cmd.message.size());
381 auto pubkey = crypto::ecdsa_recover_public_key<crypto::Sha256Hasher, secp256k1::fq, secp256k1::fr, secp256k1::g1>(
382 message_str, sig);
383 return { .public_key = secp256k1_point_to_wire(pubkey) };
384}
385wire::EcdsaSecp256r1RecoverPublicKeyResponse handle_ecdsa_secp256r1_recover_public_key(
386 BBApiRequest& /*ctx*/, wire::EcdsaSecp256r1RecoverPublicKey&& cmd)
387{
388 crypto::ecdsa_signature sig = { cmd.r, cmd.s, cmd.v };
389 std::string message_str(reinterpret_cast<const char*>(cmd.message.data()), cmd.message.size());
390 auto pubkey = crypto::ecdsa_recover_public_key<crypto::Sha256Hasher, secp256r1::fq, secp256r1::fr, secp256r1::g1>(
391 message_str, sig);
392 return { .public_key = secp256r1_point_to_wire(pubkey) };
393}
394wire::EcdsaSecp256k1VerifySignatureResponse handle_ecdsa_secp256k1_verify_signature(
395 BBApiRequest& /*ctx*/, wire::EcdsaSecp256k1VerifySignature&& cmd)
396{
397 crypto::ecdsa_signature sig = { cmd.r, cmd.s, cmd.v };
398 std::string message_str(reinterpret_cast<const char*>(cmd.message.data()), cmd.message.size());
399 auto pubkey = secp256k1_point_from_wire(cmd.public_key);
400 bool verified = crypto::ecdsa_verify_signature<crypto::Sha256Hasher, secp256k1::fq, secp256k1::fr, secp256k1::g1>(
401 message_str, pubkey, sig);
402 return { .verified = verified };
403}
404wire::EcdsaSecp256r1VerifySignatureResponse handle_ecdsa_secp256r1_verify_signature(
405 BBApiRequest& /*ctx*/, wire::EcdsaSecp256r1VerifySignature&& cmd)
406{
407 crypto::ecdsa_signature sig = { cmd.r, cmd.s, cmd.v };
408 std::string message_str(reinterpret_cast<const char*>(cmd.message.data()), cmd.message.size());
409 auto pubkey = secp256r1_point_from_wire(cmd.public_key);
410 bool verified = crypto::ecdsa_verify_signature<crypto::Sha256Hasher, secp256r1::fq, secp256r1::fr, secp256r1::g1>(
411 message_str, pubkey, sig);
412 return { .verified = verified };
413}
414
415// ===========================================================================
416// SRS init
417// ===========================================================================
418
419wire::SrsInitSrsResponse handle_srs_init_srs(BBApiRequest& /*ctx*/, wire::SrsInitSrs&& cmd)
420{
421 constexpr size_t COMPRESSED_POINT_SIZE = 32;
422 constexpr size_t UNCOMPRESSED_POINT_SIZE = sizeof(g1::affine_element); // 64
423
424 auto& points_buf = cmd.points_buf;
425 auto num_points = cmd.num_points;
426 size_t bytes_per_point = num_points > 0 ? points_buf.size() / num_points : 0;
427 std::vector<g1::affine_element> g1_points(num_points);
428 std::vector<uint8_t> uncompressed_out;
429
430 if (bytes_per_point == UNCOMPRESSED_POINT_SIZE) {
431 parallel_for([&](ThreadChunk chunk) {
432 for (auto i : chunk.range(static_cast<size_t>(num_points))) {
433 g1_points[i] = from_buffer<g1::affine_element>(points_buf.data(), i * UNCOMPRESSED_POINT_SIZE);
434 }
435 });
436 } else if (bytes_per_point == COMPRESSED_POINT_SIZE) {
437 if (points_buf.size() == 0 || points_buf.size() % bb::srs::SRS_CHUNK_SIZE_BYTES != 0) {
438 throw_or_abort("SrsInitSrs: compressed points_buf size " + std::to_string(points_buf.size()) +
439 " must be a positive multiple of " + std::to_string(bb::srs::SRS_CHUNK_SIZE_BYTES));
440 }
441 size_t num_full_chunks = points_buf.size() / bb::srs::SRS_CHUNK_SIZE_BYTES;
442 size_t chunks_to_verify = std::min(num_full_chunks, static_cast<size_t>(bb::srs::SRS_NUM_FULL_CHUNKS));
443 for (size_t i = 0; i < chunks_to_verify; ++i) {
444 auto chunk = std::span<const uint8_t>(points_buf.data() + i * bb::srs::SRS_CHUNK_SIZE_BYTES,
445 bb::srs::SRS_CHUNK_SIZE_BYTES);
446 auto hash = bb::crypto::sha256(chunk);
447 if (hash != bb::srs::BN254_G1_CHUNK_HASHES[i]) {
448 throw_or_abort("SrsInitSrs: g1 compressed chunk " + std::to_string(i) + " SHA-256 mismatch");
449 }
450 }
451 parallel_for([&](ThreadChunk chunk) {
452 for (auto i : chunk.range(static_cast<size_t>(num_points))) {
453 uint256_t c = from_buffer<uint256_t>(points_buf.data(), i * COMPRESSED_POINT_SIZE);
454 g1_points[i] = g1::affine_element::from_compressed(c);
455 }
456 });
457 uncompressed_out.resize(static_cast<size_t>(num_points) * UNCOMPRESSED_POINT_SIZE);
458 parallel_for([&](ThreadChunk chunk) {
459 for (auto i : chunk.range(static_cast<size_t>(num_points))) {
460 auto buf = to_buffer(g1_points[i]);
461 std::copy(buf.begin(), buf.end(), &uncompressed_out[i * UNCOMPRESSED_POINT_SIZE]);
462 }
463 });
464 } else {
465 throw_or_abort("SrsInitSrs: invalid points_buf size. Expected 32 or 64 bytes per point, got " +
466 std::to_string(bytes_per_point));
467 }
468
469 if (num_points >= 1 && g1_points[0] != bb::srs::BN254_G1_FIRST_ELEMENT) {
470 throw_or_abort("SrsInitSrs: g1_points[0] is not the canonical BN254 generator");
471 }
472 if (num_points >= 2 && g1_points[1] != bb::srs::get_bn254_g1_second_element()) {
473 throw_or_abort("SrsInitSrs: g1_points[1] does not match the canonical trusted-setup tau·G");
474 }
475
476 auto g2_hash = bb::crypto::sha256(std::span<const uint8_t>(cmd.g2_point.data(), cmd.g2_point.size()));
477 if (g2_hash != bb::srs::BN254_G2_ELEMENT_SHA256) {
478 throw_or_abort("SrsInitSrs: g2_point bytes do not match the canonical Aztec [x]_2 SHA-256");
479 }
480 auto g2_point_elem = from_buffer<g2::affine_element>(cmd.g2_point.data());
481 if (!g2_point_elem.is_in_prime_subgroup()) {
482 throw_or_abort("SrsInitSrs: g2_point is not in the BN254 G2 prime-order subgroup");
483 }
484
485 bb::srs::init_bn254_mem_crs_factory(g1_points, g2_point_elem);
486 return { .points_buf = std::move(uncompressed_out) };
487}
488wire::SrsInitGrumpkinSrsResponse handle_srs_init_grumpkin_srs(BBApiRequest& /*ctx*/, wire::SrsInitGrumpkinSrs&& cmd)
489{
490 const size_t required_size = static_cast<size_t>(cmd.num_points) * sizeof(curve::Grumpkin::AffineElement);
491 if (cmd.points_buf.size() < required_size) {
492 throw_or_abort("SrsInitGrumpkinSrs: points_buf too small (" + std::to_string(cmd.points_buf.size()) +
493 " bytes) for num_points=" + std::to_string(cmd.num_points) + " (need " +
494 std::to_string(required_size) + ")");
495 }
496 std::vector<curve::Grumpkin::AffineElement> points(cmd.num_points);
497 for (uint32_t i = 0; i < cmd.num_points; ++i) {
498 points[i] = from_buffer<curve::Grumpkin::AffineElement>(cmd.points_buf.data(),
500 }
502 return {};
503}
504
505} // namespace bb::bbapi
#define BB_ASSERT(expression,...)
Definition assert.hpp:70
#define BB_ASSERT_EQ(actual, expected,...)
Definition assert.hpp:83
Stateful Chonk batch-verifier service used by the IPC handlers.
Non-template handler declarations for the bb service.
Shared type definitions for the Barretenberg RPC API.
#define BBAPI_ERROR(request, msg)
Macro to set error in BBApiRequest and return default response.
Wire <-> domain conversion helpers for the bbapi handlers.
std::vector< std::pair< std::string, uint64_t > > snapshot() const
Definition stats.cpp:55
static Stats & get()
Definition stats.cpp:10
void reset()
Definition stats.cpp:16
static FF hash(const std::vector< FF > &input)
Hashes a vector of field elements.
Applies the Poseidon2 permutation function from https://eprint.iacr.org/2023/323.
static AffineElement commit_native(const std::vector< Fq > &inputs, GeneratorContext context={})
Given a vector of fields, generate a pedersen commitment using the indexed generators.
Definition pedersen.cpp:24
static Fq hash_buffer(const std::vector< uint8_t > &input, GeneratorContext context={})
Given an arbitrary length of bytes, convert them to fields and hash the result using the default gene...
Definition pedersen.cpp:92
static Fq hash(const std::vector< Fq > &inputs, GeneratorContext context={})
Given a vector of fields, generate a pedersen hash using generators from context.
Definition pedersen.cpp:78
typename Group::affine_element AffineElement
Definition grumpkin.hpp:64
constexpr bool on_curve() const noexcept
group_elements::affine_element< Fq, Fr, Params > affine_element
Definition group.hpp:44
static constexpr element one
Definition group.hpp:48
FF a
FF b
stdlib::Poseidon2Permutation< Builder > Permutation
AvmProvingInputs inputs
wire::EcdsaSecp256k1ComputePublicKeyResponse handle_ecdsa_secp256k1_compute_public_key(BBApiRequest &, wire::EcdsaSecp256k1ComputePublicKey &&cmd)
wire::GrumpkinReduce512Response handle_grumpkin_reduce512(BBApiRequest &, wire::GrumpkinReduce512 &&cmd)
wire::AesDecryptResponse handle_aes_decrypt(BBApiRequest &, wire::AesDecrypt &&cmd)
wire::GrumpkinBatchMulResponse handle_grumpkin_batch_mul(BBApiRequest &request, wire::GrumpkinBatchMul &&cmd)
wire::PedersenCommitResponse handle_pedersen_commit(BBApiRequest &, wire::PedersenCommit &&cmd)
wire::Bn254G1MulResponse handle_bn254_g1_mul(BBApiRequest &request, wire::Bn254G1Mul &&cmd)
wire::PedersenHashBufferResponse handle_pedersen_hash_buffer(BBApiRequest &, wire::PedersenHashBuffer &&cmd)
wire::SrsInitGrumpkinSrsResponse handle_srs_init_grumpkin_srs(BBApiRequest &, wire::SrsInitGrumpkinSrs &&cmd)
wire::Bn254G2MulResponse handle_bn254_g2_mul(BBApiRequest &request, wire::Bn254G2Mul &&cmd)
wire::SchnorrComputePublicKeyResponse handle_schnorr_compute_public_key(BBApiRequest &, wire::SchnorrComputePublicKey &&cmd)
wire::Poseidon2HashResponse handle_poseidon2_hash(BBApiRequest &, wire::Poseidon2Hash &&cmd)
wire::Bn254G1FromCompressedResponse handle_bn254_g1_from_compressed(BBApiRequest &request, wire::Bn254G1FromCompressed &&cmd)
wire::SrsInitSrsResponse handle_srs_init_srs(BBApiRequest &, wire::SrsInitSrs &&cmd)
wire::Secp256k1GetRandomFrResponse handle_secp256k1_get_random_fr(BBApiRequest &, wire::Secp256k1GetRandomFr &&)
wire::Bn254FqSqrtResponse handle_bn254_fq_sqrt(BBApiRequest &, wire::Bn254FqSqrt &&cmd)
wire::EcdsaSecp256r1ComputePublicKeyResponse handle_ecdsa_secp256r1_compute_public_key(BBApiRequest &, wire::EcdsaSecp256r1ComputePublicKey &&cmd)
wire::EcdsaSecp256r1ConstructSignatureResponse handle_ecdsa_secp256r1_construct_signature(BBApiRequest &, wire::EcdsaSecp256r1ConstructSignature &&cmd)
std::vector< Fr > fr_vec_to_wire(const std::vector< bb::fr > &d)
wire::SchnorrConstructSignatureResponse handle_schnorr_construct_signature(BBApiRequest &, wire::SchnorrConstructSignature &&cmd)
wire::SchnorrVerifySignatureResponse handle_schnorr_verify_signature(BBApiRequest &, wire::SchnorrVerifySignature &&cmd)
wire::Blake2sToFieldResponse handle_blake2s_to_field(BBApiRequest &, wire::Blake2sToField &&cmd)
wire::AvmCheckCircuitResponse handle_avm_check_circuit(BBApiRequest &, wire::AvmCheckCircuit &&cmd)
wire::Bn254G1IsOnCurveResponse handle_bn254_g1_is_on_curve(BBApiRequest &, wire::Bn254G1IsOnCurve &&cmd)
Fr fr_to_wire(const bb::fr &d)
wire::Bn254G2Point bn254_g2_point_to_wire(const bb::g2::affine_element &d)
wire::EcdsaSecp256k1VerifySignatureResponse handle_ecdsa_secp256k1_verify_signature(BBApiRequest &, wire::EcdsaSecp256k1VerifySignature &&cmd)
secp256r1::g1::affine_element secp256r1_point_from_wire(const wire::Secp256r1Point &w)
std::vector< grumpkin::g1::affine_element > grumpkin_point_vec_from_wire(const std::vector< wire::GrumpkinPoint > &w)
wire::EcdsaSecp256k1ConstructSignatureResponse handle_ecdsa_secp256k1_construct_signature(BBApiRequest &, wire::EcdsaSecp256k1ConstructSignature &&cmd)
wire::EcdsaSecp256r1RecoverPublicKeyResponse handle_ecdsa_secp256r1_recover_public_key(BBApiRequest &, wire::EcdsaSecp256r1RecoverPublicKey &&cmd)
wire::AvmVerifyResponse handle_avm_verify(BBApiRequest &, wire::AvmVerify &&cmd)
wire::GrumpkinGetRandomFrResponse handle_grumpkin_get_random_fr(BBApiRequest &, wire::GrumpkinGetRandomFr &&)
wire::AesEncryptResponse handle_aes_encrypt(BBApiRequest &, wire::AesEncrypt &&cmd)
wire::GrumpkinAddResponse handle_grumpkin_add(BBApiRequest &request, wire::GrumpkinAdd &&cmd)
secp256k1::g1::affine_element secp256k1_point_from_wire(const wire::Secp256k1Point &w)
wire::PedersenHashResponse handle_pedersen_hash(BBApiRequest &, wire::PedersenHash &&cmd)
bb::fr fr_from_wire(const Fr &w)
bb::g1::affine_element bn254_g1_point_from_wire(const wire::Bn254G1Point &w)
wire::EcdsaSecp256r1VerifySignatureResponse handle_ecdsa_secp256r1_verify_signature(BBApiRequest &, wire::EcdsaSecp256r1VerifySignature &&cmd)
wire::GrumpkinPoint grumpkin_point_to_wire(const grumpkin::g1::affine_element &d)
bb::g2::affine_element bn254_g2_point_from_wire(const wire::Bn254G2Point &w)
wire::Poseidon2PermutationResponse handle_poseidon2_permutation(BBApiRequest &, wire::Poseidon2Permutation &&cmd)
std::vector< bb::fr > fr_vec_from_wire(const std::vector< Fr > &w)
std::vector< wire::GrumpkinPoint > grumpkin_point_vec_to_wire(const std::vector< grumpkin::g1::affine_element > &d)
wire::Blake2sResponse handle_blake2s(BBApiRequest &, wire::Blake2s &&cmd)
wire::Bn254G1Point bn254_g1_point_to_wire(const bb::g1::affine_element &d)
wire::Secp256r1Point secp256r1_point_to_wire(const secp256r1::g1::affine_element &d)
wire::Bn254FrSqrtResponse handle_bn254_fr_sqrt(BBApiRequest &, wire::Bn254FrSqrt &&cmd)
grumpkin::g1::affine_element grumpkin_point_from_wire(const wire::GrumpkinPoint &w)
wire::EcdsaSecp256k1RecoverPublicKeyResponse handle_ecdsa_secp256k1_recover_public_key(BBApiRequest &, wire::EcdsaSecp256k1RecoverPublicKey &&cmd)
wire::AvmProveResponse handle_avm_prove(BBApiRequest &, wire::AvmProve &&cmd)
wire::Secp256k1Point secp256k1_point_to_wire(const secp256k1::g1::affine_element &d)
wire::Secp256k1MulResponse handle_secp256k1_mul(BBApiRequest &request, wire::Secp256k1Mul &&cmd)
wire::GrumpkinMulResponse handle_grumpkin_mul(BBApiRequest &request, wire::GrumpkinMul &&cmd)
wire::Secp256k1Reduce512Response handle_secp256k1_reduce512(BBApiRequest &, wire::Secp256k1Reduce512 &&cmd)
void aes128_decrypt_buffer_cbc(uint8_t *buffer, uint8_t *iv, const uint8_t *key, const size_t length)
Definition aes128.cpp:257
Sha256Hash sha256(const ByteContainer &input)
SHA-256 hash function (FIPS 180-4)
Definition sha256.cpp:150
std::array< uint8_t, BLAKE2S_OUTBYTES > blake2s(std::vector< uint8_t > const &input)
Definition blake2s.cpp:232
void aes128_encrypt_buffer_cbc(uint8_t *buffer, uint8_t *iv, const uint8_t *key, const size_t length)
Definition aes128.cpp:234
void secure_erase_bytes(void *ptr, size_t size)
Definition hmac.hpp:18
constexpr std::array< uint8_t, 32 > BN254_G2_ELEMENT_SHA256
SHA-256 hash of BN254_G2_ELEMENT_BYTES.
constexpr g1::affine_element BN254_G1_FIRST_ELEMENT
Expected first G1 element from BN254 CRS.
void init_grumpkin_mem_crs_factory(std::vector< curve::Grumpkin::AffineElement > const &points)
g1::affine_element get_bn254_g1_second_element()
Expected second G1 element from BN254 CRS.
void init_bn254_mem_crs_factory(std::vector< g1::affine_element > const &points, g2::affine_element const &g2_point)
bool avm_check_circuit_from_bytes(std::vector< uint8_t > inputs)
Check the AVM circuit from serialized inputs (msgpack bytes).
Definition api_avm.cpp:121
bool avm_verify_from_bytes(std::vector< bb::fr > proof, std::vector< uint8_t > public_inputs)
Verify an AVM proof from serialized data.
Definition api_avm.cpp:109
AvmProveResult avm_prove_from_bytes(std::vector< uint8_t > inputs)
Prove an AVM transaction from serialized inputs (msgpack bytes). Callers that need to verify the proo...
Definition api_avm.cpp:98
void parallel_for(size_t num_iterations, const std::function< void(size_t)> &func)
Definition thread.cpp:111
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::string to_string(bb::avm2::ValueTag tag)
std::vector< uint8_t > to_buffer(T const &value)
auto range(size_t size, size_t offset=0) const
Definition thread.hpp:152
std::array< uint8_t, 32 > r
Definition ecdsa.hpp:31
static constexpr uint256_t modulus
static field random_element(numeric::RNG *engine=nullptr) noexcept
static field serialize_from_buffer(const uint8_t *buffer)
constexpr std::pair< bool, field > sqrt() const noexcept
Compute square root of the field element.
void throw_or_abort(std::string const &err)