19#include "barretenberg/bbapi/generated/bb_dispatch.hpp"
53 result.reserve(snapshot.size());
54 for (
auto& [name,
value] : snapshot) {
55 result.push_back(wire::AvmStat{ .name =
std::move(name), .value_ms =
value });
70 return { .proof =
fr_vec_to_wire(result.proof), .stats = snapshot_avm_stats_wire() };
75 return { .verified = verified };
81 return { .passed = passed, .stats = snapshot_avm_stats_wire() };
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) };
111 gctx.
offset =
static_cast<size_t>(cmd.hash_index);
119 gctx.
offset =
static_cast<size_t>(cmd.hash_index);
127 gctx.
offset =
static_cast<size_t>(cmd.hash_index);
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");
145 std::vector<uint8_t> result =
std::move(cmd.plaintext);
146 result.resize(cmd.length);
148 return { .ciphertext =
std::move(result) };
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");
155 std::vector<uint8_t> result =
std::move(cmd.ciphertext);
156 result.resize(cmd.length);
158 return { .plaintext =
std::move(result) };
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");
179 BBAPI_ERROR(request,
"Input point_a must be on the curve");
182 BBAPI_ERROR(request,
"Input point_b must be on the curve");
189 auto scalar = field_from_wire<grumpkin::fr>(cmd.scalar);
190 for (
const auto& p : points) {
192 BBAPI_ERROR(request,
"Input point must be on the curve");
195 auto output = grumpkin::g1::element::batch_mul_with_endomorphism(points, scalar);
199 wire::GrumpkinGetRandomFr&& )
205 auto bigint_input = from_buffer<uint512_t>(cmd.input.data());
207 uint512_t target_output = bigint_input % barretenberg_modulus;
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");
225 wire::Secp256k1GetRandomFr&& )
231 auto bigint_input = from_buffer<uint512_t>(cmd.input.data());
233 uint512_t target_output = bigint_input % secp256k1_modulus;
234 return { .value = field_to_wire_as<Secp256k1Fr>(
secp256k1::fr(target_output.
lo)) };
244 return { .is_square_root = is_sqr, .value =
fr_to_wire(root) };
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) };
255 if (!point.on_curve()) {
256 BBAPI_ERROR(request,
"Input point must be on the curve");
258 auto result = point * scalar;
259 if (!result.on_curve()) {
260 BBAPI_ERROR(request,
"Output point must be on the curve");
268 if (!point.on_curve()) {
269 BBAPI_ERROR(request,
"Input point must be on the curve");
274 if (!point.is_in_prime_subgroup()) {
275 BBAPI_ERROR(request,
"Input point must lie in the prime-order subgroup");
277 auto result = point * scalar;
278 if (!result.on_curve()) {
279 BBAPI_ERROR(request,
"Output point must be on the curve");
288 wire::Bn254G1FromCompressed&& cmd)
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");
303 wire::SchnorrComputePublicKey&& cmd)
305 auto private_key = field_from_wire<grumpkin::fr>(cmd.private_key);
312 wire::SchnorrConstructSignature&& cmd)
314 auto private_key = field_from_wire<grumpkin::fr>(cmd.private_key);
319 cmd.message.size(),
size_t{ 32 },
"SchnorrConstructSignature: message must be 32 bytes (field element)");
321 auto sig = crypto::schnorr_construct_signature<grumpkin::fr, grumpkin::g1>(message_field, key_pair);
324 return { .s = field_to_wire<grumpkin::fr>(sig.s), .e = field_to_wire<grumpkin::fr>(sig.e) };
327 wire::SchnorrVerifySignature&& cmd)
329 BB_ASSERT_EQ(cmd.message.size(),
size_t{ 32 },
"SchnorrVerifySignature: message must be 32 bytes (field element)");
334 bool result = crypto::schnorr_verify_signature<grumpkin::fr, grumpkin::g1>(message_field, public_key, sig);
335 return { .verified = result };
343 BBApiRequest& , wire::EcdsaSecp256k1ComputePublicKey&& cmd)
345 auto private_key = field_from_wire<secp256k1::fr>(cmd.private_key);
349 BBApiRequest& , wire::EcdsaSecp256r1ComputePublicKey&& cmd)
351 auto private_key = field_from_wire<secp256r1::fr>(cmd.private_key);
355 BBApiRequest& , wire::EcdsaSecp256k1ConstructSignature&& cmd)
357 auto private_key = field_from_wire<secp256k1::fr>(cmd.private_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 };
366 BBApiRequest& , wire::EcdsaSecp256r1ConstructSignature&& cmd)
368 auto private_key = field_from_wire<secp256r1::fr>(cmd.private_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 };
377 BBApiRequest& , wire::EcdsaSecp256k1RecoverPublicKey&& cmd)
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>(
386 BBApiRequest& , wire::EcdsaSecp256r1RecoverPublicKey&& cmd)
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>(
395 BBApiRequest& , wire::EcdsaSecp256k1VerifySignature&& cmd)
398 std::string message_str(
reinterpret_cast<const char*
>(cmd.message.data()), cmd.message.size());
400 bool verified = crypto::ecdsa_verify_signature<crypto::Sha256Hasher, secp256k1::fq, secp256k1::fr, secp256k1::g1>(
401 message_str, pubkey, sig);
402 return { .verified = verified };
405 BBApiRequest& , wire::EcdsaSecp256r1VerifySignature&& cmd)
408 std::string message_str(
reinterpret_cast<const char*
>(cmd.message.data()), cmd.message.size());
410 bool verified = crypto::ecdsa_verify_signature<crypto::Sha256Hasher, secp256r1::fq, secp256r1::fr, secp256r1::g1>(
411 message_str, pubkey, sig);
412 return { .verified = verified };
421 constexpr size_t COMPRESSED_POINT_SIZE = 32;
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;
428 std::vector<uint8_t> uncompressed_out;
430 if (bytes_per_point == UNCOMPRESSED_POINT_SIZE) {
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);
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) {
439 " must be a positive multiple of " +
std::to_string(bb::srs::SRS_CHUNK_SIZE_BYTES));
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) {
445 bb::srs::SRS_CHUNK_SIZE_BYTES);
447 if (hash != bb::srs::BN254_G1_CHUNK_HASHES[i]) {
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);
457 uncompressed_out.resize(
static_cast<size_t>(num_points) * UNCOMPRESSED_POINT_SIZE);
459 for (
auto i : chunk.
range(
static_cast<size_t>(num_points))) {
461 std::copy(buf.begin(), buf.end(), &uncompressed_out[i * UNCOMPRESSED_POINT_SIZE]);
465 throw_or_abort(
"SrsInitSrs: invalid points_buf size. Expected 32 or 64 bytes per point, got " +
470 throw_or_abort(
"SrsInitSrs: g1_points[0] is not the canonical BN254 generator");
473 throw_or_abort(
"SrsInitSrs: g1_points[1] does not match the canonical trusted-setup tau·G");
478 throw_or_abort(
"SrsInitSrs: g2_point bytes do not match the canonical Aztec [x]_2 SHA-256");
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");
486 return { .points_buf =
std::move(uncompressed_out) };
491 if (cmd.points_buf.size() < required_size) {
493 " bytes) for num_points=" +
std::to_string(cmd.num_points) +
" (need " +
497 for (uint32_t i = 0; i < cmd.num_points; ++i) {
498 points[i] = from_buffer<curve::Grumpkin::AffineElement>(cmd.points_buf.data(),
#define BB_ASSERT(expression,...)
#define BB_ASSERT_EQ(actual, expected,...)
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
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.
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...
static Fq hash(const std::vector< Fq > &inputs, GeneratorContext context={})
Given a vector of fields, generate a pedersen hash using generators from context.
typename Group::affine_element AffineElement
constexpr bool on_curve() const noexcept
group_elements::affine_element< Fq, Fr, Params > affine_element
static constexpr element one
stdlib::Poseidon2Permutation< Builder > Permutation
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)
Sha256Hash sha256(const ByteContainer &input)
SHA-256 hash function (FIPS 180-4)
std::array< uint8_t, BLAKE2S_OUTBYTES > blake2s(std::vector< uint8_t > const &input)
void aes128_encrypt_buffer_cbc(uint8_t *buffer, uint8_t *iv, const uint8_t *key, const size_t length)
void secure_erase_bytes(void *ptr, size_t size)
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).
bool avm_verify_from_bytes(std::vector< bb::fr > proof, std::vector< uint8_t > public_inputs)
Verify an AVM proof from serialized data.
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...
void parallel_for(size_t num_iterations, const std::function< void(size_t)> &func)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
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
std::array< uint8_t, 32 > r
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)