diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/hash/benchmarks/CMakeLists.txt b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/hash/benchmarks/CMakeLists.txt index e758f7c8b0b..ef200979db3 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/hash/benchmarks/CMakeLists.txt +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/hash/benchmarks/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory(sha256) -add_subdirectory(external) \ No newline at end of file +add_subdirectory(external) +add_subdirectory(celer) \ No newline at end of file diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/hash/benchmarks/celer/CMakeLists.txt b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/hash/benchmarks/celer/CMakeLists.txt new file mode 100644 index 00000000000..e79cbdf5776 --- /dev/null +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/hash/benchmarks/celer/CMakeLists.txt @@ -0,0 +1 @@ +barretenberg_module(celer stdlib_sha256) \ No newline at end of file diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/hash/benchmarks/celer/sha256.bench.cpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/hash/benchmarks/celer/sha256.bench.cpp new file mode 100644 index 00000000000..d160c1b8d77 --- /dev/null +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/hash/benchmarks/celer/sha256.bench.cpp @@ -0,0 +1,114 @@ +/** + * @file sha256.bench.cpp + * @author Rumata888 + * @brief This file contains benchmarks for an external benchmark project https://github.com/celer-network/zk-benchmark + * @version 0.1 + * @date 2023-08-02 + * + */ +#include "barretenberg/stdlib/hash/sha256/sha256.hpp" +#include "barretenberg/plonk/composer/ultra_composer.hpp" +#include +#include + +using namespace benchmark; + +using Builder = proof_system::UltraCircuitBuilder; +using Composer = proof_system::plonk::UltraComposer; +using Prover = proof_system::plonk::UltraProver; +using Verifier = proof_system::plonk::UltraVerifier; + +constexpr size_t NUM_HASHES = 20; +constexpr size_t CHUNK_SIZE = 64; +constexpr size_t MINIMUM_CHUNKS = 1; +constexpr size_t MAXIMUM_CHUNKS = 1024; + +/** + * @brief Generate a circuit computing sha256 hash of a 0-filled array of num_bytes + * + * @param builder circuit builder + * @param num_bytes Length of the array + */ +void generate_test_plonk_circuit(Builder& builder, size_t num_bytes) +{ + std::string in; + in.resize(num_bytes); + proof_system::plonk::stdlib::packed_byte_array input(&builder, in); + + proof_system::plonk::stdlib::sha256(input); +} + +// Because of the way we do internal allocations in some of our more complex structures, we can't just globally allocate +// them +Builder* builders[NUM_HASHES]; +Composer* composers[NUM_HASHES]; +Prover provers[NUM_HASHES]; +Verifier verifiers[NUM_HASHES]; +plonk::proof proofs[NUM_HASHES]; + +/** + * @brief Benchmark for constructing the circuit, witness polynomials, proving and verification key + * + * @param state + */ +void preprocess_and_construct_witnesses_bench(State& state) noexcept +{ + for (auto _ : state) { + size_t num_chunks = static_cast(state.range(0)); + size_t idx = static_cast(std::countr_zero(num_chunks)); + builders[idx] = new Builder(); + generate_test_plonk_circuit(*builders[idx], num_chunks * CHUNK_SIZE); + composers[idx] = new Composer(); + provers[idx] = (composers[idx])->create_prover(*builders[idx]); + std::cout << "prover subgroup size = " << provers[idx].key->small_domain.size << std::endl; + + verifiers[idx] = (composers[idx])->create_verifier(*builders[idx]); + } +} +BENCHMARK(preprocess_and_construct_witnesses_bench) + ->RangeMultiplier(2) + ->Range(MINIMUM_CHUNKS, MAXIMUM_CHUNKS) + ->Unit(benchmark::kMillisecond); + +/** + * @brief Benchmark for creating the proof with preprocessed data + * + * @param state + */ +void construct_proofs_bench(State& state) noexcept +{ + for (auto _ : state) { + size_t num_chunks = static_cast(state.range(0)); + size_t idx = static_cast(std::countr_zero(num_chunks)); + + proofs[idx] = provers[idx].construct_proof(); + std::cout << "Plonk proof size: " << proofs[idx].proof_data.size() << std::endl; + state.PauseTiming(); + provers[idx].reset(); + state.ResumeTiming(); + } +} +BENCHMARK(construct_proofs_bench) + ->RangeMultiplier(2) + ->Range(MINIMUM_CHUNKS, MAXIMUM_CHUNKS) + ->Unit(benchmark::kMillisecond); + +/** + * @brief Benchmark for proof verification + * + * @param state + */ +void verify_proofs_bench(State& state) noexcept +{ + for (auto _ : state) { + size_t num_chunks = static_cast(state.range(0)); + size_t idx = static_cast(std::countr_zero(num_chunks)); + verifiers[idx].verify_proof(proofs[idx]); + } +} +BENCHMARK(verify_proofs_bench) + ->RangeMultiplier(2) + ->Range(MINIMUM_CHUNKS, MAXIMUM_CHUNKS) + ->Unit(benchmark::kMillisecond); + +BENCHMARK_MAIN();