From 0038bb60b1b0adca829552503e0a093637a00b77 Mon Sep 17 00:00:00 2001 From: Charlie Lye Date: Sun, 21 May 2023 18:32:29 +0000 Subject: [PATCH 01/29] Initial --- cpp/scripts/build_libacvm_backend.sh | 51 ++++ cpp/src/CMakeLists.txt | 42 +++- cpp/src/barretenberg/common/c_bind.cpp | 2 + cpp/src/barretenberg/common/serialize.hpp | 6 +- cpp/src/barretenberg/common/wasm_export.hpp | 9 +- .../crypto/pedersen_commitment/pedersen.cpp | 22 +- .../crypto/pedersen_hash/pedersen.cpp | 14 +- .../dsl/acir_format/acir_format.cpp | 23 +- .../dsl/acir_format/acir_format.hpp | 14 +- .../dsl/acir_proofs/acir_composer.cpp | 68 +++++ .../dsl/acir_proofs/acir_composer.hpp | 35 +++ .../dsl/acir_proofs/acir_proofs.cpp | 157 ------------ .../dsl/acir_proofs/acir_proofs.hpp | 20 -- .../barretenberg/dsl/acir_proofs/c_bind.cpp | 72 +++--- .../barretenberg/dsl/acir_proofs/c_bind.hpp | 42 ++-- exports.json | 140 +++++++++++ scripts/bindgen.sh | 1 - scripts/c_bind_files.txt | 1 + ts/package.json | 4 + ts/src/barretenberg_api/index.ts | 236 +++++++++--------- ts/src/barretenberg_wasm/barretenberg_wasm.ts | 4 +- ts/src/bindgen/mappings.ts | 2 + ts/src/bindgen/typescript.ts | 2 +- ts/src/factory/index.ts | 23 ++ ts/src/main-dev.ts | 2 + ts/src/main.ts | 50 ++++ 26 files changed, 646 insertions(+), 396 deletions(-) create mode 100755 cpp/scripts/build_libacvm_backend.sh create mode 100644 cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp create mode 100644 cpp/src/barretenberg/dsl/acir_proofs/acir_composer.hpp delete mode 100644 cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.cpp delete mode 100644 cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.hpp create mode 100644 ts/src/factory/index.ts create mode 100755 ts/src/main-dev.ts create mode 100755 ts/src/main.ts diff --git a/cpp/scripts/build_libacvm_backend.sh b/cpp/scripts/build_libacvm_backend.sh new file mode 100755 index 0000000000..ed42572df2 --- /dev/null +++ b/cpp/scripts/build_libacvm_backend.sh @@ -0,0 +1,51 @@ +#!/bin/bash +set -eu + +BB_TARGETS=( + libenv.a + libcommon.a + libcrypto_blake2s.a + libcrypto_pedersen_hash.a + libcrypto_pedersen_commitment.a + libcrypto_keccak.a + libcrypto_schnorr.a + libcrypto_generators.a + libnumeric.a +) + +CMD="cmake --preset wasm && cmake --build --preset wasm" +for target in "${BB_TARGETS[@]}"; do CMD="$CMD --target $target"; done +eval $CMD + +cd ./build-wasm/lib + +LIBS=( + $PWD/libenv.a + $PWD/libcommon.a + $PWD/libcrypto_blake2s.a + $PWD/libcrypto_pedersen_hash.a + $PWD/libcrypto_pedersen_commitment.a + $PWD/libcrypto_keccak.a + $PWD/libcrypto_schnorr.a + $PWD/libcrypto_generators.a + $PWD/libnumeric.a + $PWD/../../src/wasi-sdk-20.0/share/wasi-sysroot/lib/wasm32-wasi/libc++.a + $PWD/../../src/wasi-sdk-20.0/share/wasi-sysroot/lib/wasm32-wasi/libc++abi.a +) + +rm -rf scratch +mkdir -p scratch +cd scratch + +for LIB_FILE_PATH in "${LIBS[@]}"; do + LIB=$(basename $LIB_FILE_PATH) + echo Extracting lib: $LIB + mkdir $LIB + cd $LIB + ar x $LIB_FILE_PATH + cd .. +done + +rm -f ../libacvm_backend.a +#../../../src/wasi-sdk-12.0/bin/ar rcs ../libxyz.a libcrypto_blake2s.a/* libc++.a/* libc++abi.a/* libcrypto_pedersen_commitment.a/* +find . -type f -print0 | xargs -0 ../../../src/wasi-sdk-20.0/bin/ar rcs ../libacvm_backend.a diff --git a/cpp/src/CMakeLists.txt b/cpp/src/CMakeLists.txt index 6522078499..f71c57aed9 100644 --- a/cpp/src/CMakeLists.txt +++ b/cpp/src/CMakeLists.txt @@ -70,6 +70,8 @@ endif() include(GNUInstallDirs) +# For this library we include everything but the wasi module, as it is the responsibility of the +# consumer of this library to define how and in what environment its artefact will run. message(STATUS "Compiling all-in-one barretenberg archive") add_library( barretenberg @@ -106,16 +108,50 @@ add_library( $ $ $ + $ ) if(WASM) + # When building this wasm "executable", we include the wasi module but exclude the env module. + # That's because we expect this wasm to be run as a wasi "reactor" and for the host environment + # to implement the functions in env. add_executable( barretenberg.wasm $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ ) - target_link_libraries(barretenberg.wasm barretenberg) - # With binaryen installed, it seems its wasm backend optimiser gets invoked automatically. # Due to either a bug in the optimiser, or non-standards compliant c++ in crypto/aes, tests start failing with # -O3 level optimisations. We force down to -O2 for current workaround. @@ -125,7 +161,7 @@ if(WASM) target_link_options( barretenberg.wasm PRIVATE - -nostartfiles -Wl,--whole-archive,--no-entry,--export-dynamic,--allow-undefined + -nostartfiles -Wl,--no-entry,--export-dynamic,--allow-undefined ) if(INSTALL_BARRETENBERG) diff --git a/cpp/src/barretenberg/common/c_bind.cpp b/cpp/src/barretenberg/common/c_bind.cpp index 11de5a72a8..a68ef3ffd5 100644 --- a/cpp/src/barretenberg/common/c_bind.cpp +++ b/cpp/src/barretenberg/common/c_bind.cpp @@ -1,3 +1,4 @@ +#ifndef NO_MULTITHREADING #include "./c_bind.hpp" #include "./mem.hpp" #include "./timer.hpp" @@ -67,3 +68,4 @@ WASM_EXPORT void test_abort() std::abort(); } } +#endif \ No newline at end of file diff --git a/cpp/src/barretenberg/common/serialize.hpp b/cpp/src/barretenberg/common/serialize.hpp index 861a4a8ccd..1dfecea981 100644 --- a/cpp/src/barretenberg/common/serialize.hpp +++ b/cpp/src/barretenberg/common/serialize.hpp @@ -442,7 +442,11 @@ using in_buf64 = uint8_t const*; using out_buf64 = uint8_t*; using in_buf128 = uint8_t const*; using out_buf128 = uint8_t*; + +// Variable length string buffers. Prefixed with length. using in_str_buf = uint8_t const*; -using out_str_buf = uint8_t*; +using out_str_buf = uint8_t**; + +// Use these to pass a raw memory pointer. using in_ptr = void* const*; using out_ptr = void**; \ No newline at end of file diff --git a/cpp/src/barretenberg/common/wasm_export.hpp b/cpp/src/barretenberg/common/wasm_export.hpp index f5ae500838..7bbe9feb61 100644 --- a/cpp/src/barretenberg/common/wasm_export.hpp +++ b/cpp/src/barretenberg/common/wasm_export.hpp @@ -1,7 +1,8 @@ #ifdef __clang__ -#define WASM_EXPORT __attribute__((visibility("default"))) __attribute__((annotate("wasm_export"))) -#define ASYNC_WASM_EXPORT __attribute__((visibility("default"))) __attribute__((annotate("async_wasm_export"))) +#define WASM_EXPORT extern "C" __attribute__((visibility("default"))) __attribute__((annotate("wasm_export"))) +#define ASYNC_WASM_EXPORT \ + extern "C" __attribute__((visibility("default"))) __attribute__((annotate("async_wasm_export"))) #else -#define WASM_EXPORT __attribute__((visibility("default"))) -#define ASYNC_WASM_EXPORT __attribute__((visibility("default"))) +#define WASM_EXPORT extern "C" __attribute__((visibility("default"))) +#define ASYNC_WASM_EXPORT extern "C" __attribute__((visibility("default"))) #endif \ No newline at end of file diff --git a/cpp/src/barretenberg/crypto/pedersen_commitment/pedersen.cpp b/cpp/src/barretenberg/crypto/pedersen_commitment/pedersen.cpp index ae410af019..3cb88b0aab 100644 --- a/cpp/src/barretenberg/crypto/pedersen_commitment/pedersen.cpp +++ b/cpp/src/barretenberg/crypto/pedersen_commitment/pedersen.cpp @@ -2,9 +2,9 @@ #include "./convert_buffer_to_field.hpp" #include "barretenberg/common/throw_or_abort.hpp" #include -#ifndef NO_OMP_MULTITHREADING -#include -#endif +// #ifndef NO_OMP_MULTITHREADING +// #include +// #endif using namespace crypto::generators; @@ -51,11 +51,11 @@ grumpkin::g1::affine_element commit_native(const std::vector& inpu ASSERT((inputs.size() < (1 << 16)) && "too many inputs for 16 bit index"); std::vector out(inputs.size()); -#ifndef NO_OMP_MULTITHREADING - // Ensure generator data is initialized before threading... + // #ifndef NO_OMP_MULTITHREADING + // // Ensure generator data is initialized before threading... init_generator_data(); -#pragma omp parallel for num_threads(inputs.size()) -#endif + // #pragma omp parallel for num_threads(inputs.size()) + // #endif for (size_t i = 0; i < inputs.size(); ++i) { generator_index_t index = { hash_index, i }; out[i] = commit_single(inputs[i], index); @@ -73,11 +73,11 @@ grumpkin::g1::affine_element commit_native(const std::vector out(input_pairs.size()); -#ifndef NO_OMP_MULTITHREADING - // Ensure generator data is initialized before threading... + // #ifndef NO_OMP_MULTITHREADING + // // Ensure generator data is initialized before threading... init_generator_data(); -#pragma omp parallel for num_threads(input_pairs.size()) -#endif + // #pragma omp parallel for num_threads(input_pairs.size()) + // #endif for (size_t i = 0; i < input_pairs.size(); ++i) { out[i] = commit_single(input_pairs[i].first, input_pairs[i].second); } diff --git a/cpp/src/barretenberg/crypto/pedersen_hash/pedersen.cpp b/cpp/src/barretenberg/crypto/pedersen_hash/pedersen.cpp index 6debd1b9ff..c43460b9a8 100644 --- a/cpp/src/barretenberg/crypto/pedersen_hash/pedersen.cpp +++ b/cpp/src/barretenberg/crypto/pedersen_hash/pedersen.cpp @@ -1,8 +1,8 @@ #include "./pedersen.hpp" #include -#ifndef NO_OMP_MULTITHREADING -#include -#endif +// #ifndef NO_OMP_MULTITHREADING +// #include +// #endif namespace crypto { namespace pedersen_hash { @@ -49,11 +49,11 @@ grumpkin::fq hash_multiple(const std::vector& inputs, const size_t ASSERT((inputs.size() < (1 << 16)) && "too many inputs for 16 bit index"); std::vector out(inputs.size()); -#ifndef NO_OMP_MULTITHREADING - // Ensure generator data is initialized before threading... + // #ifndef NO_OMP_MULTITHREADING + // // Ensure generator data is initialized before threading... init_generator_data(); -#pragma omp parallel for num_threads(inputs.size()) -#endif + // #pragma omp parallel for num_threads(inputs.size()) + // #endif for (size_t i = 0; i < inputs.size(); ++i) { generator_index_t index = { hash_index, i }; out[i] = hash_single(inputs[i], index); diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp index 8f2c4d17f5..93c89d76dd 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp @@ -3,7 +3,7 @@ namespace acir_format { -void read_witness(Composer& composer, std::vector witness) +void read_witness(Composer& composer, std::vector const& witness) { composer.variables[0] = 0; for (size_t i = 0; i < witness.size(); ++i) { @@ -11,7 +11,7 @@ void read_witness(Composer& composer, std::vector witness) } } -void create_circuit(Composer& composer, const acir_format& constraint_system) +void create_circuit(Composer& composer, acir_format const& constraint_system) { if (constraint_system.public_inputs.size() > constraint_system.varnum) { info("create_circuit: too many public inputs!"); @@ -96,13 +96,14 @@ void create_circuit(Composer& composer, const acir_format& constraint_system) } Composer create_circuit(const acir_format& constraint_system, - std::unique_ptr&& crs_factory) + std::shared_ptr const& crs_factory) { if (constraint_system.public_inputs.size() > constraint_system.varnum) { info("create_circuit: too many public inputs!"); } - Composer composer(std::move(crs_factory)); + // TODO: Figure out size_hint from constraint_system. + Composer composer(crs_factory); for (size_t i = 1; i < constraint_system.varnum; ++i) { // If the index is in the public inputs vector, then we add it as a public input @@ -185,15 +186,15 @@ Composer create_circuit(const acir_format& constraint_system, return composer; } -Composer create_circuit_with_witness(const acir_format& constraint_system, - std::vector witness, - std::unique_ptr&& crs_factory) +Composer create_circuit_with_witness(acir_format const& constraint_system, + std::vector const& witness, + std::shared_ptr const& crs_factory) { if (constraint_system.public_inputs.size() > constraint_system.varnum) { info("create_circuit_with_witness: too many public inputs!"); } - Composer composer(std::move(crs_factory)); + Composer composer(crs_factory); for (size_t i = 1; i < constraint_system.varnum; ++i) { // If the index is in the public inputs vector, then we add it as a public input @@ -278,7 +279,7 @@ Composer create_circuit_with_witness(const acir_format& constraint_system, return composer; } -Composer create_circuit_with_witness(const acir_format& constraint_system, std::vector witness) +Composer create_circuit_with_witness(const acir_format& constraint_system, std::vector const& witness) { if (constraint_system.public_inputs.size() > constraint_system.varnum) { info("create_circuit_with_witness: too many public inputs!"); @@ -369,7 +370,9 @@ Composer create_circuit_with_witness(const acir_format& constraint_system, std:: return composer; } -void create_circuit_with_witness(Composer& composer, const acir_format& constraint_system, std::vector witness) +void create_circuit_with_witness(Composer& composer, + acir_format const& constraint_system, + std::vector const& witness) { if (constraint_system.public_inputs.size() > constraint_system.varnum) { info("create_circuit_with_witness: too many public inputs!"); diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp index cf14558c31..f526c250be 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp @@ -40,20 +40,22 @@ struct acir_format { friend bool operator==(acir_format const& lhs, acir_format const& rhs) = default; }; -void read_witness(Composer& composer, std::vector witness); +void read_witness(Composer& composer, std::vector const& witness); void create_circuit(Composer& composer, const acir_format& constraint_system); Composer create_circuit(const acir_format& constraint_system, - std::unique_ptr&& crs_factory); + std::shared_ptr const& crs_factory); Composer create_circuit_with_witness(const acir_format& constraint_system, - std::vector witness, - std::unique_ptr&& crs_factory); + std::vector const& witness, + std::shared_ptr const& crs_factory); -Composer create_circuit_with_witness(const acir_format& constraint_system, std::vector witness); +Composer create_circuit_with_witness(const acir_format& constraint_system, std::vector const& witness); -void create_circuit_with_witness(Composer& composer, const acir_format& constraint_system, std::vector witness); +void create_circuit_with_witness(Composer& composer, + const acir_format& constraint_system, + std::vector const& witness); // Serialisation template inline void read(B& buf, acir_format& data) diff --git a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp new file mode 100644 index 0000000000..bd4efc4244 --- /dev/null +++ b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp @@ -0,0 +1,68 @@ + +#include "acir_composer.hpp" +#include "barretenberg/common/serialize.hpp" +#include "barretenberg/common/throw_or_abort.hpp" +#include "barretenberg/plonk/proof_system/proving_key/serialize.hpp" +#include "barretenberg/dsl/acir_format/acir_format.hpp" +#include "barretenberg/dsl/types.hpp" +#include "barretenberg/srs/reference_string/pippenger_reference_string.hpp" +#include "barretenberg/plonk/proof_system/verification_key/sol_gen.hpp" +#include "barretenberg/srs/reference_string/reference_string.hpp" + +namespace acir_proofs { + +AcirComposer::AcirComposer(std::shared_ptr const& crs_factory) + : crs_factory_(crs_factory) +{} + +void AcirComposer::init_proving_key(acir_format::acir_format&& constraint_system) +{ + constraint_system_ = std::move(constraint_system); + auto composer = create_circuit(constraint_system_, crs_factory_); + exact_circuit_size_ = composer.get_num_gates(); + total_circuit_size_ = composer.get_total_circuit_size(); + proving_key_ = composer.compute_proving_key(); +} + +std::vector AcirComposer::create_proof(std::vector const& witness) +{ + acir_format::Composer composer(proving_key_, nullptr, total_circuit_size_); + + create_circuit_with_witness(composer, constraint_system_, witness); + + auto prover = composer.create_ultra_with_keccak_prover(); + return prover.construct_proof().proof_data; +} + +void AcirComposer::init_verification_key() +{ + if (!proving_key_) { + throw_or_abort("init_proving_key must be called first."); + } + acir_format::Composer composer(proving_key_, nullptr); + verification_key_ = composer.compute_verification_key(); + + // verification_key_ = + // acir_format::Composer::compute_verification_key_base(proving_key_, crs_factory_->get_verifier_crs()); + + // The composer_type has not yet been set. We need to set the composer_type for when we later read in and + // construct the verification key so that we have the correct polynomial manifest + // verification_key->composer_type = proof_system::ComposerType::PLOOKUP; +} + +bool AcirComposer::verify_proof(std::vector const& proof) +{ + acir_format::Composer composer(nullptr, verification_key_); + composer.create_ultra_with_keccak_verifier(); + auto verifier = composer.create_ultra_with_keccak_verifier(); + return verifier.verify_proof({ proof }); +} + +std::string AcirComposer::get_solidity_verifier() +{ + std::ostringstream stream; + output_vk_sol(stream, verification_key_, "UltraVerificationKey"); + return stream.str(); +} + +} // namespace acir_proofs diff --git a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.hpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.hpp new file mode 100644 index 0000000000..9feed5a69a --- /dev/null +++ b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.hpp @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include +#include + +namespace acir_proofs { + +class AcirComposer { + public: + AcirComposer(std::shared_ptr const& crs_factory); + + void init_proving_key(acir_format::acir_format&& constraint_system); + + std::vector create_proof(std::vector const& witness); + + void init_verification_key(); + + bool verify_proof(std::vector const& proof); + + std::string get_solidity_verifier(); + size_t get_exact_circuit_size() { return exact_circuit_size_; }; + size_t get_total_circuit_size() { return total_circuit_size_; }; + + private: + std::shared_ptr crs_factory_; + acir_format::acir_format constraint_system_; + size_t exact_circuit_size_; + size_t total_circuit_size_; + std::shared_ptr proving_key_; + std::shared_ptr verification_key_; +}; + +} // namespace acir_proofs diff --git a/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.cpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.cpp deleted file mode 100644 index 2010c592fb..0000000000 --- a/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.cpp +++ /dev/null @@ -1,157 +0,0 @@ - -#include "acir_proofs.hpp" -#include "barretenberg/plonk/proof_system/proving_key/serialize.hpp" -#include "barretenberg/dsl/acir_format/acir_format.hpp" -#include "barretenberg/dsl/types.hpp" -#include "barretenberg/srs/reference_string/pippenger_reference_string.hpp" -#include "barretenberg/plonk/proof_system/verification_key/sol_gen.hpp" - -namespace acir_proofs { - -size_t get_solidity_verifier(uint8_t const* g2x, uint8_t const* vk_buf, uint8_t** output_buf) -{ - auto crs = std::make_shared(g2x); - proof_system::plonk::verification_key_data vk_data; - read(vk_buf, vk_data); - auto verification_key = std::make_shared(std::move(vk_data), crs); - - std::ostringstream stream; - // TODO(blaine): Should we just use "VerificationKey" generically? - output_vk_sol(stream, verification_key, "UltraVerificationKey"); - - auto content_str = stream.str(); - auto raw_buf = (uint8_t*)malloc(content_str.size()); - memcpy(raw_buf, (void*)content_str.data(), content_str.size()); - *output_buf = raw_buf; - - return content_str.size(); -} - -uint32_t get_exact_circuit_size(uint8_t const* constraint_system_buf) -{ - auto constraint_system = from_buffer(constraint_system_buf); - auto crs_factory = std::make_unique(); - auto composer = create_circuit(constraint_system, std::move(crs_factory)); - - auto num_gates = composer.get_num_gates(); - return static_cast(num_gates); -} - -uint32_t get_total_circuit_size(uint8_t const* constraint_system_buf) -{ - auto constraint_system = from_buffer(constraint_system_buf); - auto crs_factory = std::make_unique(); - auto composer = create_circuit(constraint_system, std::move(crs_factory)); - - return static_cast(composer.get_total_circuit_size()); -} - -size_t init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf) -{ - auto constraint_system = from_buffer(constraint_system_buf); - - // We know that we don't actually need any CRS to create a proving key, so just feed in a nothing. - // Hacky, but, right now it needs *something*. - auto crs_factory = std::make_unique(); - auto composer = create_circuit(constraint_system, std::move(crs_factory)); - auto proving_key = composer.compute_proving_key(); - - auto buffer = to_buffer(*proving_key); - auto raw_buf = (uint8_t*)malloc(buffer.size()); - memcpy(raw_buf, (void*)buffer.data(), buffer.size()); - *pk_buf = raw_buf; - - return buffer.size(); -} - -size_t init_verification_key(void* pippenger, uint8_t const* g2x, uint8_t const* pk_buf, uint8_t const** vk_buf) -{ - std::shared_ptr crs; - plonk::proving_key_data pk_data; - read(pk_buf, pk_data); - auto proving_key = std::make_shared(std::move(pk_data), crs); - - auto crs_factory = std::make_unique( - reinterpret_cast(pippenger), g2x); - proving_key->reference_string = crs_factory->get_prover_crs(proving_key->circuit_size); - - acir_format::Composer composer(proving_key, nullptr); - auto verification_key = - acir_format::Composer::compute_verification_key_base(proving_key, crs_factory->get_verifier_crs()); - - // The composer_type has not yet been set. We need to set the composer_type for when we later read in and - // construct the verification key so that we have the correct polynomial manifest - verification_key->composer_type = proof_system::ComposerType::PLOOKUP; - - auto buffer = to_buffer(*verification_key); - auto raw_buf = (uint8_t*)malloc(buffer.size()); - memcpy(raw_buf, (void*)buffer.data(), buffer.size()); - *vk_buf = raw_buf; - - return buffer.size(); -} - -size_t new_proof(void* pippenger, - uint8_t const* g2x, - uint8_t const* pk_buf, - uint8_t const* constraint_system_buf, - uint8_t const* witness_buf, - uint8_t** proof_data_buf) -{ - auto constraint_system = from_buffer(constraint_system_buf); - - std::shared_ptr crs; - plonk::proving_key_data pk_data; - read(pk_buf, pk_data); - auto proving_key = std::make_shared(std::move(pk_data), crs); - - auto witness = from_buffer>(witness_buf); - - auto crs_factory = std::make_unique( - reinterpret_cast(pippenger), g2x); - proving_key->reference_string = crs_factory->get_prover_crs(proving_key->circuit_size); - - acir_format::Composer composer(proving_key, nullptr); - - create_circuit_with_witness(composer, constraint_system, witness); - - auto prover = composer.create_ultra_with_keccak_prover(); - - auto heapProver = new acir_format::Prover(std::move(prover)); - auto& proof_data = heapProver->construct_proof().proof_data; - *proof_data_buf = proof_data.data(); - - return proof_data.size(); -} - -bool verify_proof( - uint8_t const* g2x, uint8_t const* vk_buf, uint8_t const* constraint_system_buf, uint8_t* proof, uint32_t length) -{ - bool verified = false; - -#ifndef __wasm__ - try { -#endif - auto constraint_system = from_buffer(constraint_system_buf); - auto crs = std::make_shared(g2x); - plonk::verification_key_data vk_data; - read(vk_buf, vk_data); - auto verification_key = std::make_shared(std::move(vk_data), crs); - - acir_format::Composer composer(nullptr, verification_key); - create_circuit(composer, constraint_system); - plonk::proof pp = { std::vector(proof, proof + length) }; - - auto verifier = composer.create_ultra_with_keccak_verifier(); - - verified = verifier.verify_proof(pp); -#ifndef __wasm__ - } catch (const std::exception& e) { - verified = false; - info(e.what()); - } -#endif - return verified; -} - -} // namespace acir_proofs diff --git a/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.hpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.hpp deleted file mode 100644 index 4bd126aae9..0000000000 --- a/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include - -namespace acir_proofs { - -size_t get_solidity_verifier(uint8_t const* g2x, uint8_t const* vk_buf, uint8_t** output_buf); -uint32_t get_exact_circuit_size(uint8_t const* constraint_system_buf); -uint32_t get_total_circuit_size(uint8_t const* constraint_system_buf); -size_t init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf); -size_t init_verification_key(void* pippenger, uint8_t const* g2x, uint8_t const* pk_buf, uint8_t const** vk_buf); -size_t new_proof(void* pippenger, - uint8_t const* g2x, - uint8_t const* pk_buf, - uint8_t const* constraint_system_buf, - uint8_t const* witness_buf, - uint8_t** proof_data_buf); -bool verify_proof( - uint8_t const* g2x, uint8_t const* vk_buf, uint8_t const* constraint_system_buf, uint8_t* proof, uint32_t length); - -} // namespace acir_proofs diff --git a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp index 4051aada3a..a2a2f41c24 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp @@ -1,53 +1,67 @@ #include "c_bind.hpp" -#include "acir_proofs.hpp" +#include "acir_composer.hpp" #include +#include +#include "barretenberg/common/net.hpp" +#include "barretenberg/dsl/acir_format/acir_format.hpp" +#include "barretenberg/srs/reference_string/pippenger_reference_string.hpp" -#define WASM_EXPORT __attribute__((visibility("default"))) - -extern "C" { - -WASM_EXPORT size_t acir_proofs_get_solidity_verifier(uint8_t const* g2x, uint8_t const* vk_buf, uint8_t** output_buf) +WASM_EXPORT void acir_new_acir_composer(in_ptr pippenger, uint8_t const* g2x, out_ptr out) { - return acir_proofs::get_solidity_verifier(g2x, vk_buf, output_buf); + auto crs_factory = std::make_shared( + reinterpret_cast(*pippenger), g2x); + *out = new acir_proofs::AcirComposer(crs_factory); } -// Get the exact circuit size for the constraint system. -WASM_EXPORT uint32_t acir_proofs_get_exact_circuit_size(uint8_t const* constraint_system_buf) +WASM_EXPORT void acir_delete_acir_composer(in_ptr acir_composer_ptr) { - return acir_proofs::get_exact_circuit_size(constraint_system_buf); + delete reinterpret_cast(*acir_composer_ptr); } -WASM_EXPORT uint32_t acir_proofs_get_total_circuit_size(uint8_t const* constraint_system_buf) +WASM_EXPORT void acir_init_proving_key(in_ptr acir_composer_ptr, uint8_t const* constraint_system_buf) { - return acir_proofs::get_total_circuit_size(constraint_system_buf); + auto acir_composer = reinterpret_cast(*acir_composer_ptr); + auto constraint_system_vec = from_buffer>(constraint_system_buf); + info("length: ", constraint_system_vec.size()); + auto constraint_system = from_buffer(constraint_system_vec); + info("here"); + acir_composer->init_proving_key(std::move(constraint_system)); } -WASM_EXPORT size_t acir_proofs_init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf) +WASM_EXPORT void acir_create_proof(in_ptr acir_composer_ptr, barretenberg::fr::vec_in_buf witness_buf) { - return acir_proofs::init_proving_key(constraint_system_buf, pk_buf); + auto acir_composer = reinterpret_cast(*acir_composer_ptr); + auto witness = from_buffer>(witness_buf); + acir_composer->create_proof(witness); } -WASM_EXPORT size_t acir_proofs_init_verification_key(void* pippenger, - uint8_t const* g2x, - uint8_t const* pk_buf, - uint8_t const** vk_buf) +WASM_EXPORT void acir_init_verification_key(in_ptr acir_composer_ptr) { - return acir_proofs::init_verification_key(pippenger, g2x, pk_buf, vk_buf); + auto acir_composer = reinterpret_cast(*acir_composer_ptr); + acir_composer->init_verification_key(); } -WASM_EXPORT size_t acir_proofs_new_proof(void* pippenger, - uint8_t const* g2x, - uint8_t const* pk_buf, - uint8_t const* constraint_system_buf, - uint8_t const* witness_buf, - uint8_t** proof_data_buf) +WASM_EXPORT void acir_verify_proof(in_ptr acir_composer_ptr, uint8_t const* proof_buf, bool* result) { - return acir_proofs::new_proof(pippenger, g2x, pk_buf, constraint_system_buf, witness_buf, proof_data_buf); + auto acir_composer = reinterpret_cast(*acir_composer_ptr); + auto proof = from_buffer>(proof_buf); + *result = acir_composer->verify_proof(proof); } -WASM_EXPORT bool acir_proofs_verify_proof( - uint8_t const* g2x, uint8_t const* vk_buf, uint8_t const* constraint_system_buf, uint8_t* proof, uint32_t length) +WASM_EXPORT void acir_get_solidity_verifier(in_ptr acir_composer_ptr, out_str_buf out) { - return acir_proofs::verify_proof(g2x, vk_buf, constraint_system_buf, proof, length); + auto acir_composer = reinterpret_cast(*acir_composer_ptr); + *out = to_heap_buffer(acir_composer->get_solidity_verifier()); } + +WASM_EXPORT void acir_get_exact_circuit_size(in_ptr acir_composer_ptr, uint32_t* out) +{ + auto acir_composer = reinterpret_cast(*acir_composer_ptr); + *out = htonl(acir_composer->get_exact_circuit_size()); } + +WASM_EXPORT void acir_get_total_circuit_size(in_ptr acir_composer_ptr, uint32_t* out) +{ + auto acir_composer = reinterpret_cast(*acir_composer_ptr); + *out = htonl(acir_composer->get_total_circuit_size()); +} \ No newline at end of file diff --git a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp index a628c928cb..f6e82ccbcd 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp @@ -1,25 +1,23 @@ #include #include +#include +#include +#include -#define WASM_EXPORT __attribute__((visibility("default"))) - -extern "C" { - -WASM_EXPORT size_t acir_proofs_get_solidity_verifier(uint8_t const* g2x, uint8_t const* vk_buf, uint8_t** output_buf); -WASM_EXPORT uint32_t acir_proofs_get_exact_circuit_size(uint8_t const* constraint_system_buf); -WASM_EXPORT uint32_t acir_proofs_get_total_circuit_size(uint8_t const* constraint_system_buf); -// Construct composer using prover and verifier key buffers -WASM_EXPORT size_t acir_proofs_init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf); -WASM_EXPORT size_t acir_proofs_init_verification_key(void* pippenger, - uint8_t const* g2x, - uint8_t const* pk_buf, - uint8_t const** vk_buf); -WASM_EXPORT size_t acir_proofs_new_proof(void* pippenger, - uint8_t const* g2x, - uint8_t const* pk_buf, - uint8_t const* constraint_system_buf, - uint8_t const* witness_buf, - uint8_t** proof_data_buf); -WASM_EXPORT bool acir_proofs_verify_proof( - uint8_t const* g2x, uint8_t const* vk_buf, uint8_t const* constraint_system_buf, uint8_t* proof, uint32_t length); -} +WASM_EXPORT void acir_new_acir_composer(in_ptr pippenger, uint8_t const* g2x, out_ptr out); + +WASM_EXPORT void acir_delete_acir_composer(in_ptr acir_composer_ptr); + +WASM_EXPORT void acir_init_proving_key(in_ptr acir_composer_ptr, uint8_t const* constraint_system_buf); + +WASM_EXPORT void acir_create_proof(in_ptr acir_composer_ptr, barretenberg::fr::vec_in_buf witness_buf); + +WASM_EXPORT void acir_init_verification_key(in_ptr acir_composer_ptr); + +WASM_EXPORT void acir_verify_proof(in_ptr acir_composer_ptr, uint8_t const* proof_buf, bool* result); + +WASM_EXPORT void acir_get_solidity_verifier(in_ptr acir_composer_ptr, out_str_buf out); + +WASM_EXPORT void acir_get_exact_circuit_size(in_ptr acir_composer_ptr, uint32_t* out); + +WASM_EXPORT void acir_get_total_circuit_size(in_ptr acir_composer_ptr, uint32_t* out); \ No newline at end of file diff --git a/exports.json b/exports.json index 623ac44eb8..c8510a3594 100644 --- a/exports.json +++ b/exports.json @@ -592,5 +592,145 @@ "inArgs": [], "outArgs": [], "isAsync": false + }, + { + "functionName": "acir_new_acir_composer", + "inArgs": [ + { + "name": "pippenger", + "type": "in_ptr" + }, + { + "name": "g2x", + "type": "const uint8_t *" + } + ], + "outArgs": [ + { + "name": "out", + "type": "out_ptr" + } + ], + "isAsync": false + }, + { + "functionName": "acir_delete_acir_composer", + "inArgs": [ + { + "name": "acir_composer_ptr", + "type": "in_ptr" + } + ], + "outArgs": [], + "isAsync": false + }, + { + "functionName": "acir_init_proving_key", + "inArgs": [ + { + "name": "acir_composer_ptr", + "type": "in_ptr" + }, + { + "name": "constraint_system_buf", + "type": "const uint8_t *" + } + ], + "outArgs": [], + "isAsync": false + }, + { + "functionName": "acir_create_proof", + "inArgs": [ + { + "name": "acir_composer_ptr", + "type": "in_ptr" + }, + { + "name": "witness_buf", + "type": "barretenberg::fr::vec_in_buf" + } + ], + "outArgs": [], + "isAsync": false + }, + { + "functionName": "acir_init_verification_key", + "inArgs": [ + { + "name": "acir_composer_ptr", + "type": "in_ptr" + } + ], + "outArgs": [], + "isAsync": false + }, + { + "functionName": "acir_verify_proof", + "inArgs": [ + { + "name": "acir_composer_ptr", + "type": "in_ptr" + }, + { + "name": "proof_buf", + "type": "const uint8_t *" + } + ], + "outArgs": [ + { + "name": "result", + "type": "bool *" + } + ], + "isAsync": false + }, + { + "functionName": "acir_get_solidity_verifier", + "inArgs": [ + { + "name": "acir_composer_ptr", + "type": "in_ptr" + } + ], + "outArgs": [ + { + "name": "out", + "type": "out_str_buf" + } + ], + "isAsync": false + }, + { + "functionName": "acir_get_exact_circuit_size", + "inArgs": [ + { + "name": "acir_composer_ptr", + "type": "in_ptr" + } + ], + "outArgs": [ + { + "name": "out", + "type": "uint32_t *" + } + ], + "isAsync": false + }, + { + "functionName": "acir_get_total_circuit_size", + "inArgs": [ + { + "name": "acir_composer_ptr", + "type": "in_ptr" + } + ], + "outArgs": [ + { + "name": "out", + "type": "uint32_t *" + } + ], + "isAsync": false } ] diff --git a/scripts/bindgen.sh b/scripts/bindgen.sh index 94150775c3..1a2034a213 100755 --- a/scripts/bindgen.sh +++ b/scripts/bindgen.sh @@ -1,7 +1,6 @@ #!/bin/bash set -eu -(cd ./cpp && cmake --build --preset wasm-threads) #find ./cpp/src -type f -name "c_bind*.hpp" | ./scripts/decls_json.py > exports.json cat ./scripts/c_bind_files.txt | ./scripts/decls_json.py > exports.json (cd ./ts && yarn ts-node-esm ./src/bindgen/index.ts ../exports.json > ./src/barretenberg_api/index.ts) diff --git a/scripts/c_bind_files.txt b/scripts/c_bind_files.txt index a0bbba84e3..1672812fa7 100644 --- a/scripts/c_bind_files.txt +++ b/scripts/c_bind_files.txt @@ -5,3 +5,4 @@ ./cpp/src/barretenberg/ecc/c_bind.hpp ./cpp/src/barretenberg/examples/c_bind.hpp ./cpp/src/barretenberg/common/c_bind.hpp +./cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp diff --git a/ts/package.json b/ts/package.json index aa866a07d6..f4c7afde95 100644 --- a/ts/package.json +++ b/ts/package.json @@ -7,6 +7,10 @@ "displayName": "Barretenberg.js", "tsconfig": "./tsconfig.json" }, + "bin": { + "bb.js": "./dest/main.js", + "bb.js-dev": "./src/main-dev.ts" + }, "scripts": { "clean": "rm -rf ./dest .tsbuildinfo", "build": "yarn clean && yarn build:wasm && tsc -b && webpack", diff --git a/ts/src/barretenberg_api/index.ts b/ts/src/barretenberg_api/index.ts index dc8ea807f7..8fc74e2135 100644 --- a/ts/src/barretenberg_api/index.ts +++ b/ts/src/barretenberg_api/index.ts @@ -1,7 +1,7 @@ // WARNING: FILE CODE GENERATED BY BINDGEN UTILITY. DO NOT EDIT! /* eslint-disable @typescript-eslint/no-unused-vars */ import { BarretenbergBinder, BarretenbergBinderSync } from '../barretenberg_binder/index.js'; -import { BufferDeserializer, NumberDeserializer, VectorDeserializer, BoolDeserializer } from '../serialize/index.js'; +import { BufferDeserializer, NumberDeserializer, VectorDeserializer, BoolDeserializer, StringDeserializer } from '../serialize/index.js'; import { Fr, Fq, Point, Buffer32, Buffer128, Ptr } from '../types/index.js'; export class BarretenbergApi { @@ -37,11 +37,7 @@ export class BarretenbergApi { } async pedersenCompressWithHashIndex(inputsBuffer: Fr[], hashIndex: number): Promise { - const result = await this.binder.callWasmExport( - 'pedersen_compress_with_hash_index', - [inputsBuffer, hashIndex], - [Fr], - ); + const result = await this.binder.callWasmExport('pedersen_compress_with_hash_index', [inputsBuffer, hashIndex], [Fr]); return result[0]; } @@ -76,11 +72,7 @@ export class BarretenbergApi { } async pedersenHashMultipleWithHashIndex(inputsBuffer: Fr[], hashIndex: number): Promise { - const result = await this.binder.callWasmExport( - 'pedersen_hash_multiple_with_hash_index', - [inputsBuffer, hashIndex], - [Fr], - ); + const result = await this.binder.callWasmExport('pedersen_hash_multiple_with_hash_index', [inputsBuffer, hashIndex], [Fr]); return result[0]; } @@ -110,76 +102,37 @@ export class BarretenbergApi { } async schnorrConstructSignature(message: Uint8Array, privateKey: Fr): Promise<[Buffer32, Buffer32]> { - const result = await this.binder.callWasmExport( - 'schnorr_construct_signature', - [message, privateKey], - [Buffer32, Buffer32], - ); + const result = await this.binder.callWasmExport('schnorr_construct_signature', [message, privateKey], [Buffer32, Buffer32]); return result as any; } async schnorrVerifySignature(message: Uint8Array, pubKey: Point, sigS: Buffer32, sigE: Buffer32): Promise { - const result = await this.binder.callWasmExport( - 'schnorr_verify_signature', - [message, pubKey, sigS, sigE], - [BoolDeserializer()], - ); + const result = await this.binder.callWasmExport('schnorr_verify_signature', [message, pubKey, sigS, sigE], [BoolDeserializer()]); return result[0]; } async schnorrMultisigCreateMultisigPublicKey(privateKey: Fq): Promise { - const result = await this.binder.callWasmExport( - 'schnorr_multisig_create_multisig_public_key', - [privateKey], - [Buffer128], - ); + const result = await this.binder.callWasmExport('schnorr_multisig_create_multisig_public_key', [privateKey], [Buffer128]); return result[0]; } async schnorrMultisigValidateAndCombineSignerPubkeys(signerPubkeyBuf: Buffer128[]): Promise<[Point, boolean]> { - const result = await this.binder.callWasmExport( - 'schnorr_multisig_validate_and_combine_signer_pubkeys', - [signerPubkeyBuf], - [Point, BoolDeserializer()], - ); + const result = await this.binder.callWasmExport('schnorr_multisig_validate_and_combine_signer_pubkeys', [signerPubkeyBuf], [Point, BoolDeserializer()]); return result as any; } async schnorrMultisigConstructSignatureRound1(): Promise<[Buffer128, Buffer128]> { - const result = await this.binder.callWasmExport( - 'schnorr_multisig_construct_signature_round_1', - [], - [Buffer128, Buffer128], - ); + const result = await this.binder.callWasmExport('schnorr_multisig_construct_signature_round_1', [], [Buffer128, Buffer128]); return result as any; } - async schnorrMultisigConstructSignatureRound2( - message: Uint8Array, - privateKey: Fq, - signerRoundOnePrivateBuf: Buffer128, - signerPubkeysBuf: Buffer128[], - roundOnePublicBuf: Buffer128[], - ): Promise<[Fq, boolean]> { - const result = await this.binder.callWasmExport( - 'schnorr_multisig_construct_signature_round_2', - [message, privateKey, signerRoundOnePrivateBuf, signerPubkeysBuf, roundOnePublicBuf], - [Fq, BoolDeserializer()], - ); + async schnorrMultisigConstructSignatureRound2(message: Uint8Array, privateKey: Fq, signerRoundOnePrivateBuf: Buffer128, signerPubkeysBuf: Buffer128[], roundOnePublicBuf: Buffer128[]): Promise<[Fq, boolean]> { + const result = await this.binder.callWasmExport('schnorr_multisig_construct_signature_round_2', [message, privateKey, signerRoundOnePrivateBuf, signerPubkeysBuf, roundOnePublicBuf], [Fq, BoolDeserializer()]); return result as any; } - async schnorrMultisigCombineSignatures( - message: Uint8Array, - signerPubkeysBuf: Buffer128[], - roundOneBuf: Buffer128[], - roundTwoBuf: Fr[], - ): Promise<[Buffer32, Buffer32, boolean]> { - const result = await this.binder.callWasmExport( - 'schnorr_multisig_combine_signatures', - [message, signerPubkeysBuf, roundOneBuf, roundTwoBuf], - [Buffer32, Buffer32, BoolDeserializer()], - ); + async schnorrMultisigCombineSignatures(message: Uint8Array, signerPubkeysBuf: Buffer128[], roundOneBuf: Buffer128[], roundTwoBuf: Fr[]): Promise<[Buffer32, Buffer32, boolean]> { + const result = await this.binder.callWasmExport('schnorr_multisig_combine_signatures', [message, signerPubkeysBuf, roundOneBuf, roundTwoBuf], [Buffer32, Buffer32, BoolDeserializer()]); return result as any; } @@ -194,11 +147,7 @@ export class BarretenbergApi { } async eccPippengerUnsafe(pippengerPtr: Ptr, scalarsPtr: Ptr, from: number, range: number): Promise { - const result = await this.binder.callWasmExport( - 'ecc_pippenger_unsafe', - [pippengerPtr, scalarsPtr, from, range], - [Point], - ); + const result = await this.binder.callWasmExport('ecc_pippenger_unsafe', [pippengerPtr, scalarsPtr, from, range], [Point]); return result[0]; } @@ -208,11 +157,7 @@ export class BarretenbergApi { } async examplesSimpleCreateAndVerifyProof(pippenger: Ptr, g2x: Uint8Array): Promise { - const result = await this.binder.callWasmExport( - 'examples_simple_create_and_verify_proof', - [pippenger, g2x], - [BoolDeserializer()], - ); + const result = await this.binder.callWasmExport('examples_simple_create_and_verify_proof', [pippenger, g2x], [BoolDeserializer()]); return result[0]; } @@ -230,6 +175,51 @@ export class BarretenbergApi { const result = await this.binder.callWasmExport('test_abort', [], []); return; } + + async acirNewAcirComposer(pippenger: Ptr, g2x: Uint8Array): Promise { + const result = await this.binder.callWasmExport('acir_new_acir_composer', [pippenger, g2x], [Ptr]); + return result[0]; + } + + async acirDeleteAcirComposer(acirComposerPtr: Ptr): Promise { + const result = await this.binder.callWasmExport('acir_delete_acir_composer', [acirComposerPtr], []); + return; + } + + async acirInitProvingKey(acirComposerPtr: Ptr, constraintSystemBuf: Uint8Array): Promise { + const result = await this.binder.callWasmExport('acir_init_proving_key', [acirComposerPtr, constraintSystemBuf], []); + return; + } + + async acirCreateProof(acirComposerPtr: Ptr, witnessBuf: Fr[]): Promise { + const result = await this.binder.callWasmExport('acir_create_proof', [acirComposerPtr, witnessBuf], []); + return; + } + + async acirInitVerificationKey(acirComposerPtr: Ptr): Promise { + const result = await this.binder.callWasmExport('acir_init_verification_key', [acirComposerPtr], []); + return; + } + + async acirVerifyProof(acirComposerPtr: Ptr, proofBuf: Uint8Array): Promise { + const result = await this.binder.callWasmExport('acir_verify_proof', [acirComposerPtr, proofBuf], [BoolDeserializer()]); + return result[0]; + } + + async acirGetSolidityVerifier(acirComposerPtr: Ptr): Promise { + const result = await this.binder.callWasmExport('acir_get_solidity_verifier', [acirComposerPtr], [StringDeserializer()]); + return result[0]; + } + + async acirGetExactCircuitSize(acirComposerPtr: Ptr): Promise { + const result = await this.binder.callWasmExport('acir_get_exact_circuit_size', [acirComposerPtr], [NumberDeserializer()]); + return result[0]; + } + + async acirGetTotalCircuitSize(acirComposerPtr: Ptr): Promise { + const result = await this.binder.callWasmExport('acir_get_total_circuit_size', [acirComposerPtr], [NumberDeserializer()]); + return result[0]; + } } export class BarretenbergApiSync { @@ -300,11 +290,7 @@ export class BarretenbergApiSync { } pedersenHashMultipleWithHashIndex(inputsBuffer: Fr[], hashIndex: number): Fr { - const result = this.binder.callWasmExport( - 'pedersen_hash_multiple_with_hash_index', - [inputsBuffer, hashIndex], - [Fr], - ); + const result = this.binder.callWasmExport('pedersen_hash_multiple_with_hash_index', [inputsBuffer, hashIndex], [Fr]); return result[0]; } @@ -334,20 +320,12 @@ export class BarretenbergApiSync { } schnorrConstructSignature(message: Uint8Array, privateKey: Fr): [Buffer32, Buffer32] { - const result = this.binder.callWasmExport( - 'schnorr_construct_signature', - [message, privateKey], - [Buffer32, Buffer32], - ); + const result = this.binder.callWasmExport('schnorr_construct_signature', [message, privateKey], [Buffer32, Buffer32]); return result as any; } schnorrVerifySignature(message: Uint8Array, pubKey: Point, sigS: Buffer32, sigE: Buffer32): boolean { - const result = this.binder.callWasmExport( - 'schnorr_verify_signature', - [message, pubKey, sigS, sigE], - [BoolDeserializer()], - ); + const result = this.binder.callWasmExport('schnorr_verify_signature', [message, pubKey, sigS, sigE], [BoolDeserializer()]); return result[0]; } @@ -357,49 +335,22 @@ export class BarretenbergApiSync { } schnorrMultisigValidateAndCombineSignerPubkeys(signerPubkeyBuf: Buffer128[]): [Point, boolean] { - const result = this.binder.callWasmExport( - 'schnorr_multisig_validate_and_combine_signer_pubkeys', - [signerPubkeyBuf], - [Point, BoolDeserializer()], - ); + const result = this.binder.callWasmExport('schnorr_multisig_validate_and_combine_signer_pubkeys', [signerPubkeyBuf], [Point, BoolDeserializer()]); return result as any; } schnorrMultisigConstructSignatureRound1(): [Buffer128, Buffer128] { - const result = this.binder.callWasmExport( - 'schnorr_multisig_construct_signature_round_1', - [], - [Buffer128, Buffer128], - ); + const result = this.binder.callWasmExport('schnorr_multisig_construct_signature_round_1', [], [Buffer128, Buffer128]); return result as any; } - schnorrMultisigConstructSignatureRound2( - message: Uint8Array, - privateKey: Fq, - signerRoundOnePrivateBuf: Buffer128, - signerPubkeysBuf: Buffer128[], - roundOnePublicBuf: Buffer128[], - ): [Fq, boolean] { - const result = this.binder.callWasmExport( - 'schnorr_multisig_construct_signature_round_2', - [message, privateKey, signerRoundOnePrivateBuf, signerPubkeysBuf, roundOnePublicBuf], - [Fq, BoolDeserializer()], - ); + schnorrMultisigConstructSignatureRound2(message: Uint8Array, privateKey: Fq, signerRoundOnePrivateBuf: Buffer128, signerPubkeysBuf: Buffer128[], roundOnePublicBuf: Buffer128[]): [Fq, boolean] { + const result = this.binder.callWasmExport('schnorr_multisig_construct_signature_round_2', [message, privateKey, signerRoundOnePrivateBuf, signerPubkeysBuf, roundOnePublicBuf], [Fq, BoolDeserializer()]); return result as any; } - schnorrMultisigCombineSignatures( - message: Uint8Array, - signerPubkeysBuf: Buffer128[], - roundOneBuf: Buffer128[], - roundTwoBuf: Fr[], - ): [Buffer32, Buffer32, boolean] { - const result = this.binder.callWasmExport( - 'schnorr_multisig_combine_signatures', - [message, signerPubkeysBuf, roundOneBuf, roundTwoBuf], - [Buffer32, Buffer32, BoolDeserializer()], - ); + schnorrMultisigCombineSignatures(message: Uint8Array, signerPubkeysBuf: Buffer128[], roundOneBuf: Buffer128[], roundTwoBuf: Fr[]): [Buffer32, Buffer32, boolean] { + const result = this.binder.callWasmExport('schnorr_multisig_combine_signatures', [message, signerPubkeysBuf, roundOneBuf, roundTwoBuf], [Buffer32, Buffer32, BoolDeserializer()]); return result as any; } @@ -424,11 +375,7 @@ export class BarretenbergApiSync { } examplesSimpleCreateAndVerifyProof(pippenger: Ptr, g2x: Uint8Array): boolean { - const result = this.binder.callWasmExport( - 'examples_simple_create_and_verify_proof', - [pippenger, g2x], - [BoolDeserializer()], - ); + const result = this.binder.callWasmExport('examples_simple_create_and_verify_proof', [pippenger, g2x], [BoolDeserializer()]); return result[0]; } @@ -446,4 +393,49 @@ export class BarretenbergApiSync { const result = this.binder.callWasmExport('test_abort', [], []); return; } + + acirNewAcirComposer(pippenger: Ptr, g2x: Uint8Array): Ptr { + const result = this.binder.callWasmExport('acir_new_acir_composer', [pippenger, g2x], [Ptr]); + return result[0]; + } + + acirDeleteAcirComposer(acirComposerPtr: Ptr): void { + const result = this.binder.callWasmExport('acir_delete_acir_composer', [acirComposerPtr], []); + return; + } + + acirInitProvingKey(acirComposerPtr: Ptr, constraintSystemBuf: Uint8Array): void { + const result = this.binder.callWasmExport('acir_init_proving_key', [acirComposerPtr, constraintSystemBuf], []); + return; + } + + acirCreateProof(acirComposerPtr: Ptr, witnessBuf: Fr[]): void { + const result = this.binder.callWasmExport('acir_create_proof', [acirComposerPtr, witnessBuf], []); + return; + } + + acirInitVerificationKey(acirComposerPtr: Ptr): void { + const result = this.binder.callWasmExport('acir_init_verification_key', [acirComposerPtr], []); + return; + } + + acirVerifyProof(acirComposerPtr: Ptr, proofBuf: Uint8Array): boolean { + const result = this.binder.callWasmExport('acir_verify_proof', [acirComposerPtr, proofBuf], [BoolDeserializer()]); + return result[0]; + } + + acirGetSolidityVerifier(acirComposerPtr: Ptr): string { + const result = this.binder.callWasmExport('acir_get_solidity_verifier', [acirComposerPtr], [StringDeserializer()]); + return result[0]; + } + + acirGetExactCircuitSize(acirComposerPtr: Ptr): number { + const result = this.binder.callWasmExport('acir_get_exact_circuit_size', [acirComposerPtr], [NumberDeserializer()]); + return result[0]; + } + + acirGetTotalCircuitSize(acirComposerPtr: Ptr): number { + const result = this.binder.callWasmExport('acir_get_total_circuit_size', [acirComposerPtr], [NumberDeserializer()]); + return result[0]; + } } diff --git a/ts/src/barretenberg_wasm/barretenberg_wasm.ts b/ts/src/barretenberg_wasm/barretenberg_wasm.ts index c91eeb4710..25e89e62e5 100644 --- a/ts/src/barretenberg_wasm/barretenberg_wasm.ts +++ b/ts/src/barretenberg_wasm/barretenberg_wasm.ts @@ -29,9 +29,9 @@ export class BarretenbergWasm { private nextThreadId = 1; private logger: (msg: string) => void = debug; - public static async new(threads = Math.min(getNumCpu(), this.MAX_THREADS)) { + public static async new() { const barretenberg = new BarretenbergWasm(); - await barretenberg.init(threads); + await barretenberg.init(1); return barretenberg; } diff --git a/ts/src/bindgen/mappings.ts b/ts/src/bindgen/mappings.ts index ad9427516e..2b6c2ffa6d 100644 --- a/ts/src/bindgen/mappings.ts +++ b/ts/src/bindgen/mappings.ts @@ -2,6 +2,8 @@ const typeMap: { [key: string]: string } = { in_ptr: 'Ptr', out_ptr: 'Ptr', + 'barretenberg::fr::in_buf': 'Fr', + 'barretenberg::fr::vec_in_buf': 'Fr[]', 'fr::in_buf': 'Fr', 'fr::out_buf': 'Fr', 'fr::vec_in_buf': 'Fr[]', diff --git a/ts/src/bindgen/typescript.ts b/ts/src/bindgen/typescript.ts index 630335d3f5..5dda779bd8 100644 --- a/ts/src/bindgen/typescript.ts +++ b/ts/src/bindgen/typescript.ts @@ -10,7 +10,7 @@ export function generateTypeScriptCode(filename: string) { let output = `// WARNING: FILE CODE GENERATED BY BINDGEN UTILITY. DO NOT EDIT! /* eslint-disable @typescript-eslint/no-unused-vars */ import { BarretenbergBinder, BarretenbergBinderSync } from '../barretenberg_binder/index.js'; -import { BufferDeserializer, NumberDeserializer, VectorDeserializer, BoolDeserializer } from '../serialize/index.js'; +import { BufferDeserializer, NumberDeserializer, VectorDeserializer, BoolDeserializer, StringDeserializer } from '../serialize/index.js'; import { Fr, Fq, Point, Buffer32, Buffer128, Ptr } from '../types/index.js'; export class BarretenbergApi { diff --git a/ts/src/factory/index.ts b/ts/src/factory/index.ts new file mode 100644 index 0000000000..b837a7928e --- /dev/null +++ b/ts/src/factory/index.ts @@ -0,0 +1,23 @@ +import { BarretenbergApi, BarretenbergApiSync } from '../barretenberg_api/index.js'; +import { BarretenbergBinder, BarretenbergBinderSync } from '../barretenberg_binder/index.js'; +import { BarretenbergWasm, BarretenbergWasmWorker } from '../barretenberg_wasm/index.js'; + +export async function newSingleThreaded() { + return new BarretenbergApiSync(new BarretenbergBinderSync(await BarretenbergWasm.new())); +} + +class BarretenbergApiAsync extends BarretenbergApi { + constructor(private worker: any, private wasm: BarretenbergWasmWorker) { + super(new BarretenbergBinder(wasm)); + } + + async destroy() { + await this.wasm.destroy(); + await this.worker.terminate(); + } +} + +export async function newMultiThreaded() { + const { wasm, worker } = await BarretenbergWasm.newWorker(); + return new BarretenbergApiAsync(worker, wasm); +} diff --git a/ts/src/main-dev.ts b/ts/src/main-dev.ts new file mode 100755 index 0000000000..8c090cb92d --- /dev/null +++ b/ts/src/main-dev.ts @@ -0,0 +1,2 @@ +#!/usr/bin/env -S node --loader ts-node/esm --no-warnings +import './main.js'; diff --git a/ts/src/main.ts b/ts/src/main.ts new file mode 100755 index 0000000000..a04f37f01a --- /dev/null +++ b/ts/src/main.ts @@ -0,0 +1,50 @@ +#!/usr/bin/env node +import { Crs } from './crs/index.js'; +import createDebug from 'debug'; +import { newMultiThreaded } from './factory/index.js'; +import { readFileSync } from 'fs'; +import { gunzipSync } from 'zlib'; + +const debug = createDebug('bb.js'); +createDebug.enable('*'); + +function getBytecode() { + const json = readFileSync('/mnt/user-data/charlie/noir-projects/512k/target/main.json', 'utf-8'); + console.log(json.length); + const parsed = JSON.parse(json); + + const buffer = Buffer.from(parsed.bytecode, 'base64'); + console.log(buffer.length); + + const decompressed = gunzipSync(buffer); + console.log(decompressed.length); + + return decompressed; +} + +export async function main() { + debug('starting test...'); + const api = await newMultiThreaded(); + try { + // Plus 1 needed! + const crs = await Crs.new(2 ** 19 + 1); + const pippengerPtr = await api.eccNewPippenger(crs.getG1Data(), crs.numPoints); + + const acirComposer = await api.acirNewAcirComposer(pippengerPtr, crs.getG2Data()); + const bytecode = getBytecode(); + await api.acirInitProvingKey(acirComposer, bytecode); + const exactCircuitSize = await api.acirGetExactCircuitSize(acirComposer); + debug(exactCircuitSize); + + // for (let i = 0; i < 10; ++i) { + // debug(`iteration ${i} starting...`); + // await api.examplesSimpleCreateAndVerifyProof(pippengerPtr, crs.getG2Data()); + // } + + debug('test complete.'); + } finally { + await api.destroy(); + } +} + +await main().catch(console.error); From 284eac239fa437d156d445c3d098d8d2ec4f5b09 Mon Sep 17 00:00:00 2001 From: Charlie Lye Date: Sun, 21 May 2023 21:25:48 +0000 Subject: [PATCH 02/29] Separate thread build dir. --- cpp/CMakePresets.json | 1 + .../crypto/pedersen_commitment/pedersen_lookup.test.cpp | 7 +++++++ ts/src/barretenberg_wasm/barretenberg-threads.wasm | 1 + ts/src/barretenberg_wasm/barretenberg_wasm.ts | 3 ++- ts/src/barretenberg_wasm/browser/index.ts | 4 ++-- ts/src/barretenberg_wasm/node/index.ts | 4 ++-- 6 files changed, 15 insertions(+), 5 deletions(-) create mode 120000 ts/src/barretenberg_wasm/barretenberg-threads.wasm diff --git a/cpp/CMakePresets.json b/cpp/CMakePresets.json index 8534af50bf..e12ba2add6 100644 --- a/cpp/CMakePresets.json +++ b/cpp/CMakePresets.json @@ -139,6 +139,7 @@ "name": "wasm-threads", "displayName": "Build for pthread enabled WASM", "description": "Build for pthread enabled WASM", + "binaryDir": "build-wasm-threads", "inherits": "wasm", "environment": { "WASI_SDK_PREFIX": "${sourceDir}/src/wasi-sdk-20.0+threads", diff --git a/cpp/src/barretenberg/crypto/pedersen_commitment/pedersen_lookup.test.cpp b/cpp/src/barretenberg/crypto/pedersen_commitment/pedersen_lookup.test.cpp index a06f5cea58..fa38853d74 100644 --- a/cpp/src/barretenberg/crypto/pedersen_commitment/pedersen_lookup.test.cpp +++ b/cpp/src/barretenberg/crypto/pedersen_commitment/pedersen_lookup.test.cpp @@ -59,6 +59,13 @@ auto compute_expected(const grumpkin::fq exponent, size_t generator_offset) return (accumulators[0] + accumulators[1]); } +TEST(pedersen_lookup, zero_one) +{ + auto r = + crypto::pedersen_commitment::lookup::compress_native({ barretenberg::fr::zero(), barretenberg::fr::one() }); + EXPECT_EQ(format(r), "0x0c5e1ddecd49de44ed5e5798d3f6fb7c71fe3d37f5bee8664cf88a445b5ba0af"); +} + TEST(pedersen_lookup, endomorphism_test) { typedef grumpkin::fq fq; diff --git a/ts/src/barretenberg_wasm/barretenberg-threads.wasm b/ts/src/barretenberg_wasm/barretenberg-threads.wasm new file mode 120000 index 0000000000..7e9341265a --- /dev/null +++ b/ts/src/barretenberg_wasm/barretenberg-threads.wasm @@ -0,0 +1 @@ +../../../cpp/build-wasm-threads/bin/barretenberg.wasm \ No newline at end of file diff --git a/ts/src/barretenberg_wasm/barretenberg_wasm.ts b/ts/src/barretenberg_wasm/barretenberg_wasm.ts index 25e89e62e5..816d76af7c 100644 --- a/ts/src/barretenberg_wasm/barretenberg_wasm.ts +++ b/ts/src/barretenberg_wasm/barretenberg_wasm.ts @@ -71,7 +71,8 @@ export class BarretenbergWasm { this.memory = new WebAssembly.Memory({ initial, maximum, shared: true }); - const { instance, module } = await WebAssembly.instantiate(await fetchCode(), this.getImportObj(this.memory)); + const code = await fetchCode(threads > 1 ? 'barretenberg-threads.wasm' : 'barretenberg.wasm'); + const { instance, module } = await WebAssembly.instantiate(code, this.getImportObj(this.memory)); this.instance = instance; diff --git a/ts/src/barretenberg_wasm/browser/index.ts b/ts/src/barretenberg_wasm/browser/index.ts index 81c4340cca..ebd521a6b7 100644 --- a/ts/src/barretenberg_wasm/browser/index.ts +++ b/ts/src/barretenberg_wasm/browser/index.ts @@ -2,8 +2,8 @@ import { wrap } from 'comlink'; import { BarretenbergWasmWorker, type BarretenbergWasm } from '../barretenberg_wasm.js'; import debug from 'debug'; -export async function fetchCode() { - const res = await fetch('/barretenberg.wasm'); +export async function fetchCode(name: string) { + const res = await fetch('/' + name); return await res.arrayBuffer(); } diff --git a/ts/src/barretenberg_wasm/node/index.ts b/ts/src/barretenberg_wasm/node/index.ts index dbc437e371..9897b2f26b 100644 --- a/ts/src/barretenberg_wasm/node/index.ts +++ b/ts/src/barretenberg_wasm/node/index.ts @@ -8,9 +8,9 @@ import { wrap } from 'comlink'; import { nodeEndpoint } from './node_endpoint.js'; import { writeSync } from 'fs'; -export async function fetchCode() { +export async function fetchCode(name: string) { const __dirname = dirname(fileURLToPath(import.meta.url)); - return await readFile(__dirname + '/../barretenberg.wasm'); + return await readFile(__dirname + '/../' + name); } export function createWorker() { From afef84263cf70452a7afade816322bc9518ca7a4 Mon Sep 17 00:00:00 2001 From: Charlie Lye Date: Mon, 22 May 2023 10:32:21 +0000 Subject: [PATCH 03/29] Large vector slab allocator. --- .vscode/settings.json | 3 +- cpp/CMakePresets.json | 2 +- cpp/src/CMakeLists.txt | 3 ++ cpp/src/barretenberg/common/c_bind.cpp | 7 ++-- cpp/src/barretenberg/common/c_bind.hpp | 5 ++- .../barretenberg/common/slab_allocator.cpp | 8 +++-- .../barretenberg/common/slab_allocator.hpp | 32 +++++++++++++++++++ cpp/src/barretenberg/ecc/c_bind.cpp | 6 ++++ cpp/src/barretenberg/ecc/c_bind.hpp | 4 ++- .../plonk/composer/composer_base.cpp | 2 +- .../plonk/composer/composer_base.hpp | 11 ++++--- .../plonk/composer/turbo_composer.cpp | 2 +- exports.json | 31 ++++++++++++++++++ ts/src/barretenberg_api/index.ts | 28 +++++++++++++--- ts/src/examples/simple.rawtest.ts | 7 +++- 15 files changed, 129 insertions(+), 22 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 61ccd9f458..0134c08493 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -110,7 +110,8 @@ "solidity.compileUsingRemoteVersion": "v0.6.10+commit.00c0fcaf", "search.exclude": { "**/.yarn": true, - "**/.pnp.*": true + "**/.pnp.*": true, + "**/msgpack-c/**": true }, "typescript.tsdk": "ts/.yarn/sdks/typescript/lib", "typescript.enablePromptUseWorkspaceTsdk": true, diff --git a/cpp/CMakePresets.json b/cpp/CMakePresets.json index e12ba2add6..a7a79fe950 100644 --- a/cpp/CMakePresets.json +++ b/cpp/CMakePresets.json @@ -139,8 +139,8 @@ "name": "wasm-threads", "displayName": "Build for pthread enabled WASM", "description": "Build for pthread enabled WASM", - "binaryDir": "build-wasm-threads", "inherits": "wasm", + "binaryDir": "build-wasm-threads", "environment": { "WASI_SDK_PREFIX": "${sourceDir}/src/wasi-sdk-20.0+threads", "CMAKE_BUILD_TYPE": "Release" diff --git a/cpp/src/CMakeLists.txt b/cpp/src/CMakeLists.txt index f71c57aed9..ef3a7b3b36 100644 --- a/cpp/src/CMakeLists.txt +++ b/cpp/src/CMakeLists.txt @@ -28,9 +28,12 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") endif() # We enable -O1 level optimsations, even when compiling debug wasm, otherwise we get "local count too large" at runtime. +# We prioritise reducing size of final artefacts in release with -Oz. if(WASM) set(CMAKE_CXX_FLAGS_DEBUG "-O1 -g") set(CMAKE_C_FLAGS_DEBUG "-O1 -g") + set(CMAKE_CXX_FLAGS_RELEASE "-Oz -DNDEBUG") + set(CMAKE_C_FLAGS_RELEASE "-Oz -DNDEBUG") add_link_options(-Wl,--export-memory,--import-memory,--stack-first,-z,stack-size=1048576,--max-memory=4294967296) endif() diff --git a/cpp/src/barretenberg/common/c_bind.cpp b/cpp/src/barretenberg/common/c_bind.cpp index a68ef3ffd5..0d99414262 100644 --- a/cpp/src/barretenberg/common/c_bind.cpp +++ b/cpp/src/barretenberg/common/c_bind.cpp @@ -3,6 +3,7 @@ #include "./mem.hpp" #include "./timer.hpp" #include "./serialize.hpp" +#include "./slab_allocator.hpp" #include #include @@ -32,8 +33,6 @@ void thread_test_abort_entry_point(void*) std::abort(); } -extern "C" { - WASM_EXPORT void test_threads(uint32_t const* thread_num, uint32_t const* iterations, uint32_t* out) { info("test starting..."); @@ -67,5 +66,9 @@ WASM_EXPORT void test_abort() info("test_abort aborting"); std::abort(); } + +WASM_EXPORT void common_init_slab_allocator(uint32_t const* circuit_size) +{ + barretenberg::init_slab_allocator(ntohl(*circuit_size)); } #endif \ No newline at end of file diff --git a/cpp/src/barretenberg/common/c_bind.hpp b/cpp/src/barretenberg/common/c_bind.hpp index 350bd3f331..8cc7a9df1d 100644 --- a/cpp/src/barretenberg/common/c_bind.hpp +++ b/cpp/src/barretenberg/common/c_bind.hpp @@ -2,11 +2,10 @@ #include "./wasm_export.hpp" #include "./serialize.hpp" -extern "C" { - WASM_EXPORT void test_threads(uint32_t const* threads, uint32_t const* iterations, uint32_t* out); WASM_EXPORT void test_thread_abort(); WASM_EXPORT void test_abort(); -} + +WASM_EXPORT void common_init_slab_allocator(uint32_t const* circuit_size); diff --git a/cpp/src/barretenberg/common/slab_allocator.cpp b/cpp/src/barretenberg/common/slab_allocator.cpp index 7c2f166a08..d3357456d9 100644 --- a/cpp/src/barretenberg/common/slab_allocator.cpp +++ b/cpp/src/barretenberg/common/slab_allocator.cpp @@ -78,6 +78,7 @@ void SlabAllocator::init(size_t circuit_size_hint) // Think max I saw was 65 extra related to pippenger runtime state. Likely related to the machine having 64 cores. // Strange things may happen here if double to 128 cores, might request 129 extra? size_t overalloc = 128; + size_t tiny_size = 4 * circuit_size_hint; size_t small_size = 32 * (circuit_size_hint + overalloc); size_t large_size = small_size * 4; @@ -88,7 +89,10 @@ void SlabAllocator::init(size_t circuit_size_hint) // on repeated prover runs as the memory becomes fragmented. Maybe best to just recreate the WASM // for each proof for now, if not too expensive. std::map prealloc_num; - prealloc_num[small_size] = 4 + // Monomial wires. + prealloc_num[tiny_size] = 4 + // Composer base wire vectors. + 1; // Miscellaneous. + prealloc_num[small_size] = 11 + // Composer base selector vectors. + 4 + // Monomial wires. 4 + // Lagrange wires. 15 + // Monomial constraint selectors. 15 + // Lagrange constraint selectors. @@ -98,7 +102,7 @@ void SlabAllocator::init(size_t circuit_size_hint) 5 + // Lagrange sorted poly. 2 + // Perm poly. 4 + // Quotient poly. - 7; // Miscellaneous. + 8; // Miscellaneous. prealloc_num[small_size * 2] = 1; // Miscellaneous. prealloc_num[large_size] = 4 + // Coset-fft wires. 15 + // Coset-fft constraint selectors. diff --git a/cpp/src/barretenberg/common/slab_allocator.hpp b/cpp/src/barretenberg/common/slab_allocator.hpp index d4ffef3bf9..de39189cf7 100644 --- a/cpp/src/barretenberg/common/slab_allocator.hpp +++ b/cpp/src/barretenberg/common/slab_allocator.hpp @@ -3,6 +3,7 @@ #include #include #include +#include "./log.hpp" #ifndef NO_MULTITHREADING #include #endif @@ -30,4 +31,35 @@ void init_slab_allocator(size_t circuit_size); */ std::shared_ptr get_mem_slab(size_t size); +template class ContainerSlabAllocator { + public: + using value_type = T; + using pointer = T*; + using const_pointer = const T*; + using size_type = std::size_t; + + ContainerSlabAllocator() = default; + ~ContainerSlabAllocator() = default; + + template struct rebind { + using other = ContainerSlabAllocator; + }; + + pointer allocate(size_type n) + { + // info("ContainerSlabAllocator allocating: ", n * sizeof(T)); + std::shared_ptr ptr = get_mem_slab(n * sizeof(T)); + slab = ptr; // Keep a copy of the shared_ptr so the memory is not freed. + return static_cast(ptr.get()); + } + + void deallocate(pointer /*p*/, size_type /*unused*/) + { + // Memory will be automatically deallocated when slab goes out of scope and its ref count becomes 0. + } + + private: + std::shared_ptr slab; +}; + } // namespace barretenberg \ No newline at end of file diff --git a/cpp/src/barretenberg/ecc/c_bind.cpp b/cpp/src/barretenberg/ecc/c_bind.cpp index e559eccc13..109b8ff0eb 100644 --- a/cpp/src/barretenberg/ecc/c_bind.cpp +++ b/cpp/src/barretenberg/ecc/c_bind.cpp @@ -14,6 +14,12 @@ WASM_EXPORT void ecc_new_pippenger(uint8_t const* points, uint32_t const* num_po *out = new scalar_multiplication::Pippenger(points_vec.data(), num_points); } +WASM_EXPORT void ecc_new_pippenger_mem_prealloced(in_ptr points, uint32_t const* num_points_buf, out_ptr out) +{ + auto num_points = ntohl(*num_points_buf); + *out = new scalar_multiplication::Pippenger((g1::affine_element*)*points, num_points); +} + WASM_EXPORT void ecc_delete_pippenger(in_ptr pippenger) { delete (scalar_multiplication::Pippenger*)(*pippenger); diff --git a/cpp/src/barretenberg/ecc/c_bind.hpp b/cpp/src/barretenberg/ecc/c_bind.hpp index f2761b890b..c7e8f8fa5b 100644 --- a/cpp/src/barretenberg/ecc/c_bind.hpp +++ b/cpp/src/barretenberg/ecc/c_bind.hpp @@ -7,7 +7,9 @@ extern "C" { using namespace barretenberg; using affine_element = g1::affine_element; -WASM_EXPORT void ecc_new_pippenger(uint8_t const* points, uint32_t const* num_points, out_ptr out); +WASM_EXPORT void ecc_new_pippenger(uint8_t const* points, uint32_t const* num_points_buf, out_ptr out); + +WASM_EXPORT void ecc_new_pippenger_mem_prealloced(in_ptr points, uint32_t const* num_points, out_ptr out); WASM_EXPORT void ecc_delete_pippenger(in_ptr pippenger); diff --git a/cpp/src/barretenberg/plonk/composer/composer_base.cpp b/cpp/src/barretenberg/plonk/composer/composer_base.cpp index 12bfd4f18f..53a0745f0c 100644 --- a/cpp/src/barretenberg/plonk/composer/composer_base.cpp +++ b/cpp/src/barretenberg/plonk/composer/composer_base.cpp @@ -257,7 +257,7 @@ std::shared_ptr ComposerBase::compute_proving_key_base(const Compos circuit_proving_key = std::make_shared(subgroup_size, public_inputs.size(), crs, composer_type); for (size_t i = 0; i < num_selectors; ++i) { - std::vector& selector_values = selectors[i]; + auto& selector_values = selectors[i]; const auto& properties = selector_properties[i]; ASSERT(num_gates == selector_values.size()); diff --git a/cpp/src/barretenberg/plonk/composer/composer_base.hpp b/cpp/src/barretenberg/plonk/composer/composer_base.hpp index a3e57bc383..ceed749b44 100644 --- a/cpp/src/barretenberg/plonk/composer/composer_base.hpp +++ b/cpp/src/barretenberg/plonk/composer/composer_base.hpp @@ -1,4 +1,5 @@ #pragma once +#include "barretenberg/common/slab_allocator.hpp" #include "barretenberg/ecc/curves/bn254/fr.hpp" #include "barretenberg/proof_system/arithmetization/gate_data.hpp" #include "barretenberg/plonk/proof_system/prover/prover.hpp" @@ -293,10 +294,10 @@ class ComposerBase { public: size_t num_gates; - std::vector w_l; - std::vector w_r; - std::vector w_o; - std::vector w_4; + std::vector> w_l; + std::vector> w_r; + std::vector> w_o; + std::vector> w_4; std::vector public_inputs; std::vector variables; std::vector next_var_index; // index of next variable in equivalence class (=REAL_VARIABLE if you're last) @@ -318,7 +319,7 @@ class ComposerBase { std::shared_ptr crs_factory_; size_t num_selectors; - std::vector> selectors; + std::vector>> selectors; /** * @brief Contains the properties of each selector: * + name diff --git a/cpp/src/barretenberg/plonk/composer/turbo_composer.cpp b/cpp/src/barretenberg/plonk/composer/turbo_composer.cpp index f3339cf147..a002a7f8f1 100644 --- a/cpp/src/barretenberg/plonk/composer/turbo_composer.cpp +++ b/cpp/src/barretenberg/plonk/composer/turbo_composer.cpp @@ -551,7 +551,7 @@ std::vector TurboComposer::decompose_into_base4_accumulators(const uin size_t num_quad_gates = (num_bits >> 3); num_quad_gates = (num_quad_gates << 3 == num_bits) ? num_quad_gates : num_quad_gates + 1; - std::vector* wires[4]{ &w_4, &w_o, &w_r, &w_l }; + decltype(w_4)* wires[4]{ &w_4, &w_o, &w_r, &w_l }; // num_quads = the number of accumulators used in the table, not including the output row. const size_t num_quads = (num_quad_gates << 2); diff --git a/exports.json b/exports.json index c8510a3594..985b508703 100644 --- a/exports.json +++ b/exports.json @@ -469,6 +469,26 @@ "name": "points", "type": "const uint8_t *" }, + { + "name": "num_points_buf", + "type": "const uint32_t *" + } + ], + "outArgs": [ + { + "name": "out", + "type": "out_ptr" + } + ], + "isAsync": false + }, + { + "functionName": "ecc_new_pippenger_mem_prealloced", + "inArgs": [ + { + "name": "points", + "type": "in_ptr" + }, { "name": "num_points", "type": "const uint32_t *" @@ -593,6 +613,17 @@ "outArgs": [], "isAsync": false }, + { + "functionName": "common_init_slab_allocator", + "inArgs": [ + { + "name": "circuit_size", + "type": "const uint32_t *" + } + ], + "outArgs": [], + "isAsync": false + }, { "functionName": "acir_new_acir_composer", "inArgs": [ diff --git a/ts/src/barretenberg_api/index.ts b/ts/src/barretenberg_api/index.ts index 8fc74e2135..9427146e42 100644 --- a/ts/src/barretenberg_api/index.ts +++ b/ts/src/barretenberg_api/index.ts @@ -136,8 +136,13 @@ export class BarretenbergApi { return result as any; } - async eccNewPippenger(points: Uint8Array, numPoints: number): Promise { - const result = await this.binder.callWasmExport('ecc_new_pippenger', [points, numPoints], [Ptr]); + async eccNewPippenger(points: Uint8Array, numPointsBuf: number): Promise { + const result = await this.binder.callWasmExport('ecc_new_pippenger', [points, numPointsBuf], [Ptr]); + return result[0]; + } + + async eccNewPippengerMemPrealloced(points: Ptr, numPoints: number): Promise { + const result = await this.binder.callWasmExport('ecc_new_pippenger_mem_prealloced', [points, numPoints], [Ptr]); return result[0]; } @@ -176,6 +181,11 @@ export class BarretenbergApi { return; } + async commonInitSlabAllocator(circuitSize: number): Promise { + const result = await this.binder.callWasmExport('common_init_slab_allocator', [circuitSize], []); + return; + } + async acirNewAcirComposer(pippenger: Ptr, g2x: Uint8Array): Promise { const result = await this.binder.callWasmExport('acir_new_acir_composer', [pippenger, g2x], [Ptr]); return result[0]; @@ -354,8 +364,13 @@ export class BarretenbergApiSync { return result as any; } - eccNewPippenger(points: Uint8Array, numPoints: number): Ptr { - const result = this.binder.callWasmExport('ecc_new_pippenger', [points, numPoints], [Ptr]); + eccNewPippenger(points: Uint8Array, numPointsBuf: number): Ptr { + const result = this.binder.callWasmExport('ecc_new_pippenger', [points, numPointsBuf], [Ptr]); + return result[0]; + } + + eccNewPippengerMemPrealloced(points: Ptr, numPoints: number): Ptr { + const result = this.binder.callWasmExport('ecc_new_pippenger_mem_prealloced', [points, numPoints], [Ptr]); return result[0]; } @@ -394,6 +409,11 @@ export class BarretenbergApiSync { return; } + commonInitSlabAllocator(circuitSize: number): void { + const result = this.binder.callWasmExport('common_init_slab_allocator', [circuitSize], []); + return; + } + acirNewAcirComposer(pippenger: Ptr, g2x: Uint8Array): Ptr { const result = this.binder.callWasmExport('acir_new_acir_composer', [pippenger, g2x], [Ptr]); return result[0]; diff --git a/ts/src/examples/simple.rawtest.ts b/ts/src/examples/simple.rawtest.ts index 4d9ff24c75..547d497d26 100644 --- a/ts/src/examples/simple.rawtest.ts +++ b/ts/src/examples/simple.rawtest.ts @@ -8,12 +8,17 @@ createDebug.enable('*'); const debug = createDebug('simple_test'); async function main() { + const CIRCUIT_SIZE = 2 ** 19; + debug('starting test...'); const { wasm, worker } = await BarretenbergWasm.newWorker(); const api = new BarretenbergApi(new BarretenbergBinder(wasm)); + // Import to init slab allocator as first thing, to ensure maximum memory efficiency. + await api.commonInitSlabAllocator(CIRCUIT_SIZE); + // Plus 1 needed! - const crs = await Crs.new(2 ** 19 + 1); + const crs = await Crs.new(CIRCUIT_SIZE + 1); const pippengerPtr = await api.eccNewPippenger(crs.getG1Data(), crs.numPoints); for (let i = 0; i < 10; ++i) { From 4c39ac62c63e6996172b30165d8bd37d0cd7e5ba Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Mon, 22 May 2023 18:55:51 +0100 Subject: [PATCH 04/29] format msgpack serialization and excldue msgpack-c from clang-format (#467) --- cpp/src/barretenberg/common/fuzzer.hpp | 137 +++++++++--------- cpp/src/barretenberg/common/log.hpp | 12 +- cpp/src/barretenberg/crypto/hmac/hmac.hpp | 4 +- .../dsl/acir_format/acir_format.test.cpp | 2 +- .../barretenberg/ecc/curves/bn254/fq.test.cpp | 2 +- .../barretenberg/ecc/curves/bn254/fr.test.cpp | 2 +- .../barretenberg/ecc/fields/field_impl.hpp | 20 +-- .../ecc/fields/field_impl_x64.hpp | 128 ++++++++-------- .../ecc/groups/group_impl_asm.tcc | 16 +- cpp/src/barretenberg/ecc/serialize.test.cpp | 2 +- cpp/src/barretenberg/env/crs.hpp | 6 +- .../barretenberg/honk/proof_system/prover.hpp | 3 +- .../honk/proof_system/ultra_prover.hpp | 3 +- cpp/src/barretenberg/serialize/cbind.hpp | 11 +- cpp/src/barretenberg/serialize/msgpack.hpp | 9 +- .../serialize/msgpack_impl/concepts.hpp | 12 +- .../serialize/msgpack_impl/func_traits.hpp | 32 ++-- .../msgpack_impl/name_value_pair_macro.hpp | 6 +- .../serialize/msgpack_impl/schema_impl.hpp | 12 +- .../msgpack_impl/struct_map_impl.hpp | 8 +- .../serialize/msgpack_impl/variant_impl.hpp | 8 +- .../barretenberg/serialize/raw_pointer.hpp | 17 +-- .../stdlib/hash/keccak/keccak.test.cpp | 2 - cpp/src/msgpack-c/.clang-format | 2 + 24 files changed, 226 insertions(+), 230 deletions(-) create mode 100644 cpp/src/msgpack-c/.clang-format diff --git a/cpp/src/barretenberg/common/fuzzer.hpp b/cpp/src/barretenberg/common/fuzzer.hpp index adf0aa5d1b..202b733884 100644 --- a/cpp/src/barretenberg/common/fuzzer.hpp +++ b/cpp/src/barretenberg/common/fuzzer.hpp @@ -84,80 +84,83 @@ class FastRandom { * * @tparam T */ -template -concept SimpleRng = requires(T a) { - { - a.next() - } -> std::convertible_to; - }; +template concept SimpleRng = requires(T a) +{ + { + a.next() + } + ->std::convertible_to; +}; /** * @brief Concept for forcing ArgumentSizes to be size_t * * @tparam T */ -template -concept InstructionArgumentSizes = requires { - { - std::make_tuple(T::CONSTANT, - T::WITNESS, - T::CONSTANT_WITNESS, - T::ADD, - T::SUBTRACT, - T::MULTIPLY, - T::DIVIDE, - T::ADD_TWO, - T::MADD, - T::MULT_MADD, - T::MSUB_DIV, - T::SQR, - T::SQR_ADD, - T::SUBTRACT_WITH_CONSTRAINT, - T::DIVIDE_WITH_CONSTRAINTS, - T::SLICE, - T::ASSERT_ZERO, - T::ASSERT_NOT_ZERO) - } -> std::same_as>; - }; +template concept InstructionArgumentSizes = requires +{ + { + std::make_tuple(T::CONSTANT, + T::WITNESS, + T::CONSTANT_WITNESS, + T::ADD, + T::SUBTRACT, + T::MULTIPLY, + T::DIVIDE, + T::ADD_TWO, + T::MADD, + T::MULT_MADD, + T::MSUB_DIV, + T::SQR, + T::SQR_ADD, + T::SUBTRACT_WITH_CONSTRAINT, + T::DIVIDE_WITH_CONSTRAINTS, + T::SLICE, + T::ASSERT_ZERO, + T::ASSERT_NOT_ZERO) + } + ->std::same_as>; +}; /** * @brief Concept for Havoc Configurations * * @tparam T */ -template -concept HavocConfigConstraint = - requires { - { - std::make_tuple(T::GEN_MUTATION_COUNT_LOG, T::GEN_STRUCTURAL_MUTATION_PROBABILITY) - } -> std::same_as>; - T::GEN_MUTATION_COUNT_LOG <= 7; - }; +template concept HavocConfigConstraint = requires +{ + { + std::make_tuple(T::GEN_MUTATION_COUNT_LOG, T::GEN_STRUCTURAL_MUTATION_PROBABILITY) + } + ->std::same_as>; + T::GEN_MUTATION_COUNT_LOG <= 7; +}; /** * @brief Concept specifying the class used by the fuzzer * * @tparam T */ -template -concept ArithmeticFuzzHelperConstraint = requires { - typename T::ArgSizes; - typename T::Instruction; - typename T::ExecutionState; - typename T::ExecutionHandler; - InstructionArgumentSizes; - // HavocConfigConstraint; - }; +template concept ArithmeticFuzzHelperConstraint = requires +{ + typename T::ArgSizes; + typename T::Instruction; + typename T::ExecutionState; + typename T::ExecutionHandler; + InstructionArgumentSizes; + // HavocConfigConstraint; +}; /** * @brief Fuzzer uses only composers with check_circuit function * * @tparam T */ -template -concept CheckableComposer = requires(T a) { - { - a.check_circuit() - } -> std::same_as; - }; +template concept CheckableComposer = requires(T a) +{ + { + a.check_circuit() + } + ->std::same_as; +}; /** * @brief The fuzzer can use a postprocessing function that is specific to the type being fuzzed @@ -167,11 +170,13 @@ concept CheckableComposer = requires(T a) { * @tparam Context The class containing the full context */ template -concept PostProcessingEnabled = requires(Composer composer, Context context) { - { - T::postProcess(&composer, context) - } -> std::same_as; - }; +concept PostProcessingEnabled = requires(Composer composer, Context context) +{ + { + T::postProcess(&composer, context) + } + ->std::same_as; +}; /** * @brief This concept is used when we want to limit the number of executions of certain instructions (for example, @@ -179,19 +184,17 @@ concept PostProcessingEnabled = requires(Composer composer, Context context) { * * @tparam T */ -template -concept InstructionWeightsEnabled = requires { - typename T::InstructionWeights; - T::InstructionWeights::_LIMIT; - }; +template concept InstructionWeightsEnabled = requires +{ + typename T::InstructionWeights; + T::InstructionWeights::_LIMIT; +}; /** * @brief A templated class containing most of the fuzzing logic for a generic Arithmetic class * * @tparam T */ -template - requires ArithmeticFuzzHelperConstraint -class ArithmeticFuzzHelper { +template requires ArithmeticFuzzHelperConstraint class ArithmeticFuzzHelper { private: /** * @brief Mutator swapping two instructions together @@ -494,8 +497,8 @@ class ArithmeticFuzzHelper { * @param instructions */ template - inline static void executeInstructions(std::vector& instructions) - requires CheckableComposer + inline static void executeInstructions( + std::vector& instructions) requires CheckableComposer { typename T::ExecutionState state; Composer composer = Composer(); diff --git a/cpp/src/barretenberg/common/log.hpp b/cpp/src/barretenberg/common/log.hpp index f581645883..37f8af23c7 100644 --- a/cpp/src/barretenberg/common/log.hpp +++ b/cpp/src/barretenberg/common/log.hpp @@ -10,11 +10,13 @@ #define BENCHMARK_INFO_SUFFIX "##BENCHMARK_INFO_SUFFIX##" #define GET_COMPOSER_NAME_STRING(composer) \ - (typeid(composer) == typeid(plonk::StandardComposer) ? "StandardPlonk" \ - : typeid(composer) == typeid(plonk::TurboComposer) ? "TurboPlonk" \ - : typeid(composer) == typeid(plonk::UltraComposer) ? "UltraPlonk" \ - : typeid(composer) == typeid(honk::StandardHonkComposer) ? "StandardHonk" \ - : "NULLPlonk") + (typeid(composer) == typeid(plonk::StandardComposer) \ + ? "StandardPlonk" \ + : typeid(composer) == typeid(plonk::TurboComposer) \ + ? "TurboPlonk" \ + : typeid(composer) == typeid(plonk::UltraComposer) \ + ? "UltraPlonk" \ + : typeid(composer) == typeid(honk::StandardHonkComposer) ? "StandardHonk" : "NULLPlonk") namespace { diff --git a/cpp/src/barretenberg/crypto/hmac/hmac.hpp b/cpp/src/barretenberg/crypto/hmac/hmac.hpp index e78ef5206c..e1f83905e5 100644 --- a/cpp/src/barretenberg/crypto/hmac/hmac.hpp +++ b/cpp/src/barretenberg/crypto/hmac/hmac.hpp @@ -93,8 +93,8 @@ std::array hmac(const MessageContainer& message, con * @return Fr output field element as uint512_t( H(10...0 || HMAC(k,m)) || H(00...0 || HMAC(k,m)) ) % r */ template -Fr get_unbiased_field_from_hmac(const MessageContainer& message, const KeyContainer& key) - requires(Hash::OUTPUT_SIZE == 32) +Fr get_unbiased_field_from_hmac(const MessageContainer& message, + const KeyContainer& key) requires(Hash::OUTPUT_SIZE == 32) { // Strong assumption that works for now with our suite of Hashers static_assert(Hash::BLOCK_SIZE > Hash::OUTPUT_SIZE); diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp index a7b39363d4..b9fed48eb9 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp @@ -7,7 +7,7 @@ #include "ecdsa_secp256k1.hpp" TEST(acir_format, msgpack_logic_constraint) { - auto [actual, expected] = msgpack_roundtrip(acir_format::LogicConstraint {}); + auto [actual, expected] = msgpack_roundtrip(acir_format::LogicConstraint{}); EXPECT_EQ(actual, expected); } TEST(acir_format, test_logic_gate_from_noir_circuit) diff --git a/cpp/src/barretenberg/ecc/curves/bn254/fq.test.cpp b/cpp/src/barretenberg/ecc/curves/bn254/fq.test.cpp index ce5e663236..0249eef031 100644 --- a/cpp/src/barretenberg/ecc/curves/bn254/fq.test.cpp +++ b/cpp/src/barretenberg/ecc/curves/bn254/fq.test.cpp @@ -7,7 +7,7 @@ using namespace barretenberg; TEST(fq, msgpack) { - auto [actual, expected] = msgpack_roundtrip(barretenberg::fq{1ull, 2ull, 3ull, 4ull}); + auto [actual, expected] = msgpack_roundtrip(barretenberg::fq{ 1ull, 2ull, 3ull, 4ull }); EXPECT_EQ(actual, expected); } diff --git a/cpp/src/barretenberg/ecc/curves/bn254/fr.test.cpp b/cpp/src/barretenberg/ecc/curves/bn254/fr.test.cpp index 28cd331e1b..afa148fd04 100644 --- a/cpp/src/barretenberg/ecc/curves/bn254/fr.test.cpp +++ b/cpp/src/barretenberg/ecc/curves/bn254/fr.test.cpp @@ -6,7 +6,7 @@ using namespace barretenberg; TEST(fr, msgpack) { - auto [actual, expected] = msgpack_roundtrip(barretenberg::fr{1ull, 2ull, 3ull, 4ull}); + auto [actual, expected] = msgpack_roundtrip(barretenberg::fr{ 1ull, 2ull, 3ull, 4ull }); EXPECT_EQ(actual, expected); } diff --git a/cpp/src/barretenberg/ecc/fields/field_impl.hpp b/cpp/src/barretenberg/ecc/fields/field_impl.hpp index a486aab45f..9b1bcd12a2 100644 --- a/cpp/src/barretenberg/ecc/fields/field_impl.hpp +++ b/cpp/src/barretenberg/ecc/fields/field_impl.hpp @@ -606,16 +606,16 @@ template constexpr field field::multiplicative_generator() noexc return target; } -// This function is used to serialize a field. It matches the old serialization format by first -// converting the field from Montgomery form, which is a special representation used for efficient +// This function is used to serialize a field. It matches the old serialization format by first +// converting the field from Montgomery form, which is a special representation used for efficient // modular arithmetic. template void field::msgpack_pack(auto& packer) const { // The field is first converted from Montgomery form, similar to how the old format did it. auto adjusted = from_montgomery_form(); - // The data is then converted to big endian format using htonll, which stands for "host to network long long". - // This is necessary because the data will be written to a raw msgpack buffer, which requires big endian format. + // The data is then converted to big endian format using htonll, which stands for "host to network long long". + // This is necessary because the data will be written to a raw msgpack buffer, which requires big endian format. uint64_t bin_data[4] = { htonll(adjusted.data[3]), htonll(adjusted.data[2]), htonll(adjusted.data[1]), htonll(adjusted.data[0]) }; @@ -625,22 +625,22 @@ template void field::msgpack_pack(auto& packer) const packer.pack_bin_body((const char*)bin_data, sizeof(bin_data)); } -// This function is used to deserialize a field. It also matches the old deserialization format by -// reading the binary data as big endian uint64_t's, correcting them to the host endianness, and -// then converting the field back to Montgomery form. +// This function is used to deserialize a field. It also matches the old deserialization format by +// reading the binary data as big endian uint64_t's, correcting them to the host endianness, and +// then converting the field back to Montgomery form. template void field::msgpack_unpack(auto o) { // The binary data is first extracted from the msgpack object. std::array raw_data = o; - // The binary data is then read as big endian uint64_t's. This is done by casting the raw data to uint64_t* and then + // The binary data is then read as big endian uint64_t's. This is done by casting the raw data to uint64_t* and then // using ntohll ("network to host long long") to correct the endianness to the host's endianness. uint64_t* cast_data = (uint64_t*)&raw_data[0]; - uint64_t reversed[] = {ntohll(cast_data[3]), ntohll(cast_data[2]), ntohll(cast_data[1]), ntohll(cast_data[0])}; + uint64_t reversed[] = { ntohll(cast_data[3]), ntohll(cast_data[2]), ntohll(cast_data[1]), ntohll(cast_data[0]) }; // The corrected data is then copied back into the field's data array. for (int i = 0; i < 4; i++) { - data[i] = reversed[i]; + data[i] = reversed[i]; } // Finally, the field is converted back to Montgomery form, just like in the old format. diff --git a/cpp/src/barretenberg/ecc/fields/field_impl_x64.hpp b/cpp/src/barretenberg/ecc/fields/field_impl_x64.hpp index 0f59db209c..2664f12345 100644 --- a/cpp/src/barretenberg/ecc/fields/field_impl_x64.hpp +++ b/cpp/src/barretenberg/ecc/fields/field_impl_x64.hpp @@ -87,12 +87,12 @@ template field field::asm_mul_with_coarse_reduction(const field& : "%r"(&a), "%r"(&b), "r"(&r), - [modulus_0] "m"(modulus_0), - [modulus_1] "m"(modulus_1), - [modulus_2] "m"(modulus_2), - [modulus_3] "m"(modulus_3), - [r_inv] "m"(r_inv), - [zero_reference] "m"(zero_ref) + [ modulus_0 ] "m"(modulus_0), + [ modulus_1 ] "m"(modulus_1), + [ modulus_2 ] "m"(modulus_2), + [ modulus_3 ] "m"(modulus_3), + [ r_inv ] "m"(r_inv), + [ zero_reference ] "m"(zero_ref) : "%rdx", "%rdi", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory"); return r; } @@ -119,12 +119,12 @@ template void field::asm_self_mul_with_coarse_reduction(const field : : "r"(&a), "r"(&b), - [modulus_0] "m"(modulus_0), - [modulus_1] "m"(modulus_1), - [modulus_2] "m"(modulus_2), - [modulus_3] "m"(modulus_3), - [r_inv] "m"(r_inv), - [zero_reference] "m"(zero_ref) + [ modulus_0 ] "m"(modulus_0), + [ modulus_1 ] "m"(modulus_1), + [ modulus_2 ] "m"(modulus_2), + [ modulus_3 ] "m"(modulus_3), + [ r_inv ] "m"(r_inv), + [ zero_reference ] "m"(zero_ref) : "%rdx", "%rdi", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory"); } @@ -157,12 +157,12 @@ template field field::asm_sqr_with_coarse_reduction(const field& : "%r"(&a), "%r"(&a), "r"(&r), - [modulus_0] "m"(modulus_0), - [modulus_1] "m"(modulus_1), - [modulus_2] "m"(modulus_2), - [modulus_3] "m"(modulus_3), - [r_inv] "m"(r_inv), - [zero_reference] "m"(zero_ref) + [ modulus_0 ] "m"(modulus_0), + [ modulus_1 ] "m"(modulus_1), + [ modulus_2 ] "m"(modulus_2), + [ modulus_3 ] "m"(modulus_3), + [ r_inv ] "m"(r_inv), + [ zero_reference ] "m"(zero_ref) : "%rdx", "%rdi", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory"); #else @@ -181,12 +181,12 @@ template field field::asm_sqr_with_coarse_reduction(const field& : : "r"(&a), "r"(&r), - [zero_reference] "m"(zero_ref), - [modulus_0] "m"(modulus_0), - [modulus_1] "m"(modulus_1), - [modulus_2] "m"(modulus_2), - [modulus_3] "m"(modulus_3), - [r_inv] "m"(r_inv) + [ zero_reference ] "m"(zero_ref), + [ modulus_0 ] "m"(modulus_0), + [ modulus_1 ] "m"(modulus_1), + [ modulus_2 ] "m"(modulus_2), + [ modulus_3 ] "m"(modulus_3), + [ r_inv ] "m"(r_inv) : "%rcx", "%rdx", "%rdi", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory"); #endif return r; @@ -219,12 +219,12 @@ template void field::asm_self_sqr_with_coarse_reduction(const field : : "r"(&a), "r"(&a), - [modulus_0] "m"(modulus_0), - [modulus_1] "m"(modulus_1), - [modulus_2] "m"(modulus_2), - [modulus_3] "m"(modulus_3), - [r_inv] "m"(r_inv), - [zero_reference] "m"(zero_ref) + [ modulus_0 ] "m"(modulus_0), + [ modulus_1 ] "m"(modulus_1), + [ modulus_2 ] "m"(modulus_2), + [ modulus_3 ] "m"(modulus_3), + [ r_inv ] "m"(r_inv), + [ zero_reference ] "m"(zero_ref) : "%rdx", "%rdi", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory"); #else @@ -241,12 +241,12 @@ template void field::asm_self_sqr_with_coarse_reduction(const field STORE_FIELD_ELEMENT("%0", "%%r12", "%%r13", "%%r14", "%%r15") : : "r"(&a), - [zero_reference] "m"(zero_ref), - [modulus_0] "m"(modulus_0), - [modulus_1] "m"(modulus_1), - [modulus_2] "m"(modulus_2), - [modulus_3] "m"(modulus_3), - [r_inv] "m"(r_inv) + [ zero_reference ] "m"(zero_ref), + [ modulus_0 ] "m"(modulus_0), + [ modulus_1 ] "m"(modulus_1), + [ modulus_2 ] "m"(modulus_2), + [ modulus_3 ] "m"(modulus_3), + [ r_inv ] "m"(r_inv) : "%rcx", "%rdx", "%rdi", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory"); #endif } @@ -270,10 +270,10 @@ template field field::asm_add_with_coarse_reduction(const field& : "%r"(&a), "%r"(&b), "r"(&r), - [twice_not_modulus_0] "m"(twice_not_modulus_0), - [twice_not_modulus_1] "m"(twice_not_modulus_1), - [twice_not_modulus_2] "m"(twice_not_modulus_2), - [twice_not_modulus_3] "m"(twice_not_modulus_3) + [ twice_not_modulus_0 ] "m"(twice_not_modulus_0), + [ twice_not_modulus_1 ] "m"(twice_not_modulus_1), + [ twice_not_modulus_2 ] "m"(twice_not_modulus_2), + [ twice_not_modulus_3 ] "m"(twice_not_modulus_3) : "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory"); return r; } @@ -294,10 +294,10 @@ template void field::asm_self_add_with_coarse_reduction(const field : : "r"(&a), "r"(&b), - [twice_not_modulus_0] "m"(twice_not_modulus_0), - [twice_not_modulus_1] "m"(twice_not_modulus_1), - [twice_not_modulus_2] "m"(twice_not_modulus_2), - [twice_not_modulus_3] "m"(twice_not_modulus_3) + [ twice_not_modulus_0 ] "m"(twice_not_modulus_0), + [ twice_not_modulus_1 ] "m"(twice_not_modulus_1), + [ twice_not_modulus_2 ] "m"(twice_not_modulus_2), + [ twice_not_modulus_3 ] "m"(twice_not_modulus_3) : "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory"); } @@ -318,10 +318,10 @@ template field field::asm_sub_with_coarse_reduction(const field& : "r"(&a), "r"(&b), "r"(&r), - [twice_modulus_0] "m"(twice_modulus_0), - [twice_modulus_1] "m"(twice_modulus_1), - [twice_modulus_2] "m"(twice_modulus_2), - [twice_modulus_3] "m"(twice_modulus_3) + [ twice_modulus_0 ] "m"(twice_modulus_0), + [ twice_modulus_1 ] "m"(twice_modulus_1), + [ twice_modulus_2 ] "m"(twice_modulus_2), + [ twice_modulus_3 ] "m"(twice_modulus_3) : "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory"); return r; } @@ -340,10 +340,10 @@ template void field::asm_self_sub_with_coarse_reduction(const field : : "r"(&a), "r"(&b), - [twice_modulus_0] "m"(twice_modulus_0), - [twice_modulus_1] "m"(twice_modulus_1), - [twice_modulus_2] "m"(twice_modulus_2), - [twice_modulus_3] "m"(twice_modulus_3) + [ twice_modulus_0 ] "m"(twice_modulus_0), + [ twice_modulus_1 ] "m"(twice_modulus_1), + [ twice_modulus_2 ] "m"(twice_modulus_2), + [ twice_modulus_3 ] "m"(twice_modulus_3) : "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory"); } @@ -372,10 +372,10 @@ template void field::asm_conditional_negate(field& r, const uint64_ : : "r"(predicate), "r"(&r), - [twice_modulus_0] "i"(twice_modulus_0), - [twice_modulus_1] "i"(twice_modulus_1), - [twice_modulus_2] "i"(twice_modulus_2), - [twice_modulus_3] "i"(twice_modulus_3) + [ twice_modulus_0 ] "i"(twice_modulus_0), + [ twice_modulus_1 ] "i"(twice_modulus_1), + [ twice_modulus_2 ] "i"(twice_modulus_2), + [ twice_modulus_3 ] "i"(twice_modulus_3) : "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory"); } @@ -394,10 +394,10 @@ template field field::asm_reduce_once(const field& a) noexcept : : "r"(&a), "r"(&r), - [not_modulus_0] "m"(not_modulus_0), - [not_modulus_1] "m"(not_modulus_1), - [not_modulus_2] "m"(not_modulus_2), - [not_modulus_3] "m"(not_modulus_3) + [ not_modulus_0 ] "m"(not_modulus_0), + [ not_modulus_1 ] "m"(not_modulus_1), + [ not_modulus_2 ] "m"(not_modulus_2), + [ not_modulus_3 ] "m"(not_modulus_3) : "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory"); return r; } @@ -414,10 +414,10 @@ template void field::asm_self_reduce_once(const field& a) noexcept STORE_FIELD_ELEMENT("%0", "%%r12", "%%r13", "%%r14", "%%r15") : : "r"(&a), - [not_modulus_0] "m"(not_modulus_0), - [not_modulus_1] "m"(not_modulus_1), - [not_modulus_2] "m"(not_modulus_2), - [not_modulus_3] "m"(not_modulus_3) + [ not_modulus_0 ] "m"(not_modulus_0), + [ not_modulus_1 ] "m"(not_modulus_1), + [ not_modulus_2 ] "m"(not_modulus_2), + [ not_modulus_3 ] "m"(not_modulus_3) : "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory"); } } // namespace barretenberg diff --git a/cpp/src/barretenberg/ecc/groups/group_impl_asm.tcc b/cpp/src/barretenberg/ecc/groups/group_impl_asm.tcc index 17d714b487..73a6374b95 100644 --- a/cpp/src/barretenberg/ecc/groups/group_impl_asm.tcc +++ b/cpp/src/barretenberg/ecc/groups/group_impl_asm.tcc @@ -98,10 +98,10 @@ inline void group::conditional_ne : "r"(src), "r"(dest), "r"(predicate), - [modulus_0] "i"(twice_modulus_0), - [modulus_1] "i"(twice_modulus_1), - [modulus_2] "i"(twice_modulus_2), - [modulus_3] "i"(twice_modulus_3) + [ modulus_0 ] "i"(twice_modulus_0), + [ modulus_1 ] "i"(twice_modulus_1), + [ modulus_2 ] "i"(twice_modulus_2), + [ modulus_3 ] "i"(twice_modulus_3) : "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "%ymm0", "memory", "cc"); #else __asm__ __volatile__("xorq %%r8, %%r8 \n\t" @@ -138,10 +138,10 @@ inline void group::conditional_ne : "r"(src), "r"(dest), "r"(predicate), - [modulus_0] "i"(twice_modulus_0), - [modulus_1] "i"(twice_modulus_1), - [modulus_2] "i"(twice_modulus_2), - [modulus_3] "i"(twice_modulus_3) + [ modulus_0 ] "i"(twice_modulus_0), + [ modulus_1 ] "i"(twice_modulus_1), + [ modulus_2 ] "i"(twice_modulus_2), + [ modulus_3 ] "i"(twice_modulus_3) : "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "memory", "cc"); #endif } else { diff --git a/cpp/src/barretenberg/ecc/serialize.test.cpp b/cpp/src/barretenberg/ecc/serialize.test.cpp index 6a685d3305..dee51b44fa 100644 --- a/cpp/src/barretenberg/ecc/serialize.test.cpp +++ b/cpp/src/barretenberg/ecc/serialize.test.cpp @@ -4,6 +4,6 @@ TEST(msgpack_tests, msgpack_field) { - auto [actual, expected] = msgpack_roundtrip(barretenberg::fr{1ull, 2ull, 3ull, 4ull}); + auto [actual, expected] = msgpack_roundtrip(barretenberg::fr{ 1ull, 2ull, 3ull, 4ull }); EXPECT_EQ(actual, expected); } \ No newline at end of file diff --git a/cpp/src/barretenberg/env/crs.hpp b/cpp/src/barretenberg/env/crs.hpp index 6a92c92120..871fb817d5 100644 --- a/cpp/src/barretenberg/env/crs.hpp +++ b/cpp/src/barretenberg/env/crs.hpp @@ -2,9 +2,9 @@ #include // To be provided by the environment. -// Outputs from a trusted setup "Common reference string" model: https://en.wikipedia.org/wiki/Common_reference_string_model -// For a WASM build, this is provided by the JavaScript environment. -// For a native build, this is provided in this module. +// Outputs from a trusted setup "Common reference string" model: +// https://en.wikipedia.org/wiki/Common_reference_string_model For a WASM build, this is provided by the JavaScript +// environment. For a native build, this is provided in this module. /** * @brief In WASM, loads the verifier reference string. diff --git a/cpp/src/barretenberg/honk/proof_system/prover.hpp b/cpp/src/barretenberg/honk/proof_system/prover.hpp index 477ad349c5..7c7d1d0bb8 100644 --- a/cpp/src/barretenberg/honk/proof_system/prover.hpp +++ b/cpp/src/barretenberg/honk/proof_system/prover.hpp @@ -15,8 +15,7 @@ namespace proof_system::honk { // We won't compile this class with honk::flavor::Ultra, but we will like want to compile it (at least for testing) // with a flavor that uses the curve Grumpkin, or a flavor that does/does not have zk, etc. -template -concept StandardFlavor = IsAnyOf; +template concept StandardFlavor = IsAnyOf; template class StandardProver_ { diff --git a/cpp/src/barretenberg/honk/proof_system/ultra_prover.hpp b/cpp/src/barretenberg/honk/proof_system/ultra_prover.hpp index 9bbe7314f2..bcf665711c 100644 --- a/cpp/src/barretenberg/honk/proof_system/ultra_prover.hpp +++ b/cpp/src/barretenberg/honk/proof_system/ultra_prover.hpp @@ -13,8 +13,7 @@ namespace proof_system::honk { // We won't compile this class with honk::flavor::Standard, but we will like want to compile it (at least for testing) // with a flavor that uses the curve Grumpkin, or a flavor that does/does not have zk, etc. -template -concept UltraFlavor = IsAnyOf; +template concept UltraFlavor = IsAnyOf; template class UltraProver_ { using FF = typename Flavor::FF; diff --git a/cpp/src/barretenberg/serialize/cbind.hpp b/cpp/src/barretenberg/serialize/cbind.hpp index a047615270..74983312ad 100644 --- a/cpp/src/barretenberg/serialize/cbind.hpp +++ b/cpp/src/barretenberg/serialize/cbind.hpp @@ -47,12 +47,11 @@ template constexpr auto param_tuple() // This function is intended to bind a function to a MessagePack-formatted input data, // perform the function with the unpacked data, then pack the result back into MessagePack format. -inline void msgpack_cbind_impl( - auto func, // The function to be applied - const uint8_t* input_in, // The input data in MessagePack format - size_t input_len_in, // The length of the input data - uint8_t** output_out, // The output data in MessagePack format - size_t* output_len_out) // The length of the output data +inline void msgpack_cbind_impl(auto func, // The function to be applied + const uint8_t* input_in, // The input data in MessagePack format + size_t input_len_in, // The length of the input data + uint8_t** output_out, // The output data in MessagePack format + size_t* output_len_out) // The length of the output data { // Get the parameter types of the function as a tuple. auto params = param_tuple(); diff --git a/cpp/src/barretenberg/serialize/msgpack.hpp b/cpp/src/barretenberg/serialize/msgpack.hpp index 767a2401e2..573d4c1993 100644 --- a/cpp/src/barretenberg/serialize/msgpack.hpp +++ b/cpp/src/barretenberg/serialize/msgpack.hpp @@ -1,6 +1,6 @@ #pragma once -/* Minimal header for declaring msgpack fields. -This should be included as "barretenberg/serialize/msgpack.hpp" unless a translation wants +/* Minimal header for declaring msgpack fields. +This should be included as "barretenberg/serialize/msgpack.hpp" unless a translation wants to use msgpack for bindings, then "barretenberg/serialize/cbind.hpp" should be included. ## Overview @@ -99,7 +99,4 @@ e.g. unpacking // Define a macro that takes any amount of parameters and expands to a msgpack method definition // __VA__ARGS__ expands to the parmeters, comma separated. #define MSGPACK_FIELDS(...) \ - void msgpack(auto pack_fn) \ - { \ - pack_fn(NVP(__VA_ARGS__)); \ - } + void msgpack(auto pack_fn) { pack_fn(NVP(__VA_ARGS__)); } diff --git a/cpp/src/barretenberg/serialize/msgpack_impl/concepts.hpp b/cpp/src/barretenberg/serialize/msgpack_impl/concepts.hpp index 07579bdf24..c58e2f136f 100644 --- a/cpp/src/barretenberg/serialize/msgpack_impl/concepts.hpp +++ b/cpp/src/barretenberg/serialize/msgpack_impl/concepts.hpp @@ -4,8 +4,12 @@ struct DoNothing { void operator()(auto...) {} }; namespace msgpack_concepts { -template -concept HasMsgPack = requires(T t, DoNothing nop) { t.msgpack(nop); }; -template -concept HasMsgPackPack = requires(T t, DoNothing nop) { t.msgpack_pack(nop); }; +template concept HasMsgPack = requires(T t, DoNothing nop) +{ + t.msgpack(nop); +}; +template concept HasMsgPackPack = requires(T t, DoNothing nop) +{ + t.msgpack_pack(nop); +}; } // namespace msgpack_concepts \ No newline at end of file diff --git a/cpp/src/barretenberg/serialize/msgpack_impl/func_traits.hpp b/cpp/src/barretenberg/serialize/msgpack_impl/func_traits.hpp index a514ebbba1..d328c67f52 100644 --- a/cpp/src/barretenberg/serialize/msgpack_impl/func_traits.hpp +++ b/cpp/src/barretenberg/serialize/msgpack_impl/func_traits.hpp @@ -3,31 +3,27 @@ #include "../msgpack.hpp" // Define a template struct to deduce function traits for different function types -template -struct func_traits; +template struct func_traits; // Specialization for function pointers -template -struct func_traits { +template struct func_traits { typedef std::tuple Args; // Define a tuple type that holds all argument types - Args args; // Args instance - R ret; // Holds return type - MSGPACK_FIELDS(args, ret); // Macro from msgpack library to serialize/deserialize fields + Args args; // Args instance + R ret; // Holds return type + MSGPACK_FIELDS(args, ret); // Macro from msgpack library to serialize/deserialize fields }; // Specialization for function references -template -struct func_traits { +template struct func_traits { typedef std::tuple Args; Args args; R ret; MSGPACK_FIELDS(args, ret); }; -// Specialization for member function pointers. This also includes lambda types, +// Specialization for member function pointers. This also includes lambda types, // as they are functors (objects with operator()) and hence have a member function pointer -template -struct func_traits { +template struct func_traits { typedef std::tuple Args; Args args; R ret; @@ -36,22 +32,20 @@ struct func_traits { // Define a concept that checks if the type is a lambda (or functor) type // This is done by checking if T::operator() exists -template -concept LambdaType = requires() { - typename std::enable_if_t, void>; +template concept LambdaType = requires() +{ + typename std::enable_if_t, void>; }; // Overload for lambda (or functor) types -template -constexpr auto get_func_traits() +template constexpr auto get_func_traits() { // If T is a lambda type (i.e. it has operator()), deduce its traits using func_traits return func_traits(); } // Overload for non-lambda types -template -constexpr auto get_func_traits() +template constexpr auto get_func_traits() { // If T is not a lambda, just deduce its traits using func_traits return func_traits(); diff --git a/cpp/src/barretenberg/serialize/msgpack_impl/name_value_pair_macro.hpp b/cpp/src/barretenberg/serialize/msgpack_impl/name_value_pair_macro.hpp index 1f3ccc3474..99e4411f3b 100644 --- a/cpp/src/barretenberg/serialize/msgpack_impl/name_value_pair_macro.hpp +++ b/cpp/src/barretenberg/serialize/msgpack_impl/name_value_pair_macro.hpp @@ -5,7 +5,9 @@ * used in msgpack serialization. */ // hacky counting of variadic macro params: -#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, N, ...) N +#define VA_NARGS_IMPL( \ + _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, N, ...) \ + N // AD: support for 20 fields!? one may ask. Well, after 15 not being enough... #define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) @@ -34,7 +36,7 @@ #define _NVP19(x, ...) _NVP1(x), _NVP18(__VA_ARGS__) #define _NVP20(x, ...) _NVP1(x), _NVP19(__VA_ARGS__) -#define CONCAT(a, b) a ## b +#define CONCAT(a, b) a##b #define _NVP_N(n) CONCAT(_NVP, n) #define NVP(...) _NVP_N(VA_NARGS(__VA_ARGS__))(__VA_ARGS__) // end of #define NVP \ No newline at end of file diff --git a/cpp/src/barretenberg/serialize/msgpack_impl/schema_impl.hpp b/cpp/src/barretenberg/serialize/msgpack_impl/schema_impl.hpp index a99038a1b3..c2ebd8bde2 100644 --- a/cpp/src/barretenberg/serialize/msgpack_impl/schema_impl.hpp +++ b/cpp/src/barretenberg/serialize/msgpack_impl/schema_impl.hpp @@ -58,9 +58,11 @@ inline void _schema_pack_map_content(MsgpackSchemaPacker&) } namespace msgpack_concepts { -template -concept SchemaPackable = requires(T value, MsgpackSchemaPacker packer) { msgpack_schema_pack(packer, value); }; -} +template concept SchemaPackable = requires(T value, MsgpackSchemaPacker packer) +{ + msgpack_schema_pack(packer, value); +}; +} // namespace msgpack_concepts // Helper for packing (key, value, key, value, ...) arguments template @@ -80,8 +82,8 @@ inline void _schema_pack_map_content(MsgpackSchemaPacker& packer, std::string ke * @param packer the schema packer. */ template - requires(!msgpack_concepts::HasMsgPack && !msgpack_concepts::HasMsgPackPack) -inline void msgpack_schema_pack(MsgpackSchemaPacker& packer, T const&) +requires(!msgpack_concepts::HasMsgPack && + !msgpack_concepts::HasMsgPackPack) inline void msgpack_schema_pack(MsgpackSchemaPacker& packer, T const&) { packer.pack(msgpack_schema_name(T{})); } diff --git a/cpp/src/barretenberg/serialize/msgpack_impl/struct_map_impl.hpp b/cpp/src/barretenberg/serialize/msgpack_impl/struct_map_impl.hpp index 4bdf4909c9..0bc101eeb8 100644 --- a/cpp/src/barretenberg/serialize/msgpack_impl/struct_map_impl.hpp +++ b/cpp/src/barretenberg/serialize/msgpack_impl/struct_map_impl.hpp @@ -27,9 +27,11 @@ template auto drop_keys(std::tuple&& tuple) } // namespace msgpack namespace msgpack { -template -concept MsgpackConstructible = requires(T object, Args... args) { T{ args... }; }; -} +template concept MsgpackConstructible = requires(T object, Args... args) +{ + T{ args... }; +}; +} // namespace msgpack namespace msgpack::adaptor { // reads structs with msgpack() method from a JSON-like dictionary diff --git a/cpp/src/barretenberg/serialize/msgpack_impl/variant_impl.hpp b/cpp/src/barretenberg/serialize/msgpack_impl/variant_impl.hpp index 66fe6398be..8b5d466b53 100644 --- a/cpp/src/barretenberg/serialize/msgpack_impl/variant_impl.hpp +++ b/cpp/src/barretenberg/serialize/msgpack_impl/variant_impl.hpp @@ -6,11 +6,11 @@ namespace msgpack::adaptor { // writes std::variant to msgpack format (TODO should we read std::variant?) -template -struct pack> { - auto &operator()(auto& o, std::variant const &variant) const { +template struct pack> { + auto& operator()(auto& o, std::variant const& variant) const + { std::visit([&o](const auto& arg) { o.pack(arg); }, variant); return o; } }; -} +} // namespace msgpack::adaptor diff --git a/cpp/src/barretenberg/serialize/raw_pointer.hpp b/cpp/src/barretenberg/serialize/raw_pointer.hpp index 4b6e0b16b0..47224bef72 100644 --- a/cpp/src/barretenberg/serialize/raw_pointer.hpp +++ b/cpp/src/barretenberg/serialize/raw_pointer.hpp @@ -3,31 +3,24 @@ #include "msgpack_impl/schema_name.hpp" // Holds a raw pointer to an object of type T. -// It provides methods for packing and unpacking the pointer using MessagePack, +// It provides methods for packing and unpacking the pointer using MessagePack, // a binary serialization format. -template -struct RawPointer { +template struct RawPointer { // Raw pointer to an object of type T T* ptr = nullptr; // Pack the raw pointer into a MessagePack packer. // The pointer is first cast to an integer type (uintptr_t) which can hold a pointer, // and then packed into the packer. - void msgpack_pack(auto& packer) const { - packer.pack(reinterpret_cast(ptr)); - } + void msgpack_pack(auto& packer) const { packer.pack(reinterpret_cast(ptr)); } // Unpack the raw pointer from a MessagePack object. // The object is first cast to an integer type (uintptr_t), and then to a pointer of type T. - void msgpack_unpack(auto object) { - ptr = reinterpret_cast((uintptr_t)object); - } + void msgpack_unpack(auto object) { ptr = reinterpret_cast((uintptr_t)object); } // Overload the arrow operator to return the raw pointer. // This allows users to directly access the object pointed to by the raw pointer. - T* operator->() { - return ptr; - } + T* operator->() { return ptr; } }; // help our msgpack schema compiler with this struct diff --git a/cpp/src/barretenberg/stdlib/hash/keccak/keccak.test.cpp b/cpp/src/barretenberg/stdlib/hash/keccak/keccak.test.cpp index 3a8980f2c3..f9af41eec3 100644 --- a/cpp/src/barretenberg/stdlib/hash/keccak/keccak.test.cpp +++ b/cpp/src/barretenberg/stdlib/hash/keccak/keccak.test.cpp @@ -193,7 +193,6 @@ TEST(stdlib_keccak, test_format_input_lanes) } } - auto prover = composer.create_prover(); auto verifier = composer.create_verifier(); @@ -278,7 +277,6 @@ TEST(stdlib_keccak, test_double_block_variable_length) EXPECT_EQ(output.get_value(), expected); - auto prover = composer.create_prover(); auto verifier = composer.create_verifier(); diff --git a/cpp/src/msgpack-c/.clang-format b/cpp/src/msgpack-c/.clang-format new file mode 100644 index 0000000000..a43d914ec3 --- /dev/null +++ b/cpp/src/msgpack-c/.clang-format @@ -0,0 +1,2 @@ +DisableFormat: true +SortIncludes: false \ No newline at end of file From e1318c129636862cec5e913c6bb2a4d4ca92b88e Mon Sep 17 00:00:00 2001 From: Maddiaa <47148561+Maddiaa0@users.noreply.github.com> Date: Tue, 23 May 2023 08:49:52 -0700 Subject: [PATCH 05/29] patch: temporarily remove broken solidity ci (#470) --- .github/workflows/solidity_verifier_test.yml | 23 -------------------- 1 file changed, 23 deletions(-) delete mode 100644 .github/workflows/solidity_verifier_test.yml diff --git a/.github/workflows/solidity_verifier_test.yml b/.github/workflows/solidity_verifier_test.yml deleted file mode 100644 index 8203b494ba..0000000000 --- a/.github/workflows/solidity_verifier_test.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: solidity-verifier-test - -on: - - workflow_dispatch - - push - -env: - FOUNDRY_PROFILE: ci - -jobs: - check: - strategy: - fail-fast: true - - name: Solidity Verifier Tests - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v3 - with: - submodules: recursive - - - name: Build docker image - run: docker build . -f sol/Dockerfile \ No newline at end of file From efc39262f4ff45c004aa005564ddc33cedef1389 Mon Sep 17 00:00:00 2001 From: Charlie Lye Date: Tue, 23 May 2023 15:57:14 +0000 Subject: [PATCH 06/29] progress. --- cpp/src/CMakeLists.txt | 28 ++++++++--- cpp/src/barretenberg/common/mem.cpp | 5 +- cpp/src/barretenberg/common/serialize.hpp | 4 +- .../barretenberg/common/slab_allocator.cpp | 30 +++++++++--- .../barretenberg/common/slab_allocator.hpp | 28 +++++++++-- cpp/src/barretenberg/common/streams.hpp | 8 ++-- .../dsl/acir_format/acir_format.cpp | 16 +++---- .../dsl/acir_format/acir_format.hpp | 15 ++++-- .../dsl/acir_proofs/acir_composer.cpp | 35 +++++++++----- .../dsl/acir_proofs/acir_composer.hpp | 5 +- .../barretenberg/dsl/acir_proofs/c_bind.cpp | 34 ++++++++++---- .../barretenberg/dsl/acir_proofs/c_bind.hpp | 16 +++++-- exports.json | 17 ++++++- ts/src/barretenberg_api/index.ts | 20 ++++---- ts/src/barretenberg_wasm/barretenberg_wasm.ts | 19 ++++---- ts/src/barretenberg_wasm/browser/index.ts | 7 +-- ts/src/barretenberg_wasm/node/index.ts | 2 +- ts/src/main.ts | 47 ++++++++++++++----- ts/src/serialize/serialize.ts | 4 ++ ts/src/types/index.ts | 1 + ts/src/types/raw_buffer.ts | 3 ++ 21 files changed, 237 insertions(+), 107 deletions(-) create mode 100644 ts/src/types/raw_buffer.ts diff --git a/cpp/src/CMakeLists.txt b/cpp/src/CMakeLists.txt index ef3a7b3b36..565146e1a3 100644 --- a/cpp/src/CMakeLists.txt +++ b/cpp/src/CMakeLists.txt @@ -114,7 +114,29 @@ add_library( $ ) +# Small library to provide necessary primitives for rust crate. +add_library( + acvm_backend + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ +) + if(WASM) + # With binaryen installed, it seems its wasm backend optimiser gets invoked automatically. + # Due to either a bug in the optimiser, or non-standards compliant c++ in crypto/aes, tests start failing with + # -O3 level optimisations. We force down to -O2 for current workaround. + # TODO: Time has passed, check if this is still needed. + # UPDATE: Uninstall binaryen and any need downstream. + set(CMAKE_CXX_FLAGS_RELEASE "-O2") + # When building this wasm "executable", we include the wasi module but exclude the env module. # That's because we expect this wasm to be run as a wasi "reactor" and for the host environment # to implement the functions in env. @@ -155,12 +177,6 @@ if(WASM) $ ) - # With binaryen installed, it seems its wasm backend optimiser gets invoked automatically. - # Due to either a bug in the optimiser, or non-standards compliant c++ in crypto/aes, tests start failing with - # -O3 level optimisations. We force down to -O2 for current workaround. - # TODO: Time has passed, check if this is still needed. - set(CMAKE_CXX_FLAGS_RELEASE "-O2") - target_link_options( barretenberg.wasm PRIVATE diff --git a/cpp/src/barretenberg/common/mem.cpp b/cpp/src/barretenberg/common/mem.cpp index 7b953a2d8d..58b59226d0 100644 --- a/cpp/src/barretenberg/common/mem.cpp +++ b/cpp/src/barretenberg/common/mem.cpp @@ -1,15 +1,16 @@ #include "./mem.hpp" #include "./wasm_export.hpp" +#include "./slab_allocator.hpp" extern "C" { WASM_EXPORT void* bbmalloc(size_t size) { - return aligned_alloc(64, size); + return barretenberg::get_mem_slab_raw(size); } WASM_EXPORT void bbfree(void* ptr) { - aligned_free(ptr); + barretenberg::free_mem_slab_raw(ptr); } } \ No newline at end of file diff --git a/cpp/src/barretenberg/common/serialize.hpp b/cpp/src/barretenberg/common/serialize.hpp index 1dfecea981..77f21c952d 100644 --- a/cpp/src/barretenberg/common/serialize.hpp +++ b/cpp/src/barretenberg/common/serialize.hpp @@ -276,7 +276,7 @@ template inline void write(B& buf, std::array } // Generic read of vector of types from supported buffer types. -template inline void read(B& it, std::vector& value) +template inline void read(B& it, std::vector& value) { DEBUG_CANARY_READ(it, value); uint32_t size; @@ -406,7 +406,7 @@ template uint8_t* to_heap_buffer(T const& value) std::vector buf; write(buf, value); auto* ptr = (uint8_t*)aligned_alloc(64, buf.size()); - write(ptr, buf); + std::copy(buf.begin(), buf.end(), ptr); return ptr; } diff --git a/cpp/src/barretenberg/common/slab_allocator.cpp b/cpp/src/barretenberg/common/slab_allocator.cpp index d3357456d9..ec04b5b80d 100644 --- a/cpp/src/barretenberg/common/slab_allocator.cpp +++ b/cpp/src/barretenberg/common/slab_allocator.cpp @@ -3,6 +3,7 @@ #include #include #include +#include /** * If we can guarantee that all slabs will be released before the allocator is destroyed, we wouldn't need this. @@ -14,6 +15,9 @@ namespace { bool allocator_destroyed = false; +// Slabs that are being manually managed by the user. +std::unordered_map> manual_slabs; + /** * Allows preallocating memory slabs sized to serve the fact that these slabs of memory follow certain sizing patterns * and numbers based on prover system type and circuit size. Without the slab allocator, memory fragmentation prevents @@ -36,7 +40,7 @@ class SlabAllocator { std::shared_ptr get(size_t size); - // size_t get_total_size(); + size_t get_total_size(); private: void release(void* ptr, size_t size); @@ -159,12 +163,12 @@ std::shared_ptr SlabAllocator::get(size_t req_size) } } -// size_t SlabAllocator::get_total_size() -// { -// return std::accumulate(memory_store.begin(), memory_store.end(), size_t{ 0 }, [](size_t acc, const auto& kv) { -// return acc + kv.first * kv.second.size(); -// }); -// } +size_t SlabAllocator::get_total_size() +{ + return std::accumulate(memory_store.begin(), memory_store.end(), size_t{ 0 }, [](size_t acc, const auto& kv) { + return acc + kv.first * kv.second.size(); + }); +} void SlabAllocator::release(void* ptr, size_t size) { @@ -193,4 +197,16 @@ std::shared_ptr get_mem_slab(size_t size) { return allocator.get(size); } + +void* get_mem_slab_raw(size_t size) +{ + auto slab = get_mem_slab(size); + manual_slabs[slab.get()] = slab; + return slab.get(); +} + +void free_mem_slab_raw(void* p) +{ + manual_slabs.erase(p); +} } // namespace barretenberg diff --git a/cpp/src/barretenberg/common/slab_allocator.hpp b/cpp/src/barretenberg/common/slab_allocator.hpp index de39189cf7..13ae70292e 100644 --- a/cpp/src/barretenberg/common/slab_allocator.hpp +++ b/cpp/src/barretenberg/common/slab_allocator.hpp @@ -4,6 +4,7 @@ #include #include #include "./log.hpp" +#include "./assert.hpp" #ifndef NO_MULTITHREADING #include #endif @@ -28,9 +29,18 @@ void init_slab_allocator(size_t circuit_size); /** * Returns a slab from the preallocated pool of slabs, or fallback to a new heap allocation (32 byte aligned). + * Ref counted result so no need to manually free. */ std::shared_ptr get_mem_slab(size_t size); +/** + * Sometimes you want a raw pointer to slab so you can manage when it's release manually (e.g. c_binds). + * This still gets a slab with a shared_ptr, but holds the shared_ptr internally until free_mem_slab_raw is called. + */ +void* get_mem_slab_raw(size_t size); + +void free_mem_slab_raw(void*); + template class ContainerSlabAllocator { public: using value_type = T; @@ -38,9 +48,6 @@ template class ContainerSlabAllocator { using const_pointer = const T*; using size_type = std::size_t; - ContainerSlabAllocator() = default; - ~ContainerSlabAllocator() = default; - template struct rebind { using other = ContainerSlabAllocator; }; @@ -53,9 +60,20 @@ template class ContainerSlabAllocator { return static_cast(ptr.get()); } - void deallocate(pointer /*p*/, size_type /*unused*/) + void deallocate(pointer p, size_type /*unused*/) + { + ASSERT(p == slab.get()); + slab.reset(); + } + + friend bool operator==(const ContainerSlabAllocator& lhs, const ContainerSlabAllocator& rhs) + { + return lhs.slab == rhs.slab; + } + + friend bool operator!=(const ContainerSlabAllocator& lhs, const ContainerSlabAllocator& rhs) { - // Memory will be automatically deallocated when slab goes out of scope and its ref count becomes 0. + return !(lhs == rhs); } private: diff --git a/cpp/src/barretenberg/common/streams.hpp b/cpp/src/barretenberg/common/streams.hpp index af8c9e2403..c3dd64aa7c 100644 --- a/cpp/src/barretenberg/common/streams.hpp +++ b/cpp/src/barretenberg/common/streams.hpp @@ -19,8 +19,8 @@ inline std::ostream& operator<<(std::ostream& os, std::vector const& ar return os; } -template ::value, bool> = true> -inline std::ostream& operator<<(std::ostream& os, std::vector const& arr) +template ::value, bool> = true, typename A> +inline std::ostream& operator<<(std::ostream& os, std::vector const& arr) { os << "["; for (auto element : arr) { @@ -30,8 +30,8 @@ inline std::ostream& operator<<(std::ostream& os, std::vector const& arr) return os; } -template ::value, bool> = true> -inline std::ostream& operator<<(std::ostream& os, std::vector const& arr) +template ::value, bool> = true, typename A> +inline std::ostream& operator<<(std::ostream& os, std::vector const& arr) { os << "[\n"; for (auto element : arr) { diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp index 93c89d76dd..faa7dc8324 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp @@ -3,7 +3,7 @@ namespace acir_format { -void read_witness(Composer& composer, std::vector const& witness) +void read_witness(Composer& composer, WitnessVector const& witness) { composer.variables[0] = 0; for (size_t i = 0; i < witness.size(); ++i) { @@ -96,14 +96,14 @@ void create_circuit(Composer& composer, acir_format const& constraint_system) } Composer create_circuit(const acir_format& constraint_system, - std::shared_ptr const& crs_factory) + std::shared_ptr const& crs_factory, + size_t size_hint) { if (constraint_system.public_inputs.size() > constraint_system.varnum) { info("create_circuit: too many public inputs!"); } - // TODO: Figure out size_hint from constraint_system. - Composer composer(crs_factory); + Composer composer(crs_factory, size_hint); for (size_t i = 1; i < constraint_system.varnum; ++i) { // If the index is in the public inputs vector, then we add it as a public input @@ -187,7 +187,7 @@ Composer create_circuit(const acir_format& constraint_system, } Composer create_circuit_with_witness(acir_format const& constraint_system, - std::vector const& witness, + WitnessVector const& witness, std::shared_ptr const& crs_factory) { if (constraint_system.public_inputs.size() > constraint_system.varnum) { @@ -279,7 +279,7 @@ Composer create_circuit_with_witness(acir_format const& constraint_system, return composer; } -Composer create_circuit_with_witness(const acir_format& constraint_system, std::vector const& witness) +Composer create_circuit_with_witness(const acir_format& constraint_system, WitnessVector const& witness) { if (constraint_system.public_inputs.size() > constraint_system.varnum) { info("create_circuit_with_witness: too many public inputs!"); @@ -370,9 +370,7 @@ Composer create_circuit_with_witness(const acir_format& constraint_system, std:: return composer; } -void create_circuit_with_witness(Composer& composer, - acir_format const& constraint_system, - std::vector const& witness) +void create_circuit_with_witness(Composer& composer, acir_format const& constraint_system, WitnessVector const& witness) { if (constraint_system.public_inputs.size() > constraint_system.varnum) { info("create_circuit_with_witness: too many public inputs!"); diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp index f526c250be..8e296f79cc 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp @@ -1,4 +1,5 @@ #pragma once +#include "barretenberg/common/slab_allocator.hpp" #include "logic_constraint.hpp" #include "range_constraint.hpp" #include "sha256_constraint.hpp" @@ -35,27 +36,31 @@ struct acir_format { std::vector block_constraints; // A standard plonk arithmetic constraint, as defined in the poly_triple struct, consists of selector values // for q_M,q_L,q_R,q_O,q_C and indices of three variables taking the role of left, right and output wire - std::vector constraints; + // This could be a large vector so use slab allocator, we don't expect the blackbox implementations to be so large. + std::vector> constraints; friend bool operator==(acir_format const& lhs, acir_format const& rhs) = default; }; +using WitnessVector = std::vector>; + void read_witness(Composer& composer, std::vector const& witness); void create_circuit(Composer& composer, const acir_format& constraint_system); Composer create_circuit(const acir_format& constraint_system, - std::shared_ptr const& crs_factory); + std::shared_ptr const& crs_factory, + size_t size_hint = 0); Composer create_circuit_with_witness(const acir_format& constraint_system, - std::vector const& witness, + WitnessVector const& witness, std::shared_ptr const& crs_factory); -Composer create_circuit_with_witness(const acir_format& constraint_system, std::vector const& witness); +Composer create_circuit_with_witness(const acir_format& constraint_system, WitnessVector const& witness); void create_circuit_with_witness(Composer& composer, const acir_format& constraint_system, - std::vector const& witness); + WitnessVector const& witness); // Serialisation template inline void read(B& buf, acir_format& data) diff --git a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp index bd4efc4244..12c154851e 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp @@ -1,4 +1,3 @@ - #include "acir_composer.hpp" #include "barretenberg/common/serialize.hpp" #include "barretenberg/common/throw_or_abort.hpp" @@ -15,20 +14,32 @@ AcirComposer::AcirComposer(std::shared_ptr : crs_factory_(crs_factory) {} -void AcirComposer::init_proving_key(acir_format::acir_format&& constraint_system) +void AcirComposer::init_proving_key(acir_format::acir_format& constraint_system, size_t size_hint) { - constraint_system_ = std::move(constraint_system); - auto composer = create_circuit(constraint_system_, crs_factory_); + auto composer = create_circuit(constraint_system, crs_factory_, size_hint); + + // We are done with the constraint system at this point, and we need the memory slab back. + // constraint_system = acir_format::acir_format(); + constraint_system.constraints.clear(); + constraint_system.constraints.shrink_to_fit(); + exact_circuit_size_ = composer.get_num_gates(); total_circuit_size_ = composer.get_total_circuit_size(); proving_key_ = composer.compute_proving_key(); } -std::vector AcirComposer::create_proof(std::vector const& witness) +std::vector AcirComposer::create_proof(acir_format::acir_format& constraint_system, + acir_format::WitnessVector& witness) { acir_format::Composer composer(proving_key_, nullptr, total_circuit_size_); - create_circuit_with_witness(composer, constraint_system_, witness); + create_circuit_with_witness(composer, constraint_system, witness); + + // We are done with the constraint system at this point, and we need the memory slab back. + constraint_system.constraints.clear(); + constraint_system.constraints.shrink_to_fit(); + witness.clear(); + witness.shrink_to_fit(); auto prover = composer.create_ultra_with_keccak_prover(); return prover.construct_proof().proof_data; @@ -39,20 +50,20 @@ void AcirComposer::init_verification_key() if (!proving_key_) { throw_or_abort("init_proving_key must be called first."); } - acir_format::Composer composer(proving_key_, nullptr); - verification_key_ = composer.compute_verification_key(); + // acir_format::Composer composer(proving_key_, nullptr); + // verification_key_ = composer.compute_verification_key(); - // verification_key_ = - // acir_format::Composer::compute_verification_key_base(proving_key_, crs_factory_->get_verifier_crs()); + verification_key_ = + acir_format::Composer::compute_verification_key_base(proving_key_, crs_factory_->get_verifier_crs()); // The composer_type has not yet been set. We need to set the composer_type for when we later read in and // construct the verification key so that we have the correct polynomial manifest - // verification_key->composer_type = proof_system::ComposerType::PLOOKUP; + verification_key_->composer_type = proof_system::ComposerType::PLOOKUP; } bool AcirComposer::verify_proof(std::vector const& proof) { - acir_format::Composer composer(nullptr, verification_key_); + acir_format::Composer composer(proving_key_, verification_key_); composer.create_ultra_with_keccak_verifier(); auto verifier = composer.create_ultra_with_keccak_verifier(); return verifier.verify_proof({ proof }); diff --git a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.hpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.hpp index 9feed5a69a..454989bb00 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.hpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.hpp @@ -11,9 +11,9 @@ class AcirComposer { public: AcirComposer(std::shared_ptr const& crs_factory); - void init_proving_key(acir_format::acir_format&& constraint_system); + void init_proving_key(acir_format::acir_format& constraint_system, size_t size_hint = 0); - std::vector create_proof(std::vector const& witness); + std::vector create_proof(acir_format::acir_format& constraint_system, acir_format::WitnessVector& witness); void init_verification_key(); @@ -25,7 +25,6 @@ class AcirComposer { private: std::shared_ptr crs_factory_; - acir_format::acir_format constraint_system_; size_t exact_circuit_size_; size_t total_circuit_size_; std::shared_ptr proving_key_; diff --git a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp index a2a2f41c24..943e331bc4 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp @@ -3,6 +3,9 @@ #include #include #include "barretenberg/common/net.hpp" +#include "barretenberg/common/mem.hpp" +#include "barretenberg/common/serialize.hpp" +#include "barretenberg/common/slab_allocator.hpp" #include "barretenberg/dsl/acir_format/acir_format.hpp" #include "barretenberg/srs/reference_string/pippenger_reference_string.hpp" @@ -18,21 +21,34 @@ WASM_EXPORT void acir_delete_acir_composer(in_ptr acir_composer_ptr) delete reinterpret_cast(*acir_composer_ptr); } -WASM_EXPORT void acir_init_proving_key(in_ptr acir_composer_ptr, uint8_t const* constraint_system_buf) +WASM_EXPORT void acir_init_proving_key(in_ptr acir_composer_ptr, + uint8_t const* constraint_system_buf, + uint32_t const* size_hint) { auto acir_composer = reinterpret_cast(*acir_composer_ptr); - auto constraint_system_vec = from_buffer>(constraint_system_buf); - info("length: ", constraint_system_vec.size()); - auto constraint_system = from_buffer(constraint_system_vec); - info("here"); - acir_composer->init_proving_key(std::move(constraint_system)); + auto constraint_system = from_buffer(constraint_system_buf); + + // The binder would normally free the the constraint_system_buf, but we need the memory now. + free_mem_slab_raw((void*)constraint_system_buf); + + acir_composer->init_proving_key(constraint_system, ntohl(*size_hint)); } -WASM_EXPORT void acir_create_proof(in_ptr acir_composer_ptr, barretenberg::fr::vec_in_buf witness_buf) +WASM_EXPORT void acir_create_proof(in_ptr acir_composer_ptr, + uint8_t const* constraint_system_buf, + uint8_t const* witness_buf, + uint8_t** out) { auto acir_composer = reinterpret_cast(*acir_composer_ptr); - auto witness = from_buffer>(witness_buf); - acir_composer->create_proof(witness); + auto constraint_system = from_buffer(constraint_system_buf); + auto witness = from_buffer>>(witness_buf); + + // The binder would normally free the the constraint_system_buf, but we need the memory now. + free_mem_slab_raw((void*)constraint_system_buf); + free_mem_slab_raw((void*)witness_buf); + + auto proof_data = acir_composer->create_proof(constraint_system, witness); + *out = to_heap_buffer(proof_data); } WASM_EXPORT void acir_init_verification_key(in_ptr acir_composer_ptr) diff --git a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp index f6e82ccbcd..72439c896d 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp @@ -8,9 +8,19 @@ WASM_EXPORT void acir_new_acir_composer(in_ptr pippenger, uint8_t const* g2x, ou WASM_EXPORT void acir_delete_acir_composer(in_ptr acir_composer_ptr); -WASM_EXPORT void acir_init_proving_key(in_ptr acir_composer_ptr, uint8_t const* constraint_system_buf); - -WASM_EXPORT void acir_create_proof(in_ptr acir_composer_ptr, barretenberg::fr::vec_in_buf witness_buf); +WASM_EXPORT void acir_init_proving_key(in_ptr acir_composer_ptr, + uint8_t const* constraint_system_buf, + uint32_t const* size_hint); + +/** + * It would have been nice to just hold onto the constraint_system in the acir_composer, but we can't waste the + * memory. Being able to reuse the underlying Composer would help as well. But, given the situation, we just have + * to pass it in everytime. + */ +WASM_EXPORT void acir_create_proof(in_ptr acir_composer_ptr, + uint8_t const* constraint_system_buf, + uint8_t const* witness_buf, + uint8_t** out); WASM_EXPORT void acir_init_verification_key(in_ptr acir_composer_ptr); diff --git a/exports.json b/exports.json index 985b508703..3f739f6d69 100644 --- a/exports.json +++ b/exports.json @@ -665,6 +665,10 @@ { "name": "constraint_system_buf", "type": "const uint8_t *" + }, + { + "name": "size_hint", + "type": "const uint32_t *" } ], "outArgs": [], @@ -677,12 +681,21 @@ "name": "acir_composer_ptr", "type": "in_ptr" }, + { + "name": "constraint_system_buf", + "type": "const uint8_t *" + }, { "name": "witness_buf", - "type": "barretenberg::fr::vec_in_buf" + "type": "const uint8_t *" + } + ], + "outArgs": [ + { + "name": "out", + "type": "uint8_t **" } ], - "outArgs": [], "isAsync": false }, { diff --git a/ts/src/barretenberg_api/index.ts b/ts/src/barretenberg_api/index.ts index 9427146e42..2ccee233b0 100644 --- a/ts/src/barretenberg_api/index.ts +++ b/ts/src/barretenberg_api/index.ts @@ -196,14 +196,14 @@ export class BarretenbergApi { return; } - async acirInitProvingKey(acirComposerPtr: Ptr, constraintSystemBuf: Uint8Array): Promise { - const result = await this.binder.callWasmExport('acir_init_proving_key', [acirComposerPtr, constraintSystemBuf], []); + async acirInitProvingKey(acirComposerPtr: Ptr, constraintSystemBuf: Uint8Array, sizeHint: number): Promise { + const result = await this.binder.callWasmExport('acir_init_proving_key', [acirComposerPtr, constraintSystemBuf, sizeHint], []); return; } - async acirCreateProof(acirComposerPtr: Ptr, witnessBuf: Fr[]): Promise { - const result = await this.binder.callWasmExport('acir_create_proof', [acirComposerPtr, witnessBuf], []); - return; + async acirCreateProof(acirComposerPtr: Ptr, constraintSystemBuf: Uint8Array, witnessBuf: Uint8Array): Promise { + const result = await this.binder.callWasmExport('acir_create_proof', [acirComposerPtr, constraintSystemBuf, witnessBuf], [BufferDeserializer()]); + return result[0]; } async acirInitVerificationKey(acirComposerPtr: Ptr): Promise { @@ -424,14 +424,14 @@ export class BarretenbergApiSync { return; } - acirInitProvingKey(acirComposerPtr: Ptr, constraintSystemBuf: Uint8Array): void { - const result = this.binder.callWasmExport('acir_init_proving_key', [acirComposerPtr, constraintSystemBuf], []); + acirInitProvingKey(acirComposerPtr: Ptr, constraintSystemBuf: Uint8Array, sizeHint: number): void { + const result = this.binder.callWasmExport('acir_init_proving_key', [acirComposerPtr, constraintSystemBuf, sizeHint], []); return; } - acirCreateProof(acirComposerPtr: Ptr, witnessBuf: Fr[]): void { - const result = this.binder.callWasmExport('acir_create_proof', [acirComposerPtr, witnessBuf], []); - return; + acirCreateProof(acirComposerPtr: Ptr, constraintSystemBuf: Uint8Array, witnessBuf: Uint8Array): Uint8Array { + const result = this.binder.callWasmExport('acir_create_proof', [acirComposerPtr, constraintSystemBuf, witnessBuf], [BufferDeserializer()]); + return result[0]; } acirInitVerificationKey(acirComposerPtr: Ptr): void { diff --git a/ts/src/barretenberg_wasm/barretenberg_wasm.ts b/ts/src/barretenberg_wasm/barretenberg_wasm.ts index 816d76af7c..3e2f08be1f 100644 --- a/ts/src/barretenberg_wasm/barretenberg_wasm.ts +++ b/ts/src/barretenberg_wasm/barretenberg_wasm.ts @@ -5,14 +5,7 @@ import { Remote, proxy } from 'comlink'; import { randomBytes } from '../random/index.js'; // Webpack config swaps this import with ./browser/index.js // You can toggle between these two imports to sanity check the type-safety. -import { - fetchCode, - getNumCpu, - createWorker, - getRemoteBarretenbergWasm, - threadLogger, - throwOrAbort, -} from './node/index.js'; +import { fetchCode, getNumCpu, createWorker, getRemoteBarretenbergWasm, threadLogger, killSelf } from './node/index.js'; // import { fetchCode, getNumCpu, createWorker, randomBytes } from './browser/index.js'; const debug = createDebug('wasm'); @@ -27,6 +20,7 @@ export class BarretenbergWasm { private remoteWasms: BarretenbergWasmWorker[] = []; private nextWorker = 0; private nextThreadId = 1; + private isThread = false; private logger: (msg: string) => void = debug; public static async new() { @@ -91,6 +85,7 @@ export class BarretenbergWasm { * Init as worker thread. */ public async initThread(module: WebAssembly.Module, memory: WebAssembly.Memory) { + this.isThread = true; this.logger = threadLogger() || this.logger; this.memory = memory; this.instance = await WebAssembly.instantiate(module, this.getImportObj(this.memory)); @@ -125,7 +120,7 @@ export class BarretenbergWasm { proc_exit: () => { this.logger('HUNG: proc_exit was called. This is caused by unstable experimental wasi pthreads. Try again.'); this.logger(new Error().stack!); - throwOrAbort(); + killSelf(); }, }, wasi: { @@ -185,7 +180,11 @@ export class BarretenbergWasm { const message = `WASM function ${name} aborted, error: ${err}`; this.logger(message); this.logger(err.stack); - throwOrAbort(); + if (this.isThread) { + killSelf(); + } else { + throw err; + } } } diff --git a/ts/src/barretenberg_wasm/browser/index.ts b/ts/src/barretenberg_wasm/browser/index.ts index ebd521a6b7..0b89ff9505 100644 --- a/ts/src/barretenberg_wasm/browser/index.ts +++ b/ts/src/barretenberg_wasm/browser/index.ts @@ -27,9 +27,6 @@ export function threadLogger(): ((msg: string) => void) | undefined { return undefined; } -export function throwOrAbort() { - if (self?.close) { - self.close(); - } - throw new Error('throwOrAbort called.'); +export function killSelf() { + self.close(); } diff --git a/ts/src/barretenberg_wasm/node/index.ts b/ts/src/barretenberg_wasm/node/index.ts index 9897b2f26b..f8943dce3d 100644 --- a/ts/src/barretenberg_wasm/node/index.ts +++ b/ts/src/barretenberg_wasm/node/index.ts @@ -38,7 +38,7 @@ export function threadLogger(): ((msg: string) => void) | undefined { }; } -export function throwOrAbort(): never { +export function killSelf(): never { // Extordinarily hard process termination. Due to how parent threads block on child threads etc, even process.exit // doesn't seem to be able to abort the process. The following does. process.kill(process.pid); diff --git a/ts/src/main.ts b/ts/src/main.ts index a04f37f01a..20b624f603 100755 --- a/ts/src/main.ts +++ b/ts/src/main.ts @@ -4,42 +4,65 @@ import createDebug from 'debug'; import { newMultiThreaded } from './factory/index.js'; import { readFileSync } from 'fs'; import { gunzipSync } from 'zlib'; +import { RawBuffer } from './types/index.js'; +import { numToInt32BE } from './serialize/serialize.js'; const debug = createDebug('bb.js'); createDebug.enable('*'); function getBytecode() { const json = readFileSync('/mnt/user-data/charlie/noir-projects/512k/target/main.json', 'utf-8'); - console.log(json.length); const parsed = JSON.parse(json); - const buffer = Buffer.from(parsed.bytecode, 'base64'); - console.log(buffer.length); - const decompressed = gunzipSync(buffer); - console.log(decompressed.length); - return decompressed; } +function getWitness() { + const data = readFileSync('/mnt/user-data/charlie/noir-projects/512k/target/witness.tr'); + return Buffer.concat([numToInt32BE(data.length / 32), data]); +} + +// nargo use bb.js: backend -> bb.js +// backend prove --data-dir data --witness /foo/bar/witness.tr --json /foo/bar/main.json +// backend verify ... +// backend get_total_num_gates --data-dir data --json /foo/bar/main.json +// backend get_sol_contract --data-dir data --json /foo/bar/main.json --output +// backend get_features +// OPTIONAL stateful backend: +// backend start +// backend stop export async function main() { debug('starting test...'); const api = await newMultiThreaded(); try { + const CIRCUIT_SIZE = 2 ** 19; + + // Import to init slab allocator as first thing, to ensure maximum memory efficiency. + await api.commonInitSlabAllocator(CIRCUIT_SIZE); + // Plus 1 needed! const crs = await Crs.new(2 ** 19 + 1); const pippengerPtr = await api.eccNewPippenger(crs.getG1Data(), crs.numPoints); const acirComposer = await api.acirNewAcirComposer(pippengerPtr, crs.getG2Data()); + + debug('initing proving key...'); const bytecode = getBytecode(); - await api.acirInitProvingKey(acirComposer, bytecode); + await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), CIRCUIT_SIZE); + const exactCircuitSize = await api.acirGetExactCircuitSize(acirComposer); - debug(exactCircuitSize); + debug(`circuit size: ${exactCircuitSize}`); + + debug('creating proof...'); + const witness = getWitness(); + const proof = await api.acirCreateProof(acirComposer, new RawBuffer(bytecode), new RawBuffer(witness)); + + debug('initing verification key...'); + await api.acirInitVerificationKey(acirComposer); - // for (let i = 0; i < 10; ++i) { - // debug(`iteration ${i} starting...`); - // await api.examplesSimpleCreateAndVerifyProof(pippengerPtr, crs.getG2Data()); - // } + const verified = await api.acirVerifyProof(acirComposer, proof); + debug(`verified: ${verified}`); debug('test complete.'); } finally { diff --git a/ts/src/serialize/serialize.ts b/ts/src/serialize/serialize.ts index 0161989401..29613d7fc9 100644 --- a/ts/src/serialize/serialize.ts +++ b/ts/src/serialize/serialize.ts @@ -1,3 +1,5 @@ +import { RawBuffer } from '../types/raw_buffer.js'; + // For serializing bool. export function boolToBuffer(b: boolean) { const buf = new Uint8Array(1); @@ -133,6 +135,8 @@ export type Bufferable = boolean | Uint8Array | number | string | { toBuffer: () export function serializeBufferable(obj: Bufferable): Uint8Array { if (Array.isArray(obj)) { return serializeBufferArrayToVector(obj.map(serializeBufferable)); + } else if (obj instanceof RawBuffer) { + return obj; } else if (obj instanceof Uint8Array) { return serializeBufferToVector(obj); } else if (typeof obj === 'boolean') { diff --git a/ts/src/types/index.ts b/ts/src/types/index.ts index 423c75d125..cc5bba551c 100644 --- a/ts/src/types/index.ts +++ b/ts/src/types/index.ts @@ -2,3 +2,4 @@ export * from './ptr.js'; export * from './fields.js'; export * from './point.js'; export * from './fixed_size_buffer.js'; +export * from './raw_buffer.js'; diff --git a/ts/src/types/raw_buffer.ts b/ts/src/types/raw_buffer.ts new file mode 100644 index 0000000000..de2696ee62 --- /dev/null +++ b/ts/src/types/raw_buffer.ts @@ -0,0 +1,3 @@ +// Used when the data is to be sent exactly as is. i.e. no length prefix will be added. +// This is useful for sending structured data that can be parsed-as-you-go, as opposed to just an array of bytes. +export class RawBuffer extends Uint8Array {} From 0e7d32f6460cc549d4e4b7e41a50ca6642a7bfa2 Mon Sep 17 00:00:00 2001 From: ledwards2225 <98505400+ledwards2225@users.noreply.github.com> Date: Tue, 23 May 2023 13:57:10 -0700 Subject: [PATCH 07/29] Sumcheck improvements (#455) * convert partially evaluated polynomials from vectors to Polynomials and rename * rename fold method to partially_evaluate * static constexpr barycentric arrays * change purported evaluations to claimed evaluations * specify relations in Flavor --- .../barretenberg/honk/flavor/flavor.test.cpp | 12 +-- cpp/src/barretenberg/honk/flavor/standard.hpp | 37 ++++++-- cpp/src/barretenberg/honk/flavor/ultra.hpp | 48 ++++++++-- .../barretenberg/honk/proof_system/prover.cpp | 9 +- .../honk/proof_system/ultra_prover.cpp | 21 +---- .../honk/proof_system/ultra_verifier.cpp | 20 +---- .../honk/proof_system/verifier.cpp | 9 +- .../sumcheck/polynomials/barycentric_data.hpp | 77 ++++++++++------ .../polynomials/multivariates.test.cpp | 90 +++++++++---------- .../relations/relation_consistency.test.cpp | 6 +- .../relations/relation_correctness.test.cpp | 8 +- .../ultra_relation_consistency.test.cpp | 6 +- .../barretenberg/honk/sumcheck/sumcheck.hpp | 68 +++++++------- .../honk/sumcheck/sumcheck.test.cpp | 38 ++------ .../honk/sumcheck/sumcheck_output.hpp | 6 +- .../honk/sumcheck/sumcheck_round.hpp | 30 +++---- .../honk/sumcheck/sumcheck_round.test.cpp | 21 ++--- .../proof_system/flavor/flavor.hpp | 49 +++++++++- 18 files changed, 301 insertions(+), 254 deletions(-) diff --git a/cpp/src/barretenberg/honk/flavor/flavor.test.cpp b/cpp/src/barretenberg/honk/flavor/flavor.test.cpp index 1211313af4..e820310f7e 100644 --- a/cpp/src/barretenberg/honk/flavor/flavor.test.cpp +++ b/cpp/src/barretenberg/honk/flavor/flavor.test.cpp @@ -38,7 +38,7 @@ TEST(Flavor, StandardGetters) Flavor::VerificationKey verification_key; Flavor::ProverPolynomials prover_polynomials; Flavor::ExtendedEdges edges; - Flavor::PurportedEvaluations evals; + Flavor::ClaimedEvaluations evals; Flavor::CommitmentLabels commitment_labels; // Globals are also available through STL container sizes @@ -120,11 +120,11 @@ TEST(Flavor, AllEntitiesSpecialMemberFunctions) { using Flavor = proof_system::honk::flavor::Standard; using FF = Flavor::FF; - using FoldedPolynomials = Flavor::FoldedPolynomials; + using PartiallyEvaluatedMultivariates = Flavor::PartiallyEvaluatedMultivariates; using Polynomial = Polynomial; - FoldedPolynomials polynomials_A; - std::vector random_poly{ 10 }; + PartiallyEvaluatedMultivariates polynomials_A; + auto random_poly = Polynomial(10); for (auto& coeff : random_poly) { coeff = FF::random_element(); } @@ -135,10 +135,10 @@ TEST(Flavor, AllEntitiesSpecialMemberFunctions) ASSERT_EQ(random_poly, polynomials_A.w_l); - FoldedPolynomials polynomials_B(polynomials_A); + PartiallyEvaluatedMultivariates polynomials_B(polynomials_A); ASSERT_EQ(random_poly, polynomials_B.w_l); - FoldedPolynomials polynomials_C(std::move(polynomials_B)); + PartiallyEvaluatedMultivariates polynomials_C(std::move(polynomials_B)); ASSERT_EQ(random_poly, polynomials_C.w_l); } diff --git a/cpp/src/barretenberg/honk/flavor/standard.hpp b/cpp/src/barretenberg/honk/flavor/standard.hpp index a88c1b6cfc..1557fb8814 100644 --- a/cpp/src/barretenberg/honk/flavor/standard.hpp +++ b/cpp/src/barretenberg/honk/flavor/standard.hpp @@ -6,8 +6,12 @@ #include #include #include "barretenberg/honk/pcs/commitment_key.hpp" +#include "barretenberg/honk/sumcheck/polynomials/barycentric_data.hpp" #include "barretenberg/honk/sumcheck/polynomials/univariate.hpp" #include "barretenberg/ecc/curves/bn254/g1.hpp" +#include "barretenberg/honk/sumcheck/relations/arithmetic_relation.hpp" +#include "barretenberg/honk/sumcheck/relations/grand_product_computation_relation.hpp" +#include "barretenberg/honk/sumcheck/relations/grand_product_initialization_relation.hpp" #include "barretenberg/honk/transcript/transcript.hpp" #include "barretenberg/plonk/proof_system/proving_key/proving_key.hpp" #include "barretenberg/polynomials/evaluation_domain.hpp" @@ -48,6 +52,19 @@ class Standard { // The total number of witness entities not including shifts. static constexpr size_t NUM_WITNESS_ENTITIES = 4; + // define the tuple of Relations that comprise the Sumcheck relation + using Relations = std::tuple, + sumcheck::GrandProductComputationRelation, + sumcheck::GrandProductInitializationRelation>; + + static constexpr size_t MAX_RELATION_LENGTH = get_max_relation_length(); + static constexpr size_t NUM_RELATIONS = std::tuple_size::value; + + // define the container for storing the univariate contribution from each relation in Sumcheck + using UnivariateTuple = decltype(create_univariate_tuple()); + // define utilities to extend univarates from RELATION_LENGTH to MAX_RELATION_LENGTH for each Relation + using BarycentricUtils = decltype(create_barycentric_utils()); + private: /** * @brief A base class labelling precomputed entities and (ordered) subsets of interest. @@ -190,10 +207,20 @@ class Standard { using ProverPolynomials = AllEntities; /** - * @brief A container for polynomials produced after the first round of sumcheck. - * @todo TODO(#394) Use polynomial classes for guaranteed memory alignment. + * @brief A container for storing the partially evaluated multivariates produced by sumcheck. */ - using FoldedPolynomials = AllEntities, PolynomialHandle>; + class PartiallyEvaluatedMultivariates : public AllEntities { + + public: + PartiallyEvaluatedMultivariates() = default; + PartiallyEvaluatedMultivariates(const size_t circuit_size) + { + // Storage is only needed after the first partial evaluation, hence polynomials of size (n / 2) + for (auto& poly : this->_data) { + poly = Polynomial(circuit_size / 2); + } + } + }; /** * @brief A container for univariates produced during the hot loop in sumcheck. @@ -207,11 +234,11 @@ class Standard { * @brief A container for the polynomials evaluations produced during sumcheck, which are purported to be the * evaluations of polynomials committed in earlier rounds. */ - class PurportedEvaluations : public AllEntities { + class ClaimedEvaluations : public AllEntities { public: using Base = AllEntities; using Base::Base; - PurportedEvaluations(std::array _data_in) { this->_data = _data_in; } + ClaimedEvaluations(std::array _data_in) { this->_data = _data_in; } }; /** diff --git a/cpp/src/barretenberg/honk/flavor/ultra.hpp b/cpp/src/barretenberg/honk/flavor/ultra.hpp index 1c9ac16326..a3d016bd60 100644 --- a/cpp/src/barretenberg/honk/flavor/ultra.hpp +++ b/cpp/src/barretenberg/honk/flavor/ultra.hpp @@ -6,6 +6,7 @@ #include #include #include "barretenberg/honk/pcs/commitment_key.hpp" +#include "barretenberg/honk/sumcheck/polynomials/barycentric_data.hpp" #include "barretenberg/honk/sumcheck/polynomials/univariate.hpp" #include "barretenberg/ecc/curves/bn254/g1.hpp" #include "barretenberg/honk/transcript/transcript.hpp" @@ -15,6 +16,14 @@ #include "barretenberg/proof_system/circuit_constructors/ultra_circuit_constructor.hpp" #include "barretenberg/srs/reference_string/reference_string.hpp" #include "barretenberg/proof_system/flavor/flavor.hpp" +#include "barretenberg/honk/sumcheck/relations/ultra_arithmetic_relation.hpp" +#include "barretenberg/honk/sumcheck/relations/ultra_arithmetic_relation_secondary.hpp" +#include "barretenberg/honk/sumcheck/relations/grand_product_computation_relation.hpp" +#include "barretenberg/honk/sumcheck/relations/grand_product_initialization_relation.hpp" +#include "barretenberg/honk/sumcheck/relations/lookup_grand_product_relation.hpp" +#include "barretenberg/honk/sumcheck/relations/gen_perm_sort_relation.hpp" +#include "barretenberg/honk/sumcheck/relations/elliptic_relation.hpp" +#include "barretenberg/honk/sumcheck/relations/auxiliary_relation.hpp" namespace proof_system::honk::flavor { @@ -41,6 +50,25 @@ class Ultra { // The total number of witness entities not including shifts. static constexpr size_t NUM_WITNESS_ENTITIES = 11; + // define the tuple of Relations that comprise the Sumcheck relation + using Relations = std::tuple, + sumcheck::UltraArithmeticRelationSecondary, + sumcheck::UltraGrandProductComputationRelation, + sumcheck::UltraGrandProductInitializationRelation, + sumcheck::LookupGrandProductComputationRelation, + sumcheck::LookupGrandProductInitializationRelation, + sumcheck::GenPermSortRelation, + sumcheck::EllipticRelation, + sumcheck::AuxiliaryRelation>; + + static constexpr size_t MAX_RELATION_LENGTH = get_max_relation_length(); + static constexpr size_t NUM_RELATIONS = std::tuple_size::value; + + // define the container for storing the univariate contribution from each relation in Sumcheck + using UnivariateTuple = decltype(create_univariate_tuple()); + // define utilities to extend univarates from RELATION_LENGTH to MAX_RELATION_LENGTH for each Relation + using BarycentricUtils = decltype(create_barycentric_utils()); + private: template /** @@ -249,10 +277,20 @@ class Ultra { using ProverPolynomials = AllEntities; /** - * @brief A container for polynomials produced after the first round of sumcheck. - * @todo TODO(#394) Use polynomial classes for guaranteed memory alignment. + * @brief A container for storing the partially evaluated multivariates produced by sumcheck. */ - using FoldedPolynomials = AllEntities, PolynomialHandle>; + class PartiallyEvaluatedMultivariates : public AllEntities { + + public: + PartiallyEvaluatedMultivariates() = default; + PartiallyEvaluatedMultivariates(const size_t circuit_size) + { + // Storage is only needed after the first partial evaluation, hence polynomials of size (n / 2) + for (auto& poly : this->_data) { + poly = Polynomial(circuit_size / 2); + } + } + }; /** * @brief A container for univariates produced during the hot loop in sumcheck. @@ -266,11 +304,11 @@ class Ultra { * @brief A container for the polynomials evaluations produced during sumcheck, which are purported to be the * evaluations of polynomials committed in earlier rounds. */ - class PurportedEvaluations : public AllEntities { + class ClaimedEvaluations : public AllEntities { public: using Base = AllEntities; using Base::Base; - PurportedEvaluations(std::array _data_in) { this->_data = _data_in; } + ClaimedEvaluations(std::array _data_in) { this->_data = _data_in; } }; /** diff --git a/cpp/src/barretenberg/honk/proof_system/prover.cpp b/cpp/src/barretenberg/honk/proof_system/prover.cpp index ca92ca8f27..6747fc0bee 100644 --- a/cpp/src/barretenberg/honk/proof_system/prover.cpp +++ b/cpp/src/barretenberg/honk/proof_system/prover.cpp @@ -3,9 +3,6 @@ #include "barretenberg/honk/sumcheck/sumcheck.hpp" #include "barretenberg/honk/transcript/transcript.hpp" #include "barretenberg/honk/utils/power_polynomial.hpp" -#include "barretenberg/honk/sumcheck/relations/arithmetic_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/grand_product_computation_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/grand_product_initialization_relation.hpp" #include "barretenberg/honk/flavor/standard.hpp" namespace proof_system::honk { @@ -130,11 +127,7 @@ template void StandardProver_::execute_grand_pro * */ template void StandardProver_::execute_relation_check_rounds() { - using Sumcheck = sumcheck::Sumcheck, - sumcheck::ArithmeticRelation, - sumcheck::GrandProductComputationRelation, - sumcheck::GrandProductInitializationRelation>; + using Sumcheck = sumcheck::Sumcheck>; auto sumcheck = Sumcheck(key->circuit_size, transcript); diff --git a/cpp/src/barretenberg/honk/proof_system/ultra_prover.cpp b/cpp/src/barretenberg/honk/proof_system/ultra_prover.cpp index ad6cb81d70..f0d7d26089 100644 --- a/cpp/src/barretenberg/honk/proof_system/ultra_prover.cpp +++ b/cpp/src/barretenberg/honk/proof_system/ultra_prover.cpp @@ -2,8 +2,6 @@ #include #include #include "barretenberg/honk/proof_system/prover_library.hpp" -#include "barretenberg/honk/sumcheck/relations/ultra_arithmetic_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/ultra_arithmetic_relation_secondary.hpp" #include "barretenberg/honk/sumcheck/sumcheck.hpp" #include #include "barretenberg/honk/sumcheck/polynomials/univariate.hpp" // will go away @@ -15,13 +13,6 @@ #include #include "barretenberg/ecc/curves/bn254/fr.hpp" #include "barretenberg/ecc/curves/bn254/g1.hpp" -#include "barretenberg/honk/sumcheck/relations/arithmetic_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/grand_product_computation_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/grand_product_initialization_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/lookup_grand_product_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/gen_perm_sort_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/elliptic_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/auxiliary_relation.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/transcript/transcript_wrappers.hpp" #include @@ -191,17 +182,7 @@ template void UltraProver_::execute_grand_product_c */ template void UltraProver_::execute_relation_check_rounds() { - using Sumcheck = sumcheck::Sumcheck, - sumcheck::UltraArithmeticRelation, - sumcheck::UltraArithmeticRelationSecondary, - sumcheck::UltraGrandProductComputationRelation, - sumcheck::UltraGrandProductInitializationRelation, - sumcheck::LookupGrandProductComputationRelation, - sumcheck::LookupGrandProductInitializationRelation, - sumcheck::GenPermSortRelation, - sumcheck::EllipticRelation, - sumcheck::AuxiliaryRelation>; + using Sumcheck = sumcheck::Sumcheck>; auto sumcheck = Sumcheck(key->circuit_size, transcript); diff --git a/cpp/src/barretenberg/honk/proof_system/ultra_verifier.cpp b/cpp/src/barretenberg/honk/proof_system/ultra_verifier.cpp index 194d44b6e9..628a969d26 100644 --- a/cpp/src/barretenberg/honk/proof_system/ultra_verifier.cpp +++ b/cpp/src/barretenberg/honk/proof_system/ultra_verifier.cpp @@ -4,14 +4,6 @@ #include "barretenberg/honk/flavor/standard.hpp" #include "barretenberg/ecc/curves/bn254/scalar_multiplication/scalar_multiplication.hpp" #include "barretenberg/honk/utils/power_polynomial.hpp" -#include "barretenberg/honk/sumcheck/relations/ultra_arithmetic_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/ultra_arithmetic_relation_secondary.hpp" -#include "barretenberg/honk/sumcheck/relations/grand_product_initialization_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/grand_product_computation_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/lookup_grand_product_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/gen_perm_sort_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/elliptic_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/auxiliary_relation.hpp" #pragma GCC diagnostic ignored "-Wunused-variable" @@ -107,17 +99,7 @@ template bool UltraVerifier_::verify_proof(const plonk commitments.z_lookup = transcript.template receive_from_prover(commitment_labels.z_lookup); // Execute Sumcheck Verifier - auto sumcheck = Sumcheck, - honk::sumcheck::UltraArithmeticRelation, - honk::sumcheck::UltraArithmeticRelationSecondary, - honk::sumcheck::UltraGrandProductComputationRelation, - honk::sumcheck::UltraGrandProductInitializationRelation, - honk::sumcheck::LookupGrandProductComputationRelation, - honk::sumcheck::LookupGrandProductInitializationRelation, - honk::sumcheck::GenPermSortRelation, - honk::sumcheck::EllipticRelation, - honk::sumcheck::AuxiliaryRelation>(circuit_size, transcript); + auto sumcheck = Sumcheck>(circuit_size, transcript); std::optional sumcheck_output = sumcheck.execute_verifier(relation_parameters); diff --git a/cpp/src/barretenberg/honk/proof_system/verifier.cpp b/cpp/src/barretenberg/honk/proof_system/verifier.cpp index 6238f6e2e1..3506f15aaa 100644 --- a/cpp/src/barretenberg/honk/proof_system/verifier.cpp +++ b/cpp/src/barretenberg/honk/proof_system/verifier.cpp @@ -4,9 +4,6 @@ #include "barretenberg/honk/flavor/standard.hpp" #include "barretenberg/ecc/curves/bn254/scalar_multiplication/scalar_multiplication.hpp" #include "barretenberg/honk/utils/power_polynomial.hpp" -#include "barretenberg/honk/sumcheck/relations/arithmetic_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/grand_product_initialization_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/grand_product_computation_relation.hpp" using namespace barretenberg; using namespace proof_system::honk::sumcheck; @@ -111,11 +108,7 @@ template bool StandardVerifier_::verify_proof(const pl commitments.z_perm = transcript.template receive_from_prover(commitment_labels.z_perm); // Execute Sumcheck Verifier - auto sumcheck = Sumcheck, - honk::sumcheck::ArithmeticRelation, - honk::sumcheck::GrandProductComputationRelation, - honk::sumcheck::GrandProductInitializationRelation>(circuit_size, transcript); + auto sumcheck = Sumcheck>(circuit_size, transcript); std::optional sumcheck_output = sumcheck.execute_verifier(relation_parameters); // If Sumcheck does not return an output, sumcheck verification has failed diff --git a/cpp/src/barretenberg/honk/sumcheck/polynomials/barycentric_data.hpp b/cpp/src/barretenberg/honk/sumcheck/polynomials/barycentric_data.hpp index ae2d5f5d9b..f7e13ceabf 100644 --- a/cpp/src/barretenberg/honk/sumcheck/polynomials/barycentric_data.hpp +++ b/cpp/src/barretenberg/honk/sumcheck/polynomials/barycentric_data.hpp @@ -6,12 +6,10 @@ /* IMPROVEMENT(Cody): This could or should be improved in various ways. In no particular order: 1) Edge cases are not considered. One non-use case situation (I forget which) leads to a segfault. - 2) This could all be constexpr. - - 3) Precomputing for all possible size pairs is probably feasible and might be a better solution than instantiating + 2) Precomputing for all possible size pairs is probably feasible and might be a better solution than instantiating many instances separately. Then perhaps we could infer input type to `extend`. - 4) There should be more thorough testing of this class in isolation. + 3) There should be more thorough testing of this class in isolation. */ namespace proof_system::honk::sumcheck { @@ -23,54 +21,77 @@ namespace proof_system::honk::sumcheck { template class BarycentricData { public: static constexpr size_t big_domain_size = std::max(domain_size, num_evals); - // TODO(#224)(Cody): these should be static, also constexpr, but arrays are not constexpr - std::array big_domain; - std::array lagrange_denominators; - std::array precomputed_denominator_inverses; - std::array full_numerator_values; - constexpr BarycentricData() + /** + * Static constexpr methods for computing arrays of precomputable data used for barycentric extension and evaluation + */ + + // build big_domain, currently the set of x_i in {0, 1, ..., t-1} + static constexpr std::array construct_big_domain() { - // build big_domain, currently the set of x_i in {0, 1, ..., t-1} - for (size_t i = 0; i != big_domain_size; ++i) { - big_domain[i] = i; + std::array result; + for (size_t i = 0; i < big_domain_size; ++i) { + result[i] = static_cast(i); } + return result; + } - // build set of lagrange_denominators d_i = \prod_{j!=i} x_i - x_j + // build set of lagrange_denominators d_i = \prod_{j!=i} x_i - x_j + static constexpr std::array construct_lagrange_denominators(const auto& big_domain) + { + std::array result; for (size_t i = 0; i != domain_size; ++i) { - lagrange_denominators[i] = 1; + result[i] = 1; for (size_t j = 0; j != domain_size; ++j) { if (j != i) { - lagrange_denominators[i] *= big_domain[i] - big_domain[j]; + result[i] *= big_domain[i] - big_domain[j]; } } } + return result; + } - // for each x_k in the big domain, build set of domain size-many denominator inverses - // 1/(d_i*(x_k - x_j)). will multiply against each of these (rather than to divide by something) - // for each barycentric evaluation - for (size_t k = domain_size; k != num_evals; ++k) { - for (size_t j = 0; j != domain_size; ++j) { + // for each x_k in the big domain, build set of domain size-many denominator inverses + // 1/(d_i*(x_k - x_j)). will multiply against each of these (rather than to divide by something) + // for each barycentric evaluation + static constexpr std::array construct_denominator_inverses( + const auto& big_domain, const auto& lagrange_denominators) + { + std::array result{}; // default init to 0 since below does not init all elements + for (size_t k = domain_size; k < num_evals; ++k) { + for (size_t j = 0; j < domain_size; ++j) { Fr inv = lagrange_denominators[j]; inv *= (big_domain[k] - big_domain[j]); inv = Fr(1) / inv; // prob have self_inverse method; should be part of Field concept - precomputed_denominator_inverses[k * domain_size + j] = inv; + result[k * domain_size + j] = inv; } } + return result; + } - // get full numerator values - // full numerator is M(x) = \prod_{i} (x-x_i) - // these will be zero for i < domain_size, but that's ok because - // at such entries we will already have the evaluations of the polynomial + // get full numerator values + // full numerator is M(x) = \prod_{i} (x-x_i) + // these will be zero for i < domain_size, but that's ok because + // at such entries we will already have the evaluations of the polynomial + static constexpr std::array construct_full_numerator_values(const auto& big_domain) + { + std::array result; for (size_t i = 0; i != num_evals; ++i) { - full_numerator_values[i] = 1; + result[i] = 1; Fr v_i = i; for (size_t j = 0; j != domain_size; ++j) { - full_numerator_values[i] *= v_i - big_domain[j]; + result[i] *= v_i - big_domain[j]; } } + return result; } + static constexpr auto big_domain = construct_big_domain(); + static constexpr auto lagrange_denominators = construct_lagrange_denominators(big_domain); + static constexpr auto precomputed_denominator_inverses = + construct_denominator_inverses(big_domain, lagrange_denominators); + static constexpr auto full_numerator_values = construct_full_numerator_values(big_domain); + /** * @brief Given A univariate f represented by {f(0), ..., f(t-1)}, compute {f(t), ..., f(u-1)} * and return the Univariate represented by {f(0), ..., f(u-1)}. diff --git a/cpp/src/barretenberg/honk/sumcheck/polynomials/multivariates.test.cpp b/cpp/src/barretenberg/honk/sumcheck/polynomials/multivariates.test.cpp index 3e40df0113..f7417d5624 100644 --- a/cpp/src/barretenberg/honk/sumcheck/polynomials/multivariates.test.cpp +++ b/cpp/src/barretenberg/honk/sumcheck/polynomials/multivariates.test.cpp @@ -61,23 +61,23 @@ TYPED_TEST(MultivariatesTests, FoldTwoRoundsSpecial) auto full_polynomials = std::array, 1>({ f0 }); auto transcript = Transcript::init_empty(); - auto sumcheck = Sumcheck(multivariate_n, transcript); + auto sumcheck = Sumcheck(multivariate_n, transcript); FF round_challenge_0 = { 0x6c7301b49d85a46c, 0x44311531e39c64f6, 0xb13d66d8d6c1a24c, 0x04410c360230a295 }; round_challenge_0.self_to_montgomery_form(); FF expected_lo = v00 * (FF(1) - round_challenge_0) + v10 * round_challenge_0; FF expected_hi = v01 * (FF(1) - round_challenge_0) + v11 * round_challenge_0; - sumcheck.fold(full_polynomials, multivariate_n, round_challenge_0); + sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); - EXPECT_EQ(sumcheck.folded_polynomials[0][0], round_challenge_0); - EXPECT_EQ(sumcheck.folded_polynomials[0][1], FF(0)); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], round_challenge_0); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][1], FF(0)); FF round_challenge_1 = 2; FF expected_val = expected_lo * (FF(1) - round_challenge_1) + expected_hi * round_challenge_1; - sumcheck.fold(sumcheck.folded_polynomials, multivariate_n >> 1, round_challenge_1); - EXPECT_EQ(sumcheck.folded_polynomials[0][0], expected_val); + sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 1, round_challenge_1); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_val); } TYPED_TEST(MultivariatesTests, FoldTwoRoundsGeneric) @@ -98,21 +98,21 @@ TYPED_TEST(MultivariatesTests, FoldTwoRoundsGeneric) auto full_polynomials = std::array, 1>({ f0 }); auto transcript = Transcript::init_empty(); - auto sumcheck = Sumcheck(multivariate_n, transcript); + auto sumcheck = Sumcheck(multivariate_n, transcript); FF round_challenge_0 = FF::random_element(); FF expected_lo = v00 * (FF(1) - round_challenge_0) + v10 * round_challenge_0; FF expected_hi = v01 * (FF(1) - round_challenge_0) + v11 * round_challenge_0; - sumcheck.fold(full_polynomials, multivariate_n, round_challenge_0); + sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); - EXPECT_EQ(sumcheck.folded_polynomials[0][0], expected_lo); - EXPECT_EQ(sumcheck.folded_polynomials[0][1], expected_hi); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_lo); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][1], expected_hi); FF round_challenge_1 = FF::random_element(); FF expected_val = expected_lo * (FF(1) - round_challenge_1) + expected_hi * round_challenge_1; - sumcheck.fold(sumcheck.folded_polynomials, multivariate_n >> 1, round_challenge_1); - EXPECT_EQ(sumcheck.folded_polynomials[0][0], expected_val); + sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 1, round_challenge_1); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_val); } /* @@ -159,7 +159,7 @@ TYPED_TEST(MultivariatesTests, FoldThreeRoundsSpecial) auto full_polynomials = std::array, 1>({ f0 }); auto transcript = Transcript::init_empty(); - auto sumcheck = Sumcheck(multivariate_n, transcript); + auto sumcheck = Sumcheck(multivariate_n, transcript); FF round_challenge_0 = 1; FF expected_q1 = v000 * (FF(1) - round_challenge_0) + v100 * round_challenge_0; // 2 @@ -167,25 +167,25 @@ TYPED_TEST(MultivariatesTests, FoldThreeRoundsSpecial) FF expected_q3 = v001 * (FF(1) - round_challenge_0) + v101 * round_challenge_0; // 6 FF expected_q4 = v011 * (FF(1) - round_challenge_0) + v111 * round_challenge_0; // 8 - sumcheck.fold(full_polynomials, multivariate_n, round_challenge_0); + sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); - EXPECT_EQ(sumcheck.folded_polynomials[0][0], expected_q1); - EXPECT_EQ(sumcheck.folded_polynomials[0][1], expected_q2); - EXPECT_EQ(sumcheck.folded_polynomials[0][2], expected_q3); - EXPECT_EQ(sumcheck.folded_polynomials[0][3], expected_q4); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_q1); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][1], expected_q2); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][2], expected_q3); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][3], expected_q4); FF round_challenge_1 = 2; FF expected_lo = expected_q1 * (FF(1) - round_challenge_1) + expected_q2 * round_challenge_1; // 6 FF expected_hi = expected_q3 * (FF(1) - round_challenge_1) + expected_q4 * round_challenge_1; // 10 - sumcheck.fold(sumcheck.folded_polynomials, multivariate_n >> 1, round_challenge_1); - EXPECT_EQ(sumcheck.folded_polynomials[0][0], expected_lo); - EXPECT_EQ(sumcheck.folded_polynomials[0][1], expected_hi); + sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 1, round_challenge_1); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_lo); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][1], expected_hi); FF round_challenge_2 = 3; FF expected_val = expected_lo * (FF(1) - round_challenge_2) + expected_hi * round_challenge_2; // 18 - sumcheck.fold(sumcheck.folded_polynomials, multivariate_n >> 2, round_challenge_2); - EXPECT_EQ(sumcheck.folded_polynomials[0][0], expected_val); + sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 2, round_challenge_2); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_val); } TYPED_TEST(MultivariatesTests, FoldThreeRoundsGeneric) @@ -210,7 +210,7 @@ TYPED_TEST(MultivariatesTests, FoldThreeRoundsGeneric) auto full_polynomials = std::array, 1>({ f0 }); auto transcript = Transcript::init_empty(); - auto sumcheck = Sumcheck(multivariate_n, transcript); + auto sumcheck = Sumcheck(multivariate_n, transcript); FF round_challenge_0 = FF::random_element(); FF expected_q1 = v000 * (FF(1) - round_challenge_0) + v100 * round_challenge_0; @@ -218,25 +218,25 @@ TYPED_TEST(MultivariatesTests, FoldThreeRoundsGeneric) FF expected_q3 = v001 * (FF(1) - round_challenge_0) + v101 * round_challenge_0; FF expected_q4 = v011 * (FF(1) - round_challenge_0) + v111 * round_challenge_0; - sumcheck.fold(full_polynomials, multivariate_n, round_challenge_0); + sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); - EXPECT_EQ(sumcheck.folded_polynomials[0][0], expected_q1); - EXPECT_EQ(sumcheck.folded_polynomials[0][1], expected_q2); - EXPECT_EQ(sumcheck.folded_polynomials[0][2], expected_q3); - EXPECT_EQ(sumcheck.folded_polynomials[0][3], expected_q4); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_q1); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][1], expected_q2); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][2], expected_q3); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][3], expected_q4); FF round_challenge_1 = FF::random_element(); FF expected_lo = expected_q1 * (FF(1) - round_challenge_1) + expected_q2 * round_challenge_1; FF expected_hi = expected_q3 * (FF(1) - round_challenge_1) + expected_q4 * round_challenge_1; - sumcheck.fold(sumcheck.folded_polynomials, multivariate_n >> 1, round_challenge_1); - EXPECT_EQ(sumcheck.folded_polynomials[0][0], expected_lo); - EXPECT_EQ(sumcheck.folded_polynomials[0][1], expected_hi); + sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 1, round_challenge_1); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_lo); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][1], expected_hi); FF round_challenge_2 = FF::random_element(); FF expected_val = expected_lo * (FF(1) - round_challenge_2) + expected_hi * round_challenge_2; - sumcheck.fold(sumcheck.folded_polynomials, multivariate_n >> 2, round_challenge_2); - EXPECT_EQ(sumcheck.folded_polynomials[0][0], expected_val); + sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 2, round_challenge_2); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_val); } TYPED_TEST(MultivariatesTests, FoldThreeRoundsGenericMultiplePolys) @@ -272,7 +272,7 @@ TYPED_TEST(MultivariatesTests, FoldThreeRoundsGenericMultiplePolys) auto full_polynomials = std::array, 3>{ f0, f1, f2 }; auto transcript = Transcript::init_empty(); - auto sumcheck = Sumcheck(multivariate_n, transcript); + auto sumcheck = Sumcheck(multivariate_n, transcript); std::array expected_q1; std::array expected_q2; @@ -286,12 +286,12 @@ TYPED_TEST(MultivariatesTests, FoldThreeRoundsGenericMultiplePolys) expected_q4[i] = v011[i] * (FF(1) - round_challenge_0) + v111[i] * round_challenge_0; } - sumcheck.fold(full_polynomials, multivariate_n, round_challenge_0); + sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); for (size_t i = 0; i < 3; i++) { - EXPECT_EQ(sumcheck.folded_polynomials[i][0], expected_q1[i]); - EXPECT_EQ(sumcheck.folded_polynomials[i][1], expected_q2[i]); - EXPECT_EQ(sumcheck.folded_polynomials[i][2], expected_q3[i]); - EXPECT_EQ(sumcheck.folded_polynomials[i][3], expected_q4[i]); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[i][0], expected_q1[i]); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[i][1], expected_q2[i]); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[i][2], expected_q3[i]); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[i][3], expected_q4[i]); } FF round_challenge_1 = FF::random_element(); @@ -301,19 +301,19 @@ TYPED_TEST(MultivariatesTests, FoldThreeRoundsGenericMultiplePolys) expected_lo[i] = expected_q1[i] * (FF(1) - round_challenge_1) + expected_q2[i] * round_challenge_1; expected_hi[i] = expected_q3[i] * (FF(1) - round_challenge_1) + expected_q4[i] * round_challenge_1; } - sumcheck.fold(sumcheck.folded_polynomials, multivariate_n >> 1, round_challenge_1); + sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 1, round_challenge_1); for (size_t i = 0; i < 3; i++) { - EXPECT_EQ(sumcheck.folded_polynomials[i][0], expected_lo[i]); - EXPECT_EQ(sumcheck.folded_polynomials[i][1], expected_hi[i]); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[i][0], expected_lo[i]); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[i][1], expected_hi[i]); } FF round_challenge_2 = FF::random_element(); std::array expected_val; for (size_t i = 0; i < 3; i++) { expected_val[i] = expected_lo[i] * (FF(1) - round_challenge_2) + expected_hi[i] * round_challenge_2; } - sumcheck.fold(sumcheck.folded_polynomials, multivariate_n >> 2, round_challenge_2); + sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 2, round_challenge_2); for (size_t i = 0; i < 3; i++) { - EXPECT_EQ(sumcheck.folded_polynomials[i][0], expected_val[i]); + EXPECT_EQ(sumcheck.partially_evaluated_polynomials[i][0], expected_val[i]); } } diff --git a/cpp/src/barretenberg/honk/sumcheck/relations/relation_consistency.test.cpp b/cpp/src/barretenberg/honk/sumcheck/relations/relation_consistency.test.cpp index be3cce9708..0747a5b4f0 100644 --- a/cpp/src/barretenberg/honk/sumcheck/relations/relation_consistency.test.cpp +++ b/cpp/src/barretenberg/honk/sumcheck/relations/relation_consistency.test.cpp @@ -33,7 +33,7 @@ class StandardRelationConsistency : public testing::Test { public: using Flavor = honk::flavor::Standard; using FF = typename Flavor::FF; - using PurportedEvaluations = typename Flavor::PurportedEvaluations; + using ClaimedEvaluations = typename Flavor::ClaimedEvaluations; // TODO(#390): Move MAX_RELATION_LENGTH into Flavor and simplify this. template using ExtendedEdges = typename Flavor::template ExtendedEdges; @@ -82,7 +82,7 @@ class StandardRelationConsistency : public testing::Test { * @return std::array such that result[j] = univariates[j].value_at(i) */ template - static PurportedEvaluations transposed_univariate_array_at(ExtendedEdges univariates, size_t i) + static ClaimedEvaluations transposed_univariate_array_at(ExtendedEdges univariates, size_t i) { ASSERT(i < univariate_length); std::array result; @@ -117,7 +117,7 @@ class StandardRelationConsistency : public testing::Test { Univariate expected_evals_index{ 0 }; for (size_t i = 0; i < FULL_RELATION_LENGTH; ++i) { // Get an array of the same size as `extended_edges` with only the i-th element of each extended edge. - PurportedEvaluations evals_i = transposed_univariate_array_at(extended_edges, i); + ClaimedEvaluations evals_i = transposed_univariate_array_at(extended_edges, i); // Evaluate the relation relation.add_full_relation_value_contribution( expected_evals_index.value_at(i), evals_i, relation_parameters); diff --git a/cpp/src/barretenberg/honk/sumcheck/relations/relation_correctness.test.cpp b/cpp/src/barretenberg/honk/sumcheck/relations/relation_correctness.test.cpp index d9b1bc3a3e..704cdc82e9 100644 --- a/cpp/src/barretenberg/honk/sumcheck/relations/relation_correctness.test.cpp +++ b/cpp/src/barretenberg/honk/sumcheck/relations/relation_correctness.test.cpp @@ -42,7 +42,7 @@ TEST(RelationCorrectness, StandardRelationCorrectness) using Flavor = honk::flavor::Standard; using FF = typename Flavor::FF; using ProverPolynomials = typename Flavor::ProverPolynomials; - using PurportedEvaluations = typename Flavor::PurportedEvaluations; + using ClaimedEvaluations = typename Flavor::ClaimedEvaluations; // Create a composer and a dummy circuit with a few gates auto composer = StandardHonkComposer(); @@ -115,7 +115,7 @@ TEST(RelationCorrectness, StandardRelationCorrectness) for (size_t i = 0; i < prover.key->circuit_size; i++) { // Compute an array containing all the evaluations at a given row i - PurportedEvaluations evaluations_at_index_i; + ClaimedEvaluations evaluations_at_index_i; size_t poly_idx = 0; for (auto& polynomial : prover_polynomials) { evaluations_at_index_i[poly_idx] = polynomial[i]; @@ -154,7 +154,7 @@ TEST(RelationCorrectness, UltraRelationCorrectness) using Flavor = honk::flavor::Ultra; using FF = typename Flavor::FF; using ProverPolynomials = typename Flavor::ProverPolynomials; - using PurportedEvaluations = typename Flavor::PurportedEvaluations; + using ClaimedEvaluations = typename Flavor::ClaimedEvaluations; // Create a composer and then add an assortment of gates designed to ensure that the constraint(s) represented // by each relation are non-trivially exercised. @@ -379,7 +379,7 @@ TEST(RelationCorrectness, UltraRelationCorrectness) fr result = 0; for (size_t i = 0; i < prover.key->circuit_size; i++) { // Compute an array containing all the evaluations at a given row i - PurportedEvaluations evaluations_at_index_i; + ClaimedEvaluations evaluations_at_index_i; size_t poly_idx = 0; for (auto& polynomial : prover_polynomials) { evaluations_at_index_i[poly_idx] = polynomial[i]; diff --git a/cpp/src/barretenberg/honk/sumcheck/relations/ultra_relation_consistency.test.cpp b/cpp/src/barretenberg/honk/sumcheck/relations/ultra_relation_consistency.test.cpp index e363dd8725..ce44727e48 100644 --- a/cpp/src/barretenberg/honk/sumcheck/relations/ultra_relation_consistency.test.cpp +++ b/cpp/src/barretenberg/honk/sumcheck/relations/ultra_relation_consistency.test.cpp @@ -36,7 +36,7 @@ class UltraRelationConsistency : public testing::Test { public: using Flavor = honk::flavor::Ultra; using FF = typename Flavor::FF; - using PurportedEvaluations = typename Flavor::PurportedEvaluations; + using ClaimedEvaluations = typename Flavor::ClaimedEvaluations; // TODO(#390): Move MAX_RELATION_LENGTH into Flavor and simplify this. template using ExtendedEdges = typename Flavor::template ExtendedEdges; @@ -83,7 +83,7 @@ class UltraRelationConsistency : public testing::Test { * @return std::array such that result[j] = univariates[j].value_at(i) */ template - static PurportedEvaluations transposed_univariate_array_at(ExtendedEdges univariates, size_t i) + static ClaimedEvaluations transposed_univariate_array_at(ExtendedEdges univariates, size_t i) { ASSERT(i < univariate_length); std::array result; @@ -118,7 +118,7 @@ class UltraRelationConsistency : public testing::Test { Univariate expected_evals_index{ 0 }; for (size_t i = 0; i < FULL_RELATION_LENGTH; ++i) { // Get an array of the same size as `extended_edges` with only the i-th element of each extended edge. - PurportedEvaluations evals_i = transposed_univariate_array_at(extended_edges, i); + ClaimedEvaluations evals_i = transposed_univariate_array_at(extended_edges, i); // Evaluate the relation relation.add_full_relation_value_contribution( expected_evals_index.value_at(i), evals_i, relation_parameters); diff --git a/cpp/src/barretenberg/honk/sumcheck/sumcheck.hpp b/cpp/src/barretenberg/honk/sumcheck/sumcheck.hpp index 8968ee1260..3e6794e18a 100644 --- a/cpp/src/barretenberg/honk/sumcheck/sumcheck.hpp +++ b/cpp/src/barretenberg/honk/sumcheck/sumcheck.hpp @@ -18,29 +18,31 @@ namespace proof_system::honk::sumcheck { -template class... Relations> class Sumcheck { +template class Sumcheck { public: using FF = typename Flavor::FF; - using FoldedPolynomials = typename Flavor::FoldedPolynomials; - using PurportedEvaluations = typename Flavor::PurportedEvaluations; + using PartiallyEvaluatedMultivariates = typename Flavor::PartiallyEvaluatedMultivariates; + using ClaimedEvaluations = typename Flavor::ClaimedEvaluations; - static constexpr size_t MAX_RELATION_LENGTH = std::max({ Relations::RELATION_LENGTH... }); + static constexpr size_t MAX_RELATION_LENGTH = Flavor::MAX_RELATION_LENGTH; static constexpr size_t NUM_POLYNOMIALS = Flavor::NUM_ALL_ENTITIES; Transcript& transcript; const size_t multivariate_n; const size_t multivariate_d; - SumcheckRound round; + SumcheckRound round; /** * - * @brief (folded_polynomials) Suppose the Honk polynomials (multilinear in d variables) are called P_1, ..., P_N. + * @brief (partially_evaluated_polynomials) Suppose the Honk polynomials (multilinear in d variables) are called P_1, + ..., P_N. * At initialization, * we think of these as lying in a two-dimensional array, where each column records the value of one P_i on H^d. - * After the first round, the array will be updated ('folded'), so that the first n/2 rows will represent the + * After the first round, the array will be updated (partially evaluated), so that the first n/2 rows will represent + the * evaluations P_i(u0, X1, ..., X_{d-1}) as a low-degree extension on H^{d-1}. In reality, we elude copying all - * of the polynomial-defining data by only populating folded_multivariates after the first round. I.e.: + * of the polynomial-defining data by only populating partially_evaluated_polynomials after the first round. I.e.: We imagine all of the defining polynomial data in a matrix like this: | P_1 | P_2 | P_3 | P_4 | ... | P_N | N = number of multivariatesk @@ -54,7 +56,7 @@ template class... Relations \-| * | * | * | * | ... | * | vertex n-1 m = n/2 * - Each group consists of N edges |, and our construction of univariates and folding + Each group consists of N edges |, and our construction of univariates and partial evaluation * operations naturally operate on these groups of edges @@ -62,30 +64,26 @@ template class... Relations * NOTE: With ~40 columns, prob only want to allocate 256 EdgeGroup's at once to keep stack under 1MB? * TODO(#224)(Cody): might want to just do C-style multidimensional array? for guaranteed adjacency? */ - FoldedPolynomials folded_polynomials; + PartiallyEvaluatedMultivariates partially_evaluated_polynomials; // prover instantiates sumcheck with circuit size and a prover transcript Sumcheck(size_t multivariate_n, ProverTranscript& transcript) : transcript(transcript) , multivariate_n(multivariate_n) , multivariate_d(numeric::get_msb(multivariate_n)) - , round(multivariate_n, std::tuple(Relations()...)) - { - for (auto& polynomial : folded_polynomials) { - polynomial.resize(multivariate_n >> 1); - } - }; + , round(multivariate_n) + , partially_evaluated_polynomials(multivariate_n){}; // verifier instantiates sumcheck with circuit size and a verifier transcript explicit Sumcheck(size_t multivariate_n, VerifierTranscript& transcript) : transcript(transcript) , multivariate_n(multivariate_n) , multivariate_d(numeric::get_msb(multivariate_n)) - , round(std::tuple(Relations()...)){}; + , round(){}; /** - * @brief Compute univariate restriction place in transcript, generate challenge, fold,... repeat until final round, - * then compute multivariate evaluations and place in transcript. + * @brief Compute univariate restriction place in transcript, generate challenge, partially evaluate,... repeat + * until final round, then compute multivariate evaluations and place in transcript. * * @details */ @@ -100,32 +98,34 @@ template class... Relations multivariate_challenge.reserve(multivariate_d); // First round - // This populates folded_polynomials. + // This populates partially_evaluated_polynomials. auto round_univariate = round.compute_univariate(full_polynomials, relation_parameters, pow_univariate, alpha); transcript.send_to_verifier("Sumcheck:univariate_0", round_univariate); FF round_challenge = transcript.get_challenge("Sumcheck:u_0"); multivariate_challenge.emplace_back(round_challenge); - fold(full_polynomials, multivariate_n, round_challenge); + partially_evaluate(full_polynomials, multivariate_n, round_challenge); pow_univariate.partially_evaluate(round_challenge); - round.round_size = round.round_size >> 1; // TODO(#224)(Cody): Maybe fold should do this and release memory? + round.round_size = + round.round_size >> 1; // TODO(#224)(Cody): Maybe partially_evaluate should do this and release memory? // All but final round - // We operate on folded_polynomials in place. + // We operate on partially_evaluated_polynomials in place. for (size_t round_idx = 1; round_idx < multivariate_d; round_idx++) { // Write the round univariate to the transcript - round_univariate = round.compute_univariate(folded_polynomials, relation_parameters, pow_univariate, alpha); + round_univariate = + round.compute_univariate(partially_evaluated_polynomials, relation_parameters, pow_univariate, alpha); transcript.send_to_verifier("Sumcheck:univariate_" + std::to_string(round_idx), round_univariate); FF round_challenge = transcript.get_challenge("Sumcheck:u_" + std::to_string(round_idx)); multivariate_challenge.emplace_back(round_challenge); - fold(folded_polynomials, round.round_size, round_challenge); + partially_evaluate(partially_evaluated_polynomials, round.round_size, round_challenge); pow_univariate.partially_evaluate(round_challenge); round.round_size = round.round_size >> 1; } - // Final round: Extract multivariate evaluations from folded_polynomials and add to transcript - PurportedEvaluations multivariate_evaluations; + // Final round: Extract multivariate evaluations from partially_evaluated_polynomials and add to transcript + ClaimedEvaluations multivariate_evaluations; size_t evaluation_idx = 0; - for (auto& polynomial : folded_polynomials) { // TODO(#391) zip + for (auto& polynomial : partially_evaluated_polynomials) { // TODO(#391) zip multivariate_evaluations[evaluation_idx] = polynomial[0]; ++evaluation_idx; } @@ -178,7 +178,7 @@ template class... Relations } // Final round - PurportedEvaluations purported_evaluations = + ClaimedEvaluations purported_evaluations = transcript.template receive_from_prover>("Sumcheck:evaluations"); FF full_honk_relation_purported_value = round.compute_full_honk_relation_purported_value( @@ -191,14 +191,12 @@ template class... Relations return SumcheckOutput{ multivariate_challenge, purported_evaluations }; }; - // TODO(#224)(Cody): Rename. fold is not descriptive, and it's already in use in the Gemini context. - // Probably just call it partial_evaluation? /** * @brief Evaluate at the round challenge and prepare class for next round. * Illustration of layout in example of first round when d==3 (showing just one Honk polynomial, * i.e., what happens in just one column of our two-dimensional array): * - * groups vertex terms collected vertex terms groups after folding + * groups vertex terms collected vertex terms groups after partial evaluation * g0 -- v0 (1-X0)(1-X1)(1-X2) --- (v0(1-X0) + v1 X0) (1-X1)(1-X2) ---- (v0(1-u0) + v1 u0) (1-X1)(1-X2) * \- v1 X0 (1-X1)(1-X2) --/ --- (v2(1-u0) + v3 u0) X1 (1-X2) * g1 -- v2 (1-X0) X1 (1-X2) --- (v2(1-X0) + v3 X0) X1 (1-X2)-/ -- (v4(1-u0) + v5 u0) (1-X1) X2 @@ -210,12 +208,12 @@ template class... Relations * * @param challenge */ - void fold(auto& polynomials, size_t round_size, FF round_challenge) + void partially_evaluate(auto& polynomials, size_t round_size, FF round_challenge) { - // after the first round, operate in place on folded_polynomials + // after the first round, operate in place on partially_evaluated_polynomials for (size_t j = 0; j < polynomials.size(); ++j) { for (size_t i = 0; i < round_size; i += 2) { - folded_polynomials[j][i >> 1] = + partially_evaluated_polynomials[j][i >> 1] = polynomials[j][i] + round_challenge * (polynomials[j][i + 1] - polynomials[j][i]); } } diff --git a/cpp/src/barretenberg/honk/sumcheck/sumcheck.test.cpp b/cpp/src/barretenberg/honk/sumcheck/sumcheck.test.cpp index 356ad662b9..f319872b15 100644 --- a/cpp/src/barretenberg/honk/sumcheck/sumcheck.test.cpp +++ b/cpp/src/barretenberg/honk/sumcheck/sumcheck.test.cpp @@ -138,11 +138,7 @@ TEST(Sumcheck, PolynomialNormalization) auto transcript = ProverTranscript::init_empty(); - auto sumcheck = Sumcheck, - ArithmeticRelation, - GrandProductComputationRelation, - GrandProductInitializationRelation>(multivariate_n, transcript); + auto sumcheck = Sumcheck>(multivariate_n, transcript); auto [multivariate_challenge, evaluations] = sumcheck.execute_prover(full_polynomials, {}); @@ -178,7 +174,7 @@ TEST(Sumcheck, PolynomialNormalization) l_2 * full_polynomials[i][2] + l_3 * full_polynomials[i][3] + l_4 * full_polynomials[i][4] + l_5 * full_polynomials[i][5] + l_6 * full_polynomials[i][6] + l_7 * full_polynomials[i][7]; - EXPECT_EQ(hand_computed_value, sumcheck.folded_polynomials[i][0]); + EXPECT_EQ(hand_computed_value, sumcheck.partially_evaluated_polynomials[i][0]); } } @@ -238,11 +234,7 @@ TEST(Sumcheck, Prover) auto transcript = ProverTranscript::init_empty(); - auto sumcheck = Sumcheck, - ArithmeticRelation, - GrandProductComputationRelation, - GrandProductInitializationRelation>(multivariate_n, transcript); + auto sumcheck = Sumcheck>(multivariate_n, transcript); auto [multivariate_challenge, evaluations] = sumcheck.execute_prover(full_polynomials, {}); FF u_0 = multivariate_challenge[0]; @@ -319,21 +311,13 @@ TEST(Sumcheck, ProverAndVerifier) auto prover_transcript = ProverTranscript::init_empty(); - auto sumcheck_prover = Sumcheck, - ArithmeticRelation, - GrandProductComputationRelation, - GrandProductInitializationRelation>(multivariate_n, prover_transcript); + auto sumcheck_prover = Sumcheck>(multivariate_n, prover_transcript); auto prover_output = sumcheck_prover.execute_prover(full_polynomials, relation_parameters); auto verifier_transcript = VerifierTranscript::init_empty(prover_transcript); - auto sumcheck_verifier = Sumcheck, - ArithmeticRelation, - GrandProductComputationRelation, - GrandProductInitializationRelation>(multivariate_n, verifier_transcript); + auto sumcheck_verifier = Sumcheck>(multivariate_n, verifier_transcript); std::optional verifier_output = sumcheck_verifier.execute_verifier(relation_parameters); @@ -401,21 +385,13 @@ TEST(Sumcheck, ProverAndVerifierLonger) auto prover_transcript = ProverTranscript::init_empty(); - auto sumcheck_prover = Sumcheck, - ArithmeticRelation, - GrandProductComputationRelation, - GrandProductInitializationRelation>(multivariate_n, prover_transcript); + auto sumcheck_prover = Sumcheck>(multivariate_n, prover_transcript); auto prover_output = sumcheck_prover.execute_prover(full_polynomials, relation_parameters); auto verifier_transcript = VerifierTranscript::init_empty(prover_transcript); - auto sumcheck_verifier = Sumcheck, - ArithmeticRelation, - GrandProductComputationRelation, - GrandProductInitializationRelation>(multivariate_n, verifier_transcript); + auto sumcheck_verifier = Sumcheck>(multivariate_n, verifier_transcript); std::optional verifier_output = sumcheck_verifier.execute_verifier(relation_parameters); diff --git a/cpp/src/barretenberg/honk/sumcheck/sumcheck_output.hpp b/cpp/src/barretenberg/honk/sumcheck/sumcheck_output.hpp index cfe3dfb09b..c83d85c15a 100644 --- a/cpp/src/barretenberg/honk/sumcheck/sumcheck_output.hpp +++ b/cpp/src/barretenberg/honk/sumcheck/sumcheck_output.hpp @@ -10,16 +10,16 @@ namespace proof_system::honk::sumcheck { */ template struct SumcheckOutput { using FF = typename Flavor::FF; - using PurportedEvaluations = typename Flavor::PurportedEvaluations; + using ClaimedEvaluations = typename Flavor::ClaimedEvaluations; // u = (u_0, ..., u_{d-1}) std::vector challenge_point; // Evaluations in `u` of the polynomials used in Sumcheck - PurportedEvaluations purported_evaluations; + ClaimedEvaluations purported_evaluations; SumcheckOutput() : purported_evaluations(std::array()){}; - SumcheckOutput(const std::vector& _challenge_point, const PurportedEvaluations& _purported_evaluations) + SumcheckOutput(const std::vector& _challenge_point, const ClaimedEvaluations& _purported_evaluations) : challenge_point(_challenge_point) , purported_evaluations(_purported_evaluations){}; diff --git a/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.hpp b/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.hpp index 0aea53047f..4c2fbca313 100644 --- a/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.hpp +++ b/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.hpp @@ -53,26 +53,30 @@ namespace proof_system::honk::sumcheck { @todo TODO(#390): Template only on Flavor? Is it useful to have these decoupled? */ -template class... Relations> class SumcheckRound { +template class SumcheckRound { + + using Relations = typename Flavor::Relations; + using UnivariateTuple = typename Flavor::UnivariateTuple; + using BarycentricUtils = typename Flavor::BarycentricUtils; public: using FF = typename Flavor::FF; template using ExtendedEdges = typename Flavor::template ExtendedEdges; - using PurportedEvaluations = typename Flavor::PurportedEvaluations; + using ClaimedEvaluations = typename Flavor::ClaimedEvaluations; bool round_failed = false; size_t round_size; // a power of 2 - std::tuple...> relations; - static constexpr size_t NUM_RELATIONS = sizeof...(Relations); - static constexpr size_t MAX_RELATION_LENGTH = std::max({ Relations::RELATION_LENGTH... }); + Relations relations; + static constexpr size_t NUM_RELATIONS = Flavor::NUM_RELATIONS; + static constexpr size_t MAX_RELATION_LENGTH = Flavor::MAX_RELATION_LENGTH; FF target_total_sum = 0; // TODO(#224)(Cody): this barycentric stuff should be more built-in? - std::tuple::RELATION_LENGTH, MAX_RELATION_LENGTH>...> barycentric_utils; - std::tuple::RELATION_LENGTH>...> univariate_accumulators; + BarycentricUtils barycentric_utils; + UnivariateTuple univariate_accumulators; std::array relation_evaluations; ExtendedEdges extended_edges; std::array, NUM_RELATIONS> extended_univariates; @@ -81,16 +85,12 @@ template class... Relations> class SumcheckRo BarycentricData barycentric_2_to_max = BarycentricData(); // Prover constructor - SumcheckRound(size_t initial_round_size, auto&& relations) + SumcheckRound(size_t initial_round_size) : round_size(initial_round_size) - , relations(relations) - , barycentric_utils(BarycentricData::RELATION_LENGTH, MAX_RELATION_LENGTH>()...) - , univariate_accumulators(Univariate::RELATION_LENGTH>()...) {} // Verifier constructor - explicit SumcheckRound(auto relations) - : relations(relations) + explicit SumcheckRound() { // FF's default constructor may not initialize to zero (e.g., barretenberg::fr), hence we can't rely on // aggregate initialization of the evaluations array. @@ -218,7 +218,7 @@ template class... Relations> class SumcheckRo * together, with appropriate scaling factors, produces the expected value of the full Honk relation. This value is * checked against the final value of the target total sum, defined as sigma_d. */ - FF compute_full_honk_relation_purported_value(PurportedEvaluations purported_evaluations, + FF compute_full_honk_relation_purported_value(ClaimedEvaluations purported_evaluations, const RelationParameters& relation_parameters, const PowUnivariate& pow_univariate, const FF alpha) @@ -316,7 +316,7 @@ template class... Relations> class SumcheckRo */ template // TODO(#224)(Cody): Input should be an array? - void accumulate_relation_evaluations(PurportedEvaluations purported_evaluations, + void accumulate_relation_evaluations(ClaimedEvaluations purported_evaluations, const RelationParameters& relation_parameters) { std::get(relations).add_full_relation_value_contribution( diff --git a/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.test.cpp b/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.test.cpp index 97fefa6a48..9efdc23677 100644 --- a/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.test.cpp +++ b/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.test.cpp @@ -1,7 +1,4 @@ #include "sumcheck_round.hpp" -#include "relations/arithmetic_relation.hpp" -#include "relations/grand_product_computation_relation.hpp" -#include "relations/grand_product_initialization_relation.hpp" #include "polynomials/univariate.hpp" #include "barretenberg/ecc/curves/bn254/fr.hpp" #include "barretenberg/numeric/random/engine.hpp" @@ -25,7 +22,7 @@ using namespace proof_system::honk::sumcheck; using Flavor = flavor::Standard; using FF = typename Flavor::FF; using ProverPolynomials = typename Flavor::ProverPolynomials; -using PurportedEvaluations = typename Flavor::PurportedEvaluations; +using ClaimedEvaluations = typename Flavor::ClaimedEvaluations; const size_t NUM_POLYNOMIALS = Flavor::NUM_ALL_ENTITIES; const size_t max_relation_length = 5; @@ -80,12 +77,9 @@ static Univariate compute_round_univariate( const FF alpha) { size_t round_size = 1; - auto relations = std::tuple( - ArithmeticRelation(), GrandProductComputationRelation(), GrandProductInitializationRelation()); + // Improvement(Cody): This is ugly? Maye supply some/all of this data through "flavor" class? - auto round = - SumcheckRound( - round_size, relations); + auto round = SumcheckRound(round_size); auto w_l = input_polynomials[0]; auto w_r = input_polynomials[1]; auto w_o = input_polynomials[2]; @@ -187,7 +181,7 @@ static FF compute_full_purported_value(std::array& input_va const RelationParameters& relation_parameters, const FF alpha) { - PurportedEvaluations purported_evaluations; + ClaimedEvaluations purported_evaluations; purported_evaluations.w_l = input_values[0]; purported_evaluations.w_r = input_values[1]; purported_evaluations.w_o = input_values[2]; @@ -206,11 +200,8 @@ static FF compute_full_purported_value(std::array& input_va purported_evaluations.id_3 = input_values[15]; purported_evaluations.lagrange_first = input_values[16]; purported_evaluations.lagrange_last = input_values[17]; - auto relations = std::tuple( - ArithmeticRelation(), GrandProductComputationRelation(), GrandProductInitializationRelation()); - auto round = - SumcheckRound( - relations); + + auto round = SumcheckRound(); PowUnivariate pow_univariate(1); FF full_purported_value = round.compute_full_honk_relation_purported_value( purported_evaluations, relation_parameters, pow_univariate, alpha); diff --git a/cpp/src/barretenberg/proof_system/flavor/flavor.hpp b/cpp/src/barretenberg/proof_system/flavor/flavor.hpp index 047102b599..d42e3c6c9a 100644 --- a/cpp/src/barretenberg/proof_system/flavor/flavor.hpp +++ b/cpp/src/barretenberg/proof_system/flavor/flavor.hpp @@ -57,7 +57,6 @@ * empty slots. This is a conscious choice to limit complexity. Note that there is very little memory cost here since * the DataType size in that case is small. * - * @todo TODO(#394): Folded polynomials should use polynomial class. * @todo TODO(#395): Getters should return arrays? * @todo TODO(#396): Access specifiers? * @todo TODO(#397): Use more handle types? @@ -68,9 +67,11 @@ #include #include #include +#include "barretenberg/honk/sumcheck/polynomials/barycentric_data.hpp" #include "barretenberg/srs/reference_string/reference_string.hpp" #include "barretenberg/polynomials/evaluation_domain.hpp" #include "barretenberg/proof_system/types/composer_type.hpp" +#include "barretenberg/honk/sumcheck/polynomials/univariate.hpp" namespace proof_system::honk::flavor { @@ -214,6 +215,52 @@ class AllEntities_ : public Entities_ { }; }; +/** + * @brief Recursive utility function to find max RELATION_LENGTH over tuple of Relations + * + */ +template static constexpr size_t get_max_relation_length() +{ + if constexpr (Index >= std::tuple_size::value) { + return 0; // Return 0 when reach end of the tuple + } else { + constexpr size_t current_length = std::tuple_element::type::RELATION_LENGTH; + constexpr size_t next_length = get_max_relation_length(); + return (current_length > next_length) ? current_length : next_length; + } +} + +/** + * @brief Recursive utility function to construct tuple of Univariates of length RELATION_LENGTH + * + */ +template static constexpr auto create_univariate_tuple() +{ + if constexpr (Index >= std::tuple_size::value) { + return std::tuple<>{}; // Return empty when reach end of the tuple + } else { + using UnivariateType = sumcheck::Univariate::RELATION_LENGTH>; + return std::tuple_cat(std::tuple{}, create_univariate_tuple()); + } +} + +/** + * @brief Recursive helper function to construct BarycentricData to extend each Relation in a tuple + * + */ +template +static constexpr auto create_barycentric_utils() +{ + if constexpr (Index >= std::tuple_size::value) { + return std::tuple<>{}; // Return empty when reach end of the tuple + } else { + constexpr size_t relation_length = std::tuple_element_t::RELATION_LENGTH; + using BarycentricType = sumcheck::BarycentricData; + return std::tuple_cat(std::tuple{}, + create_barycentric_utils()); + } +} + } // namespace proof_system::honk::flavor // Forward declare honk flavors From 0e0b04da9f8b56ae9e82369859f589c19c688e7b Mon Sep 17 00:00:00 2001 From: Charlie Lye Date: Tue, 23 May 2023 23:23:26 +0000 Subject: [PATCH 08/29] working. but cant compute pk independently :/ --- .../barretenberg/common/slab_allocator.cpp | 8 ++-- .../barretenberg/common/slab_allocator.hpp | 47 +++++++++++++------ .../dsl/acir_proofs/acir_composer.cpp | 41 +++++++++------- .../dsl/acir_proofs/acir_composer.hpp | 2 + .../barretenberg/dsl/acir_proofs/c_bind.cpp | 5 +- .../barretenberg/examples/simple/simple.cpp | 1 + .../plonk/composer/composer_base.cpp | 7 ++- .../plonk/composer/ultra_composer.cpp | 12 +++++ .../pippenger_reference_string.hpp | 12 ++--- .../barretenberg/transcript/transcript.cpp | 5 +- ts/src/examples/simple.rawtest.ts | 1 + ts/src/main.ts | 9 ++-- 12 files changed, 99 insertions(+), 51 deletions(-) diff --git a/cpp/src/barretenberg/common/slab_allocator.cpp b/cpp/src/barretenberg/common/slab_allocator.cpp index ec04b5b80d..506a10ab2b 100644 --- a/cpp/src/barretenberg/common/slab_allocator.cpp +++ b/cpp/src/barretenberg/common/slab_allocator.cpp @@ -82,7 +82,7 @@ void SlabAllocator::init(size_t circuit_size_hint) // Think max I saw was 65 extra related to pippenger runtime state. Likely related to the machine having 64 cores. // Strange things may happen here if double to 128 cores, might request 129 extra? size_t overalloc = 128; - size_t tiny_size = 4 * circuit_size_hint; + size_t tiny_size = 4 * (circuit_size_hint + overalloc); size_t small_size = 32 * (circuit_size_hint + overalloc); size_t large_size = small_size * 4; @@ -143,7 +143,7 @@ std::shared_ptr SlabAllocator::get(size_t req_size) memory_store.erase(it); } - // info("Reusing memory slab of size: ", size, " for requested ", req_size, " total: ", get_total_size()); + info("Reusing memory slab of size: ", size, " for requested ", req_size, " total: ", get_total_size()); return std::shared_ptr(ptr, [this, size](void* p) { if (allocator_destroyed) { @@ -155,10 +155,10 @@ std::shared_ptr SlabAllocator::get(size_t req_size) } if (req_size % 32 == 0) { - // info("Allocating unmanaged memory slab of size: ", req_size); + info("Allocating unmanaged memory slab of size: ", req_size); return std::shared_ptr(aligned_alloc(32, req_size), aligned_free); } else { - // info("Allocating unaligned unmanaged memory slab of size: ", req_size); + info("Allocating unaligned unmanaged memory slab of size: ", req_size); return std::shared_ptr(malloc(req_size), free); } } diff --git a/cpp/src/barretenberg/common/slab_allocator.hpp b/cpp/src/barretenberg/common/slab_allocator.hpp index 13ae70292e..b64427ed54 100644 --- a/cpp/src/barretenberg/common/slab_allocator.hpp +++ b/cpp/src/barretenberg/common/slab_allocator.hpp @@ -48,36 +48,53 @@ template class ContainerSlabAllocator { using const_pointer = const T*; using size_type = std::size_t; + // ContainerSlabAllocator() = default; + // ContainerSlabAllocator(ContainerSlabAllocator const&) = delete; + // ContainerSlabAllocator& operator=(ContainerSlabAllocator const&) = delete; + + // // Move constructor + // ContainerSlabAllocator(ContainerSlabAllocator&& other) noexcept + // : slab(std::move(other.slab)) + // { + // other.slab = nullptr; + // } + + // // Move assignment operator + // ContainerSlabAllocator& operator=(ContainerSlabAllocator&& other) noexcept + // { + // if (this != &other) { + // slab = std::move(other.slab); + // other.slab = nullptr; + // } + // return *this; + // } + template struct rebind { using other = ContainerSlabAllocator; }; pointer allocate(size_type n) { + return reinterpret_cast(get_mem_slab_raw(n * sizeof(T))); // info("ContainerSlabAllocator allocating: ", n * sizeof(T)); - std::shared_ptr ptr = get_mem_slab(n * sizeof(T)); - slab = ptr; // Keep a copy of the shared_ptr so the memory is not freed. - return static_cast(ptr.get()); + // std::shared_ptr ptr = get_mem_slab(n * sizeof(T)); + // slab = ptr; // Keep a copy of the shared_ptr so the memory is not freed. + // return static_cast(ptr.get()); } void deallocate(pointer p, size_type /*unused*/) { - ASSERT(p == slab.get()); - slab.reset(); + free_mem_slab_raw(p); + // ASSERT(p == slab.get()); + // slab.reset(); } - friend bool operator==(const ContainerSlabAllocator& lhs, const ContainerSlabAllocator& rhs) - { - return lhs.slab == rhs.slab; - } + friend bool operator==(const ContainerSlabAllocator&, const ContainerSlabAllocator&) { return true; } - friend bool operator!=(const ContainerSlabAllocator& lhs, const ContainerSlabAllocator& rhs) - { - return !(lhs == rhs); - } + friend bool operator!=(const ContainerSlabAllocator&, const ContainerSlabAllocator&) { return false; } - private: - std::shared_ptr slab; + // private: + // std::shared_ptr slab; }; } // namespace barretenberg \ No newline at end of file diff --git a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp index 12c154851e..334b31af7a 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp @@ -12,6 +12,7 @@ namespace acir_proofs { AcirComposer::AcirComposer(std::shared_ptr const& crs_factory) : crs_factory_(crs_factory) + , composer_(0, 0, 0) {} void AcirComposer::init_proving_key(acir_format::acir_format& constraint_system, size_t size_hint) @@ -24,16 +25,22 @@ void AcirComposer::init_proving_key(acir_format::acir_format& constraint_system, constraint_system.constraints.shrink_to_fit(); exact_circuit_size_ = composer.get_num_gates(); + info("**** EXACT ", exact_circuit_size_); total_circuit_size_ = composer.get_total_circuit_size(); + info("**** TOTAL ", total_circuit_size_); + // Exact or total fed in here? + circuit_subgroup_size_ = composer.get_circuit_subgroup_size(exact_circuit_size_); + info("**** SUBGROUP ", circuit_subgroup_size_); proving_key_ = composer.compute_proving_key(); } std::vector AcirComposer::create_proof(acir_format::acir_format& constraint_system, acir_format::WitnessVector& witness) { - acir_format::Composer composer(proving_key_, nullptr, total_circuit_size_); + // composer_ = acir_format::Composer(proving_key_, nullptr, circuit_subgroup_size_); + composer_ = acir_format::Composer(crs_factory_, 1 << 19); - create_circuit_with_witness(composer, constraint_system, witness); + create_circuit_with_witness(composer_, constraint_system, witness); // We are done with the constraint system at this point, and we need the memory slab back. constraint_system.constraints.clear(); @@ -41,31 +48,31 @@ std::vector AcirComposer::create_proof(acir_format::acir_format& constr witness.clear(); witness.shrink_to_fit(); - auto prover = composer.create_ultra_with_keccak_prover(); - return prover.construct_proof().proof_data; + auto prover = composer_.create_ultra_with_keccak_prover(); + auto proof = prover.construct_proof().proof_data; + return proof; } void AcirComposer::init_verification_key() { - if (!proving_key_) { - throw_or_abort("init_proving_key must be called first."); - } - // acir_format::Composer composer(proving_key_, nullptr); - // verification_key_ = composer.compute_verification_key(); + composer_.compute_verification_key(); + // if (!proving_key_) { + // throw_or_abort("init_proving_key must be called first."); + // } + // // acir_format::Composer composer(proving_key_, nullptr); + // // verification_key_ = composer.compute_verification_key(); - verification_key_ = - acir_format::Composer::compute_verification_key_base(proving_key_, crs_factory_->get_verifier_crs()); + // verification_key_ = + // acir_format::Composer::compute_verification_key_base(proving_key_, crs_factory_->get_verifier_crs()); - // The composer_type has not yet been set. We need to set the composer_type for when we later read in and - // construct the verification key so that we have the correct polynomial manifest - verification_key_->composer_type = proof_system::ComposerType::PLOOKUP; + // // The composer_type has not yet been set. We need to set the composer_type for when we later read in and + // // construct the verification key so that we have the correct polynomial manifest + // verification_key_->composer_type = proof_system::ComposerType::PLOOKUP; } bool AcirComposer::verify_proof(std::vector const& proof) { - acir_format::Composer composer(proving_key_, verification_key_); - composer.create_ultra_with_keccak_verifier(); - auto verifier = composer.create_ultra_with_keccak_verifier(); + auto verifier = composer_.create_ultra_with_keccak_verifier(); return verifier.verify_proof({ proof }); } diff --git a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.hpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.hpp index 454989bb00..1a608df4c9 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.hpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.hpp @@ -25,8 +25,10 @@ class AcirComposer { private: std::shared_ptr crs_factory_; + acir_format::Composer composer_; size_t exact_circuit_size_; size_t total_circuit_size_; + size_t circuit_subgroup_size_; std::shared_ptr proving_key_; std::shared_ptr verification_key_; }; diff --git a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp index 943e331bc4..24eff02962 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp @@ -9,10 +9,11 @@ #include "barretenberg/dsl/acir_format/acir_format.hpp" #include "barretenberg/srs/reference_string/pippenger_reference_string.hpp" -WASM_EXPORT void acir_new_acir_composer(in_ptr pippenger, uint8_t const* g2x, out_ptr out) +WASM_EXPORT void acir_new_acir_composer(in_ptr pippenger, uint8_t const* g2x_buf, out_ptr out) { + auto g2x = from_buffer>(g2x_buf); auto crs_factory = std::make_shared( - reinterpret_cast(*pippenger), g2x); + reinterpret_cast(*pippenger), g2x.data()); *out = new acir_proofs::AcirComposer(crs_factory); } diff --git a/cpp/src/barretenberg/examples/simple/simple.cpp b/cpp/src/barretenberg/examples/simple/simple.cpp index f7d4dffa9f..0ebe62d4a3 100644 --- a/cpp/src/barretenberg/examples/simple/simple.cpp +++ b/cpp/src/barretenberg/examples/simple/simple.cpp @@ -21,6 +21,7 @@ void build_circuit(Composer& composer) Composer* create_composer(std::shared_ptr const& crs_factory) { + info(crs_factory->get_verifier_crs()->get_g2x()); // WARNING: Size hint is essential to perform 512k circuits! auto composer = std::make_unique(crs_factory, CIRCUIT_SIZE); info("building circuit..."); diff --git a/cpp/src/barretenberg/plonk/composer/composer_base.cpp b/cpp/src/barretenberg/plonk/composer/composer_base.cpp index 53a0745f0c..5bdfc65bdc 100644 --- a/cpp/src/barretenberg/plonk/composer/composer_base.cpp +++ b/cpp/src/barretenberg/plonk/composer/composer_base.cpp @@ -362,9 +362,9 @@ template void ComposerBase::compute_witness_base(const si if (computed_witness) { return; } - const size_t total_num_gates = std::max(minimum_circuit_size, num_gates + public_inputs.size()); const size_t subgroup_size = get_circuit_subgroup_size(total_num_gates + NUM_RESERVED_GATES); + info("CWB CHECKPOINT ", subgroup_size, " ", total_num_gates); // Note: randomness is added to 3 of the last 4 positions in plonk/proof_system/prover/prover.cpp // ProverBase::execute_preamble_round(). @@ -378,11 +378,13 @@ template void ComposerBase::compute_witness_base(const si w_4.emplace_back(zero_idx); } } + info("CWB CHECKPOINT"); polynomial w_1_lagrange = polynomial(subgroup_size); polynomial w_2_lagrange = polynomial(subgroup_size); polynomial w_3_lagrange = polynomial(subgroup_size); polynomial w_4_lagrange; + info("CWB CHECKPOINT"); if (program_width > 3) w_4_lagrange = polynomial(subgroup_size); @@ -397,6 +399,7 @@ template void ComposerBase::compute_witness_base(const si fr::__copy(fr::zero(), w_4_lagrange[i]); } + info("CWB CHECKPOINT ", public_inputs.size()); // Assign the variable values (which are pointed-to by the `w_` wires) to the wire witness polynomials `poly_w_`, // shifted to make room for the public inputs at the beginning. for (size_t i = public_inputs.size(); i < subgroup_size; ++i) { @@ -407,6 +410,7 @@ template void ComposerBase::compute_witness_base(const si fr::__copy(get_variable(w_4[i - public_inputs.size()]), w_4_lagrange.at(i)); } + info("CWB CHECKPOINT"); circuit_proving_key->polynomial_store.put("w_1_lagrange", std::move(w_1_lagrange)); circuit_proving_key->polynomial_store.put("w_2_lagrange", std::move(w_2_lagrange)); circuit_proving_key->polynomial_store.put("w_3_lagrange", std::move(w_3_lagrange)); @@ -414,6 +418,7 @@ template void ComposerBase::compute_witness_base(const si circuit_proving_key->polynomial_store.put("w_4_lagrange", std::move(w_4_lagrange)); } + info("CWB CHECKPOINT"); computed_witness = true; } diff --git a/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp b/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp index ce0f4eac7b..fe2eead873 100644 --- a/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp +++ b/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp @@ -86,7 +86,10 @@ UltraComposer::UltraComposer(std::shared_ptr const& p_key, size_t size_hint) : ComposerBase(p_key, v_key, UltraSelectors::NUM, size_hint, ultra_selector_properties()) { + info("***** RESERVING ", size_hint * sizeof(uint32_t)); + w_l.reserve(size_hint); w_r.reserve(size_hint); + w_o.reserve(size_hint); w_4.reserve(size_hint); zero_idx = put_constant_variable(0); tau.insert({ DUMMY_TAG, DUMMY_TAG }); @@ -698,6 +701,7 @@ void UltraComposer::compute_witness() return; } + info("MEM CHECKPOINT"); size_t tables_size = 0; size_t lookups_size = 0; for (const auto& table : lookup_tables) { @@ -705,6 +709,7 @@ void UltraComposer::compute_witness() lookups_size += table.lookup_gates.size(); } + info("MEM CHECKPOINT"); const size_t filled_gates = num_gates + public_inputs.size(); const size_t total_num_gates = std::max(filled_gates, tables_size + lookups_size); @@ -720,6 +725,7 @@ void UltraComposer::compute_witness() w_4.emplace_back(zero_idx); } + info("MEM CHECKPOINT"); // Create and store polynomials which interpolate the wire values (variable values pointed-to by the `w_`s). ComposerBase::compute_witness_base(total_num_gates); @@ -729,6 +735,7 @@ void UltraComposer::compute_witness() polynomial s_4(subgroup_size); polynomial z_lookup(subgroup_size + 1); // Only instantiated in this function; nothing assigned. + info("MEM CHECKPOINT"); // Save space for adding random scalars in the s polynomial later. // The subtracted 1 allows us to insert a `1` at the end, to ensure the evaluations (and hence coefficients) aren't // all 0. @@ -741,6 +748,7 @@ void UltraComposer::compute_witness() s_4[i] = 0; } + info("MEM CHECKPOINT"); for (auto& table : lookup_tables) { const fr table_index(table.table_index); auto& lookup_gates = table.lookup_gates; @@ -770,6 +778,7 @@ void UltraComposer::compute_witness() } } + info("MEM CHECKPOINT"); #ifdef NO_TBB std::sort(lookup_gates.begin(), lookup_gates.end()); #else @@ -786,6 +795,7 @@ void UltraComposer::compute_witness() } } + info("MEM CHECKPOINT"); // Initialise the `s_randomness` positions in the s polynomials with 0. // These will be the positions where we will be adding random scalars to add zero knowledge // to plookup (search for `Blinding` in plonk/proof_system/widgets/random_widgets/plookup_widget_impl.hpp @@ -798,11 +808,13 @@ void UltraComposer::compute_witness() ++count; } + info("MEM CHECKPOINT"); circuit_proving_key->polynomial_store.put("s_1_lagrange", std::move(s_1)); circuit_proving_key->polynomial_store.put("s_2_lagrange", std::move(s_2)); circuit_proving_key->polynomial_store.put("s_3_lagrange", std::move(s_3)); circuit_proving_key->polynomial_store.put("s_4_lagrange", std::move(s_4)); + info("MEM CHECKPOINT"); computed_witness = true; } diff --git a/cpp/src/barretenberg/srs/reference_string/pippenger_reference_string.hpp b/cpp/src/barretenberg/srs/reference_string/pippenger_reference_string.hpp index 53c6867018..087b9f5956 100644 --- a/cpp/src/barretenberg/srs/reference_string/pippenger_reference_string.hpp +++ b/cpp/src/barretenberg/srs/reference_string/pippenger_reference_string.hpp @@ -30,8 +30,9 @@ class PippengerReferenceStringFactory : public ReferenceStringFactory { public: PippengerReferenceStringFactory(scalar_multiplication::Pippenger* pippenger, uint8_t const* g2x) : pippenger_(pippenger) - , g2x_(g2x) - {} + { + verifier_crs_ = std::make_shared(g2x); + } PippengerReferenceStringFactory(PippengerReferenceStringFactory&& other) = default; @@ -41,14 +42,11 @@ class PippengerReferenceStringFactory : public ReferenceStringFactory { return std::make_shared(pippenger_); } - std::shared_ptr get_verifier_crs() override - { - return std::make_shared(g2x_); - } + std::shared_ptr get_verifier_crs() override { return verifier_crs_; } private: + std::shared_ptr verifier_crs_; scalar_multiplication::Pippenger* pippenger_; - uint8_t const* g2x_; }; } // namespace proof_system diff --git a/cpp/src/barretenberg/transcript/transcript.cpp b/cpp/src/barretenberg/transcript/transcript.cpp index 8f597c454b..1371a08eac 100644 --- a/cpp/src/barretenberg/transcript/transcript.cpp +++ b/cpp/src/barretenberg/transcript/transcript.cpp @@ -94,7 +94,10 @@ Transcript::Transcript(const std::vector& input_transcript, } // Check that the total required size is equal to the size of the input_transcript if (totalRequiredSize != input_transcript.size()) - throw_or_abort("Serialized transcript does not contain the required number of bytes"); + throw_or_abort(format("Serialized transcript does not contain the required number of bytes: ", + totalRequiredSize, + " != ", + input_transcript.size())); for (size_t i = 0; i < num_rounds; ++i) { for (auto manifest_element : input_manifest.get_round_manifest(i).elements) { diff --git a/ts/src/examples/simple.rawtest.ts b/ts/src/examples/simple.rawtest.ts index 547d497d26..908287c4e4 100644 --- a/ts/src/examples/simple.rawtest.ts +++ b/ts/src/examples/simple.rawtest.ts @@ -20,6 +20,7 @@ async function main() { // Plus 1 needed! const crs = await Crs.new(CIRCUIT_SIZE + 1); const pippengerPtr = await api.eccNewPippenger(crs.getG1Data(), crs.numPoints); + debug(Buffer.from(crs.getG2Data()).toString('hex')); for (let i = 0; i < 10; ++i) { debug(`iteration ${i} starting...`); diff --git a/ts/src/main.ts b/ts/src/main.ts index 20b624f603..3d1e3b8a8f 100755 --- a/ts/src/main.ts +++ b/ts/src/main.ts @@ -47,12 +47,12 @@ export async function main() { const acirComposer = await api.acirNewAcirComposer(pippengerPtr, crs.getG2Data()); - debug('initing proving key...'); + // debug('initing proving key...'); const bytecode = getBytecode(); - await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), CIRCUIT_SIZE); + // await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), CIRCUIT_SIZE); - const exactCircuitSize = await api.acirGetExactCircuitSize(acirComposer); - debug(`circuit size: ${exactCircuitSize}`); + // const exactCircuitSize = await api.acirGetExactCircuitSize(acirComposer); + // debug(`circuit size: ${exactCircuitSize}`); debug('creating proof...'); const witness = getWitness(); @@ -61,6 +61,7 @@ export async function main() { debug('initing verification key...'); await api.acirInitVerificationKey(acirComposer); + debug('verifying...'); const verified = await api.acirVerifyProof(acirComposer, proof); debug(`verified: ${verified}`); From b2635b6fc386cd7c73c8258101ed594a269e38b9 Mon Sep 17 00:00:00 2001 From: Charlie Lye Date: Tue, 23 May 2023 23:35:10 +0000 Subject: [PATCH 09/29] Fixed. --- .../barretenberg/common/slab_allocator.cpp | 10 +++++++--- .../dsl/acir_proofs/acir_composer.cpp | 20 +++---------------- .../plonk/composer/composer_base.cpp | 6 ------ .../plonk/composer/ultra_composer.cpp | 10 ---------- ts/src/main.ts | 9 ++++----- 5 files changed, 14 insertions(+), 41 deletions(-) diff --git a/cpp/src/barretenberg/common/slab_allocator.cpp b/cpp/src/barretenberg/common/slab_allocator.cpp index 506a10ab2b..1fc3d4d4b0 100644 --- a/cpp/src/barretenberg/common/slab_allocator.cpp +++ b/cpp/src/barretenberg/common/slab_allocator.cpp @@ -143,7 +143,7 @@ std::shared_ptr SlabAllocator::get(size_t req_size) memory_store.erase(it); } - info("Reusing memory slab of size: ", size, " for requested ", req_size, " total: ", get_total_size()); + // info("Reusing memory slab of size: ", size, " for requested ", req_size, " total: ", get_total_size()); return std::shared_ptr(ptr, [this, size](void* p) { if (allocator_destroyed) { @@ -155,10 +155,10 @@ std::shared_ptr SlabAllocator::get(size_t req_size) } if (req_size % 32 == 0) { - info("Allocating unmanaged memory slab of size: ", req_size); + // info("Allocating unmanaged memory slab of size: ", req_size); return std::shared_ptr(aligned_alloc(32, req_size), aligned_free); } else { - info("Allocating unaligned unmanaged memory slab of size: ", req_size); + // info("Allocating unaligned unmanaged memory slab of size: ", req_size); return std::shared_ptr(malloc(req_size), free); } } @@ -207,6 +207,10 @@ void* get_mem_slab_raw(size_t size) void free_mem_slab_raw(void* p) { + if (allocator_destroyed) { + aligned_free(p); + return; + } manual_slabs.erase(p); } } // namespace barretenberg diff --git a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp index 334b31af7a..0d33d32892 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp @@ -25,20 +25,18 @@ void AcirComposer::init_proving_key(acir_format::acir_format& constraint_system, constraint_system.constraints.shrink_to_fit(); exact_circuit_size_ = composer.get_num_gates(); - info("**** EXACT ", exact_circuit_size_); total_circuit_size_ = composer.get_total_circuit_size(); - info("**** TOTAL ", total_circuit_size_); // Exact or total fed in here? circuit_subgroup_size_ = composer.get_circuit_subgroup_size(exact_circuit_size_); - info("**** SUBGROUP ", circuit_subgroup_size_); proving_key_ = composer.compute_proving_key(); } std::vector AcirComposer::create_proof(acir_format::acir_format& constraint_system, acir_format::WitnessVector& witness) { - // composer_ = acir_format::Composer(proving_key_, nullptr, circuit_subgroup_size_); - composer_ = acir_format::Composer(crs_factory_, 1 << 19); + composer_ = acir_format::Composer(proving_key_, nullptr, circuit_subgroup_size_); + // You can't produce the verification key unless you manually set the crs. Which seems like a bug. + composer_.crs_factory_ = crs_factory_; create_circuit_with_witness(composer_, constraint_system, witness); @@ -56,18 +54,6 @@ std::vector AcirComposer::create_proof(acir_format::acir_format& constr void AcirComposer::init_verification_key() { composer_.compute_verification_key(); - // if (!proving_key_) { - // throw_or_abort("init_proving_key must be called first."); - // } - // // acir_format::Composer composer(proving_key_, nullptr); - // // verification_key_ = composer.compute_verification_key(); - - // verification_key_ = - // acir_format::Composer::compute_verification_key_base(proving_key_, crs_factory_->get_verifier_crs()); - - // // The composer_type has not yet been set. We need to set the composer_type for when we later read in and - // // construct the verification key so that we have the correct polynomial manifest - // verification_key_->composer_type = proof_system::ComposerType::PLOOKUP; } bool AcirComposer::verify_proof(std::vector const& proof) diff --git a/cpp/src/barretenberg/plonk/composer/composer_base.cpp b/cpp/src/barretenberg/plonk/composer/composer_base.cpp index 5bdfc65bdc..b4fdb7b130 100644 --- a/cpp/src/barretenberg/plonk/composer/composer_base.cpp +++ b/cpp/src/barretenberg/plonk/composer/composer_base.cpp @@ -364,7 +364,6 @@ template void ComposerBase::compute_witness_base(const si } const size_t total_num_gates = std::max(minimum_circuit_size, num_gates + public_inputs.size()); const size_t subgroup_size = get_circuit_subgroup_size(total_num_gates + NUM_RESERVED_GATES); - info("CWB CHECKPOINT ", subgroup_size, " ", total_num_gates); // Note: randomness is added to 3 of the last 4 positions in plonk/proof_system/prover/prover.cpp // ProverBase::execute_preamble_round(). @@ -378,13 +377,11 @@ template void ComposerBase::compute_witness_base(const si w_4.emplace_back(zero_idx); } } - info("CWB CHECKPOINT"); polynomial w_1_lagrange = polynomial(subgroup_size); polynomial w_2_lagrange = polynomial(subgroup_size); polynomial w_3_lagrange = polynomial(subgroup_size); polynomial w_4_lagrange; - info("CWB CHECKPOINT"); if (program_width > 3) w_4_lagrange = polynomial(subgroup_size); @@ -399,7 +396,6 @@ template void ComposerBase::compute_witness_base(const si fr::__copy(fr::zero(), w_4_lagrange[i]); } - info("CWB CHECKPOINT ", public_inputs.size()); // Assign the variable values (which are pointed-to by the `w_` wires) to the wire witness polynomials `poly_w_`, // shifted to make room for the public inputs at the beginning. for (size_t i = public_inputs.size(); i < subgroup_size; ++i) { @@ -410,7 +406,6 @@ template void ComposerBase::compute_witness_base(const si fr::__copy(get_variable(w_4[i - public_inputs.size()]), w_4_lagrange.at(i)); } - info("CWB CHECKPOINT"); circuit_proving_key->polynomial_store.put("w_1_lagrange", std::move(w_1_lagrange)); circuit_proving_key->polynomial_store.put("w_2_lagrange", std::move(w_2_lagrange)); circuit_proving_key->polynomial_store.put("w_3_lagrange", std::move(w_3_lagrange)); @@ -418,7 +413,6 @@ template void ComposerBase::compute_witness_base(const si circuit_proving_key->polynomial_store.put("w_4_lagrange", std::move(w_4_lagrange)); } - info("CWB CHECKPOINT"); computed_witness = true; } diff --git a/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp b/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp index fe2eead873..bf13074fdf 100644 --- a/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp +++ b/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp @@ -86,7 +86,6 @@ UltraComposer::UltraComposer(std::shared_ptr const& p_key, size_t size_hint) : ComposerBase(p_key, v_key, UltraSelectors::NUM, size_hint, ultra_selector_properties()) { - info("***** RESERVING ", size_hint * sizeof(uint32_t)); w_l.reserve(size_hint); w_r.reserve(size_hint); w_o.reserve(size_hint); @@ -701,7 +700,6 @@ void UltraComposer::compute_witness() return; } - info("MEM CHECKPOINT"); size_t tables_size = 0; size_t lookups_size = 0; for (const auto& table : lookup_tables) { @@ -709,7 +707,6 @@ void UltraComposer::compute_witness() lookups_size += table.lookup_gates.size(); } - info("MEM CHECKPOINT"); const size_t filled_gates = num_gates + public_inputs.size(); const size_t total_num_gates = std::max(filled_gates, tables_size + lookups_size); @@ -725,7 +722,6 @@ void UltraComposer::compute_witness() w_4.emplace_back(zero_idx); } - info("MEM CHECKPOINT"); // Create and store polynomials which interpolate the wire values (variable values pointed-to by the `w_`s). ComposerBase::compute_witness_base(total_num_gates); @@ -735,7 +731,6 @@ void UltraComposer::compute_witness() polynomial s_4(subgroup_size); polynomial z_lookup(subgroup_size + 1); // Only instantiated in this function; nothing assigned. - info("MEM CHECKPOINT"); // Save space for adding random scalars in the s polynomial later. // The subtracted 1 allows us to insert a `1` at the end, to ensure the evaluations (and hence coefficients) aren't // all 0. @@ -748,7 +743,6 @@ void UltraComposer::compute_witness() s_4[i] = 0; } - info("MEM CHECKPOINT"); for (auto& table : lookup_tables) { const fr table_index(table.table_index); auto& lookup_gates = table.lookup_gates; @@ -778,7 +772,6 @@ void UltraComposer::compute_witness() } } - info("MEM CHECKPOINT"); #ifdef NO_TBB std::sort(lookup_gates.begin(), lookup_gates.end()); #else @@ -795,7 +788,6 @@ void UltraComposer::compute_witness() } } - info("MEM CHECKPOINT"); // Initialise the `s_randomness` positions in the s polynomials with 0. // These will be the positions where we will be adding random scalars to add zero knowledge // to plookup (search for `Blinding` in plonk/proof_system/widgets/random_widgets/plookup_widget_impl.hpp @@ -808,13 +800,11 @@ void UltraComposer::compute_witness() ++count; } - info("MEM CHECKPOINT"); circuit_proving_key->polynomial_store.put("s_1_lagrange", std::move(s_1)); circuit_proving_key->polynomial_store.put("s_2_lagrange", std::move(s_2)); circuit_proving_key->polynomial_store.put("s_3_lagrange", std::move(s_3)); circuit_proving_key->polynomial_store.put("s_4_lagrange", std::move(s_4)); - info("MEM CHECKPOINT"); computed_witness = true; } diff --git a/ts/src/main.ts b/ts/src/main.ts index 3d1e3b8a8f..20b624f603 100755 --- a/ts/src/main.ts +++ b/ts/src/main.ts @@ -47,12 +47,12 @@ export async function main() { const acirComposer = await api.acirNewAcirComposer(pippengerPtr, crs.getG2Data()); - // debug('initing proving key...'); + debug('initing proving key...'); const bytecode = getBytecode(); - // await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), CIRCUIT_SIZE); + await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), CIRCUIT_SIZE); - // const exactCircuitSize = await api.acirGetExactCircuitSize(acirComposer); - // debug(`circuit size: ${exactCircuitSize}`); + const exactCircuitSize = await api.acirGetExactCircuitSize(acirComposer); + debug(`circuit size: ${exactCircuitSize}`); debug('creating proof...'); const witness = getWitness(); @@ -61,7 +61,6 @@ export async function main() { debug('initing verification key...'); await api.acirInitVerificationKey(acirComposer); - debug('verifying...'); const verified = await api.acirVerifyProof(acirComposer, proof); debug(`verified: ${verified}`); From 2a7e1d0ed850f91d1d9d536d19f1878833417f65 Mon Sep 17 00:00:00 2001 From: Charlie Lye Date: Wed, 24 May 2023 06:35:44 +0000 Subject: [PATCH 10/29] Better key construction separation. --- .../barretenberg/dsl/acir_proofs/acir_composer.cpp | 14 +++++++------- ts/src/main.ts | 14 ++++++++------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp index 0d33d32892..03e04d4612 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp @@ -17,24 +17,24 @@ AcirComposer::AcirComposer(std::shared_ptr void AcirComposer::init_proving_key(acir_format::acir_format& constraint_system, size_t size_hint) { - auto composer = create_circuit(constraint_system, crs_factory_, size_hint); + composer_ = create_circuit(constraint_system, crs_factory_, size_hint); // We are done with the constraint system at this point, and we need the memory slab back. // constraint_system = acir_format::acir_format(); constraint_system.constraints.clear(); constraint_system.constraints.shrink_to_fit(); - exact_circuit_size_ = composer.get_num_gates(); - total_circuit_size_ = composer.get_total_circuit_size(); + exact_circuit_size_ = composer_.get_num_gates(); + total_circuit_size_ = composer_.get_total_circuit_size(); // Exact or total fed in here? - circuit_subgroup_size_ = composer.get_circuit_subgroup_size(exact_circuit_size_); - proving_key_ = composer.compute_proving_key(); + circuit_subgroup_size_ = composer_.get_circuit_subgroup_size(exact_circuit_size_); + proving_key_ = composer_.compute_proving_key(); } std::vector AcirComposer::create_proof(acir_format::acir_format& constraint_system, acir_format::WitnessVector& witness) { - composer_ = acir_format::Composer(proving_key_, nullptr, circuit_subgroup_size_); + composer_ = acir_format::Composer(proving_key_, verification_key_, circuit_subgroup_size_); // You can't produce the verification key unless you manually set the crs. Which seems like a bug. composer_.crs_factory_ = crs_factory_; @@ -53,7 +53,7 @@ std::vector AcirComposer::create_proof(acir_format::acir_format& constr void AcirComposer::init_verification_key() { - composer_.compute_verification_key(); + verification_key_ = composer_.compute_verification_key(); } bool AcirComposer::verify_proof(std::vector const& proof) diff --git a/ts/src/main.ts b/ts/src/main.ts index 20b624f603..1bcf524dc0 100755 --- a/ts/src/main.ts +++ b/ts/src/main.ts @@ -54,15 +54,17 @@ export async function main() { const exactCircuitSize = await api.acirGetExactCircuitSize(acirComposer); debug(`circuit size: ${exactCircuitSize}`); - debug('creating proof...'); - const witness = getWitness(); - const proof = await api.acirCreateProof(acirComposer, new RawBuffer(bytecode), new RawBuffer(witness)); - debug('initing verification key...'); await api.acirInitVerificationKey(acirComposer); - const verified = await api.acirVerifyProof(acirComposer, proof); - debug(`verified: ${verified}`); + for (let i = 0; i < 10; i++) { + debug(`creating proof ${i}...`); + const witness = getWitness(); + const proof = await api.acirCreateProof(acirComposer, new RawBuffer(bytecode), new RawBuffer(witness)); + + const verified = await api.acirVerifyProof(acirComposer, proof); + debug(`verified: ${verified}`); + } debug('test complete.'); } finally { From f108b22c9317381f5abc1515881e2c3014221677 Mon Sep 17 00:00:00 2001 From: Charlie Lye Date: Wed, 24 May 2023 07:23:57 +0000 Subject: [PATCH 11/29] Clean --- .../barretenberg/common/slab_allocator.cpp | 30 ++++++++++---- .../barretenberg/common/slab_allocator.hpp | 41 +++---------------- .../crypto/pedersen_commitment/pedersen.cpp | 22 +++++----- .../crypto/pedersen_hash/pedersen.cpp | 14 +++---- .../barretenberg/examples/simple/simple.cpp | 1 - ts/src/examples/simple.rawtest.ts | 11 ++--- ts/src/examples/simple.test.ts | 12 +++--- ts/src/factory/index.ts | 15 +++++-- ts/src/main.ts | 4 +- 9 files changed, 67 insertions(+), 83 deletions(-) diff --git a/cpp/src/barretenberg/common/slab_allocator.cpp b/cpp/src/barretenberg/common/slab_allocator.cpp index 1fc3d4d4b0..89597d8cce 100644 --- a/cpp/src/barretenberg/common/slab_allocator.cpp +++ b/cpp/src/barretenberg/common/slab_allocator.cpp @@ -5,6 +5,8 @@ #include #include +#define LOGGING 0 + /** * If we can guarantee that all slabs will be released before the allocator is destroyed, we wouldn't need this. * However, there is (and maybe again) cases where a global is holding onto a slab. In such a case you will have @@ -18,10 +20,20 @@ bool allocator_destroyed = false; // Slabs that are being manually managed by the user. std::unordered_map> manual_slabs; +template inline void dbg_info(Args... args) +{ +#if LOGGING == 1 + info(args...); +#else + // Suppress warning. + (void)(sizeof...(args)); +#endif +} + /** - * Allows preallocating memory slabs sized to serve the fact that these slabs of memory follow certain sizing patterns - * and numbers based on prover system type and circuit size. Without the slab allocator, memory fragmentation prevents - * proof construction when approaching memory space limits (4GB in WASM). + * Allows preallocating memory slabs sized to serve the fact that these slabs of memory follow certain sizing + * patterns and numbers based on prover system type and circuit size. Without the slab allocator, memory + * fragmentation prevents proof construction when approaching memory space limits (4GB in WASM). * * If no circuit_size_hint is given to the constructor, it behaves as a standard memory allocator. */ @@ -72,7 +84,7 @@ void SlabAllocator::init(size_t circuit_size_hint) } memory_store.clear(); - // info("slab allocator initing for size: ", circuit_size_hint); + dbg_info("slab allocator initing for size: ", circuit_size_hint); if (circuit_size_hint == 0ULL) { return; @@ -120,7 +132,7 @@ void SlabAllocator::init(size_t circuit_size_hint) for (size_t i = 0; i < e.second; ++i) { auto size = e.first; memory_store[size].push_back(aligned_alloc(32, size)); - // info("Allocated memory slab of size: ", size, " total: ", get_total_size()); + dbg_info("Allocated memory slab of size: ", size, " total: ", get_total_size()); } } } @@ -143,7 +155,7 @@ std::shared_ptr SlabAllocator::get(size_t req_size) memory_store.erase(it); } - // info("Reusing memory slab of size: ", size, " for requested ", req_size, " total: ", get_total_size()); + dbg_info("Reusing memory slab of size: ", size, " for requested ", req_size, " total: ", get_total_size()); return std::shared_ptr(ptr, [this, size](void* p) { if (allocator_destroyed) { @@ -155,10 +167,10 @@ std::shared_ptr SlabAllocator::get(size_t req_size) } if (req_size % 32 == 0) { - // info("Allocating unmanaged memory slab of size: ", req_size); + dbg_info("Allocating unmanaged memory slab of size: ", req_size); return std::shared_ptr(aligned_alloc(32, req_size), aligned_free); } else { - // info("Allocating unaligned unmanaged memory slab of size: ", req_size); + dbg_info("Allocating unaligned unmanaged memory slab of size: ", req_size); return std::shared_ptr(malloc(req_size), free); } } @@ -176,7 +188,7 @@ void SlabAllocator::release(void* ptr, size_t size) std::unique_lock lock(memory_store_mutex); #endif memory_store[size].push_back(ptr); - // info("Pooled poly memory of size: ", size, " total: ", get_total_size()); + dbg_info("Pooled poly memory of size: ", size, " total: ", get_total_size()); } SlabAllocator allocator; diff --git a/cpp/src/barretenberg/common/slab_allocator.hpp b/cpp/src/barretenberg/common/slab_allocator.hpp index b64427ed54..2db615b00b 100644 --- a/cpp/src/barretenberg/common/slab_allocator.hpp +++ b/cpp/src/barretenberg/common/slab_allocator.hpp @@ -34,13 +34,16 @@ void init_slab_allocator(size_t circuit_size); std::shared_ptr get_mem_slab(size_t size); /** - * Sometimes you want a raw pointer to slab so you can manage when it's release manually (e.g. c_binds). + * Sometimes you want a raw pointer to a slab so you can manage when it's released manually (e.g. c_binds, containers). * This still gets a slab with a shared_ptr, but holds the shared_ptr internally until free_mem_slab_raw is called. */ void* get_mem_slab_raw(size_t size); void free_mem_slab_raw(void*); +/** + * Allocator for containers such as std::vector. Makes them leverage the underlying slab allocator where possible. + */ template class ContainerSlabAllocator { public: using value_type = T; @@ -48,53 +51,21 @@ template class ContainerSlabAllocator { using const_pointer = const T*; using size_type = std::size_t; - // ContainerSlabAllocator() = default; - // ContainerSlabAllocator(ContainerSlabAllocator const&) = delete; - // ContainerSlabAllocator& operator=(ContainerSlabAllocator const&) = delete; - - // // Move constructor - // ContainerSlabAllocator(ContainerSlabAllocator&& other) noexcept - // : slab(std::move(other.slab)) - // { - // other.slab = nullptr; - // } - - // // Move assignment operator - // ContainerSlabAllocator& operator=(ContainerSlabAllocator&& other) noexcept - // { - // if (this != &other) { - // slab = std::move(other.slab); - // other.slab = nullptr; - // } - // return *this; - // } - template struct rebind { using other = ContainerSlabAllocator; }; pointer allocate(size_type n) { - return reinterpret_cast(get_mem_slab_raw(n * sizeof(T))); // info("ContainerSlabAllocator allocating: ", n * sizeof(T)); - // std::shared_ptr ptr = get_mem_slab(n * sizeof(T)); - // slab = ptr; // Keep a copy of the shared_ptr so the memory is not freed. - // return static_cast(ptr.get()); + return reinterpret_cast(get_mem_slab_raw(n * sizeof(T))); } - void deallocate(pointer p, size_type /*unused*/) - { - free_mem_slab_raw(p); - // ASSERT(p == slab.get()); - // slab.reset(); - } + void deallocate(pointer p, size_type /*unused*/) { free_mem_slab_raw(p); } friend bool operator==(const ContainerSlabAllocator&, const ContainerSlabAllocator&) { return true; } friend bool operator!=(const ContainerSlabAllocator&, const ContainerSlabAllocator&) { return false; } - - // private: - // std::shared_ptr slab; }; } // namespace barretenberg \ No newline at end of file diff --git a/cpp/src/barretenberg/crypto/pedersen_commitment/pedersen.cpp b/cpp/src/barretenberg/crypto/pedersen_commitment/pedersen.cpp index 3cb88b0aab..ae410af019 100644 --- a/cpp/src/barretenberg/crypto/pedersen_commitment/pedersen.cpp +++ b/cpp/src/barretenberg/crypto/pedersen_commitment/pedersen.cpp @@ -2,9 +2,9 @@ #include "./convert_buffer_to_field.hpp" #include "barretenberg/common/throw_or_abort.hpp" #include -// #ifndef NO_OMP_MULTITHREADING -// #include -// #endif +#ifndef NO_OMP_MULTITHREADING +#include +#endif using namespace crypto::generators; @@ -51,11 +51,11 @@ grumpkin::g1::affine_element commit_native(const std::vector& inpu ASSERT((inputs.size() < (1 << 16)) && "too many inputs for 16 bit index"); std::vector out(inputs.size()); - // #ifndef NO_OMP_MULTITHREADING - // // Ensure generator data is initialized before threading... +#ifndef NO_OMP_MULTITHREADING + // Ensure generator data is initialized before threading... init_generator_data(); - // #pragma omp parallel for num_threads(inputs.size()) - // #endif +#pragma omp parallel for num_threads(inputs.size()) +#endif for (size_t i = 0; i < inputs.size(); ++i) { generator_index_t index = { hash_index, i }; out[i] = commit_single(inputs[i], index); @@ -73,11 +73,11 @@ grumpkin::g1::affine_element commit_native(const std::vector out(input_pairs.size()); - // #ifndef NO_OMP_MULTITHREADING - // // Ensure generator data is initialized before threading... +#ifndef NO_OMP_MULTITHREADING + // Ensure generator data is initialized before threading... init_generator_data(); - // #pragma omp parallel for num_threads(input_pairs.size()) - // #endif +#pragma omp parallel for num_threads(input_pairs.size()) +#endif for (size_t i = 0; i < input_pairs.size(); ++i) { out[i] = commit_single(input_pairs[i].first, input_pairs[i].second); } diff --git a/cpp/src/barretenberg/crypto/pedersen_hash/pedersen.cpp b/cpp/src/barretenberg/crypto/pedersen_hash/pedersen.cpp index c43460b9a8..6debd1b9ff 100644 --- a/cpp/src/barretenberg/crypto/pedersen_hash/pedersen.cpp +++ b/cpp/src/barretenberg/crypto/pedersen_hash/pedersen.cpp @@ -1,8 +1,8 @@ #include "./pedersen.hpp" #include -// #ifndef NO_OMP_MULTITHREADING -// #include -// #endif +#ifndef NO_OMP_MULTITHREADING +#include +#endif namespace crypto { namespace pedersen_hash { @@ -49,11 +49,11 @@ grumpkin::fq hash_multiple(const std::vector& inputs, const size_t ASSERT((inputs.size() < (1 << 16)) && "too many inputs for 16 bit index"); std::vector out(inputs.size()); - // #ifndef NO_OMP_MULTITHREADING - // // Ensure generator data is initialized before threading... +#ifndef NO_OMP_MULTITHREADING + // Ensure generator data is initialized before threading... init_generator_data(); - // #pragma omp parallel for num_threads(inputs.size()) - // #endif +#pragma omp parallel for num_threads(inputs.size()) +#endif for (size_t i = 0; i < inputs.size(); ++i) { generator_index_t index = { hash_index, i }; out[i] = hash_single(inputs[i], index); diff --git a/cpp/src/barretenberg/examples/simple/simple.cpp b/cpp/src/barretenberg/examples/simple/simple.cpp index 0ebe62d4a3..f7d4dffa9f 100644 --- a/cpp/src/barretenberg/examples/simple/simple.cpp +++ b/cpp/src/barretenberg/examples/simple/simple.cpp @@ -21,7 +21,6 @@ void build_circuit(Composer& composer) Composer* create_composer(std::shared_ptr const& crs_factory) { - info(crs_factory->get_verifier_crs()->get_g2x()); // WARNING: Size hint is essential to perform 512k circuits! auto composer = std::make_unique(crs_factory, CIRCUIT_SIZE); info("building circuit..."); diff --git a/ts/src/examples/simple.rawtest.ts b/ts/src/examples/simple.rawtest.ts index 908287c4e4..e7f0ce8325 100644 --- a/ts/src/examples/simple.rawtest.ts +++ b/ts/src/examples/simple.rawtest.ts @@ -1,8 +1,6 @@ -import { BarretenbergWasm } from '../barretenberg_wasm/index.js'; import { Crs } from '../crs/index.js'; import createDebug from 'debug'; -import { BarretenbergApi } from '../barretenberg_api/index.js'; -import { BarretenbergBinder } from '../barretenberg_binder/index.js'; +import { newBarretenbergApiAsync } from '../factory/index.js'; createDebug.enable('*'); const debug = createDebug('simple_test'); @@ -11,8 +9,7 @@ async function main() { const CIRCUIT_SIZE = 2 ** 19; debug('starting test...'); - const { wasm, worker } = await BarretenbergWasm.newWorker(); - const api = new BarretenbergApi(new BarretenbergBinder(wasm)); + const api = await newBarretenbergApiAsync(); // Import to init slab allocator as first thing, to ensure maximum memory efficiency. await api.commonInitSlabAllocator(CIRCUIT_SIZE); @@ -20,15 +17,13 @@ async function main() { // Plus 1 needed! const crs = await Crs.new(CIRCUIT_SIZE + 1); const pippengerPtr = await api.eccNewPippenger(crs.getG1Data(), crs.numPoints); - debug(Buffer.from(crs.getG2Data()).toString('hex')); for (let i = 0; i < 10; ++i) { debug(`iteration ${i} starting...`); await api.examplesSimpleCreateAndVerifyProof(pippengerPtr, crs.getG2Data()); } - await wasm.destroy(); - await worker.terminate(); + await api.destroy(); debug('test complete.'); } diff --git a/ts/src/examples/simple.test.ts b/ts/src/examples/simple.test.ts index a79fe4c449..0f78231f0c 100644 --- a/ts/src/examples/simple.test.ts +++ b/ts/src/examples/simple.test.ts @@ -1,13 +1,11 @@ -import { BarretenbergApiSync } from '../barretenberg_api/index.js'; -import { BarretenbergWasm } from '../barretenberg_wasm/index.js'; -import { BarretenbergBinderSync } from '../barretenberg_binder/index.js'; import { Crs } from '../index.js'; +import { BarretenbergApiAsync, newBarretenbergApiAsync } from '../factory/index.js'; describe('simple', () => { - let api: BarretenbergApiSync; + let api: BarretenbergApiAsync; beforeAll(async () => { - api = new BarretenbergApiSync(new BarretenbergBinderSync(await BarretenbergWasm.new())); + api = await newBarretenbergApiAsync(); }, 20000); afterAll(async () => { @@ -16,8 +14,8 @@ describe('simple', () => { it('should construct 512k gate proof', async () => { const crs = await Crs.new(2 ** 19 + 1); - const pippengerPtr = api.eccNewPippenger(crs.getG1Data(), crs.numPoints); - const valid = api.examplesSimpleCreateAndVerifyProof(pippengerPtr, crs.getG2Data()); + const pippengerPtr = await api.eccNewPippenger(crs.getG1Data(), crs.numPoints); + const valid = await api.examplesSimpleCreateAndVerifyProof(pippengerPtr, crs.getG2Data()); expect(valid).toBe(true); }, 60000); }); diff --git a/ts/src/factory/index.ts b/ts/src/factory/index.ts index b837a7928e..78a1812982 100644 --- a/ts/src/factory/index.ts +++ b/ts/src/factory/index.ts @@ -2,11 +2,15 @@ import { BarretenbergApi, BarretenbergApiSync } from '../barretenberg_api/index. import { BarretenbergBinder, BarretenbergBinderSync } from '../barretenberg_binder/index.js'; import { BarretenbergWasm, BarretenbergWasmWorker } from '../barretenberg_wasm/index.js'; -export async function newSingleThreaded() { +/** + * Returns a single threaded, synchronous, barretenberg api. + * Can be used on the main thread to perform small light-weight requests like hashing etc. + */ +export async function newBarretenbergApiSync() { return new BarretenbergApiSync(new BarretenbergBinderSync(await BarretenbergWasm.new())); } -class BarretenbergApiAsync extends BarretenbergApi { +export class BarretenbergApiAsync extends BarretenbergApi { constructor(private worker: any, private wasm: BarretenbergWasmWorker) { super(new BarretenbergBinder(wasm)); } @@ -17,7 +21,12 @@ class BarretenbergApiAsync extends BarretenbergApi { } } -export async function newMultiThreaded() { +/** + * Returns a multi threaded, asynchronous, barretenberg api. + * It runs in a worker, and so can be used within the browser to execute long running, multi-threaded requests + * like proof construction etc. + */ +export async function newBarretenbergApiAsync() { const { wasm, worker } = await BarretenbergWasm.newWorker(); return new BarretenbergApiAsync(worker, wasm); } diff --git a/ts/src/main.ts b/ts/src/main.ts index 1bcf524dc0..1ed9c74785 100755 --- a/ts/src/main.ts +++ b/ts/src/main.ts @@ -1,7 +1,7 @@ #!/usr/bin/env node import { Crs } from './crs/index.js'; import createDebug from 'debug'; -import { newMultiThreaded } from './factory/index.js'; +import { newBarretenbergApiAsync } from './factory/index.js'; import { readFileSync } from 'fs'; import { gunzipSync } from 'zlib'; import { RawBuffer } from './types/index.js'; @@ -34,7 +34,7 @@ function getWitness() { // backend stop export async function main() { debug('starting test...'); - const api = await newMultiThreaded(); + const api = await newBarretenbergApiAsync(); try { const CIRCUIT_SIZE = 2 ** 19; From 130c944cbcfa124cf15452e9858d9a7e9aa27a6f Mon Sep 17 00:00:00 2001 From: Charlie Lye Date: Wed, 24 May 2023 07:48:46 +0000 Subject: [PATCH 12/29] tests pass --- cpp/src/barretenberg/examples/simple/simple.cpp | 2 -- ts/src/barretenberg_api/blake2s.test.ts | 5 ++--- ts/src/barretenberg_api/common.test.ts | 14 ++++++-------- ts/src/barretenberg_api/pedersen.test.ts | 11 +++++------ ts/src/barretenberg_api/schnorr.test.ts | 5 ++--- ts/src/barretenberg_wasm/barretenberg_wasm.test.ts | 2 +- ts/src/barretenberg_wasm/barretenberg_wasm.ts | 2 +- ts/src/examples/simple.test.ts | 4 ++++ ts/src/factory/index.ts | 8 ++++++-- 9 files changed, 27 insertions(+), 26 deletions(-) diff --git a/cpp/src/barretenberg/examples/simple/simple.cpp b/cpp/src/barretenberg/examples/simple/simple.cpp index f7d4dffa9f..a331574a76 100644 --- a/cpp/src/barretenberg/examples/simple/simple.cpp +++ b/cpp/src/barretenberg/examples/simple/simple.cpp @@ -45,7 +45,6 @@ proof create_proof(Composer* composer) Timer timer; info("computing proof..."); auto prover = composer->create_ultra_with_keccak_prover(); - // auto prover = composer->create_prover(); auto proof = prover.construct_proof(); info("proof construction took ", timer.seconds(), "s"); return proof; @@ -56,7 +55,6 @@ bool verify_proof(Composer* composer, proof_system::plonk::proof const& proof) info("computing verification key..."); composer->compute_verification_key(); auto verifier = composer->create_ultra_with_keccak_verifier(); - // auto verifier = composer->create_verifier(); auto valid = verifier.verify_proof(proof); info("proof validity: ", valid); return valid; diff --git a/ts/src/barretenberg_api/blake2s.test.ts b/ts/src/barretenberg_api/blake2s.test.ts index d046c8e551..47fa77dbcc 100644 --- a/ts/src/barretenberg_api/blake2s.test.ts +++ b/ts/src/barretenberg_api/blake2s.test.ts @@ -1,5 +1,4 @@ -import { BarretenbergBinderSync } from '../barretenberg_binder/index.js'; -import { BarretenbergWasm } from '../barretenberg_wasm/index.js'; +import { newBarretenbergApiSync } from '../factory/index.js'; import { Buffer32, Fr } from '../types/index.js'; import { BarretenbergApiSync } from './index.js'; @@ -7,7 +6,7 @@ describe('blake2s', () => { let api: BarretenbergApiSync; beforeAll(async () => { - api = new BarretenbergApiSync(new BarretenbergBinderSync(await BarretenbergWasm.new(1))); + api = await newBarretenbergApiSync(); }); afterAll(async () => { diff --git a/ts/src/barretenberg_api/common.test.ts b/ts/src/barretenberg_api/common.test.ts index 40a8dc0301..29ce69fbba 100644 --- a/ts/src/barretenberg_api/common.test.ts +++ b/ts/src/barretenberg_api/common.test.ts @@ -1,23 +1,21 @@ -import { BarretenbergBinderSync } from '../barretenberg_binder/index.js'; -import { BarretenbergWasm } from '../barretenberg_wasm/index.js'; -import { BarretenbergApiSync } from './index.js'; +import { BarretenbergApiAsync, newBarretenbergApiAsync } from '../factory/index.js'; describe('env', () => { - let api: BarretenbergApiSync; + let api: BarretenbergApiAsync; beforeAll(async () => { - api = new BarretenbergApiSync(new BarretenbergBinderSync(await BarretenbergWasm.new(3))); + api = await newBarretenbergApiAsync(3); }); afterAll(async () => { await api.destroy(); }); - it('thread test', () => { + it('thread test', async () => { // Main thread doesn't do anything in this test, so -1. - const threads = api.binder.wasm.getNumThreads() - 1; + const threads = (await api.getNumThreads()) - 1; const iterations = 100000; - const result = api.testThreads(threads, iterations); + const result = await api.testThreads(threads, iterations); expect(result).toBe(iterations); }); }); diff --git a/ts/src/barretenberg_api/pedersen.test.ts b/ts/src/barretenberg_api/pedersen.test.ts index 24a4633a21..3e812f5ae7 100644 --- a/ts/src/barretenberg_api/pedersen.test.ts +++ b/ts/src/barretenberg_api/pedersen.test.ts @@ -1,5 +1,4 @@ -import { BarretenbergBinderSync } from '../barretenberg_binder/index.js'; -import { BarretenbergWasm } from '../barretenberg_wasm/barretenberg_wasm.js'; +import { newBarretenbergApiSync } from '../factory/index.js'; import { Fr } from '../types/index.js'; import { BarretenbergApiSync } from './index.js'; @@ -7,7 +6,7 @@ describe('pedersen', () => { let api: BarretenbergApiSync; beforeAll(async () => { - api = new BarretenbergApiSync(new BarretenbergBinderSync(await BarretenbergWasm.new(1))); + api = await newBarretenbergApiSync(); api.pedersenHashInit(); }); @@ -22,7 +21,7 @@ describe('pedersen', () => { it('pedersenPlookupCompressFields', () => { const result = api.pedersenPlookupCompressFields(new Fr(4n), new Fr(8n)); - expect(result).toEqual(new Fr(7508407170365331152493586290597472346478280823936748458450026785528968221772n)); + expect(result).toEqual(new Fr(21568810706345846819294487214368613840251909831689369685420108292337497444070n)); }); it('pedersenCompress', () => { @@ -32,7 +31,7 @@ describe('pedersen', () => { it('pedersenPlookupCompress', () => { const result = api.pedersenPlookupCompress([new Fr(4n), new Fr(8n), new Fr(12n)]); - expect(result).toEqual(new Fr(641613987782189905475142047603559162464012327378197326488471789040703504911n)); + expect(result).toEqual(new Fr(4213911891650716450883144878301329379460622830501147795631256054071351353887n)); }); it('pedersenCompressWithHashIndex', () => { @@ -47,7 +46,7 @@ describe('pedersen', () => { it('pedersenPlookupCommit', () => { const result = api.pedersenPlookupCommit([new Fr(4n), new Fr(8n)]); - expect(result).toEqual(new Fr(7508407170365331152493586290597472346478280823936748458450026785528968221772n)); + expect(result).toEqual(new Fr(21568810706345846819294487214368613840251909831689369685420108292337497444070n)); }); it('pedersenBufferToField', () => { diff --git a/ts/src/barretenberg_api/schnorr.test.ts b/ts/src/barretenberg_api/schnorr.test.ts index a990421f9a..2d8e9e6650 100644 --- a/ts/src/barretenberg_api/schnorr.test.ts +++ b/ts/src/barretenberg_api/schnorr.test.ts @@ -1,15 +1,14 @@ import { TextEncoder } from 'util'; import { Buffer128, Buffer32, Fr, Point } from '../types/index.js'; import { BarretenbergApiSync } from './index.js'; -import { BarretenbergBinderSync } from '../barretenberg_binder/index.js'; -import { BarretenbergWasm } from '../barretenberg_wasm/barretenberg_wasm.js'; +import { newBarretenbergApiSync } from '../factory/index.js'; describe('schnorr', () => { const msg = Buffer.from(new TextEncoder().encode('The quick brown dog jumped over the lazy fox.')); let api: BarretenbergApiSync; beforeAll(async () => { - api = new BarretenbergApiSync(new BarretenbergBinderSync(await BarretenbergWasm.new(1))); + api = await newBarretenbergApiSync(); api.pedersenInit(); }); diff --git a/ts/src/barretenberg_wasm/barretenberg_wasm.test.ts b/ts/src/barretenberg_wasm/barretenberg_wasm.test.ts index 2f7fb078ce..2cf1517083 100644 --- a/ts/src/barretenberg_wasm/barretenberg_wasm.test.ts +++ b/ts/src/barretenberg_wasm/barretenberg_wasm.test.ts @@ -5,7 +5,7 @@ describe('barretenberg wasm', () => { let wasm!: BarretenbergWasm; beforeAll(async () => { - wasm = await BarretenbergWasm.new(1); + wasm = await BarretenbergWasm.new(); }); afterAll(async () => { diff --git a/ts/src/barretenberg_wasm/barretenberg_wasm.ts b/ts/src/barretenberg_wasm/barretenberg_wasm.ts index 3e2f08be1f..a597f89812 100644 --- a/ts/src/barretenberg_wasm/barretenberg_wasm.ts +++ b/ts/src/barretenberg_wasm/barretenberg_wasm.ts @@ -63,7 +63,7 @@ export class BarretenbergWasm { `threads: ${threads}`, ); - this.memory = new WebAssembly.Memory({ initial, maximum, shared: true }); + this.memory = new WebAssembly.Memory({ initial, maximum, shared: threads > 1 }); const code = await fetchCode(threads > 1 ? 'barretenberg-threads.wasm' : 'barretenberg.wasm'); const { instance, module } = await WebAssembly.instantiate(code, this.getImportObj(this.memory)); diff --git a/ts/src/examples/simple.test.ts b/ts/src/examples/simple.test.ts index 0f78231f0c..45f6489a13 100644 --- a/ts/src/examples/simple.test.ts +++ b/ts/src/examples/simple.test.ts @@ -6,6 +6,10 @@ describe('simple', () => { beforeAll(async () => { api = await newBarretenbergApiAsync(); + + // Import to init slab allocator as first thing, to ensure maximum memory efficiency. + const CIRCUIT_SIZE = 2 ** 19; + await api.commonInitSlabAllocator(CIRCUIT_SIZE); }, 20000); afterAll(async () => { diff --git a/ts/src/factory/index.ts b/ts/src/factory/index.ts index 78a1812982..9daae9189c 100644 --- a/ts/src/factory/index.ts +++ b/ts/src/factory/index.ts @@ -15,6 +15,10 @@ export class BarretenbergApiAsync extends BarretenbergApi { super(new BarretenbergBinder(wasm)); } + async getNumThreads() { + return await this.wasm.getNumThreads(); + } + async destroy() { await this.wasm.destroy(); await this.worker.terminate(); @@ -26,7 +30,7 @@ export class BarretenbergApiAsync extends BarretenbergApi { * It runs in a worker, and so can be used within the browser to execute long running, multi-threaded requests * like proof construction etc. */ -export async function newBarretenbergApiAsync() { - const { wasm, worker } = await BarretenbergWasm.newWorker(); +export async function newBarretenbergApiAsync(threads?: number) { + const { wasm, worker } = await BarretenbergWasm.newWorker(threads); return new BarretenbergApiAsync(worker, wasm); } From 72e4c98f4415d96210afa1abdad9327855f8cf92 Mon Sep 17 00:00:00 2001 From: Charlie Lye Date: Wed, 24 May 2023 08:33:27 +0000 Subject: [PATCH 13/29] Commander --- ts/package-lock.json | 11910 +++++++++++++++++++++++ ts/package.json | 3 +- ts/src/barretenberg_wasm/node/index.ts | 2 +- ts/src/main.ts | 63 +- ts/webpack.config.js | 6 +- ts/yarn.lock | 568 +- 6 files changed, 12246 insertions(+), 306 deletions(-) create mode 100644 ts/package-lock.json diff --git a/ts/package-lock.json b/ts/package-lock.json new file mode 100644 index 0000000000..2b533c549f --- /dev/null +++ b/ts/package-lock.json @@ -0,0 +1,11910 @@ +{ + "name": "@aztec/barretenberg.js", + "version": "0.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "@aztec/barretenberg.js", + "version": "0.0.0", + "dependencies": { + "bigint-buffer": "^1.1.5", + "commander": "^10.0.1", + "tslib": "^2.4.0" + }, + "bin": { + "bb.js": "dest/main.js", + "bb.js-dev": "src/main-dev.ts" + }, + "devDependencies": { + "@jest/globals": "^29.4.3", + "@types/debug": "^4.1.7", + "@types/detect-node": "^2.0.0", + "@types/jest": "^29.4.0", + "@types/node": "^18.7.23", + "@types/source-map-support": "^0.5.6", + "@typescript-eslint/eslint-plugin": "^5.54.1", + "@typescript-eslint/parser": "^5.54.1", + "buffer": "^6.0.3", + "comlink": "^4.4.1", + "copy-webpack-plugin": "^11.0.0", + "debug": "^4.3.4", + "eslint": "^8.35.0", + "eslint-config-prettier": "^8.8.0", + "html-webpack-plugin": "^5.5.1", + "idb-keyval": "^6.2.1", + "jest": "^29.5.0", + "prettier": "^2.8.4", + "resolve-typescript-plugin": "^2.0.1", + "ts-jest": "^29.1.0", + "ts-loader": "^9.4.2", + "ts-node": "^10.9.1", + "typescript": "^5.0.4", + "webpack": "^5.82.1", + "webpack-cli": "^5.1.1", + "webpack-dev-server": "^4.15.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.21.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.21.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.21.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.4", + "@babel/helper-compilation-targets": "^7.21.4", + "@babel/helper-module-transforms": "^7.21.2", + "@babel/helpers": "^7.21.0", + "@babel/parser": "^7.21.4", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.4", + "@babel/types": "^7.21.4", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.21.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.21.4", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.21.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.21.4", + "@babel/helper-validator-option": "^7.21.0", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.18.9", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.21.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.21.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.21.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.2", + "@babel/types": "^7.21.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.20.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.20.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.19.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.21.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.0", + "@babel/types": "^7.21.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.21.4", + "dev": true, + "license": "MIT", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.21.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.21.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.20.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.21.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.4", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.21.4", + "@babel/types": "^7.21.4", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.21.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.5.1", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/js": { + "version": "8.38.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.8", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.5.0", + "@jest/reporters": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.5.0", + "jest-config": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-resolve-dependencies": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "jest-watcher": "^29.5.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.5.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "jest-mock": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.5.0", + "jest-snapshot": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.4.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.5.0", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/types": "^29.5.0", + "jest-mock": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@jridgewell/trace-mapping": "^0.3.15", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/schemas": { + "version": "29.4.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.25.16" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.4.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.15", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.5.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.5.0", + "@jridgewell/trace-mapping": "^0.3.15", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform/node_modules/convert-source-map": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@jest/types": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.4.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.18", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "dev": true, + "license": "MIT" + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.25.24", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "2.0.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.0.2", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^2.0.0" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/babel__core": { + "version": "7.20.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.18.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.3.0" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.10", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.35", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/detect-node": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/eslint": { + "version": "8.37.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/express": { + "version": "4.17.17", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.34", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.11", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/ms": { + "version": "0.7.31", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "18.15.11", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/prettier": { + "version": "2.7.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/retry": { + "version": "0.12.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/semver": { + "version": "7.3.13", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/send": { + "version": "0.17.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static/node_modules/@types/mime": { + "version": "3.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/sockjs": { + "version": "0.3.33", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/source-map-support": { + "version": "0.5.6", + "dev": true, + "license": "MIT", + "dependencies": { + "source-map": "^0.6.0" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.24", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.57.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.57.1", + "@typescript-eslint/type-utils": "5.57.1", + "@typescript-eslint/utils": "5.57.1", + "debug": "^4.3.4", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.57.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "5.57.1", + "@typescript-eslint/types": "5.57.1", + "@typescript-eslint/typescript-estree": "5.57.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.57.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "5.57.1", + "@typescript-eslint/visitor-keys": "5.57.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.57.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "5.57.1", + "@typescript-eslint/utils": "5.57.1", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.57.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.57.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "5.57.1", + "@typescript-eslint/visitor-keys": "5.57.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.57.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.57.1", + "@typescript-eslint/types": "5.57.1", + "@typescript-eslint/typescript-estree": "5.57.1", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.57.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "5.57.1", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/configtest": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/info": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/accepts": { + "version": "1.3.8", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.8.2", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "8.12.0", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/ajv/node_modules/json-schema-traverse": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "license": "Apache-2.0", + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "1.0.10", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-flatten": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/array-union": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-jest": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/transform": "^29.5.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.5.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "^29.5.0", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/batch": { + "version": "0.6.1", + "dev": true, + "license": "MIT" + }, + "node_modules/bigint-buffer": { + "version": "1.1.5", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "bindings": "^1.3.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "license": "MIT", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/body-parser": { + "version": "1.20.1", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/bonjour-service": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "array-flatten": "^2.1.2", + "dns-equal": "^1.0.0", + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.21.5", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/bytes": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001476", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "3.8.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.2", + "dev": true, + "license": "MIT" + }, + "node_modules/clean-css": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/co": { + "version": "4.6.0", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.20", + "dev": true, + "license": "MIT" + }, + "node_modules/comlink": { + "version": "4.4.1", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/commander": { + "version": "10.0.1", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/compressible": { + "version": "2.0.18", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/bytes": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/copy-webpack-plugin": { + "version": "11.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-glob": "^3.2.11", + "glob-parent": "^6.0.1", + "globby": "^13.1.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/globby": { + "version": "13.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.11", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin/node_modules/slash": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/create-require": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-select": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/dedent": { + "version": "0.7.0", + "dev": true, + "license": "MIT" + }, + "node_modules/deep-is": { + "version": "0.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/diff": { + "version": "4.0.2", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "29.4.3", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dns-equal": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/dns-packet": { + "version": "5.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "utila": "~0.4" + } + }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "4.3.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.4.356", + "dev": true, + "license": "ISC" + }, + "node_modules/emittery": { + "version": "0.13.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.14.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "2.2.0", + "dev": true, + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/envinfo": { + "version": "7.8.1", + "dev": true, + "license": "MIT", + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-module-lexer": { + "version": "1.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/escalade": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "8.38.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.2", + "@eslint/js": "8.38.0", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-visitor-keys": "^3.4.0", + "espree": "^9.5.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-prettier": { + "version": "8.8.0", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-scope/node_modules/estraverse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.1.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "9.5.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/express": { + "version": "4.18.2", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/array-flatten": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.2.12", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastq": { + "version": "1.15.0", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/fill-range": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/find-up": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-monkey": { + "version": "1.0.3", + "dev": true, + "license": "Unlicense" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/function-bind": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/globals": { + "version": "13.20.0", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "dev": true, + "license": "ISC" + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/has": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/he": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-entities": { + "version": "2.3.3", + "dev": true, + "license": "MIT" + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/html-minifier-terser": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/html-minifier-terser/node_modules/commander": { + "version": "8.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/html-webpack-plugin": { + "version": "5.5.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/html-webpack-plugin" + }, + "peerDependencies": { + "webpack": "^5.20.0" + } + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "dev": true, + "license": "MIT" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "dev": true, + "license": "MIT" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/idb-keyval": { + "version": "6.2.1", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/ieee754": { + "version": "1.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.2.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "node_modules/interpret": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.11.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.5", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^29.5.0", + "@jest/types": "^29.5.0", + "import-local": "^3.0.2", + "jest-cli": "^29.5.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^5.0.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.5.0", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.5.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-cli": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.5.0", + "@jest/types": "^29.5.0", + "babel-jest": "^29.5.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.5.0", + "jest-environment-node": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.5.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-diff": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "29.4.3", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.5.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.4.3", + "jest-util": "^29.5.0", + "pretty-format": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.4.3", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.5.0", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.5.0", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.5.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.5.0", + "@types/node": "*", + "jest-util": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.4.3", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-regex-util": "^29.4.3", + "jest-snapshot": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.5.0", + "@jest/environment": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.4.3", + "jest-environment-node": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-leak-detector": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-resolve": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-util": "^29.5.0", + "jest-watcher": "^29.5.0", + "jest-worker": "^29.5.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner/node_modules/source-map-support": { + "version": "0.5.13", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/globals": "^29.5.0", + "@jest/source-map": "^29.4.3", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.5.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.5.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.5.0", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.4.3", + "leven": "^3.1.0", + "pretty-format": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.5.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.5.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-sdsl": { + "version": "4.4.0", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/js-yaml/node_modules/argparse": { + "version": "2.0.1", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/jsesc": { + "version": "2.5.2", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/launch-editor": { + "version": "2.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.7.3" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "dev": true, + "license": "MIT" + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "dev": true, + "license": "MIT" + }, + "node_modules/lower-case": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "dev": true, + "license": "ISC" + }, + "node_modules/makeerror": { + "version": "1.0.12", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "3.5.1", + "dev": true, + "license": "Unlicense", + "dependencies": { + "fs-monkey": "^1.0.3" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "dev": true, + "license": "MIT" + }, + "node_modules/no-case": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "dev": true, + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.10", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "4.6.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-retry/node_modules/retry": { + "version": "0.13.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/param-case": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.8.7", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pretty-error": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "node_modules/pretty-format": { + "version": "29.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/prompts": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pure-rand": { + "version": "6.0.1", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, + "node_modules/qs": { + "version": "6.11.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.1", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/react-is": { + "version": "18.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/renderkid": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-typescript-plugin": { + "version": "2.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "tslib": "2.5.0" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/schema-utils": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/selfsigned": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.3.8", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.18.0", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/serialize-javascript": { + "version": "6.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "dev": true, + "license": "ISC" + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "dev": true, + "license": "ISC" + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.15.0", + "dev": true, + "license": "MIT", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "dev": true, + "license": "ISC" + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "dev": true, + "license": "ISC" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/slash": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "dev": true, + "license": "MIT", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spdy": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.17.3", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.2", + "acorn": "^8.5.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.17", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.16.8" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/terser-webpack-plugin/node_modules/jest-worker": { + "version": "27.5.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "dev": true, + "license": "MIT" + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/thunky": { + "version": "1.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/tmpl": { + "version": "1.0.5", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ts-jest": { + "version": "29.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/ts-loader": { + "version": "9.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" + } + }, + "node_modules/ts-loader/node_modules/semver": { + "version": "7.5.0", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.5.0", + "license": "0BSD" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "dev": true, + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "dev": true, + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typescript": { + "version": "5.0.4", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.10", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/utila": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/v8-to-istanbul": { + "version": "9.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/watchpack": { + "version": "2.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "dev": true, + "license": "MIT", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/webpack": { + "version": "5.82.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.14.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.2", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.7", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "5.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.0", + "@webpack-cli/info": "^2.0.1", + "@webpack-cli/serve": "^2.0.4", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware": { + "version": "5.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/webpack-dev-server": { + "version": "4.15.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.1", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.13.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.37.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ipaddr.js": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/webpack-merge": { + "version": "5.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "3.5.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/ws": { + "version": "8.13.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@ampproject/remapping": { + "version": "2.2.1", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@babel/code-frame": { + "version": "7.21.4", + "dev": true, + "requires": { + "@babel/highlight": "^7.18.6" + } + }, + "@babel/compat-data": { + "version": "7.21.4", + "dev": true + }, + "@babel/core": { + "version": "7.21.4", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.4", + "@babel/helper-compilation-targets": "^7.21.4", + "@babel/helper-module-transforms": "^7.21.2", + "@babel/helpers": "^7.21.0", + "@babel/parser": "^7.21.4", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.4", + "@babel/types": "^7.21.4", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.21.4", + "dev": true, + "requires": { + "@babel/types": "^7.21.4", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.21.4", + "dev": true, + "requires": { + "@babel/compat-data": "^7.21.4", + "@babel/helper-validator-option": "^7.21.0", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + }, + "dependencies": { + "lru-cache": { + "version": "5.1.1", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "semver": { + "version": "6.3.0", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "dev": true + } + } + }, + "@babel/helper-environment-visitor": { + "version": "7.18.9", + "dev": true + }, + "@babel/helper-function-name": { + "version": "7.21.0", + "dev": true, + "requires": { + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.18.6", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-module-imports": { + "version": "7.21.4", + "dev": true, + "requires": { + "@babel/types": "^7.21.4" + } + }, + "@babel/helper-module-transforms": { + "version": "7.21.2", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.2", + "@babel/types": "^7.21.2" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.20.2", + "dev": true + }, + "@babel/helper-simple-access": { + "version": "7.20.2", + "dev": true, + "requires": { + "@babel/types": "^7.20.2" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.18.6", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-string-parser": { + "version": "7.19.4", + "dev": true + }, + "@babel/helper-validator-identifier": { + "version": "7.19.1", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.21.0", + "dev": true + }, + "@babel/helpers": { + "version": "7.21.0", + "dev": true, + "requires": { + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.0", + "@babel/types": "^7.21.0" + } + }, + "@babel/highlight": { + "version": "7.18.6", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.21.4", + "dev": true + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.21.4", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.20.2" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.21.4", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.20.2" + } + }, + "@babel/template": { + "version": "7.20.7", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + } + }, + "@babel/traverse": { + "version": "7.21.4", + "dev": true, + "requires": { + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.4", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.21.4", + "@babel/types": "^7.21.4", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "dependencies": { + "globals": { + "version": "11.12.0", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.21.4", + "dev": true, + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "dev": true + }, + "@cspotcode/source-map-support": { + "version": "0.8.1", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "dependencies": { + "@jridgewell/resolve-uri": { + "version": "3.1.1", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + } + } + }, + "@discoveryjs/json-ext": { + "version": "0.5.7", + "dev": true + }, + "@eslint-community/eslint-utils": { + "version": "4.4.0", + "dev": true, + "requires": { + "eslint-visitor-keys": "^3.3.0" + } + }, + "@eslint-community/regexpp": { + "version": "4.5.0", + "dev": true + }, + "@eslint/eslintrc": { + "version": "2.0.2", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.5.1", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + } + } + }, + "@eslint/js": { + "version": "8.38.0", + "dev": true + }, + "@humanwhocodes/config-array": { + "version": "0.11.8", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + } + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "dev": true + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "dev": true + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "js-yaml": { + "version": "3.14.1", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "dev": true + }, + "@jest/console": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "slash": "^3.0.0" + } + }, + "@jest/core": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/console": "^29.5.0", + "@jest/reporters": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.5.0", + "jest-config": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-resolve-dependencies": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "jest-watcher": "^29.5.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.5.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "@jest/environment": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "jest-mock": "^29.5.0" + } + }, + "@jest/expect": { + "version": "29.5.0", + "dev": true, + "requires": { + "expect": "^29.5.0", + "jest-snapshot": "^29.5.0" + } + }, + "@jest/expect-utils": { + "version": "29.5.0", + "dev": true, + "requires": { + "jest-get-type": "^29.4.3" + } + }, + "@jest/fake-timers": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/types": "^29.5.0", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" + } + }, + "@jest/globals": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/types": "^29.5.0", + "jest-mock": "^29.5.0" + } + }, + "@jest/reporters": { + "version": "29.5.0", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@jridgewell/trace-mapping": "^0.3.15", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + } + }, + "@jest/schemas": { + "version": "29.4.3", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.25.16" + } + }, + "@jest/source-map": { + "version": "29.4.3", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.15", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + } + }, + "@jest/test-result": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/console": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/test-result": "^29.5.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "slash": "^3.0.0" + } + }, + "@jest/transform": { + "version": "29.5.0", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.5.0", + "@jridgewell/trace-mapping": "^0.3.15", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "dependencies": { + "convert-source-map": { + "version": "2.0.0", + "dev": true + } + } + }, + "@jest/types": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/schemas": "^29.4.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@jridgewell/gen-mapping": { + "version": "0.3.3", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "dev": true + }, + "@jridgewell/source-map": { + "version": "0.3.3", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.18", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + }, + "dependencies": { + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "dev": true + } + } + }, + "@leichtgewicht/ip-codec": { + "version": "2.0.4", + "dev": true + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@sinclair/typebox": { + "version": "0.25.24", + "dev": true + }, + "@sinonjs/commons": { + "version": "2.0.0", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "10.0.2", + "dev": true, + "requires": { + "@sinonjs/commons": "^2.0.0" + } + }, + "@tsconfig/node10": { + "version": "1.0.9", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.11", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.3", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.3", + "dev": true + }, + "@types/babel__core": { + "version": "7.20.0", + "dev": true, + "requires": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.4", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.1", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.18.3", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/body-parser": { + "version": "1.19.2", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/bonjour": { + "version": "3.5.10", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.35", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/connect-history-api-fallback": { + "version": "1.5.0", + "dev": true, + "requires": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "@types/debug": { + "version": "4.1.7", + "dev": true, + "requires": { + "@types/ms": "*" + } + }, + "@types/detect-node": { + "version": "2.0.0", + "dev": true + }, + "@types/eslint": { + "version": "8.37.0", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint-scope": { + "version": "3.7.4", + "dev": true, + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "@types/estree": { + "version": "1.0.1", + "dev": true + }, + "@types/express": { + "version": "4.17.17", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.34", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "@types/graceful-fs": { + "version": "4.1.6", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/html-minifier-terser": { + "version": "6.1.0", + "dev": true + }, + "@types/http-proxy": { + "version": "1.17.11", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.4", + "dev": true + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/jest": { + "version": "29.5.0", + "dev": true, + "requires": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "@types/json-schema": { + "version": "7.0.11", + "dev": true + }, + "@types/mime": { + "version": "1.3.2", + "dev": true + }, + "@types/ms": { + "version": "0.7.31", + "dev": true + }, + "@types/node": { + "version": "18.15.11", + "dev": true + }, + "@types/prettier": { + "version": "2.7.2", + "dev": true + }, + "@types/qs": { + "version": "6.9.7", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.4", + "dev": true + }, + "@types/retry": { + "version": "0.12.0", + "dev": true + }, + "@types/semver": { + "version": "7.3.13", + "dev": true + }, + "@types/send": { + "version": "0.17.1", + "dev": true, + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "@types/serve-index": { + "version": "1.9.1", + "dev": true, + "requires": { + "@types/express": "*" + } + }, + "@types/serve-static": { + "version": "1.15.1", + "dev": true, + "requires": { + "@types/mime": "*", + "@types/node": "*" + }, + "dependencies": { + "@types/mime": { + "version": "3.0.1", + "dev": true + } + } + }, + "@types/sockjs": { + "version": "0.3.33", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/source-map-support": { + "version": "0.5.6", + "dev": true, + "requires": { + "source-map": "^0.6.0" + } + }, + "@types/stack-utils": { + "version": "2.0.1", + "dev": true + }, + "@types/ws": { + "version": "8.5.4", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/yargs": { + "version": "17.0.24", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "21.0.0", + "dev": true + }, + "@typescript-eslint/eslint-plugin": { + "version": "5.57.1", + "dev": true, + "requires": { + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.57.1", + "@typescript-eslint/type-utils": "5.57.1", + "@typescript-eslint/utils": "5.57.1", + "debug": "^4.3.4", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/parser": { + "version": "5.57.1", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.57.1", + "@typescript-eslint/types": "5.57.1", + "@typescript-eslint/typescript-estree": "5.57.1", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.57.1", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.57.1", + "@typescript-eslint/visitor-keys": "5.57.1" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.57.1", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "5.57.1", + "@typescript-eslint/utils": "5.57.1", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/types": { + "version": "5.57.1", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.57.1", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.57.1", + "@typescript-eslint/visitor-keys": "5.57.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/utils": { + "version": "5.57.1", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.57.1", + "@typescript-eslint/types": "5.57.1", + "@typescript-eslint/typescript-estree": "5.57.1", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.57.1", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.57.1", + "eslint-visitor-keys": "^3.3.0" + } + }, + "@webassemblyjs/ast": { + "version": "1.11.6", + "dev": true, + "requires": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "dev": true + }, + "@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "dev": true, + "requires": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.11.6", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.11.6", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.11.6", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.11.6", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "@webpack-cli/configtest": { + "version": "2.1.0", + "dev": true, + "requires": {} + }, + "@webpack-cli/info": { + "version": "2.0.1", + "dev": true, + "requires": {} + }, + "@webpack-cli/serve": { + "version": "2.0.4", + "dev": true, + "requires": {} + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "dev": true + }, + "accepts": { + "version": "1.3.8", + "dev": true, + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "acorn": { + "version": "8.8.2", + "dev": true + }, + "acorn-import-assertions": { + "version": "1.9.0", + "dev": true, + "requires": {} + }, + "acorn-jsx": { + "version": "5.3.2", + "dev": true, + "requires": {} + }, + "acorn-walk": { + "version": "8.2.0", + "dev": true + }, + "ajv": { + "version": "8.12.0", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "dependencies": { + "json-schema-traverse": { + "version": "1.0.0", + "dev": true + } + } + }, + "ajv-formats": { + "version": "2.1.1", + "dev": true, + "requires": { + "ajv": "^8.0.0" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "ansi-escapes": { + "version": "4.3.2", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + }, + "dependencies": { + "type-fest": { + "version": "0.21.3", + "dev": true + } + } + }, + "ansi-html-community": { + "version": "0.0.8", + "dev": true + }, + "ansi-regex": { + "version": "5.0.1", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.3", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "arg": { + "version": "4.1.3", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-flatten": { + "version": "2.1.2", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "dev": true + }, + "babel-jest": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/transform": "^29.5.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.5.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + } + }, + "babel-plugin-istanbul": { + "version": "6.1.1", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "29.5.0", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-current-node-syntax": { + "version": "1.0.1", + "dev": true, + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + } + }, + "babel-preset-jest": { + "version": "29.5.0", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^29.5.0", + "babel-preset-current-node-syntax": "^1.0.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "dev": true + }, + "base64-js": { + "version": "1.5.1", + "dev": true + }, + "batch": { + "version": "0.6.1", + "dev": true + }, + "bigint-buffer": { + "version": "1.1.5", + "requires": { + "bindings": "^1.3.0" + } + }, + "binary-extensions": { + "version": "2.2.0", + "dev": true + }, + "bindings": { + "version": "1.5.0", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "body-parser": { + "version": "1.20.1", + "dev": true, + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "dev": true + } + } + }, + "bonjour-service": { + "version": "1.1.1", + "dev": true, + "requires": { + "array-flatten": "^2.1.2", + "dns-equal": "^1.0.0", + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "boolbase": { + "version": "1.0.0", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browserslist": { + "version": "4.21.5", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" + } + }, + "bs-logger": { + "version": "0.2.6", + "dev": true, + "requires": { + "fast-json-stable-stringify": "2.x" + } + }, + "bser": { + "version": "2.1.1", + "dev": true, + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer": { + "version": "6.0.3", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "buffer-from": { + "version": "1.1.2", + "dev": true + }, + "bytes": { + "version": "3.1.2", + "dev": true + }, + "call-bind": { + "version": "1.0.2", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "dev": true + }, + "camel-case": { + "version": "4.1.2", + "dev": true, + "requires": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "camelcase": { + "version": "5.3.1", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001476", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "char-regex": { + "version": "1.0.2", + "dev": true + }, + "chokidar": { + "version": "3.5.3", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, + "chrome-trace-event": { + "version": "1.0.3", + "dev": true + }, + "ci-info": { + "version": "3.8.0", + "dev": true + }, + "cjs-module-lexer": { + "version": "1.2.2", + "dev": true + }, + "clean-css": { + "version": "5.3.2", + "dev": true, + "requires": { + "source-map": "~0.6.0" + } + }, + "cliui": { + "version": "8.0.1", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "clone-deep": { + "version": "4.0.1", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } + }, + "co": { + "version": "4.6.0", + "dev": true + }, + "collect-v8-coverage": { + "version": "1.0.1", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "dev": true + }, + "colorette": { + "version": "2.0.20", + "dev": true + }, + "comlink": { + "version": "4.4.1", + "dev": true + }, + "commander": { + "version": "10.0.1" + }, + "compressible": { + "version": "2.0.18", + "dev": true, + "requires": { + "mime-db": ">= 1.43.0 < 2" + } + }, + "compression": { + "version": "1.7.4", + "dev": true, + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "dependencies": { + "bytes": { + "version": "3.0.0", + "dev": true + }, + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "dev": true + } + } + }, + "concat-map": { + "version": "0.0.1", + "dev": true + }, + "connect-history-api-fallback": { + "version": "2.0.0", + "dev": true + }, + "content-disposition": { + "version": "0.5.4", + "dev": true, + "requires": { + "safe-buffer": "5.2.1" + } + }, + "content-type": { + "version": "1.0.5", + "dev": true + }, + "convert-source-map": { + "version": "1.9.0", + "dev": true + }, + "cookie": { + "version": "0.5.0", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "dev": true + }, + "copy-webpack-plugin": { + "version": "11.0.0", + "dev": true, + "requires": { + "fast-glob": "^3.2.11", + "glob-parent": "^6.0.1", + "globby": "^13.1.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0" + }, + "dependencies": { + "globby": { + "version": "13.1.4", + "dev": true, + "requires": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.11", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^4.0.0" + } + }, + "slash": { + "version": "4.0.0", + "dev": true + } + } + }, + "core-util-is": { + "version": "1.0.3", + "dev": true + }, + "create-require": { + "version": "1.1.1", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "css-select": { + "version": "4.3.0", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + } + }, + "css-what": { + "version": "6.1.0", + "dev": true + }, + "debug": { + "version": "4.3.4", + "dev": true, + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "dev": true + } + } + }, + "dedent": { + "version": "0.7.0", + "dev": true + }, + "deep-is": { + "version": "0.1.4", + "dev": true + }, + "deepmerge": { + "version": "4.3.1", + "dev": true + }, + "default-gateway": { + "version": "6.0.3", + "dev": true, + "requires": { + "execa": "^5.0.0" + } + }, + "define-lazy-prop": { + "version": "2.0.0", + "dev": true + }, + "depd": { + "version": "2.0.0", + "dev": true + }, + "destroy": { + "version": "1.2.0", + "dev": true + }, + "detect-newline": { + "version": "3.1.0", + "dev": true + }, + "detect-node": { + "version": "2.1.0", + "dev": true + }, + "diff": { + "version": "4.0.2", + "dev": true + }, + "diff-sequences": { + "version": "29.4.3", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "dns-equal": { + "version": "1.0.0", + "dev": true + }, + "dns-packet": { + "version": "5.6.0", + "dev": true, + "requires": { + "@leichtgewicht/ip-codec": "^2.0.1" + } + }, + "doctrine": { + "version": "3.0.0", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-converter": { + "version": "0.2.0", + "dev": true, + "requires": { + "utila": "~0.4" + } + }, + "dom-serializer": { + "version": "1.4.1", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + } + }, + "domelementtype": { + "version": "2.3.0", + "dev": true + }, + "domhandler": { + "version": "4.3.1", + "dev": true, + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.8.0", + "dev": true, + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, + "dot-case": { + "version": "3.0.4", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "ee-first": { + "version": "1.1.1", + "dev": true + }, + "electron-to-chromium": { + "version": "1.4.356", + "dev": true + }, + "emittery": { + "version": "0.13.1", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "dev": true + }, + "enhanced-resolve": { + "version": "5.14.0", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "entities": { + "version": "2.2.0", + "dev": true + }, + "envinfo": { + "version": "7.8.1", + "dev": true + }, + "error-ex": { + "version": "1.3.2", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-module-lexer": { + "version": "1.2.1", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "dev": true + }, + "eslint": { + "version": "8.38.0", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.2", + "@eslint/js": "8.38.0", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-visitor-keys": "^3.4.0", + "espree": "^9.5.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "dev": true + }, + "eslint-scope": { + "version": "7.1.1", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "find-up": { + "version": "5.0.0", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "6.0.0", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "p-locate": { + "version": "5.0.0", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + } + } + }, + "eslint-config-prettier": { + "version": "8.8.0", + "dev": true, + "requires": {} + }, + "eslint-scope": { + "version": "5.1.1", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "dependencies": { + "estraverse": { + "version": "4.3.0", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "3.4.0", + "dev": true + }, + "espree": { + "version": "9.5.1", + "dev": true, + "requires": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.0" + } + }, + "esprima": { + "version": "4.0.1", + "dev": true + }, + "esquery": { + "version": "1.5.0", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "dev": true + }, + "etag": { + "version": "1.8.1", + "dev": true + }, + "eventemitter3": { + "version": "4.0.7", + "dev": true + }, + "events": { + "version": "3.3.0", + "dev": true + }, + "execa": { + "version": "5.1.1", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "exit": { + "version": "0.1.2", + "dev": true + }, + "expect": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/expect-utils": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0" + } + }, + "express": { + "version": "4.18.2", + "dev": true, + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "array-flatten": { + "version": "1.1.1", + "dev": true + }, + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "dev": true + } + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "dev": true + }, + "fast-glob": { + "version": "3.2.12", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "dev": true + }, + "fastest-levenshtein": { + "version": "1.0.16", + "dev": true + }, + "fastq": { + "version": "1.15.0", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "faye-websocket": { + "version": "0.11.4", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "fb-watchman": { + "version": "2.0.2", + "dev": true, + "requires": { + "bser": "2.1.1" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "file-uri-to-path": { + "version": "1.0.0" + }, + "fill-range": { + "version": "7.0.1", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.2.0", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "dev": true + } + } + }, + "find-up": { + "version": "4.1.0", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "3.0.4", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.7", + "dev": true + }, + "follow-redirects": { + "version": "1.15.2", + "dev": true + }, + "forwarded": { + "version": "0.2.0", + "dev": true + }, + "fresh": { + "version": "0.5.2", + "dev": true + }, + "fs-monkey": { + "version": "1.0.3", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.2", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "dev": true + }, + "get-intrinsic": { + "version": "1.2.0", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "get-package-type": { + "version": "0.1.0", + "dev": true + }, + "get-stream": { + "version": "6.0.1", + "dev": true + }, + "glob": { + "version": "7.2.3", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "glob-to-regexp": { + "version": "0.4.1", + "dev": true + }, + "globals": { + "version": "13.20.0", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "globby": { + "version": "11.1.0", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.11", + "dev": true + }, + "grapheme-splitter": { + "version": "1.0.4", + "dev": true + }, + "handle-thing": { + "version": "2.0.1", + "dev": true + }, + "has": { + "version": "1.0.3", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "dev": true + }, + "he": { + "version": "1.2.0", + "dev": true + }, + "hpack.js": { + "version": "2.1.6", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.8", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "html-entities": { + "version": "2.3.3", + "dev": true + }, + "html-escaper": { + "version": "2.0.2", + "dev": true + }, + "html-minifier-terser": { + "version": "6.1.0", + "dev": true, + "requires": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "dependencies": { + "commander": { + "version": "8.3.0", + "dev": true + } + } + }, + "html-webpack-plugin": { + "version": "5.5.1", + "dev": true, + "requires": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + } + }, + "htmlparser2": { + "version": "6.1.0", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "http-deceiver": { + "version": "1.2.7", + "dev": true + }, + "http-errors": { + "version": "2.0.0", + "dev": true, + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + } + }, + "http-parser-js": { + "version": "0.5.8", + "dev": true + }, + "http-proxy": { + "version": "1.18.1", + "dev": true, + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-middleware": { + "version": "2.0.6", + "dev": true, + "requires": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + } + }, + "human-signals": { + "version": "2.1.0", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "idb-keyval": { + "version": "6.2.1", + "dev": true + }, + "ieee754": { + "version": "1.2.1", + "dev": true + }, + "ignore": { + "version": "5.2.4", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "dev": true + } + } + }, + "import-local": { + "version": "3.1.0", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "dev": true + }, + "interpret": { + "version": "3.1.1", + "dev": true + }, + "ipaddr.js": { + "version": "1.9.1", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.11.0", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-docker": { + "version": "2.2.1", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true + }, + "is-generator-fn": { + "version": "2.1.0", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "dev": true + }, + "is-path-inside": { + "version": "3.0.3", + "dev": true + }, + "is-plain-obj": { + "version": "3.0.0", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-stream": { + "version": "2.0.1", + "dev": true + }, + "is-wsl": { + "version": "2.2.0", + "dev": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.2.0", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "5.2.1", + "dev": true, + "requires": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.1", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "3.1.5", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/core": "^29.5.0", + "@jest/types": "^29.5.0", + "import-local": "^3.0.2", + "jest-cli": "^29.5.0" + } + }, + "jest-changed-files": { + "version": "29.5.0", + "dev": true, + "requires": { + "execa": "^5.0.0", + "p-limit": "^3.1.0" + } + }, + "jest-circus": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.5.0", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.5.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-cli": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/core": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + } + }, + "jest-config": { + "version": "29.5.0", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.5.0", + "@jest/types": "^29.5.0", + "babel-jest": "^29.5.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.5.0", + "jest-environment-node": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.5.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + } + }, + "jest-diff": { + "version": "29.5.0", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + } + }, + "jest-docblock": { + "version": "29.4.3", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/types": "^29.5.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.4.3", + "jest-util": "^29.5.0", + "pretty-format": "^29.5.0" + } + }, + "jest-environment-node": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" + } + }, + "jest-get-type": { + "version": "29.4.3", + "dev": true + }, + "jest-haste-map": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/types": "^29.5.0", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + } + }, + "jest-leak-detector": { + "version": "29.5.0", + "dev": true, + "requires": { + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + } + }, + "jest-matcher-utils": { + "version": "29.5.0", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + } + }, + "jest-message-util": { + "version": "29.5.0", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.5.0", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.5.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-mock": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/types": "^29.5.0", + "@types/node": "*", + "jest-util": "^29.5.0" + } + }, + "jest-pnp-resolver": { + "version": "1.2.3", + "dev": true, + "requires": {} + }, + "jest-regex-util": { + "version": "29.4.3", + "dev": true + }, + "jest-resolve": { + "version": "29.5.0", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + } + }, + "jest-resolve-dependencies": { + "version": "29.5.0", + "dev": true, + "requires": { + "jest-regex-util": "^29.4.3", + "jest-snapshot": "^29.5.0" + } + }, + "jest-runner": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/console": "^29.5.0", + "@jest/environment": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.4.3", + "jest-environment-node": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-leak-detector": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-resolve": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-util": "^29.5.0", + "jest-watcher": "^29.5.0", + "jest-worker": "^29.5.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "dependencies": { + "source-map-support": { + "version": "0.5.13", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + } + } + }, + "jest-runtime": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/globals": "^29.5.0", + "@jest/source-map": "^29.4.3", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + } + }, + "jest-snapshot": { + "version": "29.5.0", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.5.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.5.0", + "semver": "^7.3.5" + } + }, + "jest-util": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + } + }, + "jest-validate": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/types": "^29.5.0", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.4.3", + "leven": "^3.1.0", + "pretty-format": "^29.5.0" + }, + "dependencies": { + "camelcase": { + "version": "6.3.0", + "dev": true + } + } + }, + "jest-watcher": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.5.0", + "string-length": "^4.0.1" + } + }, + "jest-worker": { + "version": "29.5.0", + "dev": true, + "requires": { + "@types/node": "*", + "jest-util": "^29.5.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "dependencies": { + "supports-color": { + "version": "8.1.1", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "js-sdsl": { + "version": "4.4.0", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "dev": true, + "requires": { + "argparse": "^2.0.1" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "dev": true + } + } + }, + "jsesc": { + "version": "2.5.2", + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "dev": true + }, + "json5": { + "version": "2.2.3", + "dev": true + }, + "kind-of": { + "version": "6.0.3", + "dev": true + }, + "kleur": { + "version": "3.0.3", + "dev": true + }, + "launch-editor": { + "version": "2.6.0", + "dev": true, + "requires": { + "picocolors": "^1.0.0", + "shell-quote": "^1.7.3" + } + }, + "leven": { + "version": "3.1.0", + "dev": true + }, + "levn": { + "version": "0.4.1", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lines-and-columns": { + "version": "1.2.4", + "dev": true + }, + "loader-runner": { + "version": "4.3.0", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.21", + "dev": true + }, + "lodash.memoize": { + "version": "4.1.2", + "dev": true + }, + "lodash.merge": { + "version": "4.6.2", + "dev": true + }, + "lower-case": { + "version": "2.0.2", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, + "lru-cache": { + "version": "6.0.0", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "make-dir": { + "version": "3.1.0", + "dev": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "dev": true + } + } + }, + "make-error": { + "version": "1.3.6", + "dev": true + }, + "makeerror": { + "version": "1.0.12", + "dev": true, + "requires": { + "tmpl": "1.0.5" + } + }, + "media-typer": { + "version": "0.3.0", + "dev": true + }, + "memfs": { + "version": "3.5.1", + "dev": true, + "requires": { + "fs-monkey": "^1.0.3" + } + }, + "merge-descriptors": { + "version": "1.0.1", + "dev": true + }, + "merge-stream": { + "version": "2.0.0", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "dev": true + }, + "methods": { + "version": "1.1.2", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mime": { + "version": "1.6.0", + "dev": true + }, + "mime-db": { + "version": "1.52.0", + "dev": true + }, + "mime-types": { + "version": "2.1.35", + "dev": true, + "requires": { + "mime-db": "1.52.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "ms": { + "version": "2.1.3", + "dev": true + }, + "multicast-dns": { + "version": "7.2.5", + "dev": true, + "requires": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + } + }, + "natural-compare": { + "version": "1.4.0", + "dev": true + }, + "natural-compare-lite": { + "version": "1.4.0", + "dev": true + }, + "negotiator": { + "version": "0.6.3", + "dev": true + }, + "neo-async": { + "version": "2.6.2", + "dev": true + }, + "no-case": { + "version": "3.0.4", + "dev": true, + "requires": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node-forge": { + "version": "1.3.1", + "dev": true + }, + "node-int64": { + "version": "0.4.0", + "dev": true + }, + "node-releases": { + "version": "2.0.10", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "nth-check": { + "version": "2.1.1", + "dev": true, + "requires": { + "boolbase": "^1.0.0" + } + }, + "object-inspect": { + "version": "1.12.3", + "dev": true + }, + "obuf": { + "version": "1.1.2", + "dev": true + }, + "on-finished": { + "version": "2.4.1", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "dev": true + }, + "once": { + "version": "1.4.0", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "open": { + "version": "8.4.2", + "dev": true, + "requires": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + } + }, + "optionator": { + "version": "0.9.1", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "p-limit": { + "version": "3.1.0", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + }, + "dependencies": { + "p-limit": { + "version": "2.3.0", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + } + } + }, + "p-retry": { + "version": "4.6.2", + "dev": true, + "requires": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "dependencies": { + "retry": { + "version": "0.13.1", + "dev": true + } + } + }, + "p-try": { + "version": "2.2.0", + "dev": true + }, + "param-case": { + "version": "3.0.4", + "dev": true, + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "parent-module": { + "version": "1.0.1", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "5.2.0", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "parseurl": { + "version": "1.3.3", + "dev": true + }, + "pascal-case": { + "version": "3.1.2", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "path-exists": { + "version": "4.0.0", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "dev": true + }, + "path-type": { + "version": "4.0.0", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "dev": true + }, + "pirates": { + "version": "4.0.5", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "prelude-ls": { + "version": "1.2.1", + "dev": true + }, + "prettier": { + "version": "2.8.7", + "dev": true + }, + "pretty-error": { + "version": "4.0.0", + "dev": true, + "requires": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "pretty-format": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "dev": true + } + } + }, + "process-nextick-args": { + "version": "2.0.1", + "dev": true + }, + "prompts": { + "version": "2.4.2", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } + }, + "proxy-addr": { + "version": "2.0.7", + "dev": true, + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "punycode": { + "version": "2.3.0", + "dev": true + }, + "pure-rand": { + "version": "6.0.1", + "dev": true + }, + "qs": { + "version": "6.11.0", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + }, + "queue-microtask": { + "version": "1.2.3", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "dev": true + }, + "raw-body": { + "version": "2.5.1", + "dev": true, + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "react-is": { + "version": "18.2.0", + "dev": true + }, + "readable-stream": { + "version": "3.6.2", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "3.6.0", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "rechoir": { + "version": "0.8.0", + "dev": true, + "requires": { + "resolve": "^1.20.0" + } + }, + "relateurl": { + "version": "0.2.7", + "dev": true + }, + "renderkid": { + "version": "3.0.0", + "dev": true, + "requires": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "require-directory": { + "version": "2.1.1", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "dev": true + }, + "requires-port": { + "version": "1.0.0", + "dev": true + }, + "resolve": { + "version": "1.22.2", + "dev": true, + "requires": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "dev": true + }, + "resolve-typescript-plugin": { + "version": "2.0.1", + "dev": true, + "requires": { + "tslib": "2.5.0" + } + }, + "resolve.exports": { + "version": "2.0.2", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-parallel": { + "version": "1.2.0", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "safe-buffer": { + "version": "5.2.1", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "dev": true + }, + "schema-utils": { + "version": "4.0.1", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + } + }, + "select-hose": { + "version": "2.0.0", + "dev": true + }, + "selfsigned": { + "version": "2.1.1", + "dev": true, + "requires": { + "node-forge": "^1" + } + }, + "semver": { + "version": "7.3.8", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "send": { + "version": "0.18.0", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "dev": true + } + } + } + } + }, + "serialize-javascript": { + "version": "6.0.1", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-index": { + "version": "1.9.1", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "1.1.2", + "dev": true + }, + "http-errors": { + "version": "1.6.3", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3", + "dev": true + }, + "ms": { + "version": "2.0.0", + "dev": true + }, + "setprototypeof": { + "version": "1.1.0", + "dev": true + }, + "statuses": { + "version": "1.5.0", + "dev": true + } + } + }, + "serve-static": { + "version": "1.15.0", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + } + }, + "setprototypeof": { + "version": "1.2.0", + "dev": true + }, + "shallow-clone": { + "version": "3.0.1", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, + "shebang-command": { + "version": "2.0.0", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "dev": true + }, + "shell-quote": { + "version": "1.8.1", + "dev": true + }, + "side-channel": { + "version": "1.0.4", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "signal-exit": { + "version": "3.0.7", + "dev": true + }, + "sisteransi": { + "version": "1.0.5", + "dev": true + }, + "slash": { + "version": "3.0.0", + "dev": true + }, + "sockjs": { + "version": "0.3.24", + "dev": true, + "requires": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "source-map": { + "version": "0.6.1", + "dev": true + }, + "source-map-support": { + "version": "0.5.21", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "spdy": { + "version": "4.0.2", + "dev": true, + "requires": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + } + }, + "spdy-transport": { + "version": "3.0.0", + "dev": true, + "requires": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "sprintf-js": { + "version": "1.0.3", + "dev": true + }, + "stack-utils": { + "version": "2.0.6", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "dev": true + } + } + }, + "statuses": { + "version": "2.0.1", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "string-length": { + "version": "4.0.2", + "dev": true, + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + } + }, + "string-width": { + "version": "4.2.3", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "4.0.0", + "dev": true + }, + "strip-final-newline": { + "version": "2.0.0", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true + }, + "tapable": { + "version": "2.2.1", + "dev": true + }, + "terser": { + "version": "5.17.3", + "dev": true, + "requires": { + "@jridgewell/source-map": "^0.3.2", + "acorn": "^8.5.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "dev": true + } + } + }, + "terser-webpack-plugin": { + "version": "5.3.8", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.17", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.16.8" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "dev": true, + "requires": {} + }, + "jest-worker": { + "version": "27.5.1", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "schema-utils": { + "version": "3.1.2", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "supports-color": { + "version": "8.1.1", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "test-exclude": { + "version": "6.0.0", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "text-table": { + "version": "0.2.0", + "dev": true + }, + "thunky": { + "version": "1.1.0", + "dev": true + }, + "tmpl": { + "version": "1.0.5", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.1", + "dev": true + }, + "ts-jest": { + "version": "29.1.0", + "dev": true, + "requires": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "^21.0.1" + } + }, + "ts-loader": { + "version": "9.4.2", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4" + }, + "dependencies": { + "semver": { + "version": "7.5.0", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "ts-node": { + "version": "10.9.1", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + } + }, + "tslib": { + "version": "2.5.0" + }, + "tsutils": { + "version": "3.21.0", + "dev": true, + "requires": { + "tslib": "^1.8.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "dev": true + } + } + }, + "type-check": { + "version": "0.4.0", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-detect": { + "version": "4.0.8", + "dev": true + }, + "type-fest": { + "version": "0.20.2", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typescript": { + "version": "5.0.4", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "dev": true + }, + "update-browserslist-db": { + "version": "1.0.10", + "dev": true, + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, + "uri-js": { + "version": "4.4.1", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "dev": true + }, + "utila": { + "version": "0.4.0", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "dev": true + }, + "uuid": { + "version": "8.3.2", + "dev": true + }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "dev": true + }, + "v8-to-istanbul": { + "version": "9.1.0", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + } + }, + "vary": { + "version": "1.1.2", + "dev": true + }, + "walker": { + "version": "1.0.8", + "dev": true, + "requires": { + "makeerror": "1.0.12" + } + }, + "watchpack": { + "version": "2.4.0", + "dev": true, + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, + "wbuf": { + "version": "1.7.3", + "dev": true, + "requires": { + "minimalistic-assert": "^1.0.0" + } + }, + "webpack": { + "version": "5.82.1", + "dev": true, + "requires": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.14.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.2", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.7", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "dev": true, + "requires": {} + }, + "schema-utils": { + "version": "3.1.2", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "webpack-cli": { + "version": "5.1.1", + "dev": true, + "requires": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.0", + "@webpack-cli/info": "^2.0.1", + "@webpack-cli/serve": "^2.0.4", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + } + }, + "webpack-dev-middleware": { + "version": "5.3.3", + "dev": true, + "requires": { + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + } + }, + "webpack-dev-server": { + "version": "4.15.0", + "dev": true, + "requires": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.1", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.13.0" + }, + "dependencies": { + "ipaddr.js": { + "version": "2.0.1", + "dev": true + } + } + }, + "webpack-merge": { + "version": "5.8.0", + "dev": true, + "requires": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + } + }, + "webpack-sources": { + "version": "3.2.3", + "dev": true + }, + "websocket-driver": { + "version": "0.7.4", + "dev": true, + "requires": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.4", + "dev": true + }, + "which": { + "version": "2.0.2", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wildcard": { + "version": "2.0.1", + "dev": true + }, + "word-wrap": { + "version": "1.2.3", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "dev": true + }, + "write-file-atomic": { + "version": "4.0.2", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + } + }, + "ws": { + "version": "8.13.0", + "dev": true, + "requires": {} + }, + "y18n": { + "version": "5.0.8", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "dev": true + }, + "yargs": { + "version": "17.7.1", + "dev": true, + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "dev": true + }, + "yn": { + "version": "3.1.1", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "dev": true + } + } +} diff --git a/ts/package.json b/ts/package.json index f4c7afde95..e8bb1dc842 100644 --- a/ts/package.json +++ b/ts/package.json @@ -13,7 +13,7 @@ }, "scripts": { "clean": "rm -rf ./dest .tsbuildinfo", - "build": "yarn clean && yarn build:wasm && tsc -b && webpack", + "build": "yarn clean && yarn build:wasm && tsc -b && webpack && chmod +x ./dest/main.js", "build:dev": "tsc -b --watch", "build:wasm": "cd ../cpp && cmake --preset wasm-threads && cmake --build --preset wasm-threads", "serve": "webpack serve", @@ -41,6 +41,7 @@ }, "dependencies": { "bigint-buffer": "^1.1.5", + "commander": "^10.0.1", "tslib": "^2.4.0" }, "devDependencies": { diff --git a/ts/src/barretenberg_wasm/node/index.ts b/ts/src/barretenberg_wasm/node/index.ts index f8943dce3d..c5ced64077 100644 --- a/ts/src/barretenberg_wasm/node/index.ts +++ b/ts/src/barretenberg_wasm/node/index.ts @@ -15,7 +15,7 @@ export async function fetchCode(name: string) { export function createWorker() { const __dirname = dirname(fileURLToPath(import.meta.url)); - return new Worker(__dirname + `/worker.ts`); + return new Worker(__dirname + `/worker.js`); } export function getRemoteBarretenbergWasm(worker: Worker): BarretenbergWasmWorker { diff --git a/ts/src/main.ts b/ts/src/main.ts index 1ed9c74785..46591ac968 100755 --- a/ts/src/main.ts +++ b/ts/src/main.ts @@ -1,4 +1,4 @@ -#!/usr/bin/env node +#!/usr/bin/env -S node --no-warnings import { Crs } from './crs/index.js'; import createDebug from 'debug'; import { newBarretenbergApiAsync } from './factory/index.js'; @@ -6,34 +6,25 @@ import { readFileSync } from 'fs'; import { gunzipSync } from 'zlib'; import { RawBuffer } from './types/index.js'; import { numToInt32BE } from './serialize/serialize.js'; +import { Command } from 'commander'; const debug = createDebug('bb.js'); createDebug.enable('*'); -function getBytecode() { - const json = readFileSync('/mnt/user-data/charlie/noir-projects/512k/target/main.json', 'utf-8'); +function getBytecode(jsonPath: string) { + const json = readFileSync(jsonPath, 'utf-8'); const parsed = JSON.parse(json); const buffer = Buffer.from(parsed.bytecode, 'base64'); const decompressed = gunzipSync(buffer); return decompressed; } -function getWitness() { - const data = readFileSync('/mnt/user-data/charlie/noir-projects/512k/target/witness.tr'); +function getWitness(witnessPath: string) { + const data = readFileSync(witnessPath); return Buffer.concat([numToInt32BE(data.length / 32), data]); } -// nargo use bb.js: backend -> bb.js -// backend prove --data-dir data --witness /foo/bar/witness.tr --json /foo/bar/main.json -// backend verify ... -// backend get_total_num_gates --data-dir data --json /foo/bar/main.json -// backend get_sol_contract --data-dir data --json /foo/bar/main.json --output -// backend get_features -// OPTIONAL stateful backend: -// backend start -// backend stop -export async function main() { - debug('starting test...'); +export async function proveAndVerify(jsonPath: string, witnessPath: string) { const api = await newBarretenbergApiAsync(); try { const CIRCUIT_SIZE = 2 ** 19; @@ -48,7 +39,7 @@ export async function main() { const acirComposer = await api.acirNewAcirComposer(pippengerPtr, crs.getG2Data()); debug('initing proving key...'); - const bytecode = getBytecode(); + const bytecode = getBytecode(jsonPath); await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), CIRCUIT_SIZE); const exactCircuitSize = await api.acirGetExactCircuitSize(acirComposer); @@ -57,19 +48,39 @@ export async function main() { debug('initing verification key...'); await api.acirInitVerificationKey(acirComposer); - for (let i = 0; i < 10; i++) { - debug(`creating proof ${i}...`); - const witness = getWitness(); - const proof = await api.acirCreateProof(acirComposer, new RawBuffer(bytecode), new RawBuffer(witness)); + debug(`creating proof...`); + const witness = getWitness(witnessPath); + const proof = await api.acirCreateProof(acirComposer, new RawBuffer(bytecode), new RawBuffer(witness)); - const verified = await api.acirVerifyProof(acirComposer, proof); - debug(`verified: ${verified}`); - } + const verified = await api.acirVerifyProof(acirComposer, proof); + debug(`verified: ${verified}`); - debug('test complete.'); + return verified; } finally { await api.destroy(); } } -await main().catch(console.error); +// nargo use bb.js: backend -> bb.js +// backend prove --data-dir data --witness /foo/bar/witness.tr --json /foo/bar/main.json +// backend verify ... +// backend get_total_num_gates --data-dir data --json /foo/bar/main.json +// backend get_sol_contract --data-dir data --json /foo/bar/main.json --output +// backend get_features +// OPTIONAL stateful backend: +// backend start +// backend stop + +const program = new Command(); + +program + .command('prove_and_verify') + .description('Generate a proof and verify it. Process exits with success or failure code.') + .option('-j, --json-path ', 'Specify the JSON path', './target/main.json') + .option('-w, --witness-path ', 'Specify the witness path', './target/witness.tr') + .action(async ({ jsonPath, witnessPath }) => { + const result = await proveAndVerify(jsonPath, witnessPath); + process.exit(result ? 0 : 1); + }); + +program.parse(process.argv); diff --git a/ts/webpack.config.js b/ts/webpack.config.js index 91813fcbc7..dee0d3492c 100644 --- a/ts/webpack.config.js +++ b/ts/webpack.config.js @@ -39,7 +39,11 @@ export default { { // Point directly to the built file, not the symlink, else copy-on-change doesn't work... from: `../cpp/build-wasm/bin/barretenberg.wasm`, - to: 'barretenberg.wasm', + to: 'barretenberg_wasm/barretenberg.wasm', + }, + { + from: `../cpp/build-wasm-threads/bin/barretenberg.wasm`, + to: 'barretenberg_wasm/barretenberg-threads.wasm', }, ], }), diff --git a/ts/yarn.lock b/ts/yarn.lock index a2ae89854a..56f0530fc7 100644 --- a/ts/yarn.lock +++ b/ts/yarn.lock @@ -30,6 +30,7 @@ __metadata: bigint-buffer: ^1.1.5 buffer: ^6.0.3 comlink: ^4.4.1 + commander: ^10.0.1 copy-webpack-plugin: ^11.0.0 debug: ^4.3.4 eslint: ^8.35.0 @@ -47,10 +48,13 @@ __metadata: webpack: ^5.82.1 webpack-cli: ^5.1.1 webpack-dev-server: ^4.15.0 + bin: + bb.js: ./dest/main.js + bb.js-dev: ./src/main-dev.ts languageName: unknown linkType: soft -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.18.6, @babel/code-frame@npm:^7.21.4": +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.21.4": version: 7.21.4 resolution: "@babel/code-frame@npm:7.21.4" dependencies: @@ -59,67 +63,67 @@ __metadata: languageName: node linkType: hard -"@babel/compat-data@npm:^7.21.4": - version: 7.21.4 - resolution: "@babel/compat-data@npm:7.21.4" - checksum: 5f8b98c66f2ffba9f3c3a82c0cf354c52a0ec5ad4797b370dc32bdcd6e136ac4febe5e93d76ce76e175632e2dbf6ce9f46319aa689fcfafa41b6e49834fa4b66 +"@babel/compat-data@npm:^7.21.5": + version: 7.21.9 + resolution: "@babel/compat-data@npm:7.21.9" + checksum: df97be04955c0801f5a23846f79a100660aa98f9433cfd1fad8f53ecd9f3454538e78522e86275939aa8aa7d6f9e32f23f94bc04ae843f7246b7cd4bffe3a175 languageName: node linkType: hard "@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3": - version: 7.21.4 - resolution: "@babel/core@npm:7.21.4" + version: 7.21.8 + resolution: "@babel/core@npm:7.21.8" dependencies: "@ampproject/remapping": ^2.2.0 "@babel/code-frame": ^7.21.4 - "@babel/generator": ^7.21.4 - "@babel/helper-compilation-targets": ^7.21.4 - "@babel/helper-module-transforms": ^7.21.2 - "@babel/helpers": ^7.21.0 - "@babel/parser": ^7.21.4 + "@babel/generator": ^7.21.5 + "@babel/helper-compilation-targets": ^7.21.5 + "@babel/helper-module-transforms": ^7.21.5 + "@babel/helpers": ^7.21.5 + "@babel/parser": ^7.21.8 "@babel/template": ^7.20.7 - "@babel/traverse": ^7.21.4 - "@babel/types": ^7.21.4 + "@babel/traverse": ^7.21.5 + "@babel/types": ^7.21.5 convert-source-map: ^1.7.0 debug: ^4.1.0 gensync: ^1.0.0-beta.2 json5: ^2.2.2 semver: ^6.3.0 - checksum: a3beebb2cc79908a02f27a07dc381bcb34e8ecc58fa99f568ad0934c49e12111fc977ee9c5b51eb7ea2da66f63155d37c4dd96b6472eaeecfc35843ccb56bf3d + checksum: f28118447355af2a90bd340e2e60699f94c8020517eba9b71bf8ebff62fa9e00d63f076e033f9dfb97548053ad62ada45fafb0d96584b1a90e8aef5a3b8241b1 languageName: node linkType: hard -"@babel/generator@npm:^7.21.4, @babel/generator@npm:^7.7.2": - version: 7.21.4 - resolution: "@babel/generator@npm:7.21.4" +"@babel/generator@npm:^7.21.5, @babel/generator@npm:^7.7.2": + version: 7.21.9 + resolution: "@babel/generator@npm:7.21.9" dependencies: - "@babel/types": ^7.21.4 + "@babel/types": ^7.21.5 "@jridgewell/gen-mapping": ^0.3.2 "@jridgewell/trace-mapping": ^0.3.17 jsesc: ^2.5.1 - checksum: 9ffbb526a53bb8469b5402f7b5feac93809b09b2a9f82fcbfcdc5916268a65dae746a1f2479e03ba4fb0776facd7c892191f63baa61ab69b2cfdb24f7b92424d + checksum: 5bd10334ebdf7f2a30eb4a1fd99d369a57703aa2234527784449187512c254a1174fa739c9d4c31bcbb6018732012a0664bec7c314f12b5ec2458737ddbb01c7 languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.21.4": - version: 7.21.4 - resolution: "@babel/helper-compilation-targets@npm:7.21.4" +"@babel/helper-compilation-targets@npm:^7.21.5": + version: 7.21.5 + resolution: "@babel/helper-compilation-targets@npm:7.21.5" dependencies: - "@babel/compat-data": ^7.21.4 + "@babel/compat-data": ^7.21.5 "@babel/helper-validator-option": ^7.21.0 browserslist: ^4.21.3 lru-cache: ^5.1.1 semver: ^6.3.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: bf9c7d3e7e6adff9222c05d898724cd4ee91d7eb9d52222c7ad2a22955620c2872cc2d9bdf0e047df8efdb79f4e3af2a06b53f509286145feccc4d10ddc318be + checksum: 0edecb9c970ddc22ebda1163e77a7f314121bef9e483e0e0d9a5802540eed90d5855b6bf9bce03419b35b2e07c323e62d0353b153fa1ca34f17dbba897a83c25 languageName: node linkType: hard -"@babel/helper-environment-visitor@npm:^7.18.9": - version: 7.18.9 - resolution: "@babel/helper-environment-visitor@npm:7.18.9" - checksum: b25101f6162ddca2d12da73942c08ad203d7668e06663df685634a8fde54a98bc015f6f62938e8554457a592a024108d45b8f3e651fd6dcdb877275b73cc4420 +"@babel/helper-environment-visitor@npm:^7.21.5": + version: 7.21.5 + resolution: "@babel/helper-environment-visitor@npm:7.21.5" + checksum: e436af7b62956e919066448013a3f7e2cd0b51010c26c50f790124dcd350be81d5597b4e6ed0a4a42d098a27de1e38561cd7998a116a42e7899161192deac9a6 languageName: node linkType: hard @@ -142,7 +146,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.18.6": +"@babel/helper-module-imports@npm:^7.21.4": version: 7.21.4 resolution: "@babel/helper-module-imports@npm:7.21.4" dependencies: @@ -151,35 +155,35 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.21.2": - version: 7.21.2 - resolution: "@babel/helper-module-transforms@npm:7.21.2" +"@babel/helper-module-transforms@npm:^7.21.5": + version: 7.21.5 + resolution: "@babel/helper-module-transforms@npm:7.21.5" dependencies: - "@babel/helper-environment-visitor": ^7.18.9 - "@babel/helper-module-imports": ^7.18.6 - "@babel/helper-simple-access": ^7.20.2 + "@babel/helper-environment-visitor": ^7.21.5 + "@babel/helper-module-imports": ^7.21.4 + "@babel/helper-simple-access": ^7.21.5 "@babel/helper-split-export-declaration": ^7.18.6 "@babel/helper-validator-identifier": ^7.19.1 "@babel/template": ^7.20.7 - "@babel/traverse": ^7.21.2 - "@babel/types": ^7.21.2 - checksum: 8a1c129a4f90bdf97d8b6e7861732c9580f48f877aaaafbc376ce2482febebcb8daaa1de8bc91676d12886487603f8c62a44f9e90ee76d6cac7f9225b26a49e1 + "@babel/traverse": ^7.21.5 + "@babel/types": ^7.21.5 + checksum: 1ccfc88830675a5d485d198e918498f9683cdd46f973fdd4fe1c85b99648fb70f87fca07756c7a05dc201bd9b248c74ced06ea80c9991926ac889f53c3659675 languageName: node linkType: hard "@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.20.2, @babel/helper-plugin-utils@npm:^7.8.0": - version: 7.20.2 - resolution: "@babel/helper-plugin-utils@npm:7.20.2" - checksum: f6cae53b7fdb1bf3abd50fa61b10b4470985b400cc794d92635da1e7077bb19729f626adc0741b69403d9b6e411cddddb9c0157a709cc7c4eeb41e663be5d74b + version: 7.21.5 + resolution: "@babel/helper-plugin-utils@npm:7.21.5" + checksum: 6f086e9a84a50ea7df0d5639c8f9f68505af510ea3258b3c8ac8b175efdfb7f664436cb48996f71791a1350ba68f47ad3424131e8e718c5e2ad45564484cbb36 languageName: node linkType: hard -"@babel/helper-simple-access@npm:^7.20.2": - version: 7.20.2 - resolution: "@babel/helper-simple-access@npm:7.20.2" +"@babel/helper-simple-access@npm:^7.21.5": + version: 7.21.5 + resolution: "@babel/helper-simple-access@npm:7.21.5" dependencies: - "@babel/types": ^7.20.2 - checksum: ad1e96ee2e5f654ffee2369a586e5e8d2722bf2d8b028a121b4c33ebae47253f64d420157b9f0a8927aea3a9e0f18c0103e74fdd531815cf3650a0a4adca11a1 + "@babel/types": ^7.21.5 + checksum: ad212beaa24be3864c8c95bee02f840222457ccf5419991e2d3e3e39b0f75b77e7e857e0bf4ed428b1cd97acefc87f3831bdb0b9696d5ad0557421f398334fc3 languageName: node linkType: hard @@ -192,10 +196,10 @@ __metadata: languageName: node linkType: hard -"@babel/helper-string-parser@npm:^7.19.4": - version: 7.19.4 - resolution: "@babel/helper-string-parser@npm:7.19.4" - checksum: b2f8a3920b30dfac81ec282ac4ad9598ea170648f8254b10f475abe6d944808fb006aab325d3eb5a8ad3bea8dfa888cfa6ef471050dae5748497c110ec060943 +"@babel/helper-string-parser@npm:^7.21.5": + version: 7.21.5 + resolution: "@babel/helper-string-parser@npm:7.21.5" + checksum: 36c0ded452f3858e67634b81960d4bde1d1cd2a56b82f4ba2926e97864816021c885f111a7cf81de88a0ed025f49d84a393256700e9acbca2d99462d648705d8 languageName: node linkType: hard @@ -213,14 +217,14 @@ __metadata: languageName: node linkType: hard -"@babel/helpers@npm:^7.21.0": - version: 7.21.0 - resolution: "@babel/helpers@npm:7.21.0" +"@babel/helpers@npm:^7.21.5": + version: 7.21.5 + resolution: "@babel/helpers@npm:7.21.5" dependencies: "@babel/template": ^7.20.7 - "@babel/traverse": ^7.21.0 - "@babel/types": ^7.21.0 - checksum: 9370dad2bb665c551869a08ac87c8bdafad53dbcdce1f5c5d498f51811456a3c005d9857562715151a0f00b2e912ac8d89f56574f837b5689f5f5072221cdf54 + "@babel/traverse": ^7.21.5 + "@babel/types": ^7.21.5 + checksum: a6f74b8579713988e7f5adf1a986d8b5255757632ba65b2552f0f609ead5476edb784044c7e4b18f3681ee4818ca9d08c41feb9bd4e828648c25a00deaa1f9e4 languageName: node linkType: hard @@ -235,12 +239,12 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.21.4": - version: 7.21.4 - resolution: "@babel/parser@npm:7.21.4" +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.21.5, @babel/parser@npm:^7.21.8, @babel/parser@npm:^7.21.9": + version: 7.21.9 + resolution: "@babel/parser@npm:7.21.9" bin: parser: ./bin/babel-parser.js - checksum: de610ecd1bff331766d0c058023ca11a4f242bfafefc42caf926becccfb6756637d167c001987ca830dd4b34b93c629a4cef63f8c8c864a8564cdfde1989ac77 + checksum: 985ccc311eb286a320331fd21ff54d94935df76e081abdb304cd4591ea2051a6c799c6b0d8e26d09a9dd041797d9a91ebadeb0c50699d0101bd39fc565082d5c languageName: node linkType: hard @@ -399,42 +403,42 @@ __metadata: linkType: hard "@babel/template@npm:^7.20.7, @babel/template@npm:^7.3.3": - version: 7.20.7 - resolution: "@babel/template@npm:7.20.7" + version: 7.21.9 + resolution: "@babel/template@npm:7.21.9" dependencies: - "@babel/code-frame": ^7.18.6 - "@babel/parser": ^7.20.7 - "@babel/types": ^7.20.7 - checksum: 2eb1a0ab8d415078776bceb3473d07ab746e6bb4c2f6ca46ee70efb284d75c4a32bb0cd6f4f4946dec9711f9c0780e8e5d64b743208deac6f8e9858afadc349e + "@babel/code-frame": ^7.21.4 + "@babel/parser": ^7.21.9 + "@babel/types": ^7.21.5 + checksum: 6ec2c60d4d53b2a9230ab82c399ba6525df87e9a4e01e4b111e071cbad283b1362e7c99a1bc50027073f44f2de36a495a89c27112c4e7efe7ef9c8d9c84de2ec languageName: node linkType: hard -"@babel/traverse@npm:^7.21.0, @babel/traverse@npm:^7.21.2, @babel/traverse@npm:^7.21.4, @babel/traverse@npm:^7.7.2": - version: 7.21.4 - resolution: "@babel/traverse@npm:7.21.4" +"@babel/traverse@npm:^7.21.5, @babel/traverse@npm:^7.7.2": + version: 7.21.5 + resolution: "@babel/traverse@npm:7.21.5" dependencies: "@babel/code-frame": ^7.21.4 - "@babel/generator": ^7.21.4 - "@babel/helper-environment-visitor": ^7.18.9 + "@babel/generator": ^7.21.5 + "@babel/helper-environment-visitor": ^7.21.5 "@babel/helper-function-name": ^7.21.0 "@babel/helper-hoist-variables": ^7.18.6 "@babel/helper-split-export-declaration": ^7.18.6 - "@babel/parser": ^7.21.4 - "@babel/types": ^7.21.4 + "@babel/parser": ^7.21.5 + "@babel/types": ^7.21.5 debug: ^4.1.0 globals: ^11.1.0 - checksum: f22f067c2d9b6497abf3d4e53ea71f3aa82a21f2ed434dd69b8c5767f11f2a4c24c8d2f517d2312c9e5248e5c69395fdca1c95a2b3286122c75f5783ddb6f53c + checksum: b403733fa7d858f0c8e224f0434a6ade641bc469a4f92975363391e796629d5bf53e544761dfe85039aab92d5389ebe7721edb309d7a5bb7df2bf74f37bf9f47 languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.6, @babel/types@npm:^7.20.2, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.0, @babel/types@npm:^7.21.2, @babel/types@npm:^7.21.4, @babel/types@npm:^7.3.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.8.3": - version: 7.21.4 - resolution: "@babel/types@npm:7.21.4" +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.6, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.0, @babel/types@npm:^7.21.4, @babel/types@npm:^7.21.5, @babel/types@npm:^7.3.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.8.3": + version: 7.21.5 + resolution: "@babel/types@npm:7.21.5" dependencies: - "@babel/helper-string-parser": ^7.19.4 + "@babel/helper-string-parser": ^7.21.5 "@babel/helper-validator-identifier": ^7.19.1 to-fast-properties: ^2.0.0 - checksum: 587bc55a91ce003b0f8aa10d70070f8006560d7dc0360dc0406d306a2cb2a10154e2f9080b9c37abec76907a90b330a536406cb75e6bdc905484f37b75c73219 + checksum: 43242a99c612d13285ee4af46cc0f1066bcb6ffd38307daef7a76e8c70f36cfc3255eb9e75c8e768b40e761176c313aec4d5c0b9d97a21e494d49d5fd123a9f7 languageName: node linkType: hard @@ -473,33 +477,33 @@ __metadata: linkType: hard "@eslint-community/regexpp@npm:^4.4.0": - version: 4.5.0 - resolution: "@eslint-community/regexpp@npm:4.5.0" - checksum: 99c01335947dbd7f2129e954413067e217ccaa4e219fe0917b7d2bd96135789384b8fedbfb8eb09584d5130b27a7b876a7150ab7376f51b3a0c377d5ce026a10 + version: 4.5.1 + resolution: "@eslint-community/regexpp@npm:4.5.1" + checksum: 6d901166d64998d591fab4db1c2f872981ccd5f6fe066a1ad0a93d4e11855ecae6bfb76660869a469563e8882d4307228cebd41142adb409d182f2966771e57e languageName: node linkType: hard -"@eslint/eslintrc@npm:^2.0.2": - version: 2.0.2 - resolution: "@eslint/eslintrc@npm:2.0.2" +"@eslint/eslintrc@npm:^2.0.3": + version: 2.0.3 + resolution: "@eslint/eslintrc@npm:2.0.3" dependencies: ajv: ^6.12.4 debug: ^4.3.2 - espree: ^9.5.1 + espree: ^9.5.2 globals: ^13.19.0 ignore: ^5.2.0 import-fresh: ^3.2.1 js-yaml: ^4.1.0 minimatch: ^3.1.2 strip-json-comments: ^3.1.1 - checksum: cfcf5e12c7b2c4476482e7f12434e76eae16fcd163ee627309adb10b761e5caa4a4e52ed7be464423320ff3d11eca5b50de5bf8be3e25834222470835dd5c801 + checksum: ddc51f25f8524d8231db9c9bf03177e503d941a332e8d5ce3b10b09241be4d5584a378a529a27a527586bfbccf3031ae539eb891352033c340b012b4d0c81d92 languageName: node linkType: hard -"@eslint/js@npm:8.38.0": - version: 8.38.0 - resolution: "@eslint/js@npm:8.38.0" - checksum: 1f28987aa8c9cd93e23384e16c7220863b39b5dc4b66e46d7cdbccce868040f455a98d24cd8b567a884f26545a0555b761f7328d4a00c051e7ef689cbea5fce1 +"@eslint/js@npm:8.41.0": + version: 8.41.0 + resolution: "@eslint/js@npm:8.41.0" + checksum: af013d70fe8d0429cdf5cd8b5dcc6fc384ed026c1eccb0cfe30f5849b968ab91645111373fd1b83282b38955b1bdfbe667c1a7dbda3b06cae753521223cad775 languageName: node linkType: hard @@ -922,21 +926,21 @@ __metadata: languageName: node linkType: hard -"@sinonjs/commons@npm:^2.0.0": - version: 2.0.0 - resolution: "@sinonjs/commons@npm:2.0.0" +"@sinonjs/commons@npm:^3.0.0": + version: 3.0.0 + resolution: "@sinonjs/commons@npm:3.0.0" dependencies: type-detect: 4.0.8 - checksum: 5023ba17edf2b85ed58262313b8e9b59e23c6860681a9af0200f239fe939e2b79736d04a260e8270ddd57196851dde3ba754d7230be5c5234e777ae2ca8af137 + checksum: b4b5b73d4df4560fb8c0c7b38c7ad4aeabedd362f3373859d804c988c725889cde33550e4bcc7cd316a30f5152a2d1d43db71b6d0c38f5feef71fd8d016763f8 languageName: node linkType: hard "@sinonjs/fake-timers@npm:^10.0.2": - version: 10.0.2 - resolution: "@sinonjs/fake-timers@npm:10.0.2" + version: 10.2.0 + resolution: "@sinonjs/fake-timers@npm:10.2.0" dependencies: - "@sinonjs/commons": ^2.0.0 - checksum: c62aa98e7cefda8dedc101ce227abc888dc46b8ff9706c5f0a8dfd9c3ada97d0a5611384738d9ba0b26b59f99c2ba24efece8e779bb08329e9e87358fa309824 + "@sinonjs/commons": ^3.0.0 + checksum: 586c76e1dd90d03b0c4e754f2011325b38ac6055878c81c52434c900f36d9d245438c96ef69e08e28d9fbecf2335fb347b67850962d8b6e539dd7359d8c62802 languageName: node linkType: hard @@ -969,9 +973,9 @@ __metadata: linkType: hard "@tsconfig/node16@npm:^1.0.2": - version: 1.0.3 - resolution: "@tsconfig/node16@npm:1.0.3" - checksum: 3a8b657dd047495b7ad23437d6afd20297ce90380ff0bdee93fc7d39a900dbd8d9e26e53ff6b465e7967ce2adf0b218782590ce9013285121e6a5928fbd6819f + version: 1.0.4 + resolution: "@tsconfig/node16@npm:1.0.4" + checksum: 202319785901f942a6e1e476b872d421baec20cf09f4b266a1854060efbf78cde16a4d256e8bc949d31e6cd9a90f1e8ef8fb06af96a65e98338a2b6b0de0a0ff languageName: node linkType: hard @@ -1008,11 +1012,11 @@ __metadata: linkType: hard "@types/babel__traverse@npm:*, @types/babel__traverse@npm:^7.0.6": - version: 7.18.3 - resolution: "@types/babel__traverse@npm:7.18.3" + version: 7.18.5 + resolution: "@types/babel__traverse@npm:7.18.5" dependencies: "@babel/types": ^7.3.0 - checksum: d20953338b2f012ab7750932ece0a78e7d1645b0a6ff42d49be90f55e9998085da1374a9786a7da252df89555c6586695ba4d1d4b4e88ab2b9f306bcd35e00d3 + checksum: b9e7f39eb84626cc8f83ebf75a621d47f04b53cb085a3ea738a9633d57cf65208e503b1830db91aa5e297bc2ba761681ac0b0cbfb7a3d56afcfb2296212668ef languageName: node linkType: hard @@ -1055,11 +1059,11 @@ __metadata: linkType: hard "@types/debug@npm:^4.1.7": - version: 4.1.7 - resolution: "@types/debug@npm:4.1.7" + version: 4.1.8 + resolution: "@types/debug@npm:4.1.8" dependencies: "@types/ms": "*" - checksum: 0a7b89d8ed72526858f0b61c6fd81f477853e8c4415bb97f48b1b5545248d2ae389931680b94b393b993a7cfe893537a200647d93defe6d87159b96812305adc + checksum: a9a9bb40a199e9724aa944e139a7659173a9b274798ea7efbc277cb084bc37d32fc4c00877c3496fac4fed70a23243d284adb75c00b5fdabb38a22154d18e5df languageName: node linkType: hard @@ -1081,12 +1085,12 @@ __metadata: linkType: hard "@types/eslint@npm:*": - version: 8.37.0 - resolution: "@types/eslint@npm:8.37.0" + version: 8.40.0 + resolution: "@types/eslint@npm:8.40.0" dependencies: "@types/estree": "*" "@types/json-schema": "*" - checksum: 06d3b3fba12004294591b5c7a52e3cec439472195da54e096076b1f2ddfbb8a445973b9681046dd530a6ac31eca502f635abc1e3ce37d03513089358e6f822ee + checksum: bab41d7f590182e743853cdd5bf5359cbc4240df986223457c8a5f5674743a3fe2a8626704b65bf9121dfa0ce0a0efd760da8339cc329018f229d4d2d6ee1c43 languageName: node linkType: hard @@ -1098,14 +1102,14 @@ __metadata: linkType: hard "@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^4.17.33": - version: 4.17.34 - resolution: "@types/express-serve-static-core@npm:4.17.34" + version: 4.17.35 + resolution: "@types/express-serve-static-core@npm:4.17.35" dependencies: "@types/node": "*" "@types/qs": "*" "@types/range-parser": "*" "@types/send": "*" - checksum: 3b5242e7d6cfecca5300635fd2af0f63aca3a92754da79a4a355c4d85b57099aa2cabb1c8557fc38a8a9e6f0be996339140ad017e5be405ea1b877a8294a136d + checksum: cc8995d10c6feda475ec1b3a0e69eb0f35f21ab6b49129ad5c6f279e0bc5de8175bc04ec51304cb79a43eec3ed2f5a1e01472eb6d5f827b8c35c6ca8ad24eb6e languageName: node linkType: hard @@ -1172,12 +1176,12 @@ __metadata: linkType: hard "@types/jest@npm:^29.4.0": - version: 29.5.0 - resolution: "@types/jest@npm:29.5.0" + version: 29.5.1 + resolution: "@types/jest@npm:29.5.1" dependencies: expect: ^29.0.0 pretty-format: ^29.0.0 - checksum: cd877e5c56d299cceb8bfdcbb1a77723c706750dd3c3bc47403bc3599b8faff590a3b009c68bb5b11bf7a8c77d1fb01de5e124329b4a08e65f1cdda28b0ecdb8 + checksum: 0a22491dec86333c0e92b897be2c809c922a7b2b0aa5604ac369810d6b2360908b4a3f2c6892e8a237a54fa1f10ecefe0e823ec5fcb7915195af4dfe88d2197e languageName: node linkType: hard @@ -1209,10 +1213,17 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:^18.7.23": - version: 18.15.11 - resolution: "@types/node@npm:18.15.11" - checksum: 977b4ad04708897ff0eb049ecf82246d210939c82461922d20f7d2dcfd81bbc661582ba3af28869210f7e8b1934529dcd46bff7d448551400f9d48b9d3bddec3 +"@types/node@npm:*": + version: 20.2.3 + resolution: "@types/node@npm:20.2.3" + checksum: 576065e8fc1fa45798c8f59a6bf809169582d04abc2e25fab1a048ffc734975b9992ae31be0d960cf705a21fb37112f7fcde11aa322beddf7491e73d5a5a988c + languageName: node + linkType: hard + +"@types/node@npm:^18.7.23": + version: 18.16.14 + resolution: "@types/node@npm:18.16.14" + checksum: c11cb3c787236414efe58240ae71854971592554d82ff9d201876ce7cafd51c37aaa001c63602d002e8238614d7331bd6d48ac4c1c0caa826799980b6846fb08 languageName: node linkType: hard @@ -1245,9 +1256,9 @@ __metadata: linkType: hard "@types/semver@npm:^7.3.12": - version: 7.3.13 - resolution: "@types/semver@npm:7.3.13" - checksum: 00c0724d54757c2f4bc60b5032fe91cda6410e48689633d5f35ece8a0a66445e3e57fa1d6e07eb780f792e82ac542948ec4d0b76eb3484297b79bd18b8cf1cb0 + version: 7.5.0 + resolution: "@types/semver@npm:7.5.0" + checksum: 0a64b9b9c7424d9a467658b18dd70d1d781c2d6f033096a6e05762d20ebbad23c1b69b0083b0484722aabf35640b78ccc3de26368bcae1129c87e9df028a22e2 languageName: node linkType: hard @@ -1331,13 +1342,13 @@ __metadata: linkType: hard "@typescript-eslint/eslint-plugin@npm:^5.54.1": - version: 5.57.1 - resolution: "@typescript-eslint/eslint-plugin@npm:5.57.1" + version: 5.59.7 + resolution: "@typescript-eslint/eslint-plugin@npm:5.59.7" dependencies: "@eslint-community/regexpp": ^4.4.0 - "@typescript-eslint/scope-manager": 5.57.1 - "@typescript-eslint/type-utils": 5.57.1 - "@typescript-eslint/utils": 5.57.1 + "@typescript-eslint/scope-manager": 5.59.7 + "@typescript-eslint/type-utils": 5.59.7 + "@typescript-eslint/utils": 5.59.7 debug: ^4.3.4 grapheme-splitter: ^1.0.4 ignore: ^5.2.0 @@ -1350,43 +1361,43 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 3ea842ef9615e298e28c6687c4dc285577ea0995944410553b3ca514ce9d437534b6e89114e9398c1a370324afe7a4a251c8c49540bb3bf13dcadde9ada3ecc2 + checksum: 10d28bac7a5af9e41767be0bb9c270ee3dcdfeaa38d1b036c6822e7260b88821c460699ba943664eb1ef272d00de6a81b99d7d955332044ea87b624e7ead84a1 languageName: node linkType: hard "@typescript-eslint/parser@npm:^5.54.1": - version: 5.57.1 - resolution: "@typescript-eslint/parser@npm:5.57.1" + version: 5.59.7 + resolution: "@typescript-eslint/parser@npm:5.59.7" dependencies: - "@typescript-eslint/scope-manager": 5.57.1 - "@typescript-eslint/types": 5.57.1 - "@typescript-eslint/typescript-estree": 5.57.1 + "@typescript-eslint/scope-manager": 5.59.7 + "@typescript-eslint/types": 5.59.7 + "@typescript-eslint/typescript-estree": 5.59.7 debug: ^4.3.4 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: db61a12a67bc45d814297e7f089768c0849f18162b330279aa15121223ec3b18d80df4c327f4ca0a40a7bddb9150ba1a9379fce00bc0e4a10cc189d04e36f0e3 + checksum: bc44f37a11a44f84ae5f0156213f3e2e49aef2ecac94d9e161a0c721acd29462e288f306ad4648095ac1c0e5a5f62b78280c1735883cf39f79ee3afcba312119 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:5.57.1": - version: 5.57.1 - resolution: "@typescript-eslint/scope-manager@npm:5.57.1" +"@typescript-eslint/scope-manager@npm:5.59.7": + version: 5.59.7 + resolution: "@typescript-eslint/scope-manager@npm:5.59.7" dependencies: - "@typescript-eslint/types": 5.57.1 - "@typescript-eslint/visitor-keys": 5.57.1 - checksum: 4f03d54372f0591fbc5f6e0267a6f1b73e3012e8a319c1893829e0b8e71f882e17a696995dc8b11e700162daf74444fd2d8f55dba314e1a95221a9d3eabcfb2b + "@typescript-eslint/types": 5.59.7 + "@typescript-eslint/visitor-keys": 5.59.7 + checksum: 43f7ea93fddbe2902122a41050677fe3eff2ea468f435b981592510cfc6136e8c28ac7d3a3e05fb332c0b3078a29bd0c91c35b2b1f4e788b4eb9aaeb70e21583 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:5.57.1": - version: 5.57.1 - resolution: "@typescript-eslint/type-utils@npm:5.57.1" +"@typescript-eslint/type-utils@npm:5.59.7": + version: 5.59.7 + resolution: "@typescript-eslint/type-utils@npm:5.59.7" dependencies: - "@typescript-eslint/typescript-estree": 5.57.1 - "@typescript-eslint/utils": 5.57.1 + "@typescript-eslint/typescript-estree": 5.59.7 + "@typescript-eslint/utils": 5.59.7 debug: ^4.3.4 tsutils: ^3.21.0 peerDependencies: @@ -1394,23 +1405,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 06fab95315fc1ffdaaa011e6ec1ae538826ef3d9b422e2c926dbe9b83e55d9e8bdaa07c43317a4c0a59b40a24c5c48a7c8284e6a18780475a65894b1b949fc23 + checksum: 9cbeffad27b145b478e4cbbab2b44c5b246a9b922f01fd06d401ea4c41a4fa6dc8ba75d13a6409b3b4474ccaf2018770a4c6c599172e22ec2004110e00f4e721 languageName: node linkType: hard -"@typescript-eslint/types@npm:5.57.1": - version: 5.57.1 - resolution: "@typescript-eslint/types@npm:5.57.1" - checksum: 21789eb697904bbb44a18df961d5918e7c5bd90c79df3a8b8b835da81d0c0f42c7eeb2d05f77cafe49a7367ae7f549a0c8281656ea44b6dc56ae1bf19a3a1eae +"@typescript-eslint/types@npm:5.59.7": + version: 5.59.7 + resolution: "@typescript-eslint/types@npm:5.59.7" + checksum: 52eccec9e2d631eb2808e48b5dc33a837b5e242fa9eddace89fc707c9f2283b5364f1d38b33d418a08d64f45f6c22f051800898e1881a912f8aac0c3ae300d0a languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:5.57.1": - version: 5.57.1 - resolution: "@typescript-eslint/typescript-estree@npm:5.57.1" +"@typescript-eslint/typescript-estree@npm:5.59.7": + version: 5.59.7 + resolution: "@typescript-eslint/typescript-estree@npm:5.59.7" dependencies: - "@typescript-eslint/types": 5.57.1 - "@typescript-eslint/visitor-keys": 5.57.1 + "@typescript-eslint/types": 5.59.7 + "@typescript-eslint/visitor-keys": 5.59.7 debug: ^4.3.4 globby: ^11.1.0 is-glob: ^4.0.3 @@ -1419,35 +1430,35 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: bf96520f6de562838a40c3f009fc61fbee5369621071cd0d1dba4470b2b2f746cf79afe4ffa3fbccb8913295a2fbb3d89681d5178529e8da4987c46ed4e5cbed + checksum: eefe82eedf9ee2e14463c3f2b5b18df084c1328a859b245ee897a9a7075acce7cca0216a21fd7968b75aa64189daa008bfde1e2f9afbcc336f3dfe856e7f342e languageName: node linkType: hard -"@typescript-eslint/utils@npm:5.57.1": - version: 5.57.1 - resolution: "@typescript-eslint/utils@npm:5.57.1" +"@typescript-eslint/utils@npm:5.59.7": + version: 5.59.7 + resolution: "@typescript-eslint/utils@npm:5.59.7" dependencies: "@eslint-community/eslint-utils": ^4.2.0 "@types/json-schema": ^7.0.9 "@types/semver": ^7.3.12 - "@typescript-eslint/scope-manager": 5.57.1 - "@typescript-eslint/types": 5.57.1 - "@typescript-eslint/typescript-estree": 5.57.1 + "@typescript-eslint/scope-manager": 5.59.7 + "@typescript-eslint/types": 5.59.7 + "@typescript-eslint/typescript-estree": 5.59.7 eslint-scope: ^5.1.1 semver: ^7.3.7 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: 12e55144c8087f4e8f0f22e5693f3901b81bb7899dec42c7bfe540ac672a802028b688884bb43bd67bcf3cd3546a7205d207afcd948c731c19f551ea61267205 + checksum: d8682700187ca94cc6441480cb6b87d0514a9748103c15dd93206c5b1c6fefa59063662f27a4103e16abbcfb654a61d479bc55af8f23d96f342431b87f31bb4e languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:5.57.1": - version: 5.57.1 - resolution: "@typescript-eslint/visitor-keys@npm:5.57.1" +"@typescript-eslint/visitor-keys@npm:5.59.7": + version: 5.59.7 + resolution: "@typescript-eslint/visitor-keys@npm:5.59.7" dependencies: - "@typescript-eslint/types": 5.57.1 + "@typescript-eslint/types": 5.59.7 eslint-visitor-keys: ^3.3.0 - checksum: d187dfac044b7c0f24264a9ba5eebcf6651412d840b4aaba8eacabff7e771babcd67c738525b1f7c9eb8c94b7edfe7658f6de99f5fdc9745e409c538c1374674 + checksum: 4367f2ea68dd96a0520485434ad11e1bd26239eeeb3a2150bee7478a0f1df3c2099a39f96486722932be0456bcb7a47a483b452876d1d30bdeb9b81d354eef3d languageName: node linkType: hard @@ -2230,9 +2241,9 @@ __metadata: linkType: hard "caniuse-lite@npm:^1.0.30001449": - version: 1.0.30001476 - resolution: "caniuse-lite@npm:1.0.30001476" - checksum: 4e8b233b349330598ac8e4b77515901011ed687b0d0042b78b06cd520ba31953dbacca62348662e912f3b67892fb12406b928caed4233ab53b1603235802bc7c + version: 1.0.30001489 + resolution: "caniuse-lite@npm:1.0.30001489" + checksum: 94585a351fd7661b855c83eace474db0ee5a617159b46f2eff1f6fe4b85d7a205418471fdec8cf5cd647a7f79958706d5e664c0bbf3c7c09118b35db9bb95a1b languageName: node linkType: hard @@ -2802,9 +2813,9 @@ __metadata: linkType: hard "electron-to-chromium@npm:^1.4.284": - version: 1.4.356 - resolution: "electron-to-chromium@npm:1.4.356" - checksum: 5a61003c574f5fb6d32dcfc0ae2220a45a6a395ccadd9495c8227e9c33f36ea97cb34aa925c2b039d17dfea5a8040825026db2df01a352d2d1c0037f53dbeebb + version: 1.4.405 + resolution: "electron-to-chromium@npm:1.4.405" + checksum: d1cf421eaf63dbd5481bcc4296a94e5db5cf831bdc5cbdad283b4b0d53d8fd87254b64fa6cda88f1cb4789eab012f078c1eed4cbb01c5a34bd0ce657dcfe08c8 languageName: node linkType: hard @@ -2950,31 +2961,31 @@ __metadata: languageName: node linkType: hard -"eslint-scope@npm:^7.1.1": - version: 7.1.1 - resolution: "eslint-scope@npm:7.1.1" +"eslint-scope@npm:^7.2.0": + version: 7.2.0 + resolution: "eslint-scope@npm:7.2.0" dependencies: esrecurse: ^4.3.0 estraverse: ^5.2.0 - checksum: 9f6e974ab2db641ca8ab13508c405b7b859e72afe9f254e8131ff154d2f40c99ad4545ce326fd9fde3212ff29707102562a4834f1c48617b35d98c71a97fbf3e + checksum: 64591a2d8b244ade9c690b59ef238a11d5c721a98bcee9e9f445454f442d03d3e04eda88e95a4daec558220a99fa384309d9faae3d459bd40e7a81b4063980ae languageName: node linkType: hard -"eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.0": - version: 3.4.0 - resolution: "eslint-visitor-keys@npm:3.4.0" - checksum: 33159169462d3989321a1ec1e9aaaf6a24cc403d5d347e9886d1b5bfe18ffa1be73bdc6203143a28a606b142b1af49787f33cff0d6d0813eb5f2e8d2e1a6043c +"eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.1": + version: 3.4.1 + resolution: "eslint-visitor-keys@npm:3.4.1" + checksum: f05121d868202736b97de7d750847a328fcfa8593b031c95ea89425333db59676ac087fa905eba438d0a3c5769632f828187e0c1a0d271832a2153c1d3661c2c languageName: node linkType: hard "eslint@npm:^8.35.0": - version: 8.38.0 - resolution: "eslint@npm:8.38.0" + version: 8.41.0 + resolution: "eslint@npm:8.41.0" dependencies: "@eslint-community/eslint-utils": ^4.2.0 "@eslint-community/regexpp": ^4.4.0 - "@eslint/eslintrc": ^2.0.2 - "@eslint/js": 8.38.0 + "@eslint/eslintrc": ^2.0.3 + "@eslint/js": 8.41.0 "@humanwhocodes/config-array": ^0.11.8 "@humanwhocodes/module-importer": ^1.0.1 "@nodelib/fs.walk": ^1.2.8 @@ -2984,9 +2995,9 @@ __metadata: debug: ^4.3.2 doctrine: ^3.0.0 escape-string-regexp: ^4.0.0 - eslint-scope: ^7.1.1 - eslint-visitor-keys: ^3.4.0 - espree: ^9.5.1 + eslint-scope: ^7.2.0 + eslint-visitor-keys: ^3.4.1 + espree: ^9.5.2 esquery: ^1.4.2 esutils: ^2.0.2 fast-deep-equal: ^3.1.3 @@ -2994,13 +3005,12 @@ __metadata: find-up: ^5.0.0 glob-parent: ^6.0.2 globals: ^13.19.0 - grapheme-splitter: ^1.0.4 + graphemer: ^1.4.0 ignore: ^5.2.0 import-fresh: ^3.0.0 imurmurhash: ^0.1.4 is-glob: ^4.0.0 is-path-inside: ^3.0.3 - js-sdsl: ^4.1.4 js-yaml: ^4.1.0 json-stable-stringify-without-jsonify: ^1.0.1 levn: ^0.4.1 @@ -3013,18 +3023,18 @@ __metadata: text-table: ^0.2.0 bin: eslint: bin/eslint.js - checksum: 73b6d9b650d0434aa7c07d0a1802f099b086ee70a8d8ba7be730439a26572a5eb71def12125c82942be2ec8ee5be38a6f1b42a13e40d4b67f11a148ec9e263eb + checksum: 09979a6f8451dcc508a7005b6670845c8a518376280b3fd96657a406b8b6ef29d0e480d1ba11b4eb48da93d607e0c55c9b877676fe089d09973ec152354e23b2 languageName: node linkType: hard -"espree@npm:^9.5.1": - version: 9.5.1 - resolution: "espree@npm:9.5.1" +"espree@npm:^9.5.2": + version: 9.5.2 + resolution: "espree@npm:9.5.2" dependencies: acorn: ^8.8.0 acorn-jsx: ^5.3.2 - eslint-visitor-keys: ^3.4.0 - checksum: cdf6e43540433d917c4f2ee087c6e987b2063baa85a1d9cdaf51533d78275ebd5910c42154e7baf8e3e89804b386da0a2f7fad2264d8f04420e7506bf87b3b88 + eslint-visitor-keys: ^3.4.1 + checksum: 6506289d6eb26471c0b383ee24fee5c8ae9d61ad540be956b3127be5ce3bf687d2ba6538ee5a86769812c7c552a9d8239e8c4d150f9ea056c6d5cbe8399c03c1 languageName: node linkType: hard @@ -3423,13 +3433,14 @@ __metadata: linkType: hard "get-intrinsic@npm:^1.0.2": - version: 1.2.0 - resolution: "get-intrinsic@npm:1.2.0" + version: 1.2.1 + resolution: "get-intrinsic@npm:1.2.1" dependencies: function-bind: ^1.1.1 has: ^1.0.3 + has-proto: ^1.0.1 has-symbols: ^1.0.3 - checksum: 78fc0487b783f5c58cf2dccafc3ae656ee8d2d8062a8831ce4a95e7057af4587a1d4882246c033aca0a7b4965276f4802b45cc300338d1b77a73d3e3e3f4877d + checksum: 5b61d88552c24b0cf6fa2d1b3bc5459d7306f699de060d76442cce49a4721f52b8c560a33ab392cf5575b7810277d54ded9d4d39a1ea61855619ebc005aa7e5f languageName: node linkType: hard @@ -3556,6 +3567,13 @@ __metadata: languageName: node linkType: hard +"graphemer@npm:^1.4.0": + version: 1.4.0 + resolution: "graphemer@npm:1.4.0" + checksum: bab8f0be9b568857c7bec9fda95a89f87b783546d02951c40c33f84d05bb7da3fd10f863a9beb901463669b6583173a8c8cc6d6b306ea2b9b9d5d3d943c3a673 + languageName: node + linkType: hard + "handle-thing@npm:^2.0.0": version: 2.0.1 resolution: "handle-thing@npm:2.0.1" @@ -3577,6 +3595,13 @@ __metadata: languageName: node linkType: hard +"has-proto@npm:^1.0.1": + version: 1.0.1 + resolution: "has-proto@npm:1.0.1" + checksum: febc5b5b531de8022806ad7407935e2135f1cc9e64636c3916c6842bd7995994ca3b29871ecd7954bd35f9e2986c17b3b227880484d22259e2f8e6ce63fd383e + languageName: node + linkType: hard + "has-symbols@npm:^1.0.3": version: 1.0.3 resolution: "has-symbols@npm:1.0.3" @@ -3941,12 +3966,12 @@ __metadata: languageName: node linkType: hard -"is-core-module@npm:^2.11.0": - version: 2.11.0 - resolution: "is-core-module@npm:2.11.0" +"is-core-module@npm:^2.12.0": + version: 2.12.1 + resolution: "is-core-module@npm:2.12.1" dependencies: has: ^1.0.3 - checksum: f96fd490c6b48eb4f6d10ba815c6ef13f410b0ba6f7eb8577af51697de523e5f2cd9de1c441b51d27251bf0e4aebc936545e33a5d26d5d51f28d25698d4a8bab + checksum: f04ea30533b5e62764e7b2e049d3157dc0abd95ef44275b32489ea2081176ac9746ffb1cdb107445cf1ff0e0dfcad522726ca27c27ece64dadf3795428b8e468 languageName: node linkType: hard @@ -4568,13 +4593,6 @@ __metadata: languageName: node linkType: hard -"js-sdsl@npm:^4.1.4": - version: 4.4.0 - resolution: "js-sdsl@npm:4.4.0" - checksum: 7bb08a2d746ab7ff742720339aa006c631afe05e77d11eda988c1c35fae8e03e492e4e347e883e786e3ce6170685d4780c125619111f0730c11fdb41b04059c7 - languageName: node - linkType: hard - "js-tokens@npm:^4.0.0": version: 4.0.0 resolution: "js-tokens@npm:4.0.0" @@ -4999,10 +5017,10 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^4.0.0": - version: 4.2.5 - resolution: "minipass@npm:4.2.5" - checksum: 4f9c19af23a5d4a9e7156feefc9110634b178a8cff8f8271af16ec5ebf7e221725a97429952c856f5b17b30c2065ebd24c81722d90c93d2122611d75b952b48f +"minipass@npm:^5.0.0": + version: 5.0.0 + resolution: "minipass@npm:5.0.0" + checksum: 425dab288738853fded43da3314a0b5c035844d6f3097a8e3b5b29b328da8f3c1af6fc70618b32c29ff906284cf6406b6841376f21caaadd0793c1d5a6a620ea languageName: node linkType: hard @@ -5131,9 +5149,9 @@ __metadata: linkType: hard "node-releases@npm:^2.0.8": - version: 2.0.10 - resolution: "node-releases@npm:2.0.10" - checksum: d784ecde25696a15d449c4433077f5cce620ed30a1656c4abf31282bfc691a70d9618bae6868d247a67914d1be5cc4fde22f65a05f4398cdfb92e0fc83cadfbc + version: 2.0.12 + resolution: "node-releases@npm:2.0.12" + checksum: b8c56db82c4642a0f443332b331a4396dae452a2ac5a65c8dbd93ef89ecb2fbb0da9d42ac5366d4764973febadca816cf7587dad492dce18d2a6b2af59cda260 languageName: node linkType: hard @@ -5448,11 +5466,11 @@ __metadata: linkType: hard "prettier@npm:^2.8.4": - version: 2.8.7 - resolution: "prettier@npm:2.8.7" + version: 2.8.8 + resolution: "prettier@npm:2.8.8" bin: prettier: bin-prettier.js - checksum: fdc8f2616f099f5f0d685907f4449a70595a0fc1d081a88919604375989e0d5e9168d6121d8cc6861f21990b31665828e00472544d785d5940ea08a17660c3a6 + checksum: b49e409431bf129dd89238d64299ba80717b57ff5a6d1c1a8b1a28b590d998a34e083fa13573bc732bb8d2305becb4c9a4407f8486c81fa7d55100eb08263cf8 languageName: node linkType: hard @@ -5529,9 +5547,9 @@ __metadata: linkType: hard "pure-rand@npm:^6.0.0": - version: 6.0.1 - resolution: "pure-rand@npm:6.0.1" - checksum: 4bb565399993b815658a72e359f574ce4f04827a42a905105d61163ae86f456d91595a0e4241e7bce04328fae0638ae70ac0428d93ecb55971c465bd084f8648 + version: 6.0.2 + resolution: "pure-rand@npm:6.0.2" + checksum: 79de33876a4f515d759c48e98d00756bbd916b4ea260cc572d7adfa4b62cace9952e89f0241d0410214554503d25061140fe325c66f845213d2b1728ba8d413e languageName: node linkType: hard @@ -5713,28 +5731,28 @@ __metadata: linkType: hard "resolve@npm:^1.20.0": - version: 1.22.2 - resolution: "resolve@npm:1.22.2" + version: 1.22.3 + resolution: "resolve@npm:1.22.3" dependencies: - is-core-module: ^2.11.0 + is-core-module: ^2.12.0 path-parse: ^1.0.7 supports-preserve-symlinks-flag: ^1.0.0 bin: resolve: bin/resolve - checksum: 7e5df75796ebd429445d102d5824482ee7e567f0070b2b45897b29bb4f613dcbc262e0257b8aeedb3089330ccaea0d6a0464df1a77b2992cf331dcda0f4cb549 + checksum: fb834b81348428cb545ff1b828a72ea28feb5a97c026a1cf40aa1008352c72811ff4d4e71f2035273dc536dcfcae20c13604ba6283c612d70fa0b6e44519c374 languageName: node linkType: hard "resolve@patch:resolve@^1.20.0#~builtin": - version: 1.22.2 - resolution: "resolve@patch:resolve@npm%3A1.22.2#~builtin::version=1.22.2&hash=c3c19d" + version: 1.22.3 + resolution: "resolve@patch:resolve@npm%3A1.22.3#~builtin::version=1.22.3&hash=c3c19d" dependencies: - is-core-module: ^2.11.0 + is-core-module: ^2.12.0 path-parse: ^1.0.7 supports-preserve-symlinks-flag: ^1.0.0 bin: resolve: bin/resolve - checksum: 66cc788f13b8398de18eb4abb3aed90435c84bb8935953feafcf7231ba4cd191b2c10b4a87b1e9681afc34fb138c705f91f7330ff90bfa36f457e5584076a2b8 + checksum: ad59734723b596d0891321c951592ed9015a77ce84907f89c9d9307dd0c06e11a67906a3e628c4cae143d3e44898603478af0ddeb2bba3f229a9373efe342665 languageName: node linkType: hard @@ -5839,14 +5857,14 @@ __metadata: languageName: node linkType: hard -"semver@npm:7.x, semver@npm:^7.3.5, semver@npm:^7.3.7": - version: 7.3.8 - resolution: "semver@npm:7.3.8" +"semver@npm:7.x, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7": + version: 7.5.1 + resolution: "semver@npm:7.5.1" dependencies: lru-cache: ^6.0.0 bin: semver: bin/semver.js - checksum: ba9c7cbbf2b7884696523450a61fee1a09930d888b7a8d7579025ad93d459b2d1949ee5bbfeb188b2be5f4ac163544c5e98491ad6152df34154feebc2cc337c1 + checksum: d16dbedad53c65b086f79524b9ef766bf38670b2395bdad5c957f824dcc566b624988013564f4812bcace3f9d405355c3635e2007396a39d1bffc71cfec4a2fc languageName: node linkType: hard @@ -5859,17 +5877,6 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.3.4": - version: 7.5.0 - resolution: "semver@npm:7.5.0" - dependencies: - lru-cache: ^6.0.0 - bin: - semver: bin/semver.js - checksum: 2d266937756689a76f124ffb4c1ea3e1bbb2b263219f90ada8a11aebebe1280b13bb76cca2ca96bdee3dbc554cbc0b24752eb895b2a51577aa644427e9229f2b - languageName: node - linkType: hard - "send@npm:0.18.0": version: 0.18.0 resolution: "send@npm:0.18.0" @@ -6262,22 +6269,22 @@ __metadata: linkType: hard "tar@npm:^6.1.11, tar@npm:^6.1.2": - version: 6.1.13 - resolution: "tar@npm:6.1.13" + version: 6.1.15 + resolution: "tar@npm:6.1.15" dependencies: chownr: ^2.0.0 fs-minipass: ^2.0.0 - minipass: ^4.0.0 + minipass: ^5.0.0 minizlib: ^2.1.1 mkdirp: ^1.0.3 yallist: ^4.0.0 - checksum: 8a278bed123aa9f53549b256a36b719e317c8b96fe86a63406f3c62887f78267cea9b22dc6f7007009738509800d4a4dccc444abd71d762287c90f35b002eb1c + checksum: f23832fceeba7578bf31907aac744ae21e74a66f4a17a9e94507acf460e48f6db598c7023882db33bab75b80e027c21f276d405e4a0322d58f51c7088d428268 languageName: node linkType: hard "terser-webpack-plugin@npm:^5.3.7": - version: 5.3.8 - resolution: "terser-webpack-plugin@npm:5.3.8" + version: 5.3.9 + resolution: "terser-webpack-plugin@npm:5.3.9" dependencies: "@jridgewell/trace-mapping": ^0.3.17 jest-worker: ^27.4.5 @@ -6293,13 +6300,13 @@ __metadata: optional: true uglify-js: optional: true - checksum: 0ffc2a1949b1fd60ef9c815c4629b9817656db612bb58c5db96e3b04204c86afd142b115392e48733364edc7bf95131f54c10174c05f046ba8f2adead6b06c3c + checksum: 41705713d6f9cb83287936b21e27c658891c78c4392159f5148b5623f0e8c48559869779619b058382a4c9758e7820ea034695e57dc7c474b4962b79f553bc5f languageName: node linkType: hard "terser@npm:^5.10.0, terser@npm:^5.16.8": - version: 5.17.3 - resolution: "terser@npm:5.17.3" + version: 5.17.6 + resolution: "terser@npm:5.17.6" dependencies: "@jridgewell/source-map": ^0.3.2 acorn: ^8.5.0 @@ -6307,7 +6314,7 @@ __metadata: source-map-support: ~0.5.20 bin: terser: bin/terser - checksum: 6b5a859bf9707f34be6e4c567437bc4e47e9364eec37a48b0ae3bff46bb510ef43caf543a23a89b8f43eca47c90a6759105add171fdb0d768dd639deb4545ac9 + checksum: 9c0ab0261a99a61c5f53d05d4ecc7f68c552bae6af481464fdd596bc9d7e89ce8e21b1833cb3ce06ad5f658e2b226081d543e4fe6e324b2cdf03ee8b7eeec01a languageName: node linkType: hard @@ -6400,8 +6407,8 @@ __metadata: linkType: hard "ts-loader@npm:^9.4.2": - version: 9.4.2 - resolution: "ts-loader@npm:9.4.2" + version: 9.4.3 + resolution: "ts-loader@npm:9.4.3" dependencies: chalk: ^4.1.0 enhanced-resolve: ^5.0.0 @@ -6410,7 +6417,7 @@ __metadata: peerDependencies: typescript: "*" webpack: ^5.0.0 - checksum: 6f306ee4c615c2a159fb177561e3fb86ca2cbd6c641e710d408a64b4978e1ff3f2c9733df07bff27d3f82efbfa7c287523d4306049510c7485ac2669a9c37eb0 + checksum: 139ed53bc60717d0ca231cdffbdef7566b9feda11c72fecc697983113f1266ccca2e1cdf191f841a43afa6b87d6afe57a0caf4feecf02f30845aa7ac6f2411a4 languageName: node linkType: hard @@ -6452,7 +6459,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:2.5.0, tslib@npm:^2.0.3, tslib@npm:^2.4.0": +"tslib@npm:2.5.0": version: 2.5.0 resolution: "tslib@npm:2.5.0" checksum: ae3ed5f9ce29932d049908ebfdf21b3a003a85653a9a140d614da6b767a93ef94f460e52c3d787f0e4f383546981713f165037dc2274df212ea9f8a4541004e1 @@ -6466,6 +6473,13 @@ __metadata: languageName: node linkType: hard +"tslib@npm:^2.0.3, tslib@npm:^2.4.0": + version: 2.5.2 + resolution: "tslib@npm:2.5.2" + checksum: 4d3c1e238b94127ed0e88aa0380db3c2ddae581dc0f4bae5a982345e9f50ee5eda90835b8bfba99b02df10a5734470be197158c36f9129ac49fdc14a6a9da222 + languageName: node + linkType: hard + "tsutils@npm:^3.21.0": version: 3.21.0 resolution: "tsutils@npm:3.21.0" @@ -6563,16 +6577,16 @@ __metadata: linkType: hard "update-browserslist-db@npm:^1.0.10": - version: 1.0.10 - resolution: "update-browserslist-db@npm:1.0.10" + version: 1.0.11 + resolution: "update-browserslist-db@npm:1.0.11" dependencies: escalade: ^3.1.1 picocolors: ^1.0.0 peerDependencies: browserslist: ">= 4.21.0" bin: - browserslist-lint: cli.js - checksum: 12db73b4f63029ac407b153732e7cd69a1ea8206c9100b482b7d12859cd3cd0bc59c602d7ae31e652706189f1acb90d42c53ab24a5ba563ed13aebdddc5561a0 + update-browserslist-db: cli.js + checksum: b98327518f9a345c7cad5437afae4d2ae7d865f9779554baf2a200fdf4bac4969076b679b1115434bd6557376bdd37ca7583d0f9b8f8e302d7d4cc1e91b5f231 languageName: node linkType: hard @@ -6763,12 +6777,12 @@ __metadata: linkType: hard "webpack-merge@npm:^5.7.3": - version: 5.8.0 - resolution: "webpack-merge@npm:5.8.0" + version: 5.9.0 + resolution: "webpack-merge@npm:5.9.0" dependencies: clone-deep: ^4.0.1 wildcard: ^2.0.0 - checksum: 88786ab91013f1bd2a683834ff381be81c245a4b0f63304a5103e90f6653f44dab496a0768287f8531761f8ad957d1f9f3ccb2cb55df0de1bd9ee343e079da26 + checksum: 64fe2c23aacc5f19684452a0e84ec02c46b990423aee6fcc5c18d7d471155bd14e9a6adb02bd3656eb3e0ac2532c8e97d69412ad14c97eeafe32fa6d10050872 languageName: node linkType: hard @@ -6780,8 +6794,8 @@ __metadata: linkType: hard "webpack@npm:^5.82.1": - version: 5.82.1 - resolution: "webpack@npm:5.82.1" + version: 5.83.1 + resolution: "webpack@npm:5.83.1" dependencies: "@types/eslint-scope": ^3.7.3 "@types/estree": ^1.0.0 @@ -6812,7 +6826,7 @@ __metadata: optional: true bin: webpack: bin/webpack.js - checksum: 747ee7ebd238c15249c2652060e3c6ca6d62cc66dcf7e4e2824ecd4875b7ea5e01fce8f4179080a3e84dfdb3c8d0992700444c7c5a05ef47b38c0623d3ac76de + checksum: 219d5ef50380bc0fd3702ed17feddf13819d8173b78f7a5b857dc74ac177e63d1f79c050792754411cc088bbc02e0971b989efddadbb8e393cf27d64c0ad9ff8 languageName: node linkType: hard @@ -6940,8 +6954,8 @@ __metadata: linkType: hard "yargs@npm:^17.3.1": - version: 17.7.1 - resolution: "yargs@npm:17.7.1" + version: 17.7.2 + resolution: "yargs@npm:17.7.2" dependencies: cliui: ^8.0.1 escalade: ^3.1.1 @@ -6950,7 +6964,7 @@ __metadata: string-width: ^4.2.3 y18n: ^5.0.5 yargs-parser: ^21.1.1 - checksum: 3d8a43c336a4942bc68080768664aca85c7bd406f018bad362fd255c41c8f4e650277f42fd65d543fce99e084124ddafee7bbfc1a5c6a8fda4cec78609dcf8d4 + checksum: 73b572e863aa4a8cbef323dd911d79d193b772defd5a51aab0aca2d446655216f5002c42c5306033968193bdbf892a7a4c110b0d77954a7fdf563e653967b56a languageName: node linkType: hard From b600d99c4c1a5d9d32ebd188791bd7db1a50873f Mon Sep 17 00:00:00 2001 From: Charlie Lye Date: Wed, 24 May 2023 09:50:36 +0000 Subject: [PATCH 14/29] Fix. --- cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp | 3 --- .../dsl/acir_format/block_constraint.test.cpp | 4 ++-- .../barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp | 8 ++++---- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp index b9fed48eb9..547e350a60 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp @@ -80,7 +80,6 @@ TEST(acir_format, test_logic_gate_from_noir_circuit) // EXPR [ (1, _4, _5) (-1, _6) 0 ] // EXPR [ (1, _4, _6) (-1, _4) 0 ] // EXPR [ (-1, _6) 1 ] - std::cout << "made struct" << std::endl; acir_format::acir_format constraint_system{ .varnum = 7, @@ -111,8 +110,6 @@ TEST(acir_format, test_logic_gate_from_noir_circuit) 1, }); - std::cout << "made composer" << std::endl; - auto prover = composer.create_ultra_with_keccak_prover(); auto proof = prover.construct_proof(); diff --git a/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp b/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp index 66ab73e84a..569459f225 100644 --- a/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp @@ -6,7 +6,7 @@ #include #include -size_t generate_block_constraint(acir_format::BlockConstraint& constraint, std::vector& witness_values) +size_t generate_block_constraint(acir_format::BlockConstraint& constraint, acir_format::WitnessVector& witness_values) { size_t witness_len = 1; witness_values.emplace_back(1); @@ -100,7 +100,7 @@ size_t generate_block_constraint(acir_format::BlockConstraint& constraint, std:: TEST(up_ram, TestBlockConstraint) { acir_format::BlockConstraint block; - std::vector witness_values; + acir_format::WitnessVector witness_values; size_t num_variables = generate_block_constraint(block, witness_values); acir_format::acir_format constraint_system{ .varnum = static_cast(num_variables), diff --git a/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp b/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp index fb8b3711b0..e2500a0ab0 100644 --- a/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp @@ -10,7 +10,7 @@ using curve = proof_system::plonk::stdlib::secp256k1; size_t generate_ecdsa_constraint(acir_format::EcdsaSecp256k1Constraint& ecdsa_constraint, - std::vector& witness_values) + acir_format::WitnessVector& witness_values) { std::string message_string = "Instructions unclear, ask again later."; @@ -81,7 +81,7 @@ size_t generate_ecdsa_constraint(acir_format::EcdsaSecp256k1Constraint& ecdsa_co TEST(ECDSASecp256k1, TestECDSAConstraintSucceed) { acir_format::EcdsaSecp256k1Constraint ecdsa_constraint; - std::vector witness_values; + acir_format::WitnessVector witness_values; size_t num_variables = generate_ecdsa_constraint(ecdsa_constraint, witness_values); acir_format::acir_format constraint_system{ .varnum = static_cast(num_variables), @@ -117,7 +117,7 @@ TEST(ECDSASecp256k1, TestECDSAConstraintSucceed) TEST(ECDSASecp256k1, TestECDSACompilesForVerifier) { acir_format::EcdsaSecp256k1Constraint ecdsa_constraint; - std::vector witness_values; + acir_format::WitnessVector witness_values; size_t num_variables = generate_ecdsa_constraint(ecdsa_constraint, witness_values); acir_format::acir_format constraint_system{ .varnum = static_cast(num_variables), @@ -143,7 +143,7 @@ TEST(ECDSASecp256k1, TestECDSACompilesForVerifier) TEST(ECDSASecp256k1, TestECDSAConstraintFail) { acir_format::EcdsaSecp256k1Constraint ecdsa_constraint; - std::vector witness_values; + acir_format::WitnessVector witness_values; size_t num_variables = generate_ecdsa_constraint(ecdsa_constraint, witness_values); // set result value to be false From e51ab646be493960faa65b5462168677b18eea8f Mon Sep 17 00:00:00 2001 From: Charlie Lye Date: Wed, 24 May 2023 11:14:19 +0000 Subject: [PATCH 15/29] Fix --- cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp index 24eff02962..30c83b2e21 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp @@ -74,7 +74,7 @@ WASM_EXPORT void acir_get_solidity_verifier(in_ptr acir_composer_ptr, out_str_bu WASM_EXPORT void acir_get_exact_circuit_size(in_ptr acir_composer_ptr, uint32_t* out) { auto acir_composer = reinterpret_cast(*acir_composer_ptr); - *out = htonl(acir_composer->get_exact_circuit_size()); + *out = htonl((uint32_t)acir_composer->get_exact_circuit_size()); } WASM_EXPORT void acir_get_total_circuit_size(in_ptr acir_composer_ptr, uint32_t* out) From 14acc502236c11620456b6641b0758e5e3cca85d Mon Sep 17 00:00:00 2001 From: Charlie Lye Date: Wed, 24 May 2023 11:24:47 +0000 Subject: [PATCH 16/29] Fix serve. --- ts/src/{barretenberg_wasm => }/barretenberg-threads.wasm | 0 ts/src/{barretenberg_wasm => }/barretenberg.wasm | 0 ts/src/barretenberg_wasm/node/index.ts | 2 +- ts/webpack.config.js | 4 ++-- 4 files changed, 3 insertions(+), 3 deletions(-) rename ts/src/{barretenberg_wasm => }/barretenberg-threads.wasm (100%) rename ts/src/{barretenberg_wasm => }/barretenberg.wasm (100%) diff --git a/ts/src/barretenberg_wasm/barretenberg-threads.wasm b/ts/src/barretenberg-threads.wasm similarity index 100% rename from ts/src/barretenberg_wasm/barretenberg-threads.wasm rename to ts/src/barretenberg-threads.wasm diff --git a/ts/src/barretenberg_wasm/barretenberg.wasm b/ts/src/barretenberg.wasm similarity index 100% rename from ts/src/barretenberg_wasm/barretenberg.wasm rename to ts/src/barretenberg.wasm diff --git a/ts/src/barretenberg_wasm/node/index.ts b/ts/src/barretenberg_wasm/node/index.ts index c5ced64077..7285cbda50 100644 --- a/ts/src/barretenberg_wasm/node/index.ts +++ b/ts/src/barretenberg_wasm/node/index.ts @@ -10,7 +10,7 @@ import { writeSync } from 'fs'; export async function fetchCode(name: string) { const __dirname = dirname(fileURLToPath(import.meta.url)); - return await readFile(__dirname + '/../' + name); + return await readFile(__dirname + '/../../' + name); } export function createWorker() { diff --git a/ts/webpack.config.js b/ts/webpack.config.js index dee0d3492c..5c8623b230 100644 --- a/ts/webpack.config.js +++ b/ts/webpack.config.js @@ -39,11 +39,11 @@ export default { { // Point directly to the built file, not the symlink, else copy-on-change doesn't work... from: `../cpp/build-wasm/bin/barretenberg.wasm`, - to: 'barretenberg_wasm/barretenberg.wasm', + to: 'barretenberg.wasm', }, { from: `../cpp/build-wasm-threads/bin/barretenberg.wasm`, - to: 'barretenberg_wasm/barretenberg-threads.wasm', + to: 'barretenberg-threads.wasm', }, ], }), From e660b553f9c37e876ee6b826edbc4ef2520b031f Mon Sep 17 00:00:00 2001 From: Charlie Lye Date: Wed, 24 May 2023 11:38:03 +0000 Subject: [PATCH 17/29] Fix --- cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp index 30c83b2e21..6e0ec0d2ad 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp @@ -80,5 +80,5 @@ WASM_EXPORT void acir_get_exact_circuit_size(in_ptr acir_composer_ptr, uint32_t* WASM_EXPORT void acir_get_total_circuit_size(in_ptr acir_composer_ptr, uint32_t* out) { auto acir_composer = reinterpret_cast(*acir_composer_ptr); - *out = htonl(acir_composer->get_total_circuit_size()); + *out = htonl((uint32_t)acir_composer->get_total_circuit_size()); } \ No newline at end of file From d3278fd355c156de175ddbaf8415f9231861d3f3 Mon Sep 17 00:00:00 2001 From: Charlie Lye Date: Wed, 24 May 2023 22:02:23 +0000 Subject: [PATCH 18/29] More commands. --- .../barretenberg/dsl/acir_proofs/c_bind.cpp | 3 +- ts/src/barretenberg-threads.wasm | 2 +- ts/src/barretenberg.wasm | 2 +- ts/src/main.ts | 117 ++++++++++++++++-- ts/src/serialize/buffer_reader.ts | 2 +- 5 files changed, 112 insertions(+), 14 deletions(-) diff --git a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp index 6e0ec0d2ad..a8cf55ed40 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp @@ -68,7 +68,8 @@ WASM_EXPORT void acir_verify_proof(in_ptr acir_composer_ptr, uint8_t const* proo WASM_EXPORT void acir_get_solidity_verifier(in_ptr acir_composer_ptr, out_str_buf out) { auto acir_composer = reinterpret_cast(*acir_composer_ptr); - *out = to_heap_buffer(acir_composer->get_solidity_verifier()); + auto str = acir_composer->get_solidity_verifier(); + *out = to_heap_buffer(str); } WASM_EXPORT void acir_get_exact_circuit_size(in_ptr acir_composer_ptr, uint32_t* out) diff --git a/ts/src/barretenberg-threads.wasm b/ts/src/barretenberg-threads.wasm index 7e9341265a..1474d5ebb4 120000 --- a/ts/src/barretenberg-threads.wasm +++ b/ts/src/barretenberg-threads.wasm @@ -1 +1 @@ -../../../cpp/build-wasm-threads/bin/barretenberg.wasm \ No newline at end of file +../../cpp/build-wasm-threads/bin/barretenberg.wasm \ No newline at end of file diff --git a/ts/src/barretenberg.wasm b/ts/src/barretenberg.wasm index f6e5fe2c73..69e221f70e 120000 --- a/ts/src/barretenberg.wasm +++ b/ts/src/barretenberg.wasm @@ -1 +1 @@ -../../../cpp/build-wasm/bin/barretenberg.wasm \ No newline at end of file +../../cpp/build-wasm/bin/barretenberg.wasm \ No newline at end of file diff --git a/ts/src/main.ts b/ts/src/main.ts index 46591ac968..9659d7a522 100755 --- a/ts/src/main.ts +++ b/ts/src/main.ts @@ -2,15 +2,19 @@ import { Crs } from './crs/index.js'; import createDebug from 'debug'; import { newBarretenbergApiAsync } from './factory/index.js'; -import { readFileSync } from 'fs'; +import { readFileSync, writeFileSync } from 'fs'; import { gunzipSync } from 'zlib'; import { RawBuffer } from './types/index.js'; import { numToInt32BE } from './serialize/serialize.js'; import { Command } from 'commander'; +createDebug.log = console.error.bind(console); const debug = createDebug('bb.js'); createDebug.enable('*'); +// Maximum we support. +const CIRCUIT_SIZE = 2 ** 19; + function getBytecode(jsonPath: string) { const json = readFileSync(jsonPath, 'utf-8'); const parsed = JSON.parse(json); @@ -24,20 +28,24 @@ function getWitness(witnessPath: string) { return Buffer.concat([numToInt32BE(data.length / 32), data]); } -export async function proveAndVerify(jsonPath: string, witnessPath: string) { +async function init() { + // Plus 1 needed! + const crs = await Crs.new(CIRCUIT_SIZE + 1); + const api = await newBarretenbergApiAsync(); - try { - const CIRCUIT_SIZE = 2 ** 19; - // Import to init slab allocator as first thing, to ensure maximum memory efficiency. - await api.commonInitSlabAllocator(CIRCUIT_SIZE); + // Import to init slab allocator as first thing, to ensure maximum memory efficiency. + await api.commonInitSlabAllocator(CIRCUIT_SIZE); - // Plus 1 needed! - const crs = await Crs.new(2 ** 19 + 1); - const pippengerPtr = await api.eccNewPippenger(crs.getG1Data(), crs.numPoints); + const pippengerPtr = await api.eccNewPippenger(crs.getG1Data(), crs.numPoints); + const acirComposer = await api.acirNewAcirComposer(pippengerPtr, crs.getG2Data()); - const acirComposer = await api.acirNewAcirComposer(pippengerPtr, crs.getG2Data()); + return { api, acirComposer }; +} +export async function proveAndVerify(jsonPath: string, witnessPath: string) { + const { api, acirComposer } = await init(); + try { debug('initing proving key...'); const bytecode = getBytecode(jsonPath); await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), CIRCUIT_SIZE); @@ -54,13 +62,73 @@ export async function proveAndVerify(jsonPath: string, witnessPath: string) { const verified = await api.acirVerifyProof(acirComposer, proof); debug(`verified: ${verified}`); + return verified; + } finally { + await api.destroy(); + } +} + +export async function prove(jsonPath: string, witnessPath: string, outputPath: string) { + const { api, acirComposer } = await init(); + try { + debug('initing proving key...'); + const bytecode = getBytecode(jsonPath); + await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), CIRCUIT_SIZE); + + const exactCircuitSize = await api.acirGetExactCircuitSize(acirComposer); + debug(`circuit size: ${exactCircuitSize}`); + + debug(`creating proof...`); + const witness = getWitness(witnessPath); + const proof = await api.acirCreateProof(acirComposer, new RawBuffer(bytecode), new RawBuffer(witness)); + + writeFileSync(outputPath, proof); + debug('done.'); + } finally { + await api.destroy(); + } +} + +export async function verify(jsonPath: string, proofPath: string) { + const { api, acirComposer } = await init(); + try { + debug('initing proving key...'); + const bytecode = getBytecode(jsonPath); + await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), CIRCUIT_SIZE); + + debug('initing verification key...'); + await api.acirInitVerificationKey(acirComposer); + const verified = await api.acirVerifyProof(acirComposer, readFileSync(proofPath)); + debug(`verified: ${verified}`); return verified; } finally { await api.destroy(); } } +export async function contract(jsonPath: string, outputPath: string) { + const { api, acirComposer } = await init(); + try { + debug('initing proving key...'); + const bytecode = getBytecode(jsonPath); + await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), CIRCUIT_SIZE); + + debug('initing verification key...'); + await api.acirInitVerificationKey(acirComposer); + + const contract = await api.acirGetSolidityVerifier(acirComposer); + if (outputPath === '-') { + console.log(contract); + } else { + writeFileSync(outputPath, contract); + debug(`contract written to: ${outputPath}`); + } + } finally { + await api.destroy(); + } +} + // nargo use bb.js: backend -> bb.js // backend prove --data-dir data --witness /foo/bar/witness.tr --json /foo/bar/main.json // backend verify ... @@ -83,4 +151,33 @@ program process.exit(result ? 0 : 1); }); +program + .command('prove') + .description('Generate a proof and write it to a file.') + .option('-j, --json-path ', 'Specify the JSON path', './target/main.json') + .option('-w, --witness-path ', 'Specify the witness path', './target/witness.tr') + .option('-o, --output-dir ', 'Specify the proof output dir', './proofs') + .requiredOption('-n, --name ', 'Output file name.') + .action(async ({ jsonPath, witnessPath, outputDir, name }) => { + await prove(jsonPath, witnessPath, outputDir + '/' + name); + }); + +program + .command('verify') + .description('Verify a proof. Process exists with success or failure code.') + .option('-j, --json-path ', 'Specify the JSON path', './target/main.json') + .requiredOption('-p, --proof-path ', 'Specify the path to the proof') + .action(async ({ jsonPath, proofPath }) => { + await verify(jsonPath, proofPath); + }); + +program + .command('contract') + .description('Output solidity verification key contract.') + .option('-j, --json-path ', 'Specify the JSON path', './target/main.json') + .requiredOption('-o, --output-path ', 'Specify the path to write the contract') + .action(async ({ jsonPath, outputPath }) => { + await contract(jsonPath, outputPath); + }); + program.parse(process.argv); diff --git a/ts/src/serialize/buffer_reader.ts b/ts/src/serialize/buffer_reader.ts index 97f0c233ee..46f6560879 100644 --- a/ts/src/serialize/buffer_reader.ts +++ b/ts/src/serialize/buffer_reader.ts @@ -61,7 +61,7 @@ export class BufferReader { } public readString(): string { - return this.readBuffer().toString(); + return new TextDecoder().decode(this.readBuffer()); } public readBuffer(): Uint8Array { From ad282152836f5e3a5c8f34256b29bdea9d16b854 Mon Sep 17 00:00:00 2001 From: Innokentii Sennovskii Date: Thu, 25 May 2023 14:02:04 +0100 Subject: [PATCH 19/29] Fixed a bug in biggroup tests (#478) --- cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup.hpp b/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup.hpp index 4330c5b6b4..551d767446 100644 --- a/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup.hpp +++ b/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup.hpp @@ -472,7 +472,7 @@ template class element { { num_points = points.size(); num_fives = num_points / 5; - + num_sixes = 0; // size-6 table is expensive and only benefits us if creating them reduces the number of total tables if (num_fives * 5 == (num_points - 1)) { num_fives -= 1; From ada5d9d50f4d2abc62079718e7d79e2c3e75ed02 Mon Sep 17 00:00:00 2001 From: Charlie Lye Date: Thu, 25 May 2023 14:30:19 +0100 Subject: [PATCH 20/29] Add back custom libc++ build. --- cpp/scripts/install-wasi-sdk.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cpp/scripts/install-wasi-sdk.sh b/cpp/scripts/install-wasi-sdk.sh index 9ea9b43196..3a8eecf243 100755 --- a/cpp/scripts/install-wasi-sdk.sh +++ b/cpp/scripts/install-wasi-sdk.sh @@ -27,6 +27,5 @@ else # Replace wasi-sysroot in wasi-sdk-20.0+threads with our custom build. # It contains libc++ and a patch by yamt to improve thread join stability. # Can remove once future releases are more stable. - # UPDATE: Commenting out as we switched to "parallel_for_mutex_pool" as this we actually not very stable. - # curl -s -L https://wasi-sdk.s3.eu-west-2.amazonaws.com/yamt-wasi-sysroot-20.0.threads.tgz | tar zxfv - + curl -s -L https://wasi-sdk.s3.eu-west-2.amazonaws.com/yamt-wasi-sysroot-20.0.threads.tgz | tar zxfv - fi From f815187425c447105ec1a52c3f916d89fdbdfd22 Mon Sep 17 00:00:00 2001 From: Charlie Lye Date: Thu, 25 May 2023 14:32:24 +0100 Subject: [PATCH 21/29] Fix. --- cpp/bootstrap.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cpp/bootstrap.sh b/cpp/bootstrap.sh index e6d854c5a7..277744c161 100755 --- a/cpp/bootstrap.sh +++ b/cpp/bootstrap.sh @@ -66,5 +66,9 @@ cmake --build --preset $PRESET ${@/#/--target } ./scripts/install-wasi-sdk.sh # Build WASM. +cmake --preset wasm +cmake --build --preset wasm + +# Build WASM with new threading. cmake --preset wasm-threads cmake --build --preset wasm-threads From 0fee875822f51b8a7c96de1a011edcc37a017472 Mon Sep 17 00:00:00 2001 From: Charlie Lye Date: Thu, 25 May 2023 15:21:19 +0000 Subject: [PATCH 22/29] write_vk --- .../dsl/acir_proofs/acir_composer.cpp | 4 +-- .../dsl/acir_proofs/acir_composer.hpp | 2 +- .../barretenberg/dsl/acir_proofs/c_bind.cpp | 10 +++++++ .../barretenberg/dsl/acir_proofs/c_bind.hpp | 2 ++ exports.json | 16 +++++++++++ ts/src/barretenberg_api/index.ts | 10 +++++++ ts/src/main.ts | 28 +++++++++++++++++++ 7 files changed, 69 insertions(+), 3 deletions(-) diff --git a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp index 03e04d4612..0ef95d37ed 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp @@ -51,9 +51,9 @@ std::vector AcirComposer::create_proof(acir_format::acir_format& constr return proof; } -void AcirComposer::init_verification_key() +std::shared_ptr AcirComposer::init_verification_key() { - verification_key_ = composer_.compute_verification_key(); + return verification_key_ = composer_.compute_verification_key(); } bool AcirComposer::verify_proof(std::vector const& proof) diff --git a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.hpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.hpp index 1a608df4c9..d93a26802e 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.hpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.hpp @@ -15,7 +15,7 @@ class AcirComposer { std::vector create_proof(acir_format::acir_format& constraint_system, acir_format::WitnessVector& witness); - void init_verification_key(); + std::shared_ptr init_verification_key(); bool verify_proof(std::vector const& proof); diff --git a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp index a8cf55ed40..62baca99e0 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp @@ -58,6 +58,16 @@ WASM_EXPORT void acir_init_verification_key(in_ptr acir_composer_ptr) acir_composer->init_verification_key(); } +WASM_EXPORT void acir_get_verification_key(in_ptr acir_composer_ptr, uint8_t** out) +{ + auto acir_composer = reinterpret_cast(*acir_composer_ptr); + auto vk = acir_composer->init_verification_key(); + // to_buffer gives a vector. + // to_heap_buffer serializes that into the heap (i.e. length prefixes). + // if you just did: to_heap_buffer(*vk) you get the un-prefixed buffer. no good. + *out = to_heap_buffer(to_buffer(*vk)); +} + WASM_EXPORT void acir_verify_proof(in_ptr acir_composer_ptr, uint8_t const* proof_buf, bool* result) { auto acir_composer = reinterpret_cast(*acir_composer_ptr); diff --git a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp index 72439c896d..dc7efbdf3d 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp @@ -24,6 +24,8 @@ WASM_EXPORT void acir_create_proof(in_ptr acir_composer_ptr, WASM_EXPORT void acir_init_verification_key(in_ptr acir_composer_ptr); +WASM_EXPORT void acir_get_verification_key(in_ptr acir_composer_ptr, uint8_t** out); + WASM_EXPORT void acir_verify_proof(in_ptr acir_composer_ptr, uint8_t const* proof_buf, bool* result); WASM_EXPORT void acir_get_solidity_verifier(in_ptr acir_composer_ptr, out_str_buf out); diff --git a/exports.json b/exports.json index 3f739f6d69..2a9eb19970 100644 --- a/exports.json +++ b/exports.json @@ -709,6 +709,22 @@ "outArgs": [], "isAsync": false }, + { + "functionName": "acir_get_verification_key", + "inArgs": [ + { + "name": "acir_composer_ptr", + "type": "in_ptr" + } + ], + "outArgs": [ + { + "name": "out", + "type": "uint8_t **" + } + ], + "isAsync": false + }, { "functionName": "acir_verify_proof", "inArgs": [ diff --git a/ts/src/barretenberg_api/index.ts b/ts/src/barretenberg_api/index.ts index 2ccee233b0..671251f927 100644 --- a/ts/src/barretenberg_api/index.ts +++ b/ts/src/barretenberg_api/index.ts @@ -211,6 +211,11 @@ export class BarretenbergApi { return; } + async acirGetVerificationKey(acirComposerPtr: Ptr): Promise { + const result = await this.binder.callWasmExport('acir_get_verification_key', [acirComposerPtr], [BufferDeserializer()]); + return result[0]; + } + async acirVerifyProof(acirComposerPtr: Ptr, proofBuf: Uint8Array): Promise { const result = await this.binder.callWasmExport('acir_verify_proof', [acirComposerPtr, proofBuf], [BoolDeserializer()]); return result[0]; @@ -439,6 +444,11 @@ export class BarretenbergApiSync { return; } + acirGetVerificationKey(acirComposerPtr: Ptr): Uint8Array { + const result = this.binder.callWasmExport('acir_get_verification_key', [acirComposerPtr], [BufferDeserializer()]); + return result[0]; + } + acirVerifyProof(acirComposerPtr: Ptr, proofBuf: Uint8Array): boolean { const result = this.binder.callWasmExport('acir_verify_proof', [acirComposerPtr, proofBuf], [BoolDeserializer()]); return result[0]; diff --git a/ts/src/main.ts b/ts/src/main.ts index 9659d7a522..98779ee0ed 100755 --- a/ts/src/main.ts +++ b/ts/src/main.ts @@ -129,6 +129,25 @@ export async function contract(jsonPath: string, outputPath: string) { } } +export async function writeVk(jsonPath: string, outputPath: string) { + const { api, acirComposer } = await init(); + try { + debug('initing proving key...'); + const bytecode = getBytecode(jsonPath); + await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), CIRCUIT_SIZE); + + debug('initing verification key...'); + const vk = await api.acirGetVerificationKey(acirComposer); + if (outputPath === '-') { + process.stdout.write(vk); + } else { + writeFileSync(outputPath, vk); + debug(`vk written to: ${outputPath}`); + } + } finally { + await api.destroy(); + } +} // nargo use bb.js: backend -> bb.js // backend prove --data-dir data --witness /foo/bar/witness.tr --json /foo/bar/main.json // backend verify ... @@ -180,4 +199,13 @@ program await contract(jsonPath, outputPath); }); +program + .command('write_vk') + .description('Output verification key.') + .option('-j, --json-path ', 'Specify the JSON path', './target/main.json') + .requiredOption('-o, --output-path ', 'Specify the path to write the key') + .action(async ({ jsonPath, outputPath }) => { + await writeVk(jsonPath, outputPath); + }); + program.parse(process.argv); From 083479164411be9cf9642e755182f059c9415a53 Mon Sep 17 00:00:00 2001 From: kevaundray Date: Thu, 25 May 2023 21:17:39 +0100 Subject: [PATCH 23/29] DSL: Add KeccakVar opcode (#476) * add initial KeccakVar code * add result field * add keccak_var_constraints to fields --- .../dsl/acir_format/acir_format.cpp | 15 +++++++++ .../dsl/acir_format/acir_format.hpp | 3 ++ .../dsl/acir_format/acir_format.test.cpp | 3 ++ .../dsl/acir_format/block_constraint.test.cpp | 1 + .../dsl/acir_format/ecdsa_secp256k1.test.cpp | 3 ++ .../dsl/acir_format/keccak_constraint.cpp | 33 +++++++++++++++++++ .../dsl/acir_format/keccak_constraint.hpp | 25 ++++++++++++++ 7 files changed, 83 insertions(+) diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp index 8f2c4d17f5..933af69306 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp @@ -73,6 +73,9 @@ void create_circuit(Composer& composer, const acir_format& constraint_system) for (const auto& constraint : constraint_system.keccak_constraints) { create_keccak_constraints(composer, constraint); } + for (const auto& constraint : constraint_system.keccak_var_constraints) { + create_keccak_var_constraints(composer, constraint); + } // Add pedersen constraints for (const auto& constraint : constraint_system.pedersen_constraints) { @@ -161,6 +164,9 @@ Composer create_circuit(const acir_format& constraint_system, for (const auto& constraint : constraint_system.keccak_constraints) { create_keccak_constraints(composer, constraint); } + for (const auto& constraint : constraint_system.keccak_var_constraints) { + create_keccak_var_constraints(composer, constraint); + } // Add pedersen constraints for (const auto& constraint : constraint_system.pedersen_constraints) { @@ -255,6 +261,9 @@ Composer create_circuit_with_witness(const acir_format& constraint_system, for (const auto& constraint : constraint_system.keccak_constraints) { create_keccak_constraints(composer, constraint); } + for (const auto& constraint : constraint_system.keccak_var_constraints) { + create_keccak_var_constraints(composer, constraint); + } // Add pedersen constraints for (const auto& constraint : constraint_system.pedersen_constraints) { @@ -346,6 +355,9 @@ Composer create_circuit_with_witness(const acir_format& constraint_system, std:: for (const auto& constraint : constraint_system.keccak_constraints) { create_keccak_constraints(composer, constraint); } + for (const auto& constraint : constraint_system.keccak_var_constraints) { + create_keccak_var_constraints(composer, constraint); + } // Add pedersen constraints for (const auto& constraint : constraint_system.pedersen_constraints) { @@ -435,6 +447,9 @@ void create_circuit_with_witness(Composer& composer, const acir_format& constrai for (const auto& constraint : constraint_system.keccak_constraints) { create_keccak_constraints(composer, constraint); } + for (const auto& constraint : constraint_system.keccak_var_constraints) { + create_keccak_var_constraints(composer, constraint); + } // Add pedersen constraints for (const auto& constraint : constraint_system.pedersen_constraints) { diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp index cf14558c31..26317c5298 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp @@ -29,6 +29,7 @@ struct acir_format { std::vector sha256_constraints; std::vector blake2s_constraints; std::vector keccak_constraints; + std::vector keccak_var_constraints; std::vector hash_to_field_constraints; std::vector pedersen_constraints; std::vector compute_merkle_root_constraints; @@ -69,6 +70,7 @@ template inline void read(B& buf, acir_format& data) read(buf, data.ecdsa_constraints); read(buf, data.blake2s_constraints); read(buf, data.keccak_constraints); + read(buf, data.keccak_var_constraints); read(buf, data.pedersen_constraints); read(buf, data.hash_to_field_constraints); read(buf, data.fixed_base_scalar_mul_constraints); @@ -89,6 +91,7 @@ template inline void write(B& buf, acir_format const& data) write(buf, data.ecdsa_constraints); write(buf, data.blake2s_constraints); write(buf, data.keccak_constraints); + write(buf, data.keccak_var_constraints); write(buf, data.pedersen_constraints); write(buf, data.hash_to_field_constraints); write(buf, data.fixed_base_scalar_mul_constraints); diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp index b9fed48eb9..a3b2930545 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp @@ -93,6 +93,7 @@ TEST(acir_format, test_logic_gate_from_noir_circuit) .sha256_constraints = {}, .blake2s_constraints = {}, .keccak_constraints = {}, + .keccak_var_constraints = {}, .hash_to_field_constraints = {}, .pedersen_constraints = {}, .compute_merkle_root_constraints = {}, @@ -159,6 +160,7 @@ TEST(acir_format, test_schnorr_verify_pass) .sha256_constraints = {}, .blake2s_constraints = {}, .keccak_constraints = {}, + .keccak_var_constraints = {}, .hash_to_field_constraints = {}, .pedersen_constraints = {}, .compute_merkle_root_constraints = {}, @@ -230,6 +232,7 @@ TEST(acir_format, test_schnorr_verify_small_range) .sha256_constraints = {}, .blake2s_constraints = {}, .keccak_constraints = {}, + .keccak_var_constraints = {}, .hash_to_field_constraints = {}, .pedersen_constraints = {}, .compute_merkle_root_constraints = {}, diff --git a/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp b/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp index 66ab73e84a..ead52f5682 100644 --- a/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp @@ -113,6 +113,7 @@ TEST(up_ram, TestBlockConstraint) .sha256_constraints = {}, .blake2s_constraints = {}, .keccak_constraints = {}, + .keccak_var_constraints = {}, .hash_to_field_constraints = {}, .pedersen_constraints = {}, .compute_merkle_root_constraints = {}, diff --git a/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp b/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp index fb8b3711b0..b8d8574440 100644 --- a/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp @@ -94,6 +94,7 @@ TEST(ECDSASecp256k1, TestECDSAConstraintSucceed) .sha256_constraints = {}, .blake2s_constraints = {}, .keccak_constraints = {}, + .keccak_var_constraints = {}, .hash_to_field_constraints = {}, .pedersen_constraints = {}, .compute_merkle_root_constraints = {}, @@ -130,6 +131,7 @@ TEST(ECDSASecp256k1, TestECDSACompilesForVerifier) .sha256_constraints = {}, .blake2s_constraints = {}, .keccak_constraints = {}, + .keccak_var_constraints = {}, .hash_to_field_constraints = {}, .pedersen_constraints = {}, .compute_merkle_root_constraints = {}, @@ -163,6 +165,7 @@ TEST(ECDSASecp256k1, TestECDSAConstraintFail) .sha256_constraints = {}, .blake2s_constraints = {}, .keccak_constraints = {}, + .keccak_var_constraints = {}, .hash_to_field_constraints = {}, .pedersen_constraints = {}, .compute_merkle_root_constraints = {}, diff --git a/cpp/src/barretenberg/dsl/acir_format/keccak_constraint.cpp b/cpp/src/barretenberg/dsl/acir_format/keccak_constraint.cpp index f89e530c10..b573e57153 100644 --- a/cpp/src/barretenberg/dsl/acir_format/keccak_constraint.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/keccak_constraint.cpp @@ -35,4 +35,37 @@ void create_keccak_constraints(Composer& composer, const KeccakConstraint& const } } +void create_keccak_var_constraints(Composer& composer, const KeccakVarConstraint& constraint) +{ + + // Create byte array struct + byte_array_ct arr(&composer); + + // Get the witness assignment for each witness index + // Write the witness assignment to the byte_array + for (const auto& witness_index_num_bits : constraint.inputs) { + auto witness_index = witness_index_num_bits.witness; + auto num_bits = witness_index_num_bits.num_bits; + + // XXX: The implementation requires us to truncate the element to the nearest byte and not bit + auto num_bytes = round_to_nearest_byte(num_bits); + + field_ct element = field_ct::from_witness_index(&composer, witness_index); + byte_array_ct element_bytes(element, num_bytes); + + arr.write(element_bytes); + } + + uint32_ct length = field_ct::from_witness_index(&composer, constraint.var_message_size); + + byte_array_ct output_bytes = proof_system::plonk::stdlib::keccak::hash(arr, length); + + // Convert byte array to vector of field_t + auto bytes = output_bytes.bytes(); + + for (size_t i = 0; i < bytes.size(); ++i) { + composer.assert_equal(bytes[i].normalize().witness_index, constraint.result[i]); + } +} + } // namespace acir_format diff --git a/cpp/src/barretenberg/dsl/acir_format/keccak_constraint.hpp b/cpp/src/barretenberg/dsl/acir_format/keccak_constraint.hpp index 15322b6562..95fabe00d5 100644 --- a/cpp/src/barretenberg/dsl/acir_format/keccak_constraint.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/keccak_constraint.hpp @@ -19,7 +19,16 @@ struct KeccakConstraint { friend bool operator==(KeccakConstraint const& lhs, KeccakConstraint const& rhs) = default; }; +struct KeccakVarConstraint { + std::vector inputs; + uint32_t var_message_size; + std::vector result; + + friend bool operator==(KeccakVarConstraint const& lhs, KeccakVarConstraint const& rhs) = default; +}; + void create_keccak_constraints(Composer& composer, const KeccakConstraint& constraint); +void create_keccak_var_constraints(Composer& composer, const KeccakVarConstraint& constraint); template inline void read(B& buf, HashInput& constraint) { @@ -49,4 +58,20 @@ template inline void write(B& buf, KeccakConstraint const& constrai write(buf, constraint.result); } +template inline void read(B& buf, KeccakVarConstraint& constraint) +{ + using serialize::read; + read(buf, constraint.inputs); + read(buf, constraint.result); + read(buf, constraint.var_message_size); +} + +template inline void write(B& buf, KeccakVarConstraint const& constraint) +{ + using serialize::write; + write(buf, constraint.inputs); + write(buf, constraint.result); + write(buf, constraint.var_message_size); +} + } // namespace acir_format From 4d851dd316021496bb190180de621290de602017 Mon Sep 17 00:00:00 2001 From: ledwards2225 <98505400+ledwards2225@users.noreply.github.com> Date: Thu, 25 May 2023 14:54:05 -0700 Subject: [PATCH 24/29] Multi-constraint Relations (#444) Allow for correct and efficient batching over identities in the Sumcheck relation --- .../composer/standard_honk_composer.test.cpp | 5 +- .../composer/ultra_honk_composer.test.cpp | 6 +- cpp/src/barretenberg/honk/flavor/standard.hpp | 18 +- cpp/src/barretenberg/honk/flavor/ultra.hpp | 21 +- .../honk/proof_system/ultra_prover.hpp | 2 +- .../relations/arithmetic_relation.hpp | 29 +- .../sumcheck/relations/auxiliary_relation.hpp | 125 +++--- .../sumcheck/relations/elliptic_relation.hpp | 150 ++++--- .../relations/gen_perm_sort_relation.hpp | 83 ++-- .../grand_product_initialization_relation.hpp | 89 ----- ...oduct_relation.hpp => lookup_relation.hpp} | 173 ++++---- ..._relation.hpp => permutation_relation.hpp} | 156 +++++--- .../relations/relation_consistency.test.cpp | 187 ++++----- .../relations/relation_correctness.test.cpp | 138 +++---- .../{relation.hpp => relation_parameters.hpp} | 0 .../relations/ultra_arithmetic_relation.hpp | 145 +++++-- .../ultra_arithmetic_relation_secondary.hpp | 66 ---- .../ultra_relation_consistency.test.cpp | 368 +++++++++--------- .../barretenberg/honk/sumcheck/sumcheck.hpp | 2 +- .../honk/sumcheck/sumcheck.test.cpp | 310 ++++++++++++++- .../honk/sumcheck/sumcheck_round.hpp | 246 ++++++++---- .../honk/sumcheck/sumcheck_round.test.cpp | 186 +++++---- .../proof_system/flavor/flavor.hpp | 47 ++- 23 files changed, 1496 insertions(+), 1056 deletions(-) delete mode 100644 cpp/src/barretenberg/honk/sumcheck/relations/grand_product_initialization_relation.hpp rename cpp/src/barretenberg/honk/sumcheck/relations/{lookup_grand_product_relation.hpp => lookup_relation.hpp} (50%) rename cpp/src/barretenberg/honk/sumcheck/relations/{grand_product_computation_relation.hpp => permutation_relation.hpp} (50%) rename cpp/src/barretenberg/honk/sumcheck/relations/{relation.hpp => relation_parameters.hpp} (100%) delete mode 100644 cpp/src/barretenberg/honk/sumcheck/relations/ultra_arithmetic_relation_secondary.hpp diff --git a/cpp/src/barretenberg/honk/composer/standard_honk_composer.test.cpp b/cpp/src/barretenberg/honk/composer/standard_honk_composer.test.cpp index 78a8c930ad..a13e0df167 100644 --- a/cpp/src/barretenberg/honk/composer/standard_honk_composer.test.cpp +++ b/cpp/src/barretenberg/honk/composer/standard_honk_composer.test.cpp @@ -1,13 +1,12 @@ #include "standard_honk_composer.hpp" -#include "barretenberg/honk/sumcheck/relations/relation.hpp" +#include "barretenberg/honk/sumcheck/relations/relation_parameters.hpp" #include "barretenberg/numeric/uint256/uint256.hpp" #include #include #include #include "barretenberg/honk/proof_system/prover.hpp" #include "barretenberg/honk/sumcheck/sumcheck_round.hpp" -#include "barretenberg/honk/sumcheck/relations/grand_product_computation_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/grand_product_initialization_relation.hpp" +#include "barretenberg/honk/sumcheck/relations/permutation_relation.hpp" #include "barretenberg/polynomials/polynomial.hpp" #pragma GCC diagnostic ignored "-Wunused-variable" diff --git a/cpp/src/barretenberg/honk/composer/ultra_honk_composer.test.cpp b/cpp/src/barretenberg/honk/composer/ultra_honk_composer.test.cpp index 09b3373e7f..2eb23f820a 100644 --- a/cpp/src/barretenberg/honk/composer/ultra_honk_composer.test.cpp +++ b/cpp/src/barretenberg/honk/composer/ultra_honk_composer.test.cpp @@ -1,14 +1,13 @@ #include "ultra_honk_composer.hpp" #include "barretenberg/common/log.hpp" #include "barretenberg/honk/proof_system/ultra_prover.hpp" -#include "barretenberg/honk/sumcheck/relations/relation.hpp" +#include "barretenberg/honk/sumcheck/relations/relation_parameters.hpp" #include "barretenberg/numeric/uint256/uint256.hpp" #include #include #include "barretenberg/honk/proof_system/prover.hpp" #include "barretenberg/honk/sumcheck/sumcheck_round.hpp" -#include "barretenberg/honk/sumcheck/relations/grand_product_computation_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/grand_product_initialization_relation.hpp" +#include "barretenberg/honk/sumcheck/relations/permutation_relation.hpp" #include "barretenberg/honk/utils/grand_product_delta.hpp" #include "barretenberg/proof_system/plookup_tables/types.hpp" @@ -649,7 +648,6 @@ TEST(UltraHonkComposer, non_native_field_multiplication) fq a = fq::random_element(); fq b = fq::random_element(); - uint256_t modulus = fq::modulus; uint1024_t a_big = uint512_t(uint256_t(a)); diff --git a/cpp/src/barretenberg/honk/flavor/standard.hpp b/cpp/src/barretenberg/honk/flavor/standard.hpp index 1557fb8814..29fed767c0 100644 --- a/cpp/src/barretenberg/honk/flavor/standard.hpp +++ b/cpp/src/barretenberg/honk/flavor/standard.hpp @@ -10,8 +10,7 @@ #include "barretenberg/honk/sumcheck/polynomials/univariate.hpp" #include "barretenberg/ecc/curves/bn254/g1.hpp" #include "barretenberg/honk/sumcheck/relations/arithmetic_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/grand_product_computation_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/grand_product_initialization_relation.hpp" +#include "barretenberg/honk/sumcheck/relations/permutation_relation.hpp" #include "barretenberg/honk/transcript/transcript.hpp" #include "barretenberg/plonk/proof_system/proving_key/proving_key.hpp" #include "barretenberg/polynomials/evaluation_domain.hpp" @@ -53,17 +52,20 @@ class Standard { static constexpr size_t NUM_WITNESS_ENTITIES = 4; // define the tuple of Relations that comprise the Sumcheck relation - using Relations = std::tuple, - sumcheck::GrandProductComputationRelation, - sumcheck::GrandProductInitializationRelation>; + using Relations = std::tuple, sumcheck::PermutationRelation>; static constexpr size_t MAX_RELATION_LENGTH = get_max_relation_length(); static constexpr size_t NUM_RELATIONS = std::tuple_size::value; - // define the container for storing the univariate contribution from each relation in Sumcheck - using UnivariateTuple = decltype(create_univariate_tuple()); + // Instantiate the BarycentricData needed to extend each Relation Univariate + static_assert(instantiate_barycentric_utils()); + + // define the containers for storing the contributions from each relation in Sumcheck + using RelationUnivariates = decltype(create_relation_univariates_container()); + using RelationValues = decltype(create_relation_values_container()); + // define utilities to extend univarates from RELATION_LENGTH to MAX_RELATION_LENGTH for each Relation - using BarycentricUtils = decltype(create_barycentric_utils()); + // using BarycentricUtils = decltype(create_barycentric_utils()); private: /** diff --git a/cpp/src/barretenberg/honk/flavor/ultra.hpp b/cpp/src/barretenberg/honk/flavor/ultra.hpp index a3d016bd60..b1670666db 100644 --- a/cpp/src/barretenberg/honk/flavor/ultra.hpp +++ b/cpp/src/barretenberg/honk/flavor/ultra.hpp @@ -17,10 +17,8 @@ #include "barretenberg/srs/reference_string/reference_string.hpp" #include "barretenberg/proof_system/flavor/flavor.hpp" #include "barretenberg/honk/sumcheck/relations/ultra_arithmetic_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/ultra_arithmetic_relation_secondary.hpp" -#include "barretenberg/honk/sumcheck/relations/grand_product_computation_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/grand_product_initialization_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/lookup_grand_product_relation.hpp" +#include "barretenberg/honk/sumcheck/relations/permutation_relation.hpp" +#include "barretenberg/honk/sumcheck/relations/lookup_relation.hpp" #include "barretenberg/honk/sumcheck/relations/gen_perm_sort_relation.hpp" #include "barretenberg/honk/sumcheck/relations/elliptic_relation.hpp" #include "barretenberg/honk/sumcheck/relations/auxiliary_relation.hpp" @@ -52,11 +50,8 @@ class Ultra { // define the tuple of Relations that comprise the Sumcheck relation using Relations = std::tuple, - sumcheck::UltraArithmeticRelationSecondary, - sumcheck::UltraGrandProductComputationRelation, - sumcheck::UltraGrandProductInitializationRelation, - sumcheck::LookupGrandProductComputationRelation, - sumcheck::LookupGrandProductInitializationRelation, + sumcheck::UltraPermutationRelation, + sumcheck::LookupRelation, sumcheck::GenPermSortRelation, sumcheck::EllipticRelation, sumcheck::AuxiliaryRelation>; @@ -64,10 +59,12 @@ class Ultra { static constexpr size_t MAX_RELATION_LENGTH = get_max_relation_length(); static constexpr size_t NUM_RELATIONS = std::tuple_size::value; + // Instantiate the BarycentricData needed to extend each Relation Univariate + static_assert(instantiate_barycentric_utils()); + // define the container for storing the univariate contribution from each relation in Sumcheck - using UnivariateTuple = decltype(create_univariate_tuple()); - // define utilities to extend univarates from RELATION_LENGTH to MAX_RELATION_LENGTH for each Relation - using BarycentricUtils = decltype(create_barycentric_utils()); + using RelationUnivariates = decltype(create_relation_univariates_container()); + using RelationValues = decltype(create_relation_values_container()); private: template diff --git a/cpp/src/barretenberg/honk/proof_system/ultra_prover.hpp b/cpp/src/barretenberg/honk/proof_system/ultra_prover.hpp index bcf665711c..5b42bbd150 100644 --- a/cpp/src/barretenberg/honk/proof_system/ultra_prover.hpp +++ b/cpp/src/barretenberg/honk/proof_system/ultra_prover.hpp @@ -6,7 +6,7 @@ #include "barretenberg/honk/pcs/kzg/kzg.hpp" #include "barretenberg/honk/transcript/transcript.hpp" #include "barretenberg/honk/flavor/ultra.hpp" -#include "barretenberg/honk/sumcheck/relations/relation.hpp" +#include "barretenberg/honk/sumcheck/relations/relation_parameters.hpp" #include "barretenberg/honk/sumcheck/sumcheck_output.hpp" namespace proof_system::honk { diff --git a/cpp/src/barretenberg/honk/sumcheck/relations/arithmetic_relation.hpp b/cpp/src/barretenberg/honk/sumcheck/relations/arithmetic_relation.hpp index e7d095119c..1f0349fae5 100644 --- a/cpp/src/barretenberg/honk/sumcheck/relations/arithmetic_relation.hpp +++ b/cpp/src/barretenberg/honk/sumcheck/relations/arithmetic_relation.hpp @@ -3,7 +3,7 @@ #include #include "../polynomials/univariate.hpp" -#include "relation.hpp" +#include "relation_parameters.hpp" namespace proof_system::honk::sumcheck { @@ -12,6 +12,12 @@ template class ArithmeticRelation { // 1 + polynomial degree of this relation static constexpr size_t RELATION_LENGTH = 4; + static constexpr size_t NUM_CONSTRAINTS = 1; + static constexpr std::array CONSTRAINT_LENGTH = { 4 }; + + using RelationUnivariates = std::tuple>; + using RelationValues = std::array; + /** * @brief Expression for the StandardArithmetic gate. * @details The relation is defined as C(extended_edges(X)...) = @@ -22,7 +28,7 @@ template class ArithmeticRelation { * @param parameters contains beta, gamma, and public_input_delta, .... * @param scaling_factor optional term to scale the evaluation before adding to evals. */ - void add_edge_contribution(Univariate& evals, + void add_edge_contribution(RelationUnivariates& evals, const auto& extended_edges, const RelationParameters&, const FF& scaling_factor) const @@ -44,10 +50,17 @@ template class ArithmeticRelation { tmp += q_o * w_o; tmp += q_c; tmp *= scaling_factor; - evals += tmp; + std::get<0>(evals) += tmp; }; - void add_full_relation_value_contribution(FF& full_honk_relation_value, + /** + * @brief Add the result of each identity in this relation evaluated at the multivariate evaluations produced by the + * Sumcheck Prover. + * + * @param full_honk_relation_value + * @param purported_evaluations + */ + void add_full_relation_value_contribution(RelationValues& full_honk_relation_value, const auto& purported_evaluations, const RelationParameters&) const { @@ -60,10 +73,10 @@ template class ArithmeticRelation { auto q_o = purported_evaluations.q_o; auto q_c = purported_evaluations.q_c; - full_honk_relation_value += w_l * (q_m * w_r + q_l); - full_honk_relation_value += q_r * w_r; - full_honk_relation_value += q_o * w_o; - full_honk_relation_value += q_c; + std::get<0>(full_honk_relation_value) += w_l * (q_m * w_r + q_l); + std::get<0>(full_honk_relation_value) += q_r * w_r; + std::get<0>(full_honk_relation_value) += q_o * w_o; + std::get<0>(full_honk_relation_value) += q_c; }; }; } // namespace proof_system::honk::sumcheck diff --git a/cpp/src/barretenberg/honk/sumcheck/relations/auxiliary_relation.hpp b/cpp/src/barretenberg/honk/sumcheck/relations/auxiliary_relation.hpp index c8b7f288a2..890e16326b 100644 --- a/cpp/src/barretenberg/honk/sumcheck/relations/auxiliary_relation.hpp +++ b/cpp/src/barretenberg/honk/sumcheck/relations/auxiliary_relation.hpp @@ -4,26 +4,61 @@ #include "../polynomials/univariate.hpp" #include "barretenberg/numeric/uint256/uint256.hpp" -#include "relation.hpp" +#include "relation_parameters.hpp" namespace proof_system::honk::sumcheck { template class AuxiliaryRelation { public: // 1 + polynomial degree of this relation - static constexpr size_t RELATION_LENGTH = 6; // degree() = WORKTODO + static constexpr size_t RELATION_LENGTH = 6; + + static constexpr size_t NUM_CONSTRAINTS = 6; + static constexpr std::array CONSTRAINT_LENGTH = { 6, 6, 6, 6, 6, 6 }; // Each has degree 5 + + using RelationUnivariates = std::tuple, + Univariate, + Univariate, + Univariate, + Univariate, + Univariate>; + using RelationValues = std::array; /** * @brief Expression for the generalized permutation sort gate. - * @details The relation is defined as C(extended_edges(X)...) = - * //WORKTODO + * @details The following explanation is reproduced from the Plonk analog 'plookup_auxiliary_widget': + * Adds contributions for identities associated with several custom gates: + * * RAM/ROM read-write consistency check + * * RAM timestamp difference consistency check + * * RAM/ROM index difference consistency check + * * Bigfield product evaluation (3 in total) + * * Bigfield limb accumulation (2 in total) + * + * Multiple selectors are used to 'switch' aux gates on/off according to the following pattern: + * + * | gate type | q_aux | q_1 | q_2 | q_3 | q_4 | q_m | q_c | q_arith | + * | ---------------------------- | ----- | --- | --- | --- | --- | --- | --- | ------ | + * | Bigfield Limb Accumulation 1 | 1 | 0 | 0 | 1 | 1 | 0 | --- | 0 | + * | Bigfield Limb Accumulation 2 | 1 | 0 | 0 | 1 | 0 | 1 | --- | 0 | + * | Bigfield Product 1 | 1 | 0 | 1 | 1 | 0 | 0 | --- | 0 | + * | Bigfield Product 2 | 1 | 0 | 1 | 0 | 1 | 0 | --- | 0 | + * | Bigfield Product 3 | 1 | 0 | 1 | 0 | 0 | 1 | --- | 0 | + * | RAM/ROM access gate | 1 | 1 | 0 | 0 | 0 | 1 | --- | 0 | + * | RAM timestamp check | 1 | 1 | 0 | 0 | 1 | 0 | --- | 0 | + * | ROM consistency check | 1 | 1 | 1 | 0 | 0 | 0 | --- | 0 | + * | RAM consistency check | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | + * + * N.B. The RAM consistency check identity is degree 3. To keep the overall quotient degree at <=5, only 2 selectors + * can be used to select it. + * + * N.B.2 The q_c selector is used to store circuit-specific values in the RAM/ROM access gate * * @param evals transformed to `evals + C(extended_edges(X)...)*scaling_factor` * @param extended_edges an std::array containing the fully extended Univariate edges. * @param parameters contains beta, gamma, and public_input_delta, .... * @param scaling_factor optional term to scale the evaluation before adding to evals. */ - void add_edge_contribution(Univariate& evals, + void add_edge_contribution(RelationUnivariates& evals, const auto& extended_edges, const RelationParameters& relation_parameters, const FF& scaling_factor) const @@ -32,7 +67,6 @@ template class AuxiliaryRelation { // See https://hackmd.io/xGLuj6biSsCjzQnYN-pEiA?both const auto& eta = relation_parameters.eta; - const auto fake_alpha = FF(1); auto w_1 = UnivariateView(extended_edges.w_l); auto w_2 = UnivariateView(extended_edges.w_r); @@ -177,11 +211,9 @@ template class AuxiliaryRelation { auto adjacent_values_match_if_adjacent_indices_match = (index_delta * FF(-1) + FF(1)) * record_delta; - auto ROM_consistency_check_identity = adjacent_values_match_if_adjacent_indices_match; - ROM_consistency_check_identity *= fake_alpha; - ROM_consistency_check_identity += index_is_monotonically_increasing; - ROM_consistency_check_identity *= fake_alpha; - ROM_consistency_check_identity += memory_record_check; + std::get<1>(evals) += adjacent_values_match_if_adjacent_indices_match * (q_1 * q_2) * (q_aux * scaling_factor); + std::get<2>(evals) += index_is_monotonically_increasing * (q_1 * q_2) * (q_aux * scaling_factor); + auto ROM_consistency_check_identity = memory_record_check * (q_1 * q_2); /** * RAM Consistency Check @@ -224,14 +256,11 @@ template class AuxiliaryRelation { auto next_gate_access_type_is_boolean = next_gate_access_type * next_gate_access_type - next_gate_access_type; // Putting it all together... - auto RAM_consistency_check_identity = - adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation; - RAM_consistency_check_identity *= fake_alpha; - RAM_consistency_check_identity += index_is_monotonically_increasing; - RAM_consistency_check_identity *= fake_alpha; - RAM_consistency_check_identity += next_gate_access_type_is_boolean; - RAM_consistency_check_identity *= fake_alpha; - RAM_consistency_check_identity += access_check; + std::get<3>(evals) += adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation * + (q_arith) * (q_aux * scaling_factor); + std::get<4>(evals) += index_is_monotonically_increasing * (q_arith) * (q_aux * scaling_factor); + std::get<5>(evals) += next_gate_access_type_is_boolean * (q_arith) * (q_aux * scaling_factor); + auto RAM_consistency_check_identity = access_check * (q_arith); /** * RAM Timestamp Consistency Check @@ -251,25 +280,28 @@ template class AuxiliaryRelation { * The complete RAM/ROM memory identity * */ - auto memory_identity = ROM_consistency_check_identity * q_2; - memory_identity += RAM_timestamp_check_identity * q_4; - memory_identity += memory_record_check * q_m; - memory_identity *= q_1; - memory_identity += (RAM_consistency_check_identity * q_arith); + auto memory_identity = ROM_consistency_check_identity; + memory_identity += RAM_timestamp_check_identity * (q_4 * q_1); + memory_identity += memory_record_check * (q_m * q_1); + memory_identity += RAM_consistency_check_identity; auto auxiliary_identity = memory_identity + non_native_field_identity + limb_accumulator_identity; - auxiliary_identity *= q_aux; - auxiliary_identity *= scaling_factor; - - evals += auxiliary_identity; + auxiliary_identity *= (q_aux * scaling_factor); + std::get<0>(evals) += auxiliary_identity; }; - void add_full_relation_value_contribution(FF& full_honk_relation_value, + /** + * @brief Add the result of each identity in this relation evaluated at the multivariate evaluations produced by the + * Sumcheck Prover. + * + * @param full_honk_relation_value + * @param purported_evaluations + */ + void add_full_relation_value_contribution(RelationValues& full_honk_relation_value, const auto& purported_evaluations, const RelationParameters& relation_parameters) const { const auto& eta = relation_parameters.eta; - const auto fake_alpha = FF(1); auto w_1 = purported_evaluations.w_l; auto w_2 = purported_evaluations.w_r; @@ -417,11 +449,9 @@ template class AuxiliaryRelation { auto adjacent_values_match_if_adjacent_indices_match = (FF(1) - index_delta) * record_delta; - auto ROM_consistency_check_identity = adjacent_values_match_if_adjacent_indices_match; - ROM_consistency_check_identity *= fake_alpha; - ROM_consistency_check_identity += index_is_monotonically_increasing; - ROM_consistency_check_identity *= fake_alpha; - ROM_consistency_check_identity += memory_record_check; + std::get<1>(full_honk_relation_value) += adjacent_values_match_if_adjacent_indices_match * (q_1 * q_2) * q_aux; + std::get<2>(full_honk_relation_value) += index_is_monotonically_increasing * (q_1 * q_2) * q_aux; + auto ROM_consistency_check_identity = memory_record_check * (q_1 * q_2); /** * RAM Consistency Check @@ -465,14 +495,11 @@ template class AuxiliaryRelation { auto next_gate_access_type_is_boolean = next_gate_access_type.sqr() - next_gate_access_type; // Putting it all together... - auto RAM_consistency_check_identity = - adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation; - RAM_consistency_check_identity *= fake_alpha; - RAM_consistency_check_identity += index_is_monotonically_increasing; - RAM_consistency_check_identity *= fake_alpha; - RAM_consistency_check_identity += next_gate_access_type_is_boolean; - RAM_consistency_check_identity *= fake_alpha; - RAM_consistency_check_identity += access_check; + std::get<3>(full_honk_relation_value) += + adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation * (q_arith)*q_aux; + std::get<4>(full_honk_relation_value) += index_is_monotonically_increasing * (q_arith)*q_aux; + std::get<5>(full_honk_relation_value) += next_gate_access_type_is_boolean * (q_arith)*q_aux; + auto RAM_consistency_check_identity = access_check * (q_arith); /** * RAM Timestamp Consistency Check @@ -492,17 +519,15 @@ template class AuxiliaryRelation { * The complete RAM/ROM memory identity * */ - auto memory_identity = ROM_consistency_check_identity * q_2; - memory_identity += RAM_timestamp_check_identity * q_4; - memory_identity += memory_record_check * q_m; - memory_identity *= q_1; - memory_identity += (RAM_consistency_check_identity * q_arith); + auto memory_identity = ROM_consistency_check_identity; + memory_identity += RAM_timestamp_check_identity * q_1 * q_4; + memory_identity += memory_record_check * q_1 * q_m; + memory_identity += RAM_consistency_check_identity; // auto auxiliary_identity = limb_accumulator_identity; auto auxiliary_identity = memory_identity + non_native_field_identity + limb_accumulator_identity; auxiliary_identity *= q_aux; - - full_honk_relation_value += auxiliary_identity; + std::get<0>(full_honk_relation_value) += auxiliary_identity; }; }; } // namespace proof_system::honk::sumcheck diff --git a/cpp/src/barretenberg/honk/sumcheck/relations/elliptic_relation.hpp b/cpp/src/barretenberg/honk/sumcheck/relations/elliptic_relation.hpp index 9063a43297..f05cacbf5b 100644 --- a/cpp/src/barretenberg/honk/sumcheck/relations/elliptic_relation.hpp +++ b/cpp/src/barretenberg/honk/sumcheck/relations/elliptic_relation.hpp @@ -3,14 +3,20 @@ #include #include "../polynomials/univariate.hpp" -#include "relation.hpp" +#include "relation_parameters.hpp" namespace proof_system::honk::sumcheck { template class EllipticRelation { public: // 1 + polynomial degree of this relation - static constexpr size_t RELATION_LENGTH = 6; // degree(q_arith^2 * q_m * w_r * w_l) = 5 + static constexpr size_t RELATION_LENGTH = 5; // degree(q_elliptic * q_beta * x^3) = 5 + + static constexpr size_t NUM_CONSTRAINTS = 2; + static constexpr std::array CONSTRAINT_LENGTH = { 6, 5 }; + + using RelationUnivariates = std::tuple, Univariate>; + using RelationValues = std::array; /** * @brief Expression for the Ultra Arithmetic gate. @@ -22,64 +28,83 @@ template class EllipticRelation { * @param parameters contains beta, gamma, and public_input_delta, .... * @param scaling_factor optional term to scale the evaluation before adding to evals. */ - void add_edge_contribution(Univariate& evals, + void add_edge_contribution(RelationUnivariates& evals, const auto& extended_edges, const RelationParameters&, - const FF& scaling_factor) const - { + const FF& scaling_factor) const { // OPTIMIZATION?: Karatsuba in general, at least for some degrees? // See https://hackmd.io/xGLuj6biSsCjzQnYN-pEiA?both - - auto x_1 = UnivariateView(extended_edges.w_r); - auto y_1 = UnivariateView(extended_edges.w_o); - - auto x_2 = UnivariateView(extended_edges.w_l_shift); - auto y_2 = UnivariateView(extended_edges.w_4_shift); - auto x_3 = UnivariateView(extended_edges.w_r_shift); - auto y_3 = UnivariateView(extended_edges.w_o_shift); - - auto q_sign = UnivariateView(extended_edges.q_l); - auto q_beta = UnivariateView(extended_edges.q_o); - auto q_beta_sqr = UnivariateView(extended_edges.q_4); - auto q_elliptic = UnivariateView(extended_edges.q_elliptic); - - static const FF fake_alpha_1 = FF(1); - static const FF fake_alpha_2 = fake_alpha_1 * fake_alpha_1; - - auto beta_term = x_2 * x_1 * (x_3 + x_3 + x_1) * FF(-1); // -x_1 * x_2 * (2 * x_3 + x_1) - auto beta_sqr_term = x_2 * x_2; // x_2^2 - auto leftovers = beta_sqr_term; // x_2^2 - beta_sqr_term *= (x_3 - x_1); // x_2^2 * (x_3 - x_1) - auto sign_term = y_2 * y_1; // y_1 * y_2 - sign_term += sign_term; // 2 * y_1 * y_2 - beta_term *= q_beta; // -β * x_1 * x_2 * (2 * x_3 + x_1) - beta_sqr_term *= q_beta_sqr; // β^2 * x_2^2 * (x_3 - x_1) - sign_term *= q_sign; // 2 * y_1 * y_2 * sign - leftovers *= x_2; // x_2^3 - leftovers += x_1 * x_1 * (x_3 + x_1); // x_2^3 + x_1 * (x_3 + x_1) - leftovers -= (y_2 * y_2 + y_1 * y_1); // x_2^3 + x_1 * (x_3 + x_1) - y_2^2 - y_1^2 - - // Can be found in class description - auto x_identity = beta_term + beta_sqr_term + sign_term + leftovers; - x_identity *= fake_alpha_1; - - beta_term = x_2 * (y_3 + y_1) * q_beta; // β * x_2 * (y_3 + y_1) - sign_term = y_2 * (x_1 - x_3) * q_sign * FF(-1); // - signt * y_2 * (x_1 - x_3) - // TODO: remove extra additions if we decide to stay with this implementation - leftovers = x_1 * (y_3 + y_1) * FF(-1) + y_1 * (x_1 - x_3); // -x_1 * y_3 - x_1 * y_1 + y_1 * x_1 - y_1 * x_3 - - auto y_identity = beta_term + sign_term + leftovers; - y_identity *= fake_alpha_2; - - auto tmp = x_identity + y_identity; - tmp *= q_elliptic; - - tmp *= scaling_factor; - - evals += tmp; + // TODO(luke): Formatter doesnt properly handle explicit scoping below so turning off. Whats up? + // clang-format off + // Contribution (1) + { + static constexpr size_t LENGTH = CONSTRAINT_LENGTH[0]; + auto x_1 = UnivariateView(extended_edges.w_r); + auto y_1 = UnivariateView(extended_edges.w_o); + + auto x_2 = UnivariateView(extended_edges.w_l_shift); + auto y_2 = UnivariateView(extended_edges.w_4_shift); + auto x_3 = UnivariateView(extended_edges.w_r_shift); + + auto q_sign = UnivariateView(extended_edges.q_l); + auto q_beta = UnivariateView(extended_edges.q_o); + auto q_beta_sqr = UnivariateView(extended_edges.q_4); + auto q_elliptic = UnivariateView(extended_edges.q_elliptic); + + auto beta_term = x_2 * x_1 * (x_3 + x_3 + x_1) * FF(-1); // -x_1 * x_2 * (2 * x_3 + x_1) + auto beta_sqr_term = x_2 * x_2; // x_2^2 + auto leftovers = beta_sqr_term; // x_2^2 + beta_sqr_term *= (x_3 - x_1); // x_2^2 * (x_3 - x_1) + auto sign_term = y_2 * y_1; // y_1 * y_2 + sign_term += sign_term; // 2 * y_1 * y_2 + beta_term *= q_beta; // -β * x_1 * x_2 * (2 * x_3 + x_1) + beta_sqr_term *= q_beta_sqr; // β^2 * x_2^2 * (x_3 - x_1) + sign_term *= q_sign; // 2 * y_1 * y_2 * sign + leftovers *= x_2; // x_2^3 + leftovers += x_1 * x_1 * (x_3 + x_1); // x_2^3 + x_1 * (x_3 + x_1) + leftovers -= (y_2 * y_2 + y_1 * y_1); // x_2^3 + x_1 * (x_3 + x_1) - y_2^2 - y_1^2 + + // Can be found in class description + auto x_identity = beta_term + beta_sqr_term + sign_term + leftovers; + x_identity *= q_elliptic; + x_identity *= scaling_factor; + std::get<0>(evals) += x_identity; + } + // Contribution (2) + { + static constexpr size_t LENGTH = CONSTRAINT_LENGTH[1]; + auto x_1 = UnivariateView(extended_edges.w_r); + auto y_1 = UnivariateView(extended_edges.w_o); + + auto x_2 = UnivariateView(extended_edges.w_l_shift); + auto y_2 = UnivariateView(extended_edges.w_4_shift); + auto x_3 = UnivariateView(extended_edges.w_r_shift); + auto y_3 = UnivariateView(extended_edges.w_o_shift); + + auto q_sign = UnivariateView(extended_edges.q_l); + auto q_beta = UnivariateView(extended_edges.q_o); + auto q_elliptic = UnivariateView(extended_edges.q_elliptic); + + auto beta_term = x_2 * (y_3 + y_1) * q_beta; // β * x_2 * (y_3 + y_1) + auto sign_term = y_2 * (x_1 - x_3) * q_sign * FF(-1); // - signt * y_2 * (x_1 - x_3) + // TODO: remove extra additions if we decide to stay with this implementation + auto leftovers = x_1 * (y_3 + y_1) * FF(-1) + y_1 * (x_1 - x_3); // -x_1 * y_3 - x_1 * y_1 + y_1 * x_1 - y_1 * x_3 + + auto y_identity = beta_term + sign_term + leftovers; + y_identity *= q_elliptic; + y_identity *= scaling_factor; + std::get<1>(evals) += y_identity; + } }; - void add_full_relation_value_contribution(FF& full_honk_relation_value, + /** + * @brief Add the result of each identity in this relation evaluated at the multivariate evaluations produced by the + * Sumcheck Prover. + * + * @param full_honk_relation_value + * @param purported_evaluations + */ + void add_full_relation_value_contribution(RelationValues& full_honk_relation_value, const auto& purported_evaluations, const RelationParameters&) const { @@ -96,9 +121,7 @@ template class EllipticRelation { auto q_beta_sqr = purported_evaluations.q_4; auto q_elliptic = purported_evaluations.q_elliptic; - static const FF fake_alpha_1 = FF(1); - static const FF fake_alpha_2 = fake_alpha_1 * fake_alpha_1; - + // Contribution (1) auto beta_term = x_2 * x_1 * (x_3 + x_3 + x_1) * FF(-1); // -x_1 * x_2 * (2 * x_3 + x_1) auto beta_sqr_term = x_2 * x_2; // x_2^2 auto leftovers = beta_sqr_term; // x_2^2 @@ -114,20 +137,19 @@ template class EllipticRelation { // Can be found in class description auto x_identity = beta_term + beta_sqr_term + sign_term + leftovers; - x_identity *= fake_alpha_1; + x_identity *= q_elliptic; + std::get<0>(full_honk_relation_value) += x_identity; + // Contribution (2) beta_term = x_2 * (y_3 + y_1) * q_beta; // β * x_2 * (y_3 + y_1) sign_term = y_2 * (x_1 - x_3) * q_sign * FF(-1); // - signt * y_2 * (x_1 - x_3) // TODO: remove extra additions if we decide to stay with this implementation leftovers = x_1 * (y_3 + y_1) * FF(-1) + y_1 * (x_1 - x_3); // -x_1 * y_3 - x_1 * y_1 + y_1 * x_1 - y_1 * x_3 auto y_identity = beta_term + sign_term + leftovers; - y_identity *= fake_alpha_2; - - auto tmp = x_identity + y_identity; - tmp *= q_elliptic; - - full_honk_relation_value += tmp; + y_identity *= q_elliptic; + std::get<1>(full_honk_relation_value) += y_identity; }; }; +// clang-format on } // namespace proof_system::honk::sumcheck diff --git a/cpp/src/barretenberg/honk/sumcheck/relations/gen_perm_sort_relation.hpp b/cpp/src/barretenberg/honk/sumcheck/relations/gen_perm_sort_relation.hpp index 1eb10c0670..d4649acafa 100644 --- a/cpp/src/barretenberg/honk/sumcheck/relations/gen_perm_sort_relation.hpp +++ b/cpp/src/barretenberg/honk/sumcheck/relations/gen_perm_sort_relation.hpp @@ -3,7 +3,7 @@ #include #include "../polynomials/univariate.hpp" -#include "relation.hpp" +#include "relation_parameters.hpp" namespace proof_system::honk::sumcheck { @@ -12,6 +12,15 @@ template class GenPermSortRelation { // 1 + polynomial degree of this relation static constexpr size_t RELATION_LENGTH = 6; // degree(q_sort * D(D - 1)(D - 2)(D - 3)) = 5 + static constexpr size_t NUM_CONSTRAINTS = 4; + static constexpr std::array CONSTRAINT_LENGTH = { 6, 6, 6, 6 }; + + using RelationUnivariates = std::tuple, + Univariate, + Univariate, + Univariate>; + using RelationValues = std::array; + /** * @brief Expression for the generalized permutation sort gate. * @details The relation is defined as C(extended_edges(X)...) = @@ -27,7 +36,7 @@ template class GenPermSortRelation { * @param parameters contains beta, gamma, and public_input_delta, .... * @param scaling_factor optional term to scale the evaluation before adding to evals. */ - void add_edge_contribution(Univariate& evals, + void add_edge_contribution(RelationUnivariates& evals, const auto& extended_edges, const RelationParameters&, const FF& scaling_factor) const @@ -46,53 +55,57 @@ template class GenPermSortRelation { static const FF minus_two = FF(-2); static const FF minus_three = FF(-3); - // TODO(#427): Eventually this would be based on real alpha but this is not a full solution - // since utilizing powers of alpha internal to a relation results in incorrect powers - // being used in the ultimate univariate batching. i.e we'd wind up reusing the same power - // of alpha in multiple relations. - static const FF fake_alpha_1 = FF(1); - static const FF fake_alpha_2 = fake_alpha_1 * fake_alpha_1; - static const FF fake_alpha_3 = fake_alpha_2 * fake_alpha_1; - static const FF fake_alpha_4 = fake_alpha_3 * fake_alpha_1; - // Compute wire differences auto delta_1 = w_2 - w_1; auto delta_2 = w_3 - w_2; auto delta_3 = w_4 - w_3; auto delta_4 = w_1_shift - w_4; + // Contribution (1) auto tmp_1 = delta_1; tmp_1 *= (delta_1 + minus_one); tmp_1 *= (delta_1 + minus_two); tmp_1 *= (delta_1 + minus_three); - tmp_1 *= fake_alpha_1; // 1 + tmp_1 *= q_sort; + tmp_1 *= scaling_factor; + std::get<0>(evals) += tmp_1; + // Contribution (2) auto tmp_2 = delta_2; tmp_2 *= (delta_2 + minus_one); tmp_2 *= (delta_2 + minus_two); tmp_2 *= (delta_2 + minus_three); - tmp_2 *= fake_alpha_2; // alpha + tmp_2 *= q_sort; + tmp_2 *= scaling_factor; + std::get<1>(evals) += tmp_2; + // Contribution (3) auto tmp_3 = delta_3; tmp_3 *= (delta_3 + minus_one); tmp_3 *= (delta_3 + minus_two); tmp_3 *= (delta_3 + minus_three); - tmp_3 *= fake_alpha_3; // alpha^2 + tmp_3 *= q_sort; + tmp_3 *= scaling_factor; + std::get<2>(evals) += tmp_3; + // Contribution (4) auto tmp_4 = delta_4; tmp_4 *= (delta_4 + minus_one); tmp_4 *= (delta_4 + minus_two); tmp_4 *= (delta_4 + minus_three); - tmp_4 *= fake_alpha_4; // alpha^3 - - auto tmp = tmp_1 + tmp_2 + tmp_3 + tmp_4; - tmp *= q_sort; - tmp *= scaling_factor; - - evals += tmp; + tmp_4 *= q_sort; + tmp_4 *= scaling_factor; + std::get<3>(evals) += tmp_4; }; - void add_full_relation_value_contribution(FF& full_honk_relation_value, + /** + * @brief Add the result of each identity in this relation evaluated at the multivariate evaluations produced by the + * Sumcheck Prover. + * + * @param full_honk_relation_value + * @param purported_evaluations + */ + void add_full_relation_value_contribution(RelationValues& full_honk_relation_value, const auto& purported_evaluations, const RelationParameters&) const { @@ -107,15 +120,6 @@ template class GenPermSortRelation { static const FF minus_two = FF(-2); static const FF minus_three = FF(-3); - // TODO(#427): Eventually this would be based on real alpha but this is not a full solution - // since utilizing powers of alpha internal to a relation results in incorrect powers - // being used in the ultimate univariate batching. i.e we'd wind up reusing the same power - // of alpha in multiple relations. - static const FF fake_alpha_1 = FF(1); - static const FF fake_alpha_2 = fake_alpha_1 * fake_alpha_1; - static const FF fake_alpha_3 = fake_alpha_2 * fake_alpha_1; - static const FF fake_alpha_4 = fake_alpha_3 * fake_alpha_1; - // Compute wire differences auto delta_1 = w_2 - w_1; auto delta_2 = w_3 - w_2; @@ -126,30 +130,29 @@ template class GenPermSortRelation { tmp_1 *= (delta_1 + minus_one); tmp_1 *= (delta_1 + minus_two); tmp_1 *= (delta_1 + minus_three); - tmp_1 *= fake_alpha_1; // 1 + tmp_1 *= q_sort; + std::get<0>(full_honk_relation_value) += tmp_1; auto tmp_2 = delta_2; tmp_2 *= (delta_2 + minus_one); tmp_2 *= (delta_2 + minus_two); tmp_2 *= (delta_2 + minus_three); - tmp_2 *= fake_alpha_2; // alpha + tmp_2 *= q_sort; + std::get<1>(full_honk_relation_value) += tmp_2; auto tmp_3 = delta_3; tmp_3 *= (delta_3 + minus_one); tmp_3 *= (delta_3 + minus_two); tmp_3 *= (delta_3 + minus_three); - tmp_3 *= fake_alpha_3; // alpha^2 + tmp_3 *= q_sort; + std::get<2>(full_honk_relation_value) += tmp_3; auto tmp_4 = delta_4; tmp_4 *= (delta_4 + minus_one); tmp_4 *= (delta_4 + minus_two); tmp_4 *= (delta_4 + minus_three); - tmp_4 *= fake_alpha_4; // alpha^3 - - auto tmp = tmp_1 + tmp_2 + tmp_3 + tmp_4; - tmp *= q_sort; - - full_honk_relation_value += tmp; + tmp_4 *= q_sort; + std::get<3>(full_honk_relation_value) += tmp_4; }; }; } // namespace proof_system::honk::sumcheck diff --git a/cpp/src/barretenberg/honk/sumcheck/relations/grand_product_initialization_relation.hpp b/cpp/src/barretenberg/honk/sumcheck/relations/grand_product_initialization_relation.hpp deleted file mode 100644 index 0fd8fbd606..0000000000 --- a/cpp/src/barretenberg/honk/sumcheck/relations/grand_product_initialization_relation.hpp +++ /dev/null @@ -1,89 +0,0 @@ -#pragma once -#include "relation.hpp" -#include "../polynomials/univariate.hpp" - -namespace proof_system::honk::sumcheck { - -template class GrandProductInitializationRelation { - public: - // 1 + polynomial degree of this relation - static constexpr size_t RELATION_LENGTH = 3; - - /** - * @brief Add contribution of the permutation relation for a given edge - * - * @details There are 2 relations associated with enforcing the wire copy relations - * This file handles the relation Z_perm_shift(n_last) = 0 via the relation: - * - * C(X) = L_LAST(X) * Z_perm_shift(X) - * - * @param evals transformed to `evals + C(extended_edges(X)...)*scaling_factor` - * @param extended_edges an std::array containing the fully extended Univariate edges. - * @param parameters contains beta, gamma, and public_input_delta, .... - * @param scaling_factor optional term to scale the evaluation before adding to evals. - */ - void add_edge_contribution(Univariate& evals, - const auto& extended_edges, - const RelationParameters&, - const FF& scaling_factor) const - { - auto z_perm_shift = UnivariateView(extended_edges.z_perm_shift); - auto lagrange_last = UnivariateView(extended_edges.lagrange_last); - - evals += (lagrange_last * z_perm_shift) * scaling_factor; - }; - - void add_full_relation_value_contribution(FF& full_honk_relation_value, - auto& purported_evaluations, - const RelationParameters&) const - { - auto z_perm_shift = purported_evaluations.z_perm_shift; - auto lagrange_last = purported_evaluations.lagrange_last; - - full_honk_relation_value += lagrange_last * z_perm_shift; - }; -}; - -// TODO(luke): The only difference between the Ultra relation and the Standard version is the enum -// used to refer into the edge polynomials. Seems desireable to not duplicate the code here but -// leaving this as is until Codys Flavor work is settled. -template class UltraGrandProductInitializationRelation { - public: - // 1 + polynomial degree of this relation - static constexpr size_t RELATION_LENGTH = 3; - - /** - * @brief Add contribution of the permutation relation for a given edge - * - * @details There are 2 relations associated with enforcing the wire copy relations - * This file handles the relation Z_perm_shift(n_last) = 0 via the relation: - * - * C(X) = L_LAST(X) * Z_perm_shift(X) - * - * @param evals transformed to `evals + C(extended_edges(X)...)*scaling_factor` - * @param extended_edges an std::array containing the fully extended Univariate edges. - * @param parameters contains beta, gamma, and public_input_delta, .... - * @param scaling_factor optional term to scale the evaluation before adding to evals. - */ - void add_edge_contribution(Univariate& evals, - const auto& extended_edges, - const RelationParameters&, - const FF& scaling_factor) const - { - auto z_perm_shift = UnivariateView(extended_edges.z_perm_shift); - auto lagrange_last = UnivariateView(extended_edges.lagrange_last); - - evals += (lagrange_last * z_perm_shift) * scaling_factor; - }; - - void add_full_relation_value_contribution(FF& full_honk_relation_value, - auto& purported_evaluations, - const RelationParameters&) const - { - auto z_perm_shift = purported_evaluations.z_perm_shift; - auto lagrange_last = purported_evaluations.lagrange_last; - - full_honk_relation_value += lagrange_last * z_perm_shift; - }; -}; -} // namespace proof_system::honk::sumcheck diff --git a/cpp/src/barretenberg/honk/sumcheck/relations/lookup_grand_product_relation.hpp b/cpp/src/barretenberg/honk/sumcheck/relations/lookup_relation.hpp similarity index 50% rename from cpp/src/barretenberg/honk/sumcheck/relations/lookup_grand_product_relation.hpp rename to cpp/src/barretenberg/honk/sumcheck/relations/lookup_relation.hpp index 32830a8dc3..b08a2bdedd 100644 --- a/cpp/src/barretenberg/honk/sumcheck/relations/lookup_grand_product_relation.hpp +++ b/cpp/src/barretenberg/honk/sumcheck/relations/lookup_relation.hpp @@ -1,5 +1,5 @@ #pragma once -#include "relation.hpp" +#include "relation_parameters.hpp" #include "../polynomials/univariate.hpp" #pragma GCC diagnostic ignored "-Wunused-variable" @@ -7,11 +7,17 @@ namespace proof_system::honk::sumcheck { -template class LookupGrandProductComputationRelation { +template class LookupRelation { public: // 1 + polynomial degree of this relation static constexpr size_t RELATION_LENGTH = 6; // deg(z_lookup * column_selector * wire * q_lookup * table) = 5 + static constexpr size_t NUM_CONSTRAINTS = 2; + static constexpr std::array CONSTRAINT_LENGTH = { 6, 3 }; + + using RelationUnivariates = std::tuple, Univariate>; + using RelationValues = std::array; + /** * @brief Compute contribution of the lookup grand prod relation for a given edge (internal function) * @@ -30,7 +36,7 @@ template class LookupGrandProductComputationRelation { * @param parameters contains beta, gamma, and public_input_delta, .... * @param scaling_factor optional term to scale the evaluation before adding to evals. */ - inline void add_edge_contribution(Univariate& evals, + inline void add_edge_contribution(RelationUnivariates& evals, const auto& extended_edges, const RelationParameters& relation_parameters, const FF& scaling_factor) const @@ -45,60 +51,78 @@ template class LookupGrandProductComputationRelation { const auto eta_sqr = eta * eta; const auto eta_cube = eta_sqr * eta; - auto w_1 = UnivariateView(extended_edges.w_l); - auto w_2 = UnivariateView(extended_edges.w_r); - auto w_3 = UnivariateView(extended_edges.w_o); - - auto w_1_shift = UnivariateView(extended_edges.w_l_shift); - auto w_2_shift = UnivariateView(extended_edges.w_r_shift); - auto w_3_shift = UnivariateView(extended_edges.w_o_shift); - - auto table_1 = UnivariateView(extended_edges.table_1); - auto table_2 = UnivariateView(extended_edges.table_2); - auto table_3 = UnivariateView(extended_edges.table_3); - auto table_4 = UnivariateView(extended_edges.table_4); - - auto table_1_shift = UnivariateView(extended_edges.table_1_shift); - auto table_2_shift = UnivariateView(extended_edges.table_2_shift); - auto table_3_shift = UnivariateView(extended_edges.table_3_shift); - auto table_4_shift = UnivariateView(extended_edges.table_4_shift); - - auto s_accum = UnivariateView(extended_edges.sorted_accum); - auto s_accum_shift = UnivariateView(extended_edges.sorted_accum_shift); - - auto z_lookup = UnivariateView(extended_edges.z_lookup); - auto z_lookup_shift = UnivariateView(extended_edges.z_lookup_shift); - - auto table_index = UnivariateView(extended_edges.q_o); - auto column_1_step_size = UnivariateView(extended_edges.q_r); - auto column_2_step_size = UnivariateView(extended_edges.q_m); - auto column_3_step_size = UnivariateView(extended_edges.q_c); - auto q_lookup = UnivariateView(extended_edges.q_lookup); - - auto lagrange_first = UnivariateView(extended_edges.lagrange_first); - auto lagrange_last = UnivariateView(extended_edges.lagrange_last); - - // (w_1 + q_2*w_1_shift) + η(w_2 + q_m*w_2_shift) + η²(w_3 + q_c*w_3_shift) + η³q_index. - auto wire_accum = (w_1 + column_1_step_size * w_1_shift) + (w_2 + column_2_step_size * w_2_shift) * eta + - (w_3 + column_3_step_size * w_3_shift) * eta_sqr + table_index * eta_cube; - - // t_1 + ηt_2 + η²t_3 + η³t_4 - auto table_accum = table_1 + table_2 * eta + table_3 * eta_sqr + table_4 * eta_cube; - // t_1_shift + ηt_2_shift + η²t_3_shift + η³t_4_shift - auto table_accum_shift = - table_1_shift + table_2_shift * eta + table_3_shift * eta_sqr + table_4_shift * eta_cube; - // Contribution (1) - auto tmp = (q_lookup * wire_accum + gamma); - tmp *= (table_accum + table_accum_shift * beta + gamma_by_one_plus_beta); - tmp *= one_plus_beta; - tmp *= (z_lookup + lagrange_first); - tmp -= (z_lookup_shift + lagrange_last * grand_product_delta) * - (s_accum + s_accum_shift * beta + gamma_by_one_plus_beta); - evals += tmp * scaling_factor; + { + static constexpr size_t LENGTH = CONSTRAINT_LENGTH[0]; + auto w_1 = UnivariateView(extended_edges.w_l); + auto w_2 = UnivariateView(extended_edges.w_r); + auto w_3 = UnivariateView(extended_edges.w_o); + + auto w_1_shift = UnivariateView(extended_edges.w_l_shift); + auto w_2_shift = UnivariateView(extended_edges.w_r_shift); + auto w_3_shift = UnivariateView(extended_edges.w_o_shift); + + auto table_1 = UnivariateView(extended_edges.table_1); + auto table_2 = UnivariateView(extended_edges.table_2); + auto table_3 = UnivariateView(extended_edges.table_3); + auto table_4 = UnivariateView(extended_edges.table_4); + + auto table_1_shift = UnivariateView(extended_edges.table_1_shift); + auto table_2_shift = UnivariateView(extended_edges.table_2_shift); + auto table_3_shift = UnivariateView(extended_edges.table_3_shift); + auto table_4_shift = UnivariateView(extended_edges.table_4_shift); + + auto s_accum = UnivariateView(extended_edges.sorted_accum); + auto s_accum_shift = UnivariateView(extended_edges.sorted_accum_shift); + + auto z_lookup = UnivariateView(extended_edges.z_lookup); + auto z_lookup_shift = UnivariateView(extended_edges.z_lookup_shift); + + auto table_index = UnivariateView(extended_edges.q_o); + auto column_1_step_size = UnivariateView(extended_edges.q_r); + auto column_2_step_size = UnivariateView(extended_edges.q_m); + auto column_3_step_size = UnivariateView(extended_edges.q_c); + auto q_lookup = UnivariateView(extended_edges.q_lookup); + + auto lagrange_first = UnivariateView(extended_edges.lagrange_first); + auto lagrange_last = UnivariateView(extended_edges.lagrange_last); + + // (w_1 + q_2*w_1_shift) + η(w_2 + q_m*w_2_shift) + η²(w_3 + q_c*w_3_shift) + η³q_index. + auto wire_accum = (w_1 + column_1_step_size * w_1_shift) + (w_2 + column_2_step_size * w_2_shift) * eta + + (w_3 + column_3_step_size * w_3_shift) * eta_sqr + table_index * eta_cube; + + // t_1 + ηt_2 + η²t_3 + η³t_4 + auto table_accum = table_1 + table_2 * eta + table_3 * eta_sqr + table_4 * eta_cube; + // t_1_shift + ηt_2_shift + η²t_3_shift + η³t_4_shift + auto table_accum_shift = + table_1_shift + table_2_shift * eta + table_3_shift * eta_sqr + table_4_shift * eta_cube; + + auto tmp = (q_lookup * wire_accum + gamma); + tmp *= (table_accum + table_accum_shift * beta + gamma_by_one_plus_beta); + tmp *= one_plus_beta; + tmp *= (z_lookup + lagrange_first); + tmp -= (z_lookup_shift + lagrange_last * grand_product_delta) * + (s_accum + s_accum_shift * beta + gamma_by_one_plus_beta); + std::get<0>(evals) += tmp * scaling_factor; + } + { + static constexpr size_t LENGTH = CONSTRAINT_LENGTH[1]; + auto z_lookup_shift = UnivariateView(extended_edges.z_lookup_shift); + auto lagrange_last = UnivariateView(extended_edges.lagrange_last); + + // Contribution (2) + std::get<1>(evals) += (lagrange_last * z_lookup_shift) * scaling_factor; + } }; - void add_full_relation_value_contribution(FF& full_honk_relation_value, + /** + * @brief Add the result of each identity in this relation evaluated at the multivariate evaluations produced by the + * Sumcheck Prover. + * + * @param full_honk_relation_value + * @param purported_evaluations + */ + void add_full_relation_value_contribution(RelationValues& full_honk_relation_value, auto& purported_evaluations, const RelationParameters& relation_parameters) const { @@ -162,45 +186,10 @@ template class LookupGrandProductComputationRelation { tmp *= (z_lookup + lagrange_first); tmp -= (z_lookup_shift + lagrange_last * grand_product_delta) * (s_accum + beta * s_accum_shift + gamma_by_one_plus_beta); - full_honk_relation_value += tmp; - }; -}; - -template class LookupGrandProductInitializationRelation { - public: - // 1 + polynomial degree of this relation - static constexpr size_t RELATION_LENGTH = 3; // deg(lagrange_last * z_lookup_shift) = 2 - - /** - * @brief Compute contribution of the lookup grand prod relation for a given edge (internal function) - * - * @details This the relation confirms correct initialization of the lookup grand - * product polynomial Z_lookup with Z_lookup[circuit_size] = 0. - * - * @param evals transformed to `evals + C(extended_edges(X)...)*scaling_factor` - * @param extended_edges an std::array containing the fully extended Univariate edges. - * @param parameters contains beta, gamma, and public_input_delta, .... - * @param scaling_factor optional term to scale the evaluation before adding to evals. - */ - inline void add_edge_contribution(Univariate& evals, - const auto& extended_edges, - const RelationParameters& /*unused*/, - const FF& scaling_factor) const - { - auto z_lookup_shift = UnivariateView(extended_edges.z_lookup_shift); - auto lagrange_last = UnivariateView(extended_edges.lagrange_last); - - evals += (lagrange_last * z_lookup_shift) * scaling_factor; - }; - - void add_full_relation_value_contribution(FF& full_honk_relation_value, - auto& purported_evaluations, - const RelationParameters& /*unused*/) const - { - auto z_lookup_shift = purported_evaluations.z_lookup_shift; - auto lagrange_last = purported_evaluations.lagrange_last; + std::get<0>(full_honk_relation_value) += tmp; - full_honk_relation_value += lagrange_last * z_lookup_shift; + // Contribution (2) + std::get<1>(full_honk_relation_value) += lagrange_last * z_lookup_shift; }; }; } // namespace proof_system::honk::sumcheck \ No newline at end of file diff --git a/cpp/src/barretenberg/honk/sumcheck/relations/grand_product_computation_relation.hpp b/cpp/src/barretenberg/honk/sumcheck/relations/permutation_relation.hpp similarity index 50% rename from cpp/src/barretenberg/honk/sumcheck/relations/grand_product_computation_relation.hpp rename to cpp/src/barretenberg/honk/sumcheck/relations/permutation_relation.hpp index ff2bc0ea8f..f613f0c3b6 100644 --- a/cpp/src/barretenberg/honk/sumcheck/relations/grand_product_computation_relation.hpp +++ b/cpp/src/barretenberg/honk/sumcheck/relations/permutation_relation.hpp @@ -1,15 +1,21 @@ #pragma once -#include "relation.hpp" +#include "relation_parameters.hpp" #include "../polynomials/univariate.hpp" // TODO(luke): change name of this file to permutation_grand_product_relation(s).hpp and move 'init' relation into it. namespace proof_system::honk::sumcheck { -template class GrandProductComputationRelation { +template class PermutationRelation { public: // 1 + polynomial degree of this relation static constexpr size_t RELATION_LENGTH = 5; + static constexpr size_t NUM_CONSTRAINTS = 2; + static constexpr std::array CONSTRAINT_LENGTH = { 5, 3 }; + + using RelationUnivariates = std::tuple, Univariate>; + using RelationValues = std::array; + /** * @brief Compute contribution of the permutation relation for a given edge (internal function) * @@ -28,7 +34,7 @@ template class GrandProductComputationRelation { * @param parameters contains beta, gamma, and public_input_delta, .... * @param scaling_factor optional term to scale the evaluation before adding to evals. */ - inline void add_edge_contribution(Univariate& evals, + inline void add_edge_contribution(RelationUnivariates& evals, const auto& extended_edges, const RelationParameters& relation_parameters, const FF& scaling_factor) const @@ -37,29 +43,48 @@ template class GrandProductComputationRelation { const auto& gamma = relation_parameters.gamma; const auto& public_input_delta = relation_parameters.public_input_delta; - auto w_1 = UnivariateView(extended_edges.w_l); - auto w_2 = UnivariateView(extended_edges.w_r); - auto w_3 = UnivariateView(extended_edges.w_o); - auto sigma_1 = UnivariateView(extended_edges.sigma_1); - auto sigma_2 = UnivariateView(extended_edges.sigma_2); - auto sigma_3 = UnivariateView(extended_edges.sigma_3); - auto id_1 = UnivariateView(extended_edges.id_1); - auto id_2 = UnivariateView(extended_edges.id_2); - auto id_3 = UnivariateView(extended_edges.id_3); - auto z_perm = UnivariateView(extended_edges.z_perm); - auto z_perm_shift = UnivariateView(extended_edges.z_perm_shift); - auto lagrange_first = UnivariateView(extended_edges.lagrange_first); - auto lagrange_last = UnivariateView(extended_edges.lagrange_last); + { + static constexpr size_t LENGTH = CONSTRAINT_LENGTH[0]; + auto w_1 = UnivariateView(extended_edges.w_l); + auto w_2 = UnivariateView(extended_edges.w_r); + auto w_3 = UnivariateView(extended_edges.w_o); + auto sigma_1 = UnivariateView(extended_edges.sigma_1); + auto sigma_2 = UnivariateView(extended_edges.sigma_2); + auto sigma_3 = UnivariateView(extended_edges.sigma_3); + auto id_1 = UnivariateView(extended_edges.id_1); + auto id_2 = UnivariateView(extended_edges.id_2); + auto id_3 = UnivariateView(extended_edges.id_3); + auto z_perm = UnivariateView(extended_edges.z_perm); + auto z_perm_shift = UnivariateView(extended_edges.z_perm_shift); + auto lagrange_first = UnivariateView(extended_edges.lagrange_first); + auto lagrange_last = UnivariateView(extended_edges.lagrange_last); - // Contribution (1) - evals += (((z_perm + lagrange_first) * (w_1 + id_1 * beta + gamma) * (w_2 + id_2 * beta + gamma) * - (w_3 + id_3 * beta + gamma)) - - ((z_perm_shift + lagrange_last * public_input_delta) * (w_1 + sigma_1 * beta + gamma) * - (w_2 + sigma_2 * beta + gamma) * (w_3 + sigma_3 * beta + gamma))) * - scaling_factor; + // Contribution (1) + std::get<0>(evals) += + (((z_perm + lagrange_first) * (w_1 + id_1 * beta + gamma) * (w_2 + id_2 * beta + gamma) * + (w_3 + id_3 * beta + gamma)) - + ((z_perm_shift + lagrange_last * public_input_delta) * (w_1 + sigma_1 * beta + gamma) * + (w_2 + sigma_2 * beta + gamma) * (w_3 + sigma_3 * beta + gamma))) * + scaling_factor; + } + { + static constexpr size_t LENGTH = CONSTRAINT_LENGTH[1]; + auto z_perm_shift = UnivariateView(extended_edges.z_perm_shift); + auto lagrange_last = UnivariateView(extended_edges.lagrange_last); + + // Contribution (2) + std::get<1>(evals) += (lagrange_last * z_perm_shift) * scaling_factor; + } }; - void add_full_relation_value_contribution(FF& full_honk_relation_value, + /** + * @brief Add the result of each identity in this relation evaluated at the multivariate evaluations produced by the + * Sumcheck Prover. + * + * @param full_honk_relation_value + * @param purported_evaluations + */ + void add_full_relation_value_contribution(RelationValues& full_honk_relation_value, auto& purported_evaluations, const RelationParameters& relation_parameters) const { @@ -82,21 +107,30 @@ template class GrandProductComputationRelation { auto lagrange_last = purported_evaluations.lagrange_last; // Contribution (1) - full_honk_relation_value += + std::get<0>(full_honk_relation_value) += ((z_perm + lagrange_first) * (w_1 + beta * id_1 + gamma) * (w_2 + beta * id_2 + gamma) * (w_3 + beta * id_3 + gamma) - (z_perm_shift + lagrange_last * public_input_delta) * (w_1 + beta * sigma_1 + gamma) * (w_2 + beta * sigma_2 + gamma) * (w_3 + beta * sigma_3 + gamma)); + + // Contribution (2) + std::get<1>(full_honk_relation_value) += lagrange_last * z_perm_shift; }; }; // TODO(luke): With Cody's Flavor work it should be easier to create a simple templated relation // for handling arbitrary width. For now I'm duplicating the width 3 logic for width 4. -template class UltraGrandProductComputationRelation { +template class UltraPermutationRelation { public: // 1 + polynomial degree of this relation static constexpr size_t RELATION_LENGTH = 6; + static constexpr size_t NUM_CONSTRAINTS = 2; + static constexpr std::array CONSTRAINT_LENGTH = { 6, 3 }; + + using RelationUnivariates = std::tuple, Univariate>; + using RelationValues = std::array; + /** * @brief Compute contribution of the permutation relation for a given edge (internal function) * @@ -108,7 +142,7 @@ template class UltraGrandProductComputationRelation { * @param parameters contains beta, gamma, and public_input_delta, .... * @param scaling_factor optional term to scale the evaluation before adding to evals. */ - inline void add_edge_contribution(Univariate& evals, + inline void add_edge_contribution(RelationUnivariates& evals, const auto& extended_edges, const RelationParameters& relation_parameters, const FF& scaling_factor) const @@ -117,32 +151,51 @@ template class UltraGrandProductComputationRelation { const auto& gamma = relation_parameters.gamma; const auto& public_input_delta = relation_parameters.public_input_delta; - auto w_1 = UnivariateView(extended_edges.w_l); - auto w_2 = UnivariateView(extended_edges.w_r); - auto w_3 = UnivariateView(extended_edges.w_o); - auto w_4 = UnivariateView(extended_edges.w_4); - auto sigma_1 = UnivariateView(extended_edges.sigma_1); - auto sigma_2 = UnivariateView(extended_edges.sigma_2); - auto sigma_3 = UnivariateView(extended_edges.sigma_3); - auto sigma_4 = UnivariateView(extended_edges.sigma_4); - auto id_1 = UnivariateView(extended_edges.id_1); - auto id_2 = UnivariateView(extended_edges.id_2); - auto id_3 = UnivariateView(extended_edges.id_3); - auto id_4 = UnivariateView(extended_edges.id_4); - auto z_perm = UnivariateView(extended_edges.z_perm); - auto z_perm_shift = UnivariateView(extended_edges.z_perm_shift); - auto lagrange_first = UnivariateView(extended_edges.lagrange_first); - auto lagrange_last = UnivariateView(extended_edges.lagrange_last); - // Contribution (1) - evals += (((z_perm + lagrange_first) * (w_1 + id_1 * beta + gamma) * (w_2 + id_2 * beta + gamma) * - (w_3 + id_3 * beta + gamma) * (w_4 + id_4 * beta + gamma)) - - ((z_perm_shift + lagrange_last * public_input_delta) * (w_1 + sigma_1 * beta + gamma) * - (w_2 + sigma_2 * beta + gamma) * (w_3 + sigma_3 * beta + gamma) * (w_4 + sigma_4 * beta + gamma))) * - scaling_factor; + { + static constexpr size_t LENGTH = CONSTRAINT_LENGTH[0]; + auto w_1 = UnivariateView(extended_edges.w_l); + auto w_2 = UnivariateView(extended_edges.w_r); + auto w_3 = UnivariateView(extended_edges.w_o); + auto w_4 = UnivariateView(extended_edges.w_4); + auto sigma_1 = UnivariateView(extended_edges.sigma_1); + auto sigma_2 = UnivariateView(extended_edges.sigma_2); + auto sigma_3 = UnivariateView(extended_edges.sigma_3); + auto sigma_4 = UnivariateView(extended_edges.sigma_4); + auto id_1 = UnivariateView(extended_edges.id_1); + auto id_2 = UnivariateView(extended_edges.id_2); + auto id_3 = UnivariateView(extended_edges.id_3); + auto id_4 = UnivariateView(extended_edges.id_4); + auto z_perm = UnivariateView(extended_edges.z_perm); + auto z_perm_shift = UnivariateView(extended_edges.z_perm_shift); + auto lagrange_first = UnivariateView(extended_edges.lagrange_first); + auto lagrange_last = UnivariateView(extended_edges.lagrange_last); + + std::get<0>(evals) += + (((z_perm + lagrange_first) * (w_1 + id_1 * beta + gamma) * (w_2 + id_2 * beta + gamma) * + (w_3 + id_3 * beta + gamma) * (w_4 + id_4 * beta + gamma)) - + ((z_perm_shift + lagrange_last * public_input_delta) * (w_1 + sigma_1 * beta + gamma) * + (w_2 + sigma_2 * beta + gamma) * (w_3 + sigma_3 * beta + gamma) * (w_4 + sigma_4 * beta + gamma))) * + scaling_factor; + } + // Contribution (2) + { + static constexpr size_t LENGTH = CONSTRAINT_LENGTH[1]; + auto z_perm_shift = UnivariateView(extended_edges.z_perm_shift); + auto lagrange_last = UnivariateView(extended_edges.lagrange_last); + + std::get<1>(evals) += (lagrange_last * z_perm_shift) * scaling_factor; + } }; - void add_full_relation_value_contribution(FF& full_honk_relation_value, + /** + * @brief Add the result of each identity in this relation evaluated at the multivariate evaluations produced by the + * Sumcheck Prover. + * + * @param full_honk_relation_value + * @param purported_evaluations + */ + void add_full_relation_value_contribution(RelationValues& full_honk_relation_value, auto& purported_evaluations, const RelationParameters& relation_parameters) const { @@ -168,11 +221,14 @@ template class UltraGrandProductComputationRelation { auto lagrange_last = purported_evaluations.lagrange_last; // Contribution (1) - full_honk_relation_value += + std::get<0>(full_honk_relation_value) += ((z_perm + lagrange_first) * (w_1 + beta * id_1 + gamma) * (w_2 + beta * id_2 + gamma) * (w_3 + beta * id_3 + gamma) * (w_4 + beta * id_4 + gamma) - (z_perm_shift + lagrange_last * public_input_delta) * (w_1 + beta * sigma_1 + gamma) * (w_2 + beta * sigma_2 + gamma) * (w_3 + beta * sigma_3 + gamma) * (w_4 + beta * sigma_4 + gamma)); + + // Contribution (2) + std::get<1>(full_honk_relation_value) += lagrange_last * z_perm_shift; }; }; } // namespace proof_system::honk::sumcheck diff --git a/cpp/src/barretenberg/honk/sumcheck/relations/relation_consistency.test.cpp b/cpp/src/barretenberg/honk/sumcheck/relations/relation_consistency.test.cpp index 0747a5b4f0..f794b16603 100644 --- a/cpp/src/barretenberg/honk/sumcheck/relations/relation_consistency.test.cpp +++ b/cpp/src/barretenberg/honk/sumcheck/relations/relation_consistency.test.cpp @@ -1,11 +1,9 @@ -#include "barretenberg/honk/sumcheck/relations/lookup_grand_product_relation.hpp" +#include "barretenberg/honk/sumcheck/relations/lookup_relation.hpp" #include "barretenberg/honk/sumcheck/relations/ultra_arithmetic_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/ultra_arithmetic_relation_secondary.hpp" #include "barretenberg/honk/flavor/standard.hpp" -#include "relation.hpp" +#include "relation_parameters.hpp" #include "arithmetic_relation.hpp" -#include "grand_product_initialization_relation.hpp" -#include "grand_product_computation_relation.hpp" +#include "permutation_relation.hpp" #include "../polynomials/univariate.hpp" #include "../polynomials/barycentric_data.hpp" @@ -16,14 +14,14 @@ #include using namespace proof_system::honk::sumcheck; /** - * We want to test if all three relations (namely, ArithmeticRelation, GrandProductComputationRelation, - * GrandProductInitializationRelation) provide correct contributions by manually computing their - * contributions with deterministic and random inputs. The relations are supposed to work with - * univariates (edges) of degree one (length 2) and spit out polynomials of corresponding degrees. We have - * MAX_RELATION_LENGTH = 5, meaning the output of a relation can atmost be a degree 5 polynomial. Hence, - * we use a method compute_mock_extended_edges() which starts with degree one input polynomial (two evaluation - points), - * extends them (using barycentric formula) to six evaluation points, and stores them to an array of polynomials. + * The purpose of this test suite is to show that the identity arithmetic implemented in the Relations is equivalent to + * a simpler unoptimized version implemented in the tests themselves. This is useful 1) as documentation since the + * simple implementations here should make the underlying arithmetic easier to see, and 2) as a check that optimizations + * introduced into the Relations have not changed the result. + * + * For this purpose, we simply feed (the same) random inputs into each of the two implementations and confirm that + * the outputs match. This does not confirm the correctness of the identity arithmetic (the identities will not be + * satisfied in general by random inputs) only that the two implementations are equivalent. */ static const size_t INPUT_UNIVARIATE_LENGTH = 2; @@ -38,9 +36,9 @@ class StandardRelationConsistency : public testing::Test { template using ExtendedEdges = typename Flavor::template ExtendedEdges; - // TODO(#225)(Adrian): Accept FULL_RELATION_LENGTH as a template parameter for this function only, so that the test - // can decide to which degree the polynomials must be extended. Possible accept an existing list of "edges" and - // extend them to the degree. + // TODO(#225)(Adrian): Accept FULL_RELATION_LENGTH as a template parameter for this function only, so that the + // test can decide to which degree the polynomials must be extended. Possible accept an existing list of + // "edges" and extend them to the degree. template static void compute_mock_extended_edges( ExtendedEdges& extended_edges, @@ -107,34 +105,76 @@ class StandardRelationConsistency : public testing::Test { * @param relation_parameters */ template - static void validate_evaluations(const Univariate& expected_evals, + static void validate_evaluations(const auto& expected_full_length_univariates, /* array of Univariates*/ const auto relation, const ExtendedEdges& extended_edges, const RelationParameters& relation_parameters) { + // First check that the verifier's computation on individual evaluations is correct. + // Note: since add_full_relation_value_contribution computes the identities at a single evaluation of the + // multivariates, we need only pass in one evaluation point from the extended edges. Which one we choose is + // arbitrary so we choose the 0th. - // Compute the expression index-by-index - Univariate expected_evals_index{ 0 }; - for (size_t i = 0; i < FULL_RELATION_LENGTH; ++i) { - // Get an array of the same size as `extended_edges` with only the i-th element of each extended edge. - ClaimedEvaluations evals_i = transposed_univariate_array_at(extended_edges, i); - // Evaluate the relation - relation.add_full_relation_value_contribution( - expected_evals_index.value_at(i), evals_i, relation_parameters); + // Extract the RelationValues type for the given relation + using RelationValues = typename decltype(relation)::RelationValues; + RelationValues relation_evals; + RelationValues expected_relation_evals; + + ASSERT_EQ(expected_relation_evals.size(), expected_full_length_univariates.size()); + // Initialize expected_evals to 0th coefficient of expected full length univariates + for (size_t idx = 0; idx < relation_evals.size(); ++idx) { + relation_evals[idx] = FF(0); // initialize to 0 + expected_relation_evals[idx] = expected_full_length_univariates[idx].value_at(0); } - EXPECT_EQ(expected_evals, expected_evals_index); - // Compute the expression using the class, that converts the extended edges to UnivariateView - auto expected_evals_view = Univariate(0); - // The scaling factor is essentially 1 since we are working with degree 1 univariates - relation.add_edge_contribution(expected_evals_view, extended_edges, relation_parameters, 1); + // Extract 0th evaluation from extended edges + ClaimedEvaluations edge_evaluations = transposed_univariate_array_at(extended_edges, 0); - // Tiny hack to reduce `expected_evals` to be of size `relation.RELATION_LENGTH` - Univariate expected_evals_restricted{ - UnivariateView(expected_evals) - }; - EXPECT_EQ(expected_evals_restricted, expected_evals_view); + // Evaluate the relation using the verifier functionality + relation.add_full_relation_value_contribution(relation_evals, edge_evaluations, relation_parameters); + + EXPECT_EQ(relation_evals, expected_relation_evals); + + // Next, check that the prover's computation on Univariates is correct + + using RelationUnivariates = typename decltype(relation)::RelationUnivariates; + RelationUnivariates relation_univariates; + zero_univariates<>(relation_univariates); + + constexpr std::size_t num_univariates = std::tuple_size::value; + + // Compute the relatiion univariates via the sumcheck prover functionality, then extend + // them to full length for easy comparison with the expected result. + relation.add_edge_contribution(relation_univariates, extended_edges, relation_parameters, 1); + + auto full_length_univariates = std::array, num_univariates>(); + extend_tuple_of_arrays(relation_univariates, full_length_univariates); + + EXPECT_EQ(full_length_univariates, expected_full_length_univariates); }; + + template static void zero_univariates(std::tuple& tuple) + { + auto& element = std::get(tuple); + std::fill(element.evaluations.begin(), element.evaluations.end(), FF(0)); + + if constexpr (idx + 1 < sizeof...(Ts)) { + zero_univariates(tuple); + } + } + + template + static void extend_tuple_of_arrays(std::tuple& tuple, auto& result_univariates) + { + auto& element = std::get(tuple); + using Element = std::remove_reference_t; + BarycentricData barycentric_utils; + result_univariates[idx] = barycentric_utils.extend(element); + + if constexpr (idx + 1 < sizeof...(Ts)) { + extend_tuple_of_arrays(tuple, result_univariates); + } + } }; TEST_F(StandardRelationConsistency, ArithmeticRelation) @@ -174,17 +214,19 @@ TEST_F(StandardRelationConsistency, ArithmeticRelation) const auto& q_o = extended_edges.q_o; const auto& q_c = extended_edges.q_c; - // We first compute the evaluations using UnivariateViews, with the provided hard-coded formula. - // Ensure that expression changes are detected. - // expected_evals, length 4, extends to { { 5, 22, 57, 116, 205} } for input polynomial {1, 2} - auto expected_evals = (q_m * w_r * w_l) + (q_r * w_r) + (q_l * w_l) + (q_o * w_o) + (q_c); - validate_evaluations(expected_evals, relation, extended_edges, relation_parameters); + // Compute expected full length Univariates using straight forward expressions. + // Note: expect { { 5, 22, 57, 116, 205} } for input polynomial {1, 2} + constexpr std::size_t NUM_CONSTRAINTS = decltype(relation)::NUM_CONSTRAINTS; + auto expected_full_length_univariates = std::array, NUM_CONSTRAINTS>(); + + expected_full_length_univariates[0] = (q_m * w_r * w_l) + (q_r * w_r) + (q_l * w_l) + (q_o * w_o) + (q_c); + validate_evaluations(expected_full_length_univariates, relation, extended_edges, relation_parameters); }; run_test(/* is_random_input=*/true); run_test(/* is_random_input=*/false); }; -TEST_F(StandardRelationConsistency, GrandProductComputationRelation) +TEST_F(StandardRelationConsistency, PermutationRelation) { using Flavor = honk::flavor::Standard; using FF = typename Flavor::FF; @@ -210,16 +252,11 @@ TEST_F(StandardRelationConsistency, GrandProductComputationRelation) } compute_mock_extended_edges(extended_edges, input_polynomials); }; - auto relation = GrandProductComputationRelation(); + auto relation = PermutationRelation(); const auto& beta = relation_parameters.beta; const auto& gamma = relation_parameters.gamma; const auto& public_input_delta = relation_parameters.public_input_delta; - // TODO(#225)(luke): Write a test that illustrates the following? - // Note: the below z_perm_shift = X^2 will fail because it results in a relation of degree 2*1*1*1 = 5 which - // cannot be represented by 5 points. Therefore when we do the calculation then barycentrically extend, we are - // effectively exprapolating a 4th degree polynomial instead of the correct 5th degree poly - // auto z_perm_shift = Univariate({ 1, 4, 9, 16, 25 }); // X^2 // Manually compute the expected edge contribution const auto& w_1 = extended_edges.w_l; @@ -236,55 +273,19 @@ TEST_F(StandardRelationConsistency, GrandProductComputationRelation) const auto& lagrange_first = extended_edges.lagrange_first; const auto& lagrange_last = extended_edges.lagrange_last; - // We first compute the evaluations using UnivariateViews, with the provided hard-coded formula. - // Ensure that expression changes are detected. - // expected_evals in the below step { { 27, 250, 1029, 2916, 6655 } } - { { 27, 125, 343, 729, 1331 } } - auto expected_evals = (z_perm + lagrange_first) * (w_1 + id_1 * beta + gamma) * (w_2 + id_2 * beta + gamma) * - (w_3 + id_3 * beta + gamma) - - (z_perm_shift + lagrange_last * public_input_delta) * (w_1 + sigma_1 * beta + gamma) * - (w_2 + sigma_2 * beta + gamma) * (w_3 + sigma_3 * beta + gamma); + // Compute expected full length Univariates using straight forward expressions + constexpr std::size_t NUM_CONSTRAINTS = decltype(relation)::NUM_CONSTRAINTS; + auto expected_full_length_univariates = std::array, NUM_CONSTRAINTS>(); - validate_evaluations(expected_evals, relation, extended_edges, relation_parameters); - }; - run_test(/* is_random_input=*/true); - run_test(/* is_random_input=*/false); -}; + expected_full_length_univariates[0] = (z_perm + lagrange_first) * (w_1 + id_1 * beta + gamma) * + (w_2 + id_2 * beta + gamma) * (w_3 + id_3 * beta + gamma) - + (z_perm_shift + lagrange_last * public_input_delta) * + (w_1 + sigma_1 * beta + gamma) * (w_2 + sigma_2 * beta + gamma) * + (w_3 + sigma_3 * beta + gamma); -TEST_F(StandardRelationConsistency, GrandProductInitializationRelation) -{ - using Flavor = honk::flavor::Standard; - using FF = typename Flavor::FF; - static constexpr size_t FULL_RELATION_LENGTH = 5; - using ExtendedEdges = typename Flavor::template ExtendedEdges; - static const size_t NUM_POLYNOMIALS = Flavor::NUM_ALL_ENTITIES; - - const auto relation_parameters = compute_mock_relation_parameters(); - auto run_test = [&relation_parameters](bool is_random_input) { - ExtendedEdges extended_edges; - std::array, NUM_POLYNOMIALS> input_polynomials; - if (!is_random_input) { - // evaluation form, i.e. input_univariate(0) = 1, input_univariate(1) = 2,.. The polynomial is x+1. - for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { - input_polynomials[i] = Univariate({ 1, 2 }); - } - compute_mock_extended_edges(extended_edges, input_polynomials); - } else { - // input_univariates are random polynomials of degree one - for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { - input_polynomials[i] = - Univariate({ FF::random_element(), FF::random_element() }); - } - compute_mock_extended_edges(extended_edges, input_polynomials); - }; - auto relation = GrandProductInitializationRelation(); - const auto& z_perm_shift = extended_edges.z_perm_shift; - const auto& lagrange_last = extended_edges.lagrange_last; - // We first compute the evaluations using UnivariateViews, with the provided hard-coded formula. - // Ensure that expression changes are detected. - // expected_evals, lenght 3 (coeff form = x^2 + x), extends to { { 0, 2, 6, 12, 20 } } - auto expected_evals = z_perm_shift * lagrange_last; + expected_full_length_univariates[1] = z_perm_shift * lagrange_last; - validate_evaluations(expected_evals, relation, extended_edges, relation_parameters); + validate_evaluations(expected_full_length_univariates, relation, extended_edges, relation_parameters); }; run_test(/* is_random_input=*/true); run_test(/* is_random_input=*/false); diff --git a/cpp/src/barretenberg/honk/sumcheck/relations/relation_correctness.test.cpp b/cpp/src/barretenberg/honk/sumcheck/relations/relation_correctness.test.cpp index 704cdc82e9..01d3624083 100644 --- a/cpp/src/barretenberg/honk/sumcheck/relations/relation_correctness.test.cpp +++ b/cpp/src/barretenberg/honk/sumcheck/relations/relation_correctness.test.cpp @@ -3,13 +3,11 @@ #include "barretenberg/honk/composer/ultra_honk_composer.hpp" #include "barretenberg/honk/composer/standard_honk_composer.hpp" #include "barretenberg/honk/proof_system/prover_library.hpp" -#include "barretenberg/honk/sumcheck/relations/relation.hpp" +#include "barretenberg/honk/sumcheck/relations/relation_parameters.hpp" #include "barretenberg/honk/sumcheck/relations/arithmetic_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/grand_product_initialization_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/grand_product_computation_relation.hpp" +#include "barretenberg/honk/sumcheck/relations/permutation_relation.hpp" #include "barretenberg/honk/sumcheck/relations/ultra_arithmetic_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/ultra_arithmetic_relation_secondary.hpp" -#include "barretenberg/honk/sumcheck/relations/lookup_grand_product_relation.hpp" +#include "barretenberg/honk/sumcheck/relations/lookup_relation.hpp" #include "barretenberg/honk/sumcheck/relations/gen_perm_sort_relation.hpp" #include "barretenberg/honk/sumcheck/relations/elliptic_relation.hpp" #include "barretenberg/honk/sumcheck/relations/auxiliary_relation.hpp" @@ -27,6 +25,40 @@ void ensure_non_zero(auto& polynomial) ASSERT_TRUE(has_non_zero_coefficient); } +/** + * @brief Check that a given relation is satified for a set of polynomials + * + * @tparam relation_idx Index into a tuple of provided relations + * @tparam Flavor + */ +template void check_relation(auto relation, auto circuit_size, auto polynomials, auto params) +{ + using ClaimedEvaluations = typename Flavor::ClaimedEvaluations; + for (size_t i = 0; i < circuit_size; i++) { + + // Extract an array containing all the polynomial evaluations at a given row i + ClaimedEvaluations evaluations_at_index_i; + size_t poly_idx = 0; + for (auto& poly : polynomials) { + evaluations_at_index_i[poly_idx] = poly[i]; + ++poly_idx; + } + + // Define the appropriate RelationValues type for this relation and initialize to zero + using RelationValues = typename decltype(relation)::RelationValues; + RelationValues result; + for (auto& element : result) { + element = 0; + } + + // Evaluate each constraint in the relation and check that each is satisfied + relation.add_full_relation_value_contribution(result, evaluations_at_index_i, params); + for (auto& element : result) { + ASSERT_EQ(element, 0); + } + } +} + /** * @brief Test the correctness of the Standard Honk relations * @@ -42,7 +74,7 @@ TEST(RelationCorrectness, StandardRelationCorrectness) using Flavor = honk::flavor::Standard; using FF = typename Flavor::FF; using ProverPolynomials = typename Flavor::ProverPolynomials; - using ClaimedEvaluations = typename Flavor::ClaimedEvaluations; + // using ClaimedEvaluations = typename Flavor::ClaimedEvaluations; // Create a composer and a dummy circuit with a few gates auto composer = StandardHonkComposer(); @@ -61,6 +93,7 @@ TEST(RelationCorrectness, StandardRelationCorrectness) } // Create a prover (it will compute proving key and witness) auto prover = composer.create_prover(); + auto circuit_size = prover.key->circuit_size; // Generate beta and gamma fr beta = fr::random_element(); @@ -107,34 +140,11 @@ TEST(RelationCorrectness, StandardRelationCorrectness) prover_polynomials.lagrange_last = prover.key->lagrange_last; // Construct the round for applying sumcheck relations and results for storing computed results - auto relations = std::tuple(honk::sumcheck::ArithmeticRelation(), - honk::sumcheck::GrandProductComputationRelation(), - honk::sumcheck::GrandProductInitializationRelation()); - - fr result = 0; - for (size_t i = 0; i < prover.key->circuit_size; i++) { - // Compute an array containing all the evaluations at a given row i - - ClaimedEvaluations evaluations_at_index_i; - size_t poly_idx = 0; - for (auto& polynomial : prover_polynomials) { - evaluations_at_index_i[poly_idx] = polynomial[i]; - ++poly_idx; - } - - // For each relation, call the `accumulate_relation_evaluation` over all witness/selector values at the - // i-th row/vertex of the hypercube. - // We use ASSERT_EQ instead of EXPECT_EQ so that the tests stops at the first index at which the result is not - // 0, since result = 0 + C(transposed), which we expect will equal 0. - std::get<0>(relations).add_full_relation_value_contribution(result, evaluations_at_index_i, params); - ASSERT_EQ(result, 0); - - std::get<1>(relations).add_full_relation_value_contribution(result, evaluations_at_index_i, params); - ASSERT_EQ(result, 0); + auto relations = std::tuple(honk::sumcheck::ArithmeticRelation(), honk::sumcheck::PermutationRelation()); - std::get<2>(relations).add_full_relation_value_contribution(result, evaluations_at_index_i, params); - ASSERT_EQ(result, 0); - } + // Check that each relation is satisfied across each row of the prover polynomials + check_relation(std::get<0>(relations), circuit_size, prover_polynomials, params); + check_relation(std::get<1>(relations), circuit_size, prover_polynomials, params); } /** @@ -154,7 +164,7 @@ TEST(RelationCorrectness, UltraRelationCorrectness) using Flavor = honk::flavor::Ultra; using FF = typename Flavor::FF; using ProverPolynomials = typename Flavor::ProverPolynomials; - using ClaimedEvaluations = typename Flavor::ClaimedEvaluations; + // using ClaimedEvaluations = typename Flavor::ClaimedEvaluations; // Create a composer and then add an assortment of gates designed to ensure that the constraint(s) represented // by each relation are non-trivially exercised. @@ -275,6 +285,7 @@ TEST(RelationCorrectness, UltraRelationCorrectness) // Create a prover (it will compute proving key and witness) auto prover = composer.create_prover(); + auto circuit_size = prover.key->circuit_size; // Generate eta, beta and gamma fr eta = fr::random_element(); @@ -308,10 +319,6 @@ TEST(RelationCorrectness, UltraRelationCorrectness) // Compute lookup grand product polynomial prover.key->z_lookup = prover_library::compute_lookup_grand_product(prover.key, eta, beta, gamma); - // Create an array of spans to the underlying polynomials to more easily - // get the transposition. - // Ex: polynomial_spans[3][i] returns the i-th coefficient of the third polynomial - // in the list below ProverPolynomials prover_polynomials; prover_polynomials.w_l = prover.key->w_l; @@ -367,56 +374,19 @@ TEST(RelationCorrectness, UltraRelationCorrectness) // Construct the round for applying sumcheck relations and results for storing computed results auto relations = std::tuple(honk::sumcheck::UltraArithmeticRelation(), - honk::sumcheck::UltraArithmeticRelationSecondary(), - honk::sumcheck::UltraGrandProductInitializationRelation(), - honk::sumcheck::UltraGrandProductComputationRelation(), - honk::sumcheck::LookupGrandProductComputationRelation(), - honk::sumcheck::LookupGrandProductInitializationRelation(), + honk::sumcheck::UltraPermutationRelation(), + honk::sumcheck::LookupRelation(), honk::sumcheck::GenPermSortRelation(), honk::sumcheck::EllipticRelation(), honk::sumcheck::AuxiliaryRelation()); - fr result = 0; - for (size_t i = 0; i < prover.key->circuit_size; i++) { - // Compute an array containing all the evaluations at a given row i - ClaimedEvaluations evaluations_at_index_i; - size_t poly_idx = 0; - for (auto& polynomial : prover_polynomials) { - evaluations_at_index_i[poly_idx] = polynomial[i]; - ++poly_idx; - } - - // For each relation, call the `accumulate_relation_evaluation` over all witness/selector values at the - // i-th row/vertex of the hypercube. We use ASSERT_EQ instead of EXPECT_EQ so that the tests stops at - // the first index at which the result is not 0, since result = 0 + C(transposed), which we expect will - // equal 0. - std::get<0>(relations).add_full_relation_value_contribution(result, evaluations_at_index_i, params); - ASSERT_EQ(result, 0); - - std::get<1>(relations).add_full_relation_value_contribution(result, evaluations_at_index_i, params); - ASSERT_EQ(result, 0); - - std::get<2>(relations).add_full_relation_value_contribution(result, evaluations_at_index_i, params); - ASSERT_EQ(result, 0); - - std::get<3>(relations).add_full_relation_value_contribution(result, evaluations_at_index_i, params); - ASSERT_EQ(result, 0); - - std::get<4>(relations).add_full_relation_value_contribution(result, evaluations_at_index_i, params); - ASSERT_EQ(result, 0); - - std::get<5>(relations).add_full_relation_value_contribution(result, evaluations_at_index_i, params); - ASSERT_EQ(result, 0); - - std::get<6>(relations).add_full_relation_value_contribution(result, evaluations_at_index_i, params); - ASSERT_EQ(result, 0); - - std::get<7>(relations).add_full_relation_value_contribution(result, evaluations_at_index_i, params); - ASSERT_EQ(result, 0); - - std::get<8>(relations).add_full_relation_value_contribution(result, evaluations_at_index_i, params); - ASSERT_EQ(result, 0); - } + // Check that each relation is satisfied across each row of the prover polynomials + check_relation(std::get<0>(relations), circuit_size, prover_polynomials, params); + check_relation(std::get<1>(relations), circuit_size, prover_polynomials, params); + check_relation(std::get<2>(relations), circuit_size, prover_polynomials, params); + check_relation(std::get<3>(relations), circuit_size, prover_polynomials, params); + check_relation(std::get<4>(relations), circuit_size, prover_polynomials, params); + check_relation(std::get<5>(relations), circuit_size, prover_polynomials, params); } } // namespace test_honk_relations diff --git a/cpp/src/barretenberg/honk/sumcheck/relations/relation.hpp b/cpp/src/barretenberg/honk/sumcheck/relations/relation_parameters.hpp similarity index 100% rename from cpp/src/barretenberg/honk/sumcheck/relations/relation.hpp rename to cpp/src/barretenberg/honk/sumcheck/relations/relation_parameters.hpp diff --git a/cpp/src/barretenberg/honk/sumcheck/relations/ultra_arithmetic_relation.hpp b/cpp/src/barretenberg/honk/sumcheck/relations/ultra_arithmetic_relation.hpp index dd5aa02b85..1ea1de263e 100644 --- a/cpp/src/barretenberg/honk/sumcheck/relations/ultra_arithmetic_relation.hpp +++ b/cpp/src/barretenberg/honk/sumcheck/relations/ultra_arithmetic_relation.hpp @@ -3,7 +3,7 @@ #include #include "../polynomials/univariate.hpp" -#include "relation.hpp" +#include "relation_parameters.hpp" namespace proof_system::honk::sumcheck { @@ -12,55 +12,127 @@ template class UltraArithmeticRelation { // 1 + polynomial degree of this relation static constexpr size_t RELATION_LENGTH = 6; // degree(q_arith^2 * q_m * w_r * w_l) = 5 + static constexpr size_t NUM_CONSTRAINTS = 2; + // TODO(luke): The degree of the identities varies based on q_arith. Can we do something to improve efficiency here? + static constexpr std::array CONSTRAINT_LENGTH = { 6, 5 }; + + using RelationUnivariates = std::tuple, Univariate>; + using RelationValues = std::array; + /** * @brief Expression for the Ultra Arithmetic gate. - * @details The relation is defined as C(extended_edges(X)...) = + * @details This relation encapsulates several idenitities, toggled by the value of q_arith in [0, 1, 2, 3, ...]. + * The following description is reproduced from the Plonk analog 'plookup_arithmetic_widget': + * The whole formula is: + * + * q_arith * ( ( (-1/2) * (q_arith - 3) * q_m * w_1 * w_2 + q_1 * w_1 + q_2 * w_2 + q_3 * w_3 + q_4 * w_4 + q_c ) + + * (q_arith - 1)*( α * (q_arith - 2) * (w_1 + w_4 - w_1_omega + q_m) + w_4_omega) ) = 0 + * + * This formula results in several cases depending on q_arith: + * 1. q_arith == 0: Arithmetic gate is completely disabled + * + * 2. q_arith == 1: Everything in the minigate on the right is disabled. The equation is just a standard plonk + * equation with extra wires: q_m * w_1 * w_2 + q_1 * w_1 + q_2 * w_2 + q_3 * w_3 + q_4 * w_4 + q_c = 0 + * + * 3. q_arith == 2: The (w_1 + w_4 - ...) term is disabled. THe equation is: + * (1/2) * q_m * w_1 * w_2 + q_1 * w_1 + q_2 * w_2 + q_3 * w_3 + q_4 * w_4 + q_c + w_4_omega = 0 + * It allows defining w_4 at next index (w_4_omega) in terms of current wire values + * + * 4. q_arith == 3: The product of w_1 and w_2 is disabled, but a mini addition gate is enabled. α² allows us to + * split the equation into two: + * + * q_1 * w_1 + q_2 * w_2 + q_3 * w_3 + q_4 * w_4 + q_c + 2 * w_4_omega = 0 + * + * w_1 + w_4 - w_1_omega + q_m = 0 (we are reusing q_m here) + * + * 5. q_arith > 3: The product of w_1 and w_2 is scaled by (q_arith - 3), while the w_4_omega term is scaled by + * (q_arith + * - 1). The equation can be split into two: + * + * (q_arith - 3)* q_m * w_1 * w_ 2 + q_1 * w_1 + q_2 * w_2 + q_3 * w_3 + q_4 * w_4 + q_c + (q_arith - 1) * w_4_omega + * = 0 + * + * w_1 + w_4 - w_1_omega + q_m = 0 + * + * The problem that q_m is used both in both equations can be dealt with by appropriately changing selector values + * at the next gate. Then we can treat (q_arith - 1) as a simulated q_6 selector and scale q_m to handle (q_arith - + * 3) at product. + * + * The The relation is + * defined as C(extended_edges(X)...) = q_arith * [ -1/2(q_arith - 3)(q_m * w_r * w_l) + (q_l * w_l) + (q_r * w_r) + + * (q_o * w_o) + (q_4 * w_4) + q_c + (q_arith - 1)w_4_shift ] + * * q_arith * - * [ -1/2(q_arith - 3)(q_m * w_r * w_l) + - * (q_l * w_l) + (q_r * w_r) + (q_o * w_o) + (q_4 * w_4) + q_c + - * (q_arith - 1)w_4_shift ] + * (q_arith - 2) * (q_arith - 1) * (w_l + w_4 - w_l_shift + q_m) * * @param evals transformed to `evals + C(extended_edges(X)...)*scaling_factor` * @param extended_edges an std::array containing the fully extended Univariate edges. * @param parameters contains beta, gamma, and public_input_delta, .... * @param scaling_factor optional term to scale the evaluation before adding to evals. */ - void add_edge_contribution(Univariate& evals, + void add_edge_contribution(RelationUnivariates& evals, const auto& extended_edges, const RelationParameters&, - const FF& scaling_factor) const - { + const FF& scaling_factor) const { // OPTIMIZATION?: Karatsuba in general, at least for some degrees? // See https://hackmd.io/xGLuj6biSsCjzQnYN-pEiA?both + // clang-format off + // Contribution 1 + { + static constexpr size_t LENGTH = CONSTRAINT_LENGTH[0]; + auto w_l = UnivariateView(extended_edges.w_l); + auto w_r = UnivariateView(extended_edges.w_r); + auto w_o = UnivariateView(extended_edges.w_o); + auto w_4 = UnivariateView(extended_edges.w_4); + auto w_4_shift = UnivariateView(extended_edges.w_4_shift); + auto q_m = UnivariateView(extended_edges.q_m); + auto q_l = UnivariateView(extended_edges.q_l); + auto q_r = UnivariateView(extended_edges.q_r); + auto q_o = UnivariateView(extended_edges.q_o); + auto q_4 = UnivariateView(extended_edges.q_4); + auto q_c = UnivariateView(extended_edges.q_c); + auto q_arith = UnivariateView(extended_edges.q_arith); - auto w_l = UnivariateView(extended_edges.w_l); - auto w_r = UnivariateView(extended_edges.w_r); - auto w_o = UnivariateView(extended_edges.w_o); - auto w_4 = UnivariateView(extended_edges.w_4); - auto w_4_shift = UnivariateView(extended_edges.w_4_shift); - auto q_m = UnivariateView(extended_edges.q_m); - auto q_l = UnivariateView(extended_edges.q_l); - auto q_r = UnivariateView(extended_edges.q_r); - auto q_o = UnivariateView(extended_edges.q_o); - auto q_4 = UnivariateView(extended_edges.q_4); - auto q_c = UnivariateView(extended_edges.q_c); - auto q_arith = UnivariateView(extended_edges.q_arith); + static const FF neg_half = FF(-2).invert(); - static const FF neg_half = FF(-2).invert(); + auto tmp = (q_arith - 3) * (q_m * w_r * w_l) * neg_half; + tmp += (q_l * w_l) + (q_r * w_r) + (q_o * w_o) + (q_4 * w_4) + q_c; + tmp += (q_arith - 1) * w_4_shift; + tmp *= q_arith; + tmp *= scaling_factor; + std::get<0>(evals) += tmp; + } + // Contribution 2 + { + static constexpr size_t LENGTH = CONSTRAINT_LENGTH[1]; + auto w_l = UnivariateView(extended_edges.w_l); + auto w_4 = UnivariateView(extended_edges.w_4); + auto w_l_shift = UnivariateView(extended_edges.w_l_shift); + auto q_m = UnivariateView(extended_edges.q_m); + auto q_arith = UnivariateView(extended_edges.q_arith); - auto tmp = (q_arith - 3) * (q_m * w_r * w_l) * neg_half; - tmp += (q_l * w_l) + (q_r * w_r) + (q_o * w_o) + (q_4 * w_4) + q_c; - tmp += (q_arith - 1) * w_4_shift; - tmp *= q_arith; - tmp *= scaling_factor; - evals += tmp; - }; + auto tmp = w_l + w_4 - w_l_shift + q_m; + tmp *= (q_arith - 2); + tmp *= (q_arith - 1); + tmp *= q_arith; + tmp *= scaling_factor; + std::get<1>(evals) += tmp; + } + }; // namespace proof_system::honk::sumcheck - void add_full_relation_value_contribution(FF& full_honk_relation_value, - const auto& purported_evaluations, - const RelationParameters&) const + /** + * @brief Add the result of each identity in this relation evaluated at the multivariate evaluations produced by the + * Sumcheck Prover. + * + * @param full_honk_relation_value + * @param purported_evaluations + */ + void add_full_relation_value_contribution(RelationValues& full_honk_relation_value, + const auto& purported_evaluations, + const RelationParameters&) const { auto w_l = purported_evaluations.w_l; + auto w_l_shift = purported_evaluations.w_l_shift; auto w_r = purported_evaluations.w_r; auto w_o = purported_evaluations.w_o; auto w_4 = purported_evaluations.w_4; @@ -75,11 +147,20 @@ template class UltraArithmeticRelation { static const FF neg_half = FF(-2).invert(); + // Contribution 1 auto tmp = (q_arith - 3) * (q_m * w_r * w_l) * neg_half; tmp += (q_l * w_l) + (q_r * w_r) + (q_o * w_o) + (q_4 * w_4) + q_c; tmp += (q_arith - 1) * w_4_shift; tmp *= q_arith; - full_honk_relation_value += tmp; + std::get<0>(full_honk_relation_value) += tmp; + + // Contribution 2 + tmp = w_l + w_4 - w_l_shift + q_m; + tmp *= (q_arith - 2); + tmp *= (q_arith - 1); + tmp *= q_arith; + std::get<1>(full_honk_relation_value) += tmp; }; }; +// clang-format on } // namespace proof_system::honk::sumcheck diff --git a/cpp/src/barretenberg/honk/sumcheck/relations/ultra_arithmetic_relation_secondary.hpp b/cpp/src/barretenberg/honk/sumcheck/relations/ultra_arithmetic_relation_secondary.hpp deleted file mode 100644 index 84bb0ce60c..0000000000 --- a/cpp/src/barretenberg/honk/sumcheck/relations/ultra_arithmetic_relation_secondary.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once -#include -#include - -#include "../polynomials/univariate.hpp" -#include "relation.hpp" - -// TODO(luke): Move this into ultra_arithmetic_relation.hpp. -namespace proof_system::honk::sumcheck { - -template class UltraArithmeticRelationSecondary { - public: - // 1 + polynomial degree of this relation - static constexpr size_t RELATION_LENGTH = 5; // degree(q_arith^3 * w_l) = 4 - - /** - * @brief Expression for the Ultra Arithmetic gate. - * @details The relation is defined as C(extended_edges(X)...) = - * q_arith * - * (q_arith - 2) * (q_arith - 1) * (w_l + w_4 - w_l_shift + q_m) - * - * @param evals transformed to `evals + C(extended_edges(X)...)*scaling_factor` - * @param extended_edges an std::array containing the fully extended Univariate edges. - * @param parameters contains beta, gamma, and public_input_delta, .... - * @param scaling_factor optional term to scale the evaluation before adding to evals. - */ - void add_edge_contribution(Univariate& evals, - const auto& extended_edges, - const RelationParameters&, - const FF& scaling_factor) const - { - // OPTIMIZATION?: Karatsuba in general, at least for some degrees? - // See https://hackmd.io/xGLuj6biSsCjzQnYN-pEiA?both - - auto w_l = UnivariateView(extended_edges.w_l); - auto w_4 = UnivariateView(extended_edges.w_4); - auto w_l_shift = UnivariateView(extended_edges.w_l_shift); - auto q_m = UnivariateView(extended_edges.q_m); - auto q_arith = UnivariateView(extended_edges.q_arith); - - auto tmp = w_l + w_4 - w_l_shift + q_m; - tmp *= (q_arith - 2); - tmp *= (q_arith - 1); - tmp *= q_arith; - tmp *= scaling_factor; - evals += tmp; - }; - - void add_full_relation_value_contribution(FF& full_honk_relation_value, - const auto& purported_evaluations, - const RelationParameters&) const - { - auto w_l = purported_evaluations.w_l; - auto w_4 = purported_evaluations.w_4; - auto w_l_shift = purported_evaluations.w_l_shift; - auto q_m = purported_evaluations.q_m; - auto q_arith = purported_evaluations.q_arith; - - auto tmp = w_l + w_4 - w_l_shift + q_m; - tmp *= (q_arith - 2); - tmp *= (q_arith - 1); - tmp *= q_arith; - full_honk_relation_value += tmp; - }; -}; -} // namespace proof_system::honk::sumcheck diff --git a/cpp/src/barretenberg/honk/sumcheck/relations/ultra_relation_consistency.test.cpp b/cpp/src/barretenberg/honk/sumcheck/relations/ultra_relation_consistency.test.cpp index ce44727e48..1be27d4bda 100644 --- a/cpp/src/barretenberg/honk/sumcheck/relations/ultra_relation_consistency.test.cpp +++ b/cpp/src/barretenberg/honk/sumcheck/relations/ultra_relation_consistency.test.cpp @@ -1,14 +1,13 @@ #include "barretenberg/honk/sumcheck/relations/ultra_arithmetic_relation.hpp" -#include "barretenberg/honk/sumcheck/relations/ultra_arithmetic_relation_secondary.hpp" -#include "barretenberg/honk/sumcheck/relations/lookup_grand_product_relation.hpp" +#include "barretenberg/honk/sumcheck/relations/permutation_relation.hpp" +#include "barretenberg/honk/sumcheck/relations/lookup_relation.hpp" #include "barretenberg/honk/sumcheck/relations/gen_perm_sort_relation.hpp" #include "barretenberg/honk/sumcheck/relations/elliptic_relation.hpp" #include "barretenberg/honk/sumcheck/relations/auxiliary_relation.hpp" #include "barretenberg/honk/flavor/ultra.hpp" -#include "relation.hpp" +#include "relation_parameters.hpp" #include "arithmetic_relation.hpp" -#include "grand_product_initialization_relation.hpp" -#include "grand_product_computation_relation.hpp" +#include "permutation_relation.hpp" #include "../polynomials/univariate.hpp" #include "../polynomials/barycentric_data.hpp" @@ -17,16 +16,18 @@ #include #include +// TODO(luke): This testing infrastructure was duplicated between here and relation_consistency.test.cpp with the +// orignal Flavor PR. Find a way to recombine these test suites or at least share this functionality. using namespace proof_system::honk::sumcheck; /** - * We want to test if all three relations (namely, ArithmeticRelation, GrandProductComputationRelation, - * GrandProductInitializationRelation) provide correct contributions by manually computing their - * contributions with deterministic and random inputs. The relations are supposed to work with - * univariates (edges) of degree one (length 2) and spit out polynomials of corresponding degrees. We have - * MAX_RELATION_LENGTH = 5, meaning the output of a relation can atmost be a degree 5 polynomial. Hence, - * we use a method compute_mock_extended_edges() which starts with degree one input polynomial (two evaluation - points), - * extends them (using barycentric formula) to six evaluation points, and stores them to an array of polynomials. + * The purpose of this test suite is to show that the identity arithmetic implemented in the Relations is equivalent to + * a simpler unoptimized version implemented in the tests themselves. This is useful 1) as documentation since the + * simple implementations here should make the underlying arithmetic easier to see, and 2) as a check that optimizations + * introduced into the Relations have not changed the result. + * + * For this purpose, we simply feed (the same) random inputs into each of the two implementations and confirm that + * the outputs match. This does not confirm the correctness of the identity arithmetic (the identities will not be + * satisfied in general by random inputs) only that the two implementations are equivalent. */ static const size_t INPUT_UNIVARIATE_LENGTH = 2; @@ -63,9 +64,11 @@ class UltraRelationConsistency : public testing::Test { */ RelationParameters compute_mock_relation_parameters() { - return { .beta = FF::random_element(), + return { .eta = FF::random_element(), + .beta = FF::random_element(), .gamma = FF::random_element(), - .public_input_delta = FF::random_element() }; + .public_input_delta = FF::random_element(), + .lookup_grand_product_delta = FF::random_element() }; } /** @@ -108,34 +111,76 @@ class UltraRelationConsistency : public testing::Test { * @param relation_parameters */ template - static void validate_evaluations(const Univariate& expected_evals, + static void validate_evaluations(const auto& expected_full_length_univariates, /* array of Univariates*/ const auto relation, const ExtendedEdges& extended_edges, const RelationParameters& relation_parameters) { - - // Compute the expression index-by-index - Univariate expected_evals_index{ 0 }; - for (size_t i = 0; i < FULL_RELATION_LENGTH; ++i) { - // Get an array of the same size as `extended_edges` with only the i-th element of each extended edge. - ClaimedEvaluations evals_i = transposed_univariate_array_at(extended_edges, i); - // Evaluate the relation - relation.add_full_relation_value_contribution( - expected_evals_index.value_at(i), evals_i, relation_parameters); + // First check that the verifier's computation on individual evaluations is correct. + // Note: since add_full_relation_value_contribution computes the identities at a single evaluation of the + // multivariates, we need only pass in one evaluation point from the extended edges. Which one we choose is + // arbitrary so we choose the 0th. + + // Extract the RelationValues type for the given relation + using RelationValues = typename decltype(relation)::RelationValues; + RelationValues relation_evals; + RelationValues expected_relation_evals; + + ASSERT_EQ(expected_relation_evals.size(), expected_full_length_univariates.size()); + // Initialize expected_evals to 0th coefficient of expected full length univariates + for (size_t idx = 0; idx < relation_evals.size(); ++idx) { + relation_evals[idx] = FF(0); // initialize to 0 + expected_relation_evals[idx] = expected_full_length_univariates[idx].value_at(0); } - EXPECT_EQ(expected_evals, expected_evals_index); - - // Compute the expression using the class, that converts the extended edges to UnivariateView - auto expected_evals_view = Univariate(0); - // The scaling factor is essentially 1 since we are working with degree 1 univariates - relation.add_edge_contribution(expected_evals_view, extended_edges, relation_parameters, 1); - - // Tiny hack to reduce `expected_evals` to be of size `relation.RELATION_LENGTH` - Univariate expected_evals_restricted{ - UnivariateView(expected_evals) - }; - EXPECT_EQ(expected_evals_restricted, expected_evals_view); + + // Extract 0th evaluation from extended edges + ClaimedEvaluations edge_evaluations = transposed_univariate_array_at(extended_edges, 0); + + // Evaluate the relation using the verifier functionality + relation.add_full_relation_value_contribution(relation_evals, edge_evaluations, relation_parameters); + + EXPECT_EQ(relation_evals, expected_relation_evals); + + // Next, check that the prover's computation on Univariates is correct + + using RelationUnivariates = typename decltype(relation)::RelationUnivariates; + RelationUnivariates relation_univariates; + zero_univariates<>(relation_univariates); + + constexpr std::size_t num_univariates = std::tuple_size::value; + + // Compute the relatiion univariates via the sumcheck prover functionality, then extend + // them to full length for easy comparison with the expected result. + relation.add_edge_contribution(relation_univariates, extended_edges, relation_parameters, 1); + + auto full_length_univariates = std::array, num_univariates>(); + extend_tuple_of_arrays(relation_univariates, full_length_univariates); + + EXPECT_EQ(full_length_univariates, expected_full_length_univariates); }; + + template static void zero_univariates(std::tuple& tuple) + { + auto& element = std::get(tuple); + std::fill(element.evaluations.begin(), element.evaluations.end(), FF(0)); + + if constexpr (idx + 1 < sizeof...(Ts)) { + zero_univariates(tuple); + } + } + + template + static void extend_tuple_of_arrays(std::tuple& tuple, auto& result_univariates) + { + auto& element = std::get(tuple); + using Element = std::remove_reference_t; + BarycentricData barycentric_utils; + result_univariates[idx] = barycentric_utils.extend(element); + + if constexpr (idx + 1 < sizeof...(Ts)) { + extend_tuple_of_arrays(tuple, result_univariates); + } + } }; TEST_F(UltraRelationConsistency, UltraArithmeticRelation) @@ -160,6 +205,7 @@ TEST_F(UltraRelationConsistency, UltraArithmeticRelation) // Extract the extended edges for manual computation of relation contribution const auto& w_1 = extended_edges.w_l; + const auto& w_1_shift = extended_edges.w_l_shift; const auto& w_2 = extended_edges.w_r; const auto& w_3 = extended_edges.w_o; const auto& w_4 = extended_edges.w_4; @@ -174,78 +220,25 @@ TEST_F(UltraRelationConsistency, UltraArithmeticRelation) static const FF neg_half = FF(-2).invert(); - auto expected_evals = (q_arith - 3) * (q_m * w_2 * w_1) * neg_half; - expected_evals += (q_l * w_1) + (q_r * w_2) + (q_o * w_3) + (q_4 * w_4) + q_c; - expected_evals += (q_arith - 1) * w_4_shift; - expected_evals *= q_arith; - - validate_evaluations(expected_evals, relation, extended_edges, relation_parameters); -}; - -TEST_F(UltraRelationConsistency, UltraArithmeticRelationSecondary) -{ - using Flavor = honk::flavor::Ultra; - using FF = typename Flavor::FF; - static constexpr size_t FULL_RELATION_LENGTH = 6; - using ExtendedEdges = typename Flavor::template ExtendedEdges; - static const size_t NUM_POLYNOMIALS = Flavor::NUM_ALL_ENTITIES; - - const auto relation_parameters = compute_mock_relation_parameters(); - ExtendedEdges extended_edges; - std::array, NUM_POLYNOMIALS> input_polynomials; - - // input_univariates are random polynomials of degree one - for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { - input_polynomials[i] = Univariate({ FF::random_element(), FF::random_element() }); - } - compute_mock_extended_edges(extended_edges, input_polynomials); - - auto relation = UltraArithmeticRelationSecondary(); + constexpr std::size_t NUM_CONSTRAINTS = decltype(relation)::NUM_CONSTRAINTS; + auto expected_full_length_univariates = std::array, NUM_CONSTRAINTS>(); - // Extract the extended edges for manual computation of relation contribution - const auto& w_1 = extended_edges.w_l; - const auto& w_4 = extended_edges.w_4; - const auto& w_l_shift = extended_edges.w_l_shift; - const auto& q_m = extended_edges.q_m; - const auto& q_arith = extended_edges.q_arith; + // Contribution 1 + auto contribution_1 = (q_arith - 3) * (q_m * w_2 * w_1) * neg_half; + contribution_1 += (q_l * w_1) + (q_r * w_2) + (q_o * w_3) + (q_4 * w_4) + q_c; + contribution_1 += (q_arith - 1) * w_4_shift; + contribution_1 *= q_arith; + expected_full_length_univariates[0] = contribution_1; - auto expected_evals = (w_1 + w_4 - w_l_shift + q_m); - expected_evals *= (q_arith - 2) * (q_arith - 1) * q_arith; + // Contribution 2 + auto contribution_2 = (w_1 + w_4 - w_1_shift + q_m); + contribution_2 *= (q_arith - 2) * (q_arith - 1) * q_arith; + expected_full_length_univariates[1] = contribution_2; - validate_evaluations(expected_evals, relation, extended_edges, relation_parameters); + validate_evaluations(expected_full_length_univariates, relation, extended_edges, relation_parameters); }; -TEST_F(UltraRelationConsistency, UltraGrandProductInitializationRelation) -{ - using Flavor = honk::flavor::Ultra; - using FF = typename Flavor::FF; - using Flavor = honk::flavor::Ultra; - static constexpr size_t FULL_RELATION_LENGTH = 6; - using ExtendedEdges = typename Flavor::ExtendedEdges; - static const size_t NUM_POLYNOMIALS = Flavor::NUM_ALL_ENTITIES; - auto relation_parameters = compute_mock_relation_parameters(); - ExtendedEdges extended_edges; - std::array, NUM_POLYNOMIALS> input_polynomials; - - // input_univariates are random polynomials of degree one - for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { - input_polynomials[i] = Univariate({ FF::random_element(), FF::random_element() }); - } - compute_mock_extended_edges(extended_edges, input_polynomials); - - auto relation = UltraGrandProductInitializationRelation(); - - // Extract the extended edges for manual computation of relation contribution - const auto& z_perm_shift = extended_edges.z_perm_shift; - const auto& lagrange_last = extended_edges.lagrange_last; - - // Compute the expected result using a simple to read version of the relation expression - auto expected_evals = z_perm_shift * lagrange_last; - - validate_evaluations(expected_evals, relation, extended_edges, relation_parameters); -}; - -TEST_F(UltraRelationConsistency, UltraGrandProductComputationRelation) +TEST_F(UltraRelationConsistency, UltraPermutationRelation) { using Flavor = honk::flavor::Ultra; using FF = typename Flavor::FF; @@ -263,7 +256,7 @@ TEST_F(UltraRelationConsistency, UltraGrandProductComputationRelation) } compute_mock_extended_edges(extended_edges, input_polynomials); - auto relation = UltraGrandProductComputationRelation(); + auto relation = UltraPermutationRelation(); const auto& beta = relation_parameters.beta; const auto& gamma = relation_parameters.gamma; @@ -287,17 +280,27 @@ TEST_F(UltraRelationConsistency, UltraGrandProductComputationRelation) const auto& lagrange_first = extended_edges.lagrange_first; const auto& lagrange_last = extended_edges.lagrange_last; + constexpr std::size_t NUM_CONSTRAINTS = decltype(relation)::NUM_CONSTRAINTS; + auto expected_full_length_univariates = std::array, NUM_CONSTRAINTS>(); + // Compute the expected result using a simple to read version of the relation expression - auto expected_evals = (z_perm + lagrange_first) * (w_1 + id_1 * beta + gamma) * (w_2 + id_2 * beta + gamma) * + + // Contribution 1 + auto contribution_1 = (z_perm + lagrange_first) * (w_1 + id_1 * beta + gamma) * (w_2 + id_2 * beta + gamma) * (w_3 + id_3 * beta + gamma) * (w_4 + id_4 * beta + gamma) - (z_perm_shift + lagrange_last * public_input_delta) * (w_1 + sigma_1 * beta + gamma) * (w_2 + sigma_2 * beta + gamma) * (w_3 + sigma_3 * beta + gamma) * (w_4 + sigma_4 * beta + gamma); + expected_full_length_univariates[0] = contribution_1; - validate_evaluations(expected_evals, relation, extended_edges, relation_parameters); + // Contribution 2 + auto contribution_2 = z_perm_shift * lagrange_last; + expected_full_length_univariates[1] = contribution_2; + + validate_evaluations(expected_full_length_univariates, relation, extended_edges, relation_parameters); }; -TEST_F(UltraRelationConsistency, LookupGrandProductComputationRelation) +TEST_F(UltraRelationConsistency, LookupRelation) { using Flavor = honk::flavor::Ultra; using FF = typename Flavor::FF; @@ -315,7 +318,7 @@ TEST_F(UltraRelationConsistency, LookupGrandProductComputationRelation) } compute_mock_extended_edges(extended_edges, input_polynomials); - auto relation = LookupGrandProductComputationRelation(); + auto relation = LookupRelation(); const auto eta = relation_parameters.eta; const auto beta = relation_parameters.beta; @@ -366,43 +369,23 @@ TEST_F(UltraRelationConsistency, LookupGrandProductComputationRelation) auto table_accum = table_1 + table_2 * eta + table_3 * eta_sqr + table_4 * eta_cube; auto table_accum_shift = table_1_shift + table_2_shift * eta + table_3_shift * eta_sqr + table_4_shift * eta_cube; + constexpr std::size_t NUM_CONSTRAINTS = decltype(relation)::NUM_CONSTRAINTS; + auto expected_full_length_univariates = std::array, NUM_CONSTRAINTS>(); + // Compute the expected result using a simple to read version of the relation expression - auto expected_evals = (z_lookup + lagrange_first) * (q_lookup * wire_accum + gamma) * + + // Contribution 1 + auto contribution_1 = (z_lookup + lagrange_first) * (q_lookup * wire_accum + gamma) * (table_accum + table_accum_shift * beta + gamma_by_one_plus_beta) * one_plus_beta; - expected_evals -= (z_lookup_shift + lagrange_last * grand_product_delta) * + contribution_1 -= (z_lookup_shift + lagrange_last * grand_product_delta) * (s_accum + s_accum_shift * beta + gamma_by_one_plus_beta); + expected_full_length_univariates[0] = contribution_1; - validate_evaluations(expected_evals, relation, extended_edges, relation_parameters); -}; + // Contribution 2 + auto contribution_2 = z_lookup_shift * lagrange_last; + expected_full_length_univariates[1] = contribution_2; -TEST_F(UltraRelationConsistency, LookupGrandProductInitializationRelation) -{ - using Flavor = honk::flavor::Ultra; - using FF = typename Flavor::FF; - using Flavor = honk::flavor::Ultra; - static constexpr size_t FULL_RELATION_LENGTH = 6; - using ExtendedEdges = typename Flavor::ExtendedEdges; - static const size_t NUM_POLYNOMIALS = Flavor::NUM_ALL_ENTITIES; - auto relation_parameters = compute_mock_relation_parameters(); - ExtendedEdges extended_edges; - std::array, NUM_POLYNOMIALS> input_polynomials; - - // input_univariates are random polynomials of degree one - for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { - input_polynomials[i] = Univariate({ FF::random_element(), FF::random_element() }); - } - compute_mock_extended_edges(extended_edges, input_polynomials); - - auto relation = LookupGrandProductInitializationRelation(); - - // Extract the extended edges for manual computation of relation contribution - const auto& z_lookup_shift = extended_edges.z_lookup_shift; - const auto& lagrange_last = extended_edges.lagrange_last; - - // Compute the expected result using a simple to read version of the relation expression - auto expected_evals = z_lookup_shift * lagrange_last; - - validate_evaluations(expected_evals, relation, extended_edges, relation_parameters); + validate_evaluations(expected_full_length_univariates, relation, extended_edges, relation_parameters); }; TEST_F(UltraRelationConsistency, GenPermSortRelation) @@ -436,25 +419,27 @@ TEST_F(UltraRelationConsistency, GenPermSortRelation) const auto& w_1_shift = extended_edges.w_l_shift; const auto& q_sort = extended_edges.q_sort; - static const FF fake_alpha_1 = FF(1); - static const FF fake_alpha_2 = fake_alpha_1 * fake_alpha_1; - static const FF fake_alpha_3 = fake_alpha_2 * fake_alpha_1; - static const FF fake_alpha_4 = fake_alpha_3 * fake_alpha_1; - // Compute wire differences auto delta_1 = w_2 - w_1; auto delta_2 = w_3 - w_2; auto delta_3 = w_4 - w_3; auto delta_4 = w_1_shift - w_4; + constexpr std::size_t NUM_CONSTRAINTS = decltype(relation)::NUM_CONSTRAINTS; + auto expected_full_length_univariates = std::array, NUM_CONSTRAINTS>(); + // Compute the expected result using a simple to read version of the relation expression - auto expected_evals = delta_1 * (delta_1 - 1) * (delta_1 - 2) * (delta_1 - 3) * fake_alpha_1; - expected_evals += delta_2 * (delta_2 - 1) * (delta_2 - 2) * (delta_2 - 3) * fake_alpha_2; - expected_evals += delta_3 * (delta_3 - 1) * (delta_3 - 2) * (delta_3 - 3) * fake_alpha_3; - expected_evals += delta_4 * (delta_4 - 1) * (delta_4 - 2) * (delta_4 - 3) * fake_alpha_4; - expected_evals *= q_sort; + auto contribution_1 = delta_1 * (delta_1 - 1) * (delta_1 - 2) * (delta_1 - 3); + auto contribution_2 = delta_2 * (delta_2 - 1) * (delta_2 - 2) * (delta_2 - 3); + auto contribution_3 = delta_3 * (delta_3 - 1) * (delta_3 - 2) * (delta_3 - 3); + auto contribution_4 = delta_4 * (delta_4 - 1) * (delta_4 - 2) * (delta_4 - 3); + + expected_full_length_univariates[0] = contribution_1 * q_sort; + expected_full_length_univariates[1] = contribution_2 * q_sort; + expected_full_length_univariates[2] = contribution_3 * q_sort; + expected_full_length_univariates[3] = contribution_4 * q_sort; - validate_evaluations(expected_evals, relation, extended_edges, relation_parameters); + validate_evaluations(expected_full_length_univariates, relation, extended_edges, relation_parameters); }; TEST_F(UltraRelationConsistency, EllipticRelation) @@ -491,23 +476,26 @@ TEST_F(UltraRelationConsistency, EllipticRelation) const auto& q_beta_sqr = extended_edges.q_4; const auto& q_elliptic = extended_edges.q_elliptic; - static const FF fake_alpha_1 = FF(1); - static const FF fake_alpha_2 = fake_alpha_1 * fake_alpha_1; + constexpr std::size_t NUM_CONSTRAINTS = decltype(relation)::NUM_CONSTRAINTS; + auto expected_full_length_univariates = std::array, NUM_CONSTRAINTS>(); // Compute x/y coordinate identities + + // Contribution 1 auto x_identity = q_sign * (y_1 * y_2 * 2); x_identity += q_beta * (x_1 * x_2 * x_3 * 2 + x_1 * x_1 * x_2) * FF(-1); x_identity += q_beta_sqr * (x_2 * x_2 * x_3 - x_1 * x_2 * x_2); x_identity += (x_1 * x_1 * x_3 - y_2 * y_2 - y_1 * y_1 + x_2 * x_2 * x_2 + x_1 * x_1 * x_1); + // Contribution 2 auto y_identity = q_sign * (y_2 * x_3 - y_2 * x_1); y_identity += q_beta * (x_2 * y_3 + y_1 * x_2); y_identity += (x_1 * y_1 - x_1 * y_3 - y_1 * x_3 - x_1 * y_1); - auto expected_evals = x_identity * fake_alpha_1 + y_identity * fake_alpha_2; - expected_evals *= q_elliptic; + expected_full_length_univariates[0] = x_identity * q_elliptic; + expected_full_length_univariates[1] = y_identity * q_elliptic; - validate_evaluations(expected_evals, relation, extended_edges, relation_parameters); + validate_evaluations(expected_full_length_univariates, relation, extended_edges, relation_parameters); }; TEST_F(UltraRelationConsistency, AuxiliaryRelation) @@ -531,7 +519,6 @@ TEST_F(UltraRelationConsistency, AuxiliaryRelation) auto relation = AuxiliaryRelation(); const auto& eta = relation_parameters.eta; - const auto fake_alpha = FF(1); // Extract the extended edges for manual computation of relation contribution const auto& w_1 = extended_edges.w_l; @@ -552,6 +539,9 @@ TEST_F(UltraRelationConsistency, AuxiliaryRelation) const auto& q_arith = extended_edges.q_arith; const auto& q_aux = extended_edges.q_aux; + constexpr std::size_t NUM_CONSTRAINTS = decltype(relation)::NUM_CONSTRAINTS; + auto expected_full_length_univariates = std::array, NUM_CONSTRAINTS>(); + constexpr FF LIMB_SIZE(uint256_t(1) << 68); constexpr FF SUBLIMB_SHIFT(uint256_t(1) << 14); constexpr FF SUBLIMB_SHIFT_2(SUBLIMB_SHIFT * SUBLIMB_SHIFT); @@ -572,32 +562,28 @@ TEST_F(UltraRelationConsistency, AuxiliaryRelation) non_native_field_gate_2 *= LIMB_SIZE; non_native_field_gate_2 -= w_4_shift; non_native_field_gate_2 += limb_subproduct; - non_native_field_gate_2 *= q_4; limb_subproduct *= LIMB_SIZE; limb_subproduct += (w_1_shift * w_2_shift); auto non_native_field_gate_1 = limb_subproduct; non_native_field_gate_1 -= (w_3 + w_4); - non_native_field_gate_1 *= q_3; auto non_native_field_gate_3 = limb_subproduct; non_native_field_gate_3 += w_4; non_native_field_gate_3 -= (w_3_shift + w_4_shift); - non_native_field_gate_3 *= q_m; - auto non_native_field_identity = non_native_field_gate_1 + non_native_field_gate_2 + non_native_field_gate_3; - non_native_field_identity *= q_2; + auto non_native_field_identity = q_2 * q_3 * non_native_field_gate_1; + non_native_field_identity += q_2 * q_4 * non_native_field_gate_2; + non_native_field_identity += q_2 * q_m * non_native_field_gate_3; auto limb_accumulator_1 = w_1 + w_2 * SUBLIMB_SHIFT + w_3 * SUBLIMB_SHIFT_2 + w_1_shift * SUBLIMB_SHIFT_3 + w_2_shift * SUBLIMB_SHIFT_4 - w_4; - limb_accumulator_1 *= q_4; auto limb_accumulator_2 = w_3 + w_4 * SUBLIMB_SHIFT + w_1_shift * SUBLIMB_SHIFT_2 + w_2_shift * SUBLIMB_SHIFT_3 + w_3_shift * SUBLIMB_SHIFT_4 - w_4_shift; - limb_accumulator_2 *= q_m; - auto limb_accumulator_identity = limb_accumulator_1 + limb_accumulator_2; - limb_accumulator_identity *= q_3; + auto limb_accumulator_identity = q_3 * q_4 * limb_accumulator_1; + limb_accumulator_identity += q_3 * q_m * limb_accumulator_2; /** * MEMORY @@ -627,11 +613,9 @@ TEST_F(UltraRelationConsistency, AuxiliaryRelation) // auto adjacent_values_match_if_adjacent_indices_match = (FF(1) - index_delta) * record_delta; auto adjacent_values_match_if_adjacent_indices_match = (index_delta * FF(-1) + FF(1)) * record_delta; - auto ROM_consistency_check_identity = adjacent_values_match_if_adjacent_indices_match; - ROM_consistency_check_identity *= fake_alpha; - ROM_consistency_check_identity += index_is_monotonically_increasing; - ROM_consistency_check_identity *= fake_alpha; - ROM_consistency_check_identity += memory_record_check; + expected_full_length_univariates[1] = adjacent_values_match_if_adjacent_indices_match * (q_1 * q_2); + expected_full_length_univariates[2] = index_is_monotonically_increasing * (q_1 * q_2); + auto ROM_consistency_check_identity = memory_record_check * (q_1 * q_2); /** * RAM Consistency Check @@ -659,34 +643,42 @@ TEST_F(UltraRelationConsistency, AuxiliaryRelation) auto next_gate_access_type_is_boolean = next_gate_access_type * next_gate_access_type - next_gate_access_type; // Putting it all together... - auto RAM_consistency_check_identity = - adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation; - RAM_consistency_check_identity *= fake_alpha; - RAM_consistency_check_identity += index_is_monotonically_increasing; - RAM_consistency_check_identity *= fake_alpha; - RAM_consistency_check_identity += next_gate_access_type_is_boolean; - RAM_consistency_check_identity *= fake_alpha; - RAM_consistency_check_identity += access_check; + expected_full_length_univariates[3] = + adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation * (q_arith); + expected_full_length_univariates[4] = index_is_monotonically_increasing * (q_arith); + expected_full_length_univariates[5] = next_gate_access_type_is_boolean * (q_arith); + auto RAM_consistency_check_identity = access_check * (q_arith); + + /** + * RAM/ROM access check gate + */ + memory_record_check *= (q_1 * q_m); /** * RAM Timestamp Consistency Check */ auto timestamp_delta = w_2_shift - w_2; auto RAM_timestamp_check_identity = (index_delta * FF(-1) + FF(1)) * timestamp_delta - w_3; + RAM_timestamp_check_identity *= (q_1 * q_4); /** * The complete RAM/ROM memory identity */ - auto memory_identity = ROM_consistency_check_identity * q_2; - memory_identity += RAM_timestamp_check_identity * q_4; - memory_identity += memory_record_check * q_m; - memory_identity *= q_1; - memory_identity += (RAM_consistency_check_identity * q_arith); + auto memory_identity = ROM_consistency_check_identity; + memory_identity += RAM_timestamp_check_identity; + memory_identity += memory_record_check; + memory_identity += RAM_consistency_check_identity; + + expected_full_length_univariates[0] = memory_identity + non_native_field_identity + limb_accumulator_identity; - auto expected_evals = memory_identity + non_native_field_identity + limb_accumulator_identity; - expected_evals *= q_aux; + expected_full_length_univariates[0] *= q_aux; + expected_full_length_univariates[1] *= q_aux; + expected_full_length_univariates[2] *= q_aux; + expected_full_length_univariates[3] *= q_aux; + expected_full_length_univariates[4] *= q_aux; + expected_full_length_univariates[5] *= q_aux; - validate_evaluations(expected_evals, relation, extended_edges, relation_parameters); + validate_evaluations(expected_full_length_univariates, relation, extended_edges, relation_parameters); }; } // namespace proof_system::honk_relation_tests diff --git a/cpp/src/barretenberg/honk/sumcheck/sumcheck.hpp b/cpp/src/barretenberg/honk/sumcheck/sumcheck.hpp index 3e6794e18a..399b943870 100644 --- a/cpp/src/barretenberg/honk/sumcheck/sumcheck.hpp +++ b/cpp/src/barretenberg/honk/sumcheck/sumcheck.hpp @@ -1,7 +1,7 @@ #pragma once #include "barretenberg/common/serialize.hpp" #include -#include "barretenberg/honk/sumcheck/relations/relation.hpp" +#include "barretenberg/honk/sumcheck/relations/relation_parameters.hpp" #include "barretenberg/honk/transcript/transcript.hpp" #include "barretenberg/honk/utils/grand_product_delta.hpp" #include "barretenberg/common/throw_or_abort.hpp" diff --git a/cpp/src/barretenberg/honk/sumcheck/sumcheck.test.cpp b/cpp/src/barretenberg/honk/sumcheck/sumcheck.test.cpp index f319872b15..c7dee556ca 100644 --- a/cpp/src/barretenberg/honk/sumcheck/sumcheck.test.cpp +++ b/cpp/src/barretenberg/honk/sumcheck/sumcheck.test.cpp @@ -3,8 +3,7 @@ #include "barretenberg/honk/flavor/standard.hpp" #include "barretenberg/transcript/transcript_wrappers.hpp" #include "relations/arithmetic_relation.hpp" -#include "relations/grand_product_computation_relation.hpp" -#include "relations/grand_product_initialization_relation.hpp" +#include "relations/permutation_relation.hpp" #include "barretenberg/transcript/manifest.hpp" #include #include @@ -12,6 +11,13 @@ #include "barretenberg/ecc/curves/bn254/fr.hpp" #include #include "barretenberg/numeric/random/engine.hpp" +#include "barretenberg/honk/composer/standard_honk_composer.hpp" +#include "barretenberg/honk/composer/ultra_honk_composer.hpp" +#include "barretenberg/honk/sumcheck/relations/ultra_arithmetic_relation.hpp" +#include "barretenberg/honk/sumcheck/relations/lookup_relation.hpp" +#include "barretenberg/honk/sumcheck/relations/gen_perm_sort_relation.hpp" +#include "barretenberg/honk/sumcheck/relations/elliptic_relation.hpp" +#include "barretenberg/honk/sumcheck/relations/auxiliary_relation.hpp" #include #include @@ -402,4 +408,304 @@ TEST(Sumcheck, ProverAndVerifierLonger) run_test(/* expect_verified=*/false); } +/** + * @brief Test the Standard Sumcheck Prover and Verifier for a real circuit + * + */ +TEST(Sumcheck, RealCircuitStandard) +{ + using Flavor = honk::flavor::Standard; + using FF = typename Flavor::FF; + using ProverPolynomials = typename Flavor::ProverPolynomials; + + // Create a composer and a dummy circuit with a few gates + auto composer = StandardHonkComposer(); + fr a = fr::one(); + // Using the public variable to check that public_input_delta is computed and added to the relation correctly + uint32_t a_idx = composer.add_public_variable(a); + fr b = fr::one(); + fr c = a + b; + fr d = a + c; + uint32_t b_idx = composer.add_variable(b); + uint32_t c_idx = composer.add_variable(c); + uint32_t d_idx = composer.add_variable(d); + for (size_t i = 0; i < 16; i++) { + composer.create_add_gate({ a_idx, b_idx, c_idx, fr::one(), fr::one(), fr::neg_one(), fr::zero() }); + composer.create_add_gate({ d_idx, c_idx, a_idx, fr::one(), fr::neg_one(), fr::neg_one(), fr::zero() }); + } + // Create a prover (it will compute proving key and witness) + auto prover = composer.create_prover(); + + // Generate beta and gamma + fr beta = fr::random_element(); + fr gamma = fr::random_element(); + + // Compute public input delta + const auto public_inputs = composer.circuit_constructor.get_public_inputs(); + auto public_input_delta = + honk::compute_public_input_delta(public_inputs, beta, gamma, prover.key->circuit_size); + + sumcheck::RelationParameters relation_parameters{ + .beta = beta, + .gamma = gamma, + .public_input_delta = public_input_delta, + }; + + // Compute grand product polynomial + polynomial z_permutation = prover_library::compute_permutation_grand_product(prover.key, beta, gamma); + + ProverPolynomials prover_polynomials; + + prover_polynomials.w_l = prover.key->w_l; + prover_polynomials.w_r = prover.key->w_r; + prover_polynomials.w_o = prover.key->w_o; + prover_polynomials.z_perm = z_permutation; + prover_polynomials.z_perm_shift = z_permutation.shifted(); + prover_polynomials.q_m = prover.key->q_m; + prover_polynomials.q_l = prover.key->q_l; + prover_polynomials.q_r = prover.key->q_r; + prover_polynomials.q_o = prover.key->q_o; + prover_polynomials.q_c = prover.key->q_c; + prover_polynomials.sigma_1 = prover.key->sigma_1; + prover_polynomials.sigma_2 = prover.key->sigma_2; + prover_polynomials.sigma_3 = prover.key->sigma_3; + prover_polynomials.id_1 = prover.key->id_1; + prover_polynomials.id_2 = prover.key->id_2; + prover_polynomials.id_3 = prover.key->id_3; + prover_polynomials.lagrange_first = prover.key->lagrange_first; + prover_polynomials.lagrange_last = prover.key->lagrange_last; + + auto prover_transcript = ProverTranscript::init_empty(); + + auto sumcheck_prover = Sumcheck>(prover.key->circuit_size, prover_transcript); + + auto prover_output = sumcheck_prover.execute_prover(prover_polynomials, relation_parameters); + + auto verifier_transcript = VerifierTranscript::init_empty(prover_transcript); + + auto sumcheck_verifier = Sumcheck>(prover.key->circuit_size, verifier_transcript); + + std::optional verifier_output = sumcheck_verifier.execute_verifier(relation_parameters); + + ASSERT_TRUE(verifier_output.has_value()); +} + +/** + * @brief Test the Ultra Sumcheck Prover and Verifier for a real circuit + * + */ +TEST(Sumcheck, RealCircuitUltra) +{ + using Flavor = honk::flavor::Ultra; + using FF = typename Flavor::FF; + using ProverPolynomials = typename Flavor::ProverPolynomials; + + // Create a composer and a dummy circuit with a few gates + auto composer = UltraHonkComposer(); + fr a = fr::one(); + + // Add some basic add gates + uint32_t a_idx = composer.add_variable(a); + fr b = fr::one(); + fr c = a + b; + fr d = a + c; + uint32_t b_idx = composer.add_variable(b); + uint32_t c_idx = composer.add_variable(c); + uint32_t d_idx = composer.add_variable(d); + for (size_t i = 0; i < 16; i++) { + composer.create_add_gate({ a_idx, b_idx, c_idx, 1, 1, -1, 0 }); + composer.create_add_gate({ d_idx, c_idx, a_idx, 1, -1, -1, 0 }); + } + + // Add a big add gate with use of next row to test q_arith = 2 + fr e = a + b + c + d; + uint32_t e_idx = composer.add_variable(e); + + uint32_t zero_idx = composer.get_zero_idx(); + composer.create_big_add_gate({ a_idx, b_idx, c_idx, d_idx, -1, -1, -1, -1, 0 }, true); // use next row + composer.create_big_add_gate({ zero_idx, zero_idx, zero_idx, e_idx, 0, 0, 0, 0, 0 }, false); + + // Add some lookup gates (related to pedersen hashing) + barretenberg::fr pedersen_input_value = fr::random_element(); + const fr input_hi = uint256_t(pedersen_input_value).slice(126, 256); + const fr input_lo = uint256_t(pedersen_input_value).slice(0, 126); + const auto input_hi_index = composer.add_variable(input_hi); + const auto input_lo_index = composer.add_variable(input_lo); + + const auto sequence_data_hi = plookup::get_lookup_accumulators(plookup::MultiTableId::PEDERSEN_LEFT_HI, input_hi); + const auto sequence_data_lo = plookup::get_lookup_accumulators(plookup::MultiTableId::PEDERSEN_LEFT_LO, input_lo); + + composer.create_gates_from_plookup_accumulators( + plookup::MultiTableId::PEDERSEN_LEFT_HI, sequence_data_hi, input_hi_index); + composer.create_gates_from_plookup_accumulators( + plookup::MultiTableId::PEDERSEN_LEFT_LO, sequence_data_lo, input_lo_index); + + // Add a sort gate (simply checks that consecutive inputs have a difference of < 4) + a_idx = composer.add_variable(FF(0)); + b_idx = composer.add_variable(FF(1)); + c_idx = composer.add_variable(FF(2)); + d_idx = composer.add_variable(FF(3)); + composer.create_sort_constraint({ a_idx, b_idx, c_idx, d_idx }); + + // Add an elliptic curve addition gate + grumpkin::g1::affine_element p1 = crypto::generators::get_generator_data({ 0, 0 }).generator; + grumpkin::g1::affine_element p2 = crypto::generators::get_generator_data({ 0, 1 }).generator; + + grumpkin::fq beta_scalar = grumpkin::fq::cube_root_of_unity(); + grumpkin::g1::affine_element p2_endo = p2; + p2_endo.x *= beta_scalar; + + grumpkin::g1::affine_element p3(grumpkin::g1::element(p1) - grumpkin::g1::element(p2_endo)); + + uint32_t x1 = composer.add_variable(p1.x); + uint32_t y1 = composer.add_variable(p1.y); + uint32_t x2 = composer.add_variable(p2.x); + uint32_t y2 = composer.add_variable(p2.y); + uint32_t x3 = composer.add_variable(p3.x); + uint32_t y3 = composer.add_variable(p3.y); + + ecc_add_gate gate{ x1, y1, x2, y2, x3, y3, beta_scalar, -1 }; + composer.create_ecc_add_gate(gate); + + // Add some RAM gates + uint32_t ram_values[8]{ + composer.add_variable(fr::random_element()), composer.add_variable(fr::random_element()), + composer.add_variable(fr::random_element()), composer.add_variable(fr::random_element()), + composer.add_variable(fr::random_element()), composer.add_variable(fr::random_element()), + composer.add_variable(fr::random_element()), composer.add_variable(fr::random_element()), + }; + + size_t ram_id = composer.create_RAM_array(8); + + for (size_t i = 0; i < 8; ++i) { + composer.init_RAM_element(ram_id, i, ram_values[i]); + } + + a_idx = composer.read_RAM_array(ram_id, composer.add_variable(5)); + EXPECT_EQ(a_idx != ram_values[5], true); + + b_idx = composer.read_RAM_array(ram_id, composer.add_variable(4)); + c_idx = composer.read_RAM_array(ram_id, composer.add_variable(1)); + + composer.write_RAM_array(ram_id, composer.add_variable(4), composer.add_variable(500)); + d_idx = composer.read_RAM_array(ram_id, composer.add_variable(4)); + + EXPECT_EQ(composer.get_variable(d_idx), 500); + + // ensure these vars get used in another arithmetic gate + const auto e_value = composer.get_variable(a_idx) + composer.get_variable(b_idx) + composer.get_variable(c_idx) + + composer.get_variable(d_idx); + e_idx = composer.add_variable(e_value); + + composer.create_big_add_gate({ a_idx, b_idx, c_idx, d_idx, -1, -1, -1, -1, 0 }, true); + composer.create_big_add_gate( + { + composer.get_zero_idx(), + composer.get_zero_idx(), + composer.get_zero_idx(), + e_idx, + 0, + 0, + 0, + 0, + 0, + }, + false); + + // Create a prover (it will compute proving key and witness) + auto prover = composer.create_prover(); + + // Generate eta, beta and gamma + fr eta = fr::random_element(); + fr beta = fr::random_element(); + fr gamma = fr::random_element(); + + // Compute public input delta + const auto public_inputs = composer.circuit_constructor.get_public_inputs(); + auto public_input_delta = + honk::compute_public_input_delta(public_inputs, beta, gamma, prover.key->circuit_size); + auto lookup_grand_product_delta = + honk::compute_lookup_grand_product_delta(beta, gamma, prover.key->circuit_size); + + sumcheck::RelationParameters relation_parameters{ + .eta = eta, + .beta = beta, + .gamma = gamma, + .public_input_delta = public_input_delta, + .lookup_grand_product_delta = lookup_grand_product_delta, + }; + + // Compute sorted witness-table accumulator + prover.key->sorted_accum = prover_library::compute_sorted_list_accumulator(prover.key, eta); + + // Add RAM/ROM memory records to wire four + prover_library::add_plookup_memory_records_to_wire_4(prover.key, eta); + + // Compute grand product polynomial + prover.key->z_perm = prover_library::compute_permutation_grand_product(prover.key, beta, gamma); + + // Compute lookup grand product polynomial + prover.key->z_lookup = prover_library::compute_lookup_grand_product(prover.key, eta, beta, gamma); + + ProverPolynomials prover_polynomials; + + prover_polynomials.w_l = prover.key->w_l; + prover_polynomials.w_r = prover.key->w_r; + prover_polynomials.w_o = prover.key->w_o; + prover_polynomials.w_4 = prover.key->w_4; + prover_polynomials.w_l_shift = prover.key->w_l.shifted(); + prover_polynomials.w_r_shift = prover.key->w_r.shifted(); + prover_polynomials.w_o_shift = prover.key->w_o.shifted(); + prover_polynomials.w_4_shift = prover.key->w_4.shifted(); + prover_polynomials.sorted_accum = prover.key->sorted_accum; + prover_polynomials.sorted_accum_shift = prover.key->sorted_accum.shifted(); + prover_polynomials.table_1 = prover.key->table_1; + prover_polynomials.table_2 = prover.key->table_2; + prover_polynomials.table_3 = prover.key->table_3; + prover_polynomials.table_4 = prover.key->table_4; + prover_polynomials.table_1_shift = prover.key->table_1.shifted(); + prover_polynomials.table_2_shift = prover.key->table_2.shifted(); + prover_polynomials.table_3_shift = prover.key->table_3.shifted(); + prover_polynomials.table_4_shift = prover.key->table_4.shifted(); + prover_polynomials.z_perm = prover.key->z_perm; + prover_polynomials.z_perm_shift = prover.key->z_perm.shifted(); + prover_polynomials.z_lookup = prover.key->z_lookup; + prover_polynomials.z_lookup_shift = prover.key->z_lookup.shifted(); + prover_polynomials.q_m = prover.key->q_m; + prover_polynomials.q_l = prover.key->q_l; + prover_polynomials.q_r = prover.key->q_r; + prover_polynomials.q_o = prover.key->q_o; + prover_polynomials.q_c = prover.key->q_c; + prover_polynomials.q_4 = prover.key->q_4; + prover_polynomials.q_arith = prover.key->q_arith; + prover_polynomials.q_sort = prover.key->q_sort; + prover_polynomials.q_elliptic = prover.key->q_elliptic; + prover_polynomials.q_aux = prover.key->q_aux; + prover_polynomials.q_lookup = prover.key->q_lookup; + prover_polynomials.sigma_1 = prover.key->sigma_1; + prover_polynomials.sigma_2 = prover.key->sigma_2; + prover_polynomials.sigma_3 = prover.key->sigma_3; + prover_polynomials.sigma_4 = prover.key->sigma_4; + prover_polynomials.id_1 = prover.key->id_1; + prover_polynomials.id_2 = prover.key->id_2; + prover_polynomials.id_3 = prover.key->id_3; + prover_polynomials.id_4 = prover.key->id_4; + prover_polynomials.lagrange_first = prover.key->lagrange_first; + prover_polynomials.lagrange_last = prover.key->lagrange_last; + + auto prover_transcript = ProverTranscript::init_empty(); + + auto sumcheck_prover = Sumcheck>(prover.key->circuit_size, prover_transcript); + + auto prover_output = sumcheck_prover.execute_prover(prover_polynomials, relation_parameters); + + auto verifier_transcript = VerifierTranscript::init_empty(prover_transcript); + + auto sumcheck_verifier = Sumcheck>(prover.key->circuit_size, verifier_transcript); + + std::optional verifier_output = sumcheck_verifier.execute_verifier(relation_parameters); + + ASSERT_TRUE(verifier_output.has_value()); +} + } // namespace test_sumcheck_round diff --git a/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.hpp b/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.hpp index 4c2fbca313..a90d422e51 100644 --- a/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.hpp +++ b/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.hpp @@ -6,8 +6,9 @@ #include "polynomials/barycentric_data.hpp" #include "polynomials/univariate.hpp" #include "polynomials/pow.hpp" -#include "relations/relation.hpp" -#include "barretenberg/honk/flavor/ultra.hpp" // WORKTOO +#include "relations/relation_parameters.hpp" +#include "barretenberg/honk/flavor/ultra.hpp" +#include namespace proof_system::honk::sumcheck { @@ -56,8 +57,8 @@ namespace proof_system::honk::sumcheck { template class SumcheckRound { using Relations = typename Flavor::Relations; - using UnivariateTuple = typename Flavor::UnivariateTuple; - using BarycentricUtils = typename Flavor::BarycentricUtils; + using RelationUnivariates = typename Flavor::RelationUnivariates; + using RelationEvaluations = typename Flavor::RelationValues; public: using FF = typename Flavor::FF; @@ -74,79 +75,46 @@ template class SumcheckRound { FF target_total_sum = 0; - // TODO(#224)(Cody): this barycentric stuff should be more built-in? - BarycentricUtils barycentric_utils; - UnivariateTuple univariate_accumulators; - std::array relation_evaluations; + RelationUnivariates univariate_accumulators; + RelationEvaluations relation_evaluations; + ExtendedEdges extended_edges; - std::array, NUM_RELATIONS> extended_univariates; - // TODO(#224)(Cody): this should go away and we should use constexpr method to extend + // TODO(#224)(Cody): this should go away BarycentricData barycentric_2_to_max = BarycentricData(); // Prover constructor SumcheckRound(size_t initial_round_size) : round_size(initial_round_size) - {} - - // Verifier constructor - explicit SumcheckRound() - { - // FF's default constructor may not initialize to zero (e.g., barretenberg::fr), hence we can't rely on - // aggregate initialization of the evaluations array. - std::fill(relation_evaluations.begin(), relation_evaluations.end(), FF(0)); - }; - - /** - * @brief After computing the round univariate, it is necessary to zero-out the accumulators used to compute it. - */ - template void reset_accumulators() { - auto& univariate = std::get(univariate_accumulators); - std::fill(univariate.evaluations.begin(), univariate.evaluations.end(), FF(0)); - - if constexpr (idx + 1 < NUM_RELATIONS) { - reset_accumulators(); - } - }; - // IMPROVEMENT(Cody): This is kind of ugly. There should be a one-liner with folding - // or std::apply or something. + // Initialize univariate accumulators to 0 + zero_univariates(univariate_accumulators); + } - /** - * @brief Given a tuple t = (t_0, t_1, ..., t_{NUM_RELATIONS-1}) and a challenge α, - * modify the tuple in place to (t_0, αt_1, ..., α^{NUM_RELATIONS-1}t_{NUM_RELATIONS-1}). - */ - template void scale_tuple(auto& tuple, FF challenge, FF running_challenge) - { - std::get(tuple) *= running_challenge; - running_challenge *= challenge; - if constexpr (idx + 1 < NUM_RELATIONS) { - scale_tuple(tuple, challenge, running_challenge); - } - }; + // Verifier constructor + explicit SumcheckRound() { zero_elements(relation_evaluations); }; /** * @brief Given a tuple t = (t_0, t_1, ..., t_{NUM_RELATIONS-1}) and a challenge α, * return t_0 + αt_1 + ... + α^{NUM_RELATIONS-1}t_{NUM_RELATIONS-1}). * - * @tparam T : In practice, this is an FF or a Univariate. + * @tparam T : In practice, this is a Univariate. */ - template T batch_over_relations(FF challenge) + Univariate batch_over_relations(FF challenge) { FF running_challenge = 1; - scale_tuple<>(univariate_accumulators, challenge, running_challenge); - extend_univariate_accumulators<>(); - auto result = T(); - for (size_t i = 0; i < NUM_RELATIONS; ++i) { - result += extended_univariates[i]; - } + scale_univariates(univariate_accumulators, challenge, running_challenge); + + auto result = Univariate(); + extend_and_batch_univariates(univariate_accumulators, result); + + // Reset all univariate accumulators to 0 before beginning accumulation in the next round + zero_univariates(univariate_accumulators); return result; } /** - * @brief Evaluate some relations by evaluating each edge in the edge group at - * Univariate::length-many values. Store each value separately in the corresponding - * entry of relation_evals. + * @brief Extend each edge in the edge group at to max-relation-length-many values. * * @details Should only be called externally with relation_idx equal to 0. * In practice, multivariates is one of ProverPolynomials or FoldedPolynomials. @@ -162,23 +130,6 @@ template class SumcheckRound { } } - /** - * @brief After executing each widget on each edge, producing a tuple of univariates of differing lenghths, - * extend all univariates to the max of the lenghths required by the largest relation. - * - * @tparam relation_idx - */ - template void extend_univariate_accumulators() - { - extended_univariates[relation_idx] = - std::get(barycentric_utils).extend(std::get(univariate_accumulators)); - - // Repeat for the next relation. - if constexpr (relation_idx + 1 < NUM_RELATIONS) { - extend_univariate_accumulators(); - } - } - /** * @brief Return the evaluations of the univariate restriction (S_l(X_l) in the thesis) at num_multivariates-many * values. Most likely this will end up being S_l(0), ... , S_l(t-1) where t is around 12. At the end, reset all @@ -203,11 +154,7 @@ template class SumcheckRound { pow_challenge *= pow_univariate.zeta_pow_sqr; } - auto result = batch_over_relations>(alpha); - - reset_accumulators<>(); - - return result; + return batch_over_relations(alpha); } /** @@ -225,13 +172,10 @@ template class SumcheckRound { { accumulate_relation_evaluations<>(purported_evaluations, relation_parameters); - // IMPROVEMENT(Cody): Reuse functions from univariate_accumulators batching? - FF running_challenge = 1; - FF output = 0; - for (auto& evals : relation_evaluations) { - output += evals * running_challenge; - running_challenge *= alpha; - } + auto running_challenge = FF(1); + auto output = FF(0); + scale_and_batch_elements(relation_evaluations, alpha, running_challenge, output); + output *= pow_univariate.partial_evaluation_constant; return output; @@ -320,12 +264,142 @@ template class SumcheckRound { const RelationParameters& relation_parameters) { std::get(relations).add_full_relation_value_contribution( - relation_evaluations[relation_idx], purported_evaluations, relation_parameters); + std::get(relation_evaluations), purported_evaluations, relation_parameters); // Repeat for the next relation. if constexpr (relation_idx + 1 < NUM_RELATIONS) { accumulate_relation_evaluations(purported_evaluations, relation_parameters); } } + + public: + /** + * Utility methods for tuple of tuples of Univariates + */ + + /** + * @brief Extend Univariates to specified size then sum them + * + * @tparam extended_size Size after extension + * @param tuple A tuple of tuples of Univariates + * @param result A Univariate of length extended_size + */ + template + static void extend_and_batch_univariates(auto& tuple, Univariate& result) + { + auto extend_and_sum = [&](auto& element) { + using Element = std::remove_reference_t; + // TODO(#224)(Cody): this barycentric stuff should be more built-in? + BarycentricData barycentric_utils; + result += barycentric_utils.extend(element); + }; + apply_to_tuple_of_tuples(tuple, extend_and_sum); + } + + /** + * @brief Set all coefficients of Univariates to zero + * + * @details After computing the round univariate, it is necessary to zero-out the accumulators used to compute it. + */ + static void zero_univariates(auto& tuple) + { + auto set_to_zero = [](auto& element) { + std::fill(element.evaluations.begin(), element.evaluations.end(), FF(0)); + }; + apply_to_tuple_of_tuples(tuple, set_to_zero); + } + + /** + * @brief Scale Univaraites by consecutive powers of the provided challenge + * + * @param tuple Tuple of tuples of Univariates + * @param challenge + * @param current_scalar power of the challenge + */ + static void scale_univariates(auto& tuple, const FF& challenge, FF current_scalar) + { + auto scale_by_consecutive_powers_of_challenge = [&](auto& element) { + element *= current_scalar; + current_scalar *= challenge; + }; + apply_to_tuple_of_tuples(tuple, scale_by_consecutive_powers_of_challenge); + } + + /** + * @brief General purpose method for applying an operation to a tuple of tuples of Univariates + * + * @tparam Operation Any operation valid on Univariates + * @tparam outer_idx Index into the outer tuple + * @tparam inner_idx Index into the inner tuple + * @param tuple A Tuple of tuples of Univariates + * @param operation Operation to apply to Univariates + */ + template + static void apply_to_tuple_of_tuples(auto& tuple, Operation&& operation) + { + auto& inner_tuple = std::get(tuple); + auto& univariate = std::get(inner_tuple); + + // Apply the specified operation to each Univariate + std::invoke(std::forward(operation), univariate); + + const size_t inner_size = std::tuple_size_v(tuple))>>; + const size_t outer_size = std::tuple_size_v>; + + // Recurse over inner and outer tuples + if constexpr (inner_idx + 1 < inner_size) { + apply_to_tuple_of_tuples(tuple, std::forward(operation)); + } else if constexpr (outer_idx + 1 < outer_size) { + apply_to_tuple_of_tuples(tuple, std::forward(operation)); + } + } + + /** + * Utility methods for tuple of arrays + */ + + /** + * @brief Set each element in a tuple of arrays to zero. + * @details FF's default constructor may not initialize to zero (e.g., barretenberg::fr), hence we can't rely on + * aggregate initialization of the evaluations array. + */ + template static void zero_elements(auto& tuple) + { + auto set_to_zero = [](auto& element) { std::fill(element.begin(), element.end(), FF(0)); }; + apply_to_tuple_of_arrays(set_to_zero, tuple); + }; + + /** + * @brief Scale elements by consecutive powers of the challenge then sum + * @param result Batched result + */ + static void scale_and_batch_elements(auto& tuple, const FF& challenge, FF current_scalar, FF& result) + { + auto scale_by_challenge_and_accumulate = [&](auto& element) { + for (auto& entry : element) { + result += entry * current_scalar; + current_scalar *= challenge; + } + }; + apply_to_tuple_of_arrays(scale_by_challenge_and_accumulate, tuple); + } + + /** + * @brief General purpose method for applying a tuple of arrays (of FFs) + * + * @tparam Operation Any operation valid on elements of the inner arrays (FFs) + * @param tuple Tuple of arrays (of FFs) + */ + template + static void apply_to_tuple_of_arrays(Operation&& operation, std::tuple& tuple) + { + auto& element = std::get(tuple); + + std::invoke(std::forward(operation), element); + + if constexpr (idx + 1 < sizeof...(Ts)) { + apply_to_tuple_of_arrays(operation, tuple); + } + } }; } // namespace proof_system::honk::sumcheck diff --git a/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.test.cpp b/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.test.cpp index 9efdc23677..c5e7260be4 100644 --- a/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.test.cpp +++ b/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.test.cpp @@ -29,46 +29,6 @@ const size_t max_relation_length = 5; const size_t input_polynomial_length = 2; namespace test_sumcheck_round { -template -void construct_full_polynomials(ProverPolynomials& full_polynomials, - std::array& w_l, - std::array& w_r, - std::array& w_o, - std::array& z_perm, - std::array& z_perm_shift, - std::array& q_m, - std::array& q_l, - std::array& q_r, - std::array& q_o, - std::array& q_c, - std::array& sigma_1, - std::array& sigma_2, - std::array& sigma_3, - std::array& id_1, - std::array& id_2, - std::array& id_3, - std::array& lagrange_first, - std::array& lagrange_last) -{ - full_polynomials.w_l = w_l; - full_polynomials.w_r = w_r; - full_polynomials.w_o = w_o; - full_polynomials.z_perm = z_perm; - full_polynomials.z_perm_shift = z_perm_shift; - full_polynomials.q_m = q_m; - full_polynomials.q_l = q_l; - full_polynomials.q_r = q_r; - full_polynomials.q_o = q_o; - full_polynomials.q_c = q_c; - full_polynomials.sigma_1 = sigma_1; - full_polynomials.sigma_2 = sigma_2; - full_polynomials.sigma_3 = sigma_3; - full_polynomials.id_1 = id_1; - full_polynomials.id_2 = id_2; - full_polynomials.id_3 = id_3; - full_polynomials.lagrange_first = lagrange_first; - full_polynomials.lagrange_last = lagrange_last; -} // The below two methods are used in the test ComputeUnivariateProver static Univariate compute_round_univariate( @@ -77,48 +37,29 @@ static Univariate compute_round_univariate( const FF alpha) { size_t round_size = 1; - // Improvement(Cody): This is ugly? Maye supply some/all of this data through "flavor" class? auto round = SumcheckRound(round_size); - auto w_l = input_polynomials[0]; - auto w_r = input_polynomials[1]; - auto w_o = input_polynomials[2]; - auto z_perm = input_polynomials[3]; - auto z_perm_shift = input_polynomials[4]; - auto q_m = input_polynomials[5]; - auto q_l = input_polynomials[6]; - auto q_r = input_polynomials[7]; - auto q_o = input_polynomials[8]; - auto q_c = input_polynomials[9]; - auto sigma_1 = input_polynomials[10]; - auto sigma_2 = input_polynomials[11]; - auto sigma_3 = input_polynomials[12]; - auto id_1 = input_polynomials[13]; - auto id_2 = input_polynomials[14]; - auto id_3 = input_polynomials[15]; - auto lagrange_first = input_polynomials[16]; - auto lagrange_last = input_polynomials[17]; ProverPolynomials full_polynomials; - construct_full_polynomials(full_polynomials, - w_l, - w_r, - w_o, - z_perm, - z_perm_shift, - q_m, - q_l, - q_r, - q_o, - q_c, - sigma_1, - sigma_2, - sigma_3, - id_1, - id_2, - id_3, - lagrange_first, - lagrange_last); + full_polynomials.w_l = input_polynomials[0]; + full_polynomials.w_r = input_polynomials[1]; + full_polynomials.w_o = input_polynomials[2]; + full_polynomials.z_perm = input_polynomials[3]; + full_polynomials.z_perm_shift = input_polynomials[4]; + full_polynomials.q_m = input_polynomials[5]; + full_polynomials.q_l = input_polynomials[6]; + full_polynomials.q_r = input_polynomials[7]; + full_polynomials.q_o = input_polynomials[8]; + full_polynomials.q_c = input_polynomials[9]; + full_polynomials.sigma_1 = input_polynomials[10]; + full_polynomials.sigma_2 = input_polynomials[11]; + full_polynomials.sigma_3 = input_polynomials[12]; + full_polynomials.id_1 = input_polynomials[13]; + full_polynomials.id_2 = input_polynomials[14]; + full_polynomials.id_3 = input_polynomials[15]; + full_polynomials.lagrange_first = input_polynomials[16]; + full_polynomials.lagrange_last = input_polynomials[17]; + PowUnivariate pow_zeta(1); Univariate round_univariate = round.compute_univariate(full_polynomials, relation_parameters, pow_zeta, alpha); @@ -331,4 +272,93 @@ TEST(SumcheckRound, ComputeUnivariateVerifier) run_test(/* is_random_input=*/true); } +/** + * @brief Test utility functions for applying operations to tuple of tuple of Univariates + * + */ +TEST(SumcheckRound, TupleOfTuplesOfUnivariates) +{ + using Flavor = proof_system::honk::flavor::Standard; + using FF = typename Flavor::FF; + + // Define three linear univariates of different sizes + Univariate univariate_1({ 1, 2, 3 }); + Univariate univariate_2({ 2, 4 }); + Univariate univariate_3({ 3, 4, 5, 6, 7 }); + const size_t MAX_LENGTH = 5; + + // Instantiate some barycentric extension utility classes + auto barycentric_util_1 = BarycentricData(); + auto barycentric_util_2 = BarycentricData(); + auto barycentric_util_3 = BarycentricData(); + + // Construct a tuple of tuples of the form { {univariate_1}, {univariate_2, univariate_3} } + auto tuple_of_tuples = std::make_tuple(std::make_tuple(univariate_1), std::make_tuple(univariate_2, univariate_3)); + + // Use scale_univariate_accumulators to scale by challenge powers + FF challenge = 5; + FF running_challenge = 1; + SumcheckRound::scale_univariates(tuple_of_tuples, challenge, running_challenge); + + // Use extend_and_batch_univariates to extend to MAX_LENGTH then accumulate + auto result = Univariate(); + SumcheckRound::extend_and_batch_univariates(tuple_of_tuples, result); + + // Repeat the batching process manually + auto result_expected = barycentric_util_1.extend(univariate_1) * 1 + + barycentric_util_2.extend(univariate_2) * challenge + + barycentric_util_3.extend(univariate_3) * challenge * challenge; + + // Compare final batched univarites + EXPECT_EQ(result, result_expected); + + // Reinitialize univariate accumulators to zero + SumcheckRound::zero_univariates(tuple_of_tuples); + + // Check that reinitialization was successful + Univariate expected_1({ 0, 0, 0 }); + Univariate expected_2({ 0, 0 }); + Univariate expected_3({ 0, 0, 0, 0, 0 }); + EXPECT_EQ(std::get<0>(std::get<0>(tuple_of_tuples)), expected_1); + EXPECT_EQ(std::get<0>(std::get<1>(tuple_of_tuples)), expected_2); + EXPECT_EQ(std::get<1>(std::get<1>(tuple_of_tuples)), expected_3); +} + +/** + * @brief Test utility functions for applying operations to tuple of std::arrays of field elements + * + */ +TEST(SumcheckRound, TuplesOfEvaluationArrays) +{ + using Flavor = proof_system::honk::flavor::Standard; + using FF = typename Flavor::FF; + + // Define two arrays of arbitrary elements + std::array evaluations_1 = { 4 }; + std::array evaluations_2 = { 6, 2 }; + + // Construct a tuple + auto tuple_of_arrays = std::make_tuple(evaluations_1, evaluations_2); + + // Use scale_and_batch_elements to scale by challenge powers + FF challenge = 5; + FF running_challenge = 1; + FF result = 0; + SumcheckRound::scale_and_batch_elements(tuple_of_arrays, challenge, running_challenge, result); + + // Repeat the batching process manually + auto result_expected = + evaluations_1[0] * 1 + evaluations_2[0] * challenge + evaluations_2[1] * challenge * challenge; + + // Compare batched result + EXPECT_EQ(result, result_expected); + + // Reinitialize univariate accumulators to zero + SumcheckRound::zero_elements(tuple_of_arrays); + + EXPECT_EQ(std::get<0>(tuple_of_arrays)[0], 0); + EXPECT_EQ(std::get<1>(tuple_of_arrays)[0], 0); + EXPECT_EQ(std::get<1>(tuple_of_arrays)[1], 0); +} + } // namespace test_sumcheck_round diff --git a/cpp/src/barretenberg/proof_system/flavor/flavor.hpp b/cpp/src/barretenberg/proof_system/flavor/flavor.hpp index d42e3c6c9a..f150a277a2 100644 --- a/cpp/src/barretenberg/proof_system/flavor/flavor.hpp +++ b/cpp/src/barretenberg/proof_system/flavor/flavor.hpp @@ -231,16 +231,53 @@ template static constexpr size_t get_max } /** - * @brief Recursive utility function to construct tuple of Univariates of length RELATION_LENGTH - * + * @brief Recursive utility function to construct tuple of tuple of Univariates + * @details This is the container for storing the univariate contributions from each identity in each relation. Each + * Relation contributes a tuple with num-identities many Univariates and there are num-relations many tuples in the + * outer tuple. */ -template static constexpr auto create_univariate_tuple() +template static constexpr auto create_relation_univariates_container() { if constexpr (Index >= std::tuple_size::value) { return std::tuple<>{}; // Return empty when reach end of the tuple } else { - using UnivariateType = sumcheck::Univariate::RELATION_LENGTH>; - return std::tuple_cat(std::tuple{}, create_univariate_tuple()); + using UnivariateTuple = typename std::tuple_element_t::RelationUnivariates; + return std::tuple_cat(std::tuple{}, + create_relation_univariates_container()); + } +} + +/** + * @brief Recursive utility function to construct tuple of arrays + * @details Container for storing value of each identity in each relation. Each Relation contributes an array of + * length num-identities. + */ +template static constexpr auto create_relation_values_container() +{ + if constexpr (Index >= std::tuple_size::value) { + return std::tuple<>{}; // Return empty when reach end of the tuple + } else { + using ValuesArray = typename std::tuple_element_t::RelationValues; + return std::tuple_cat(std::tuple{}, create_relation_values_container()); + } +} + +/** + * @brief Recursive helper function to instantiate BarycentricData to extend each Relation in a tuple + * @details Instantiate with lengths 2, 3, ... ExtendedLength + * @note The purpose of this function is simply to instantiate some BarycentricData so that the static member + * arrays are computed at compile time. It thus does not need a return value. It's awkward however to make + * void functions execute at compile time so we make it return true upon completion and wrap the call in a + * static_assert to ensure it has executed correctly. + */ +template static constexpr bool instantiate_barycentric_utils() +{ + if constexpr (Length > ExtendedLength) { // include ExtendedLength + return true; // Return true when finished + } else { + // We dont need to keep the result, we just want to ensure compile time computation of static members + [[maybe_unused]] auto barycentric_data = sumcheck::BarycentricData{}; + return instantiate_barycentric_utils(); } } From dff766b8dd222fd8dee3ae3ef387b3dd85f78f41 Mon Sep 17 00:00:00 2001 From: Charlie Lye Date: Fri, 26 May 2023 18:51:05 +0000 Subject: [PATCH 25/29] Clean up srs package. Add a global crs that the wasm can init once. --- cpp/src/barretenberg/api/uint.hpp | 14 ++ .../benchmark/pippenger_bench/main.cpp | 4 +- .../dsl/acir_format/acir_format.cpp | 4 +- .../dsl/acir_format/acir_format.hpp | 4 +- .../dsl/acir_format/ecdsa_secp256k1.test.cpp | 2 +- .../dsl/acir_proofs/acir_composer.cpp | 15 +- .../dsl/acir_proofs/acir_composer.hpp | 6 +- .../barretenberg/dsl/acir_proofs/c_bind.cpp | 22 ++- .../barretenberg/dsl/acir_proofs/c_bind.hpp | 6 +- cpp/src/barretenberg/ecc/fields/field2.hpp | 17 +++ cpp/src/barretenberg/examples/c_bind.cpp | 15 +- cpp/src/barretenberg/examples/c_bind.hpp | 5 +- .../barretenberg/examples/simple/simple.cpp | 2 +- .../barretenberg/examples/simple/simple.hpp | 2 +- .../examples/simple/simple.test.cpp | 4 +- .../standard_honk_composer_helper.cpp | 4 +- .../standard_honk_composer_helper.hpp | 15 +- .../ultra_honk_composer_helper.hpp | 6 +- .../honk/composer/standard_honk_composer.hpp | 14 +- .../honk/composer/ultra_honk_composer.hpp | 6 +- .../barretenberg/honk/flavor/flavor.test.cpp | 6 +- cpp/src/barretenberg/honk/flavor/standard.hpp | 2 +- cpp/src/barretenberg/honk/flavor/ultra.hpp | 2 +- .../barretenberg/honk/pcs/commitment_key.hpp | 10 +- .../honk/pcs/commitment_key.test.hpp | 2 +- .../honk/proof_system/composer_helper.lib.hpp | 2 +- .../honk/proof_system/prover_library.test.cpp | 11 +- .../proofs/compute_circuit_data.hpp | 4 +- .../proofs/join_split/c_bind.cpp | 13 +- .../join_split/compute_circuit_data.cpp | 2 +- .../join_split/compute_circuit_data.hpp | 2 +- .../proofs/join_split/join_split.cpp | 4 +- .../proofs/join_split/join_split.hpp | 6 +- .../proofs/join_split/join_split.test.cpp | 4 +- .../join_split/join_split_js_parity.test.cpp | 4 +- .../proofs/join_split/join_split_tx.test.cpp | 1 - .../join_split_example/proofs/verify.hpp | 2 +- .../plonk/composer/composer_base.cpp | 3 +- .../plonk/composer/composer_base.hpp | 14 +- .../composer_helper/composer_helper_lib.cpp | 3 +- .../composer_helper/composer_helper_lib.hpp | 3 +- .../standard_plonk_composer_helper.hpp | 12 +- .../turbo_plonk_composer_helper.hpp | 12 +- .../ultra_plonk_composer_helper.hpp | 6 +- .../splitting_tmp/standard_plonk_composer.hpp | 14 +- .../standard_plonk_composer.test.cpp | 2 +- .../splitting_tmp/turbo_plonk_composer.hpp | 12 +- .../turbo_plonk_composer.test.cpp | 2 +- .../splitting_tmp/ultra_plonk_composer.hpp | 6 +- .../plonk/composer/standard_composer.hpp | 11 +- .../plonk/composer/standard_composer.test.cpp | 2 +- .../plonk/composer/turbo_composer.cpp | 9 +- .../plonk/composer/turbo_composer.hpp | 3 +- .../plonk/composer/turbo_composer.test.cpp | 2 +- .../plonk/composer/ultra_composer.cpp | 9 +- .../plonk/composer/ultra_composer.hpp | 3 +- .../commitment_scheme.test.cpp | 9 +- .../plonk/proof_system/prover/prover.test.cpp | 4 +- .../proof_system/proving_key/proving_key.cpp | 4 +- .../proof_system/proving_key/proving_key.hpp | 8 +- .../proving_key/proving_key.test.cpp | 4 +- .../verification_key/verification_key.cpp | 5 +- .../verification_key/verification_key.hpp | 9 +- .../proof_system/verifier/verifier.test.cpp | 6 +- .../composer/composer_helper_lib.hpp | 3 +- .../composer/composer_helper_lib.test.cpp | 6 +- .../composer/permutation_helper.test.cpp | 4 +- .../proof_system/flavor/flavor.hpp | 12 +- cpp/src/barretenberg/srs/c_bind.cpp | 23 +++ cpp/src/barretenberg/srs/c_bind.hpp | 4 + .../srs/factories/crs_factory.hpp | 51 +++++++ .../srs/factories/file_crs_factory.cpp | 73 ++++++++++ .../srs/factories/file_crs_factory.hpp | 55 ++++++++ .../srs/factories/mem_crs_factory.cpp | 73 ++++++++++ .../srs/factories/mem_crs_factory.hpp | 27 ++++ .../srs/factories/mem_crs_factory.test.cpp | 44 ++++++ cpp/src/barretenberg/srs/global_crs.cpp | 23 +++ cpp/src/barretenberg/srs/global_crs.hpp | 9 ++ .../file_reference_string.cpp | 23 --- .../file_reference_string.hpp | 102 -------------- .../reference_string/mem_reference_string.cpp | 26 ---- .../reference_string/mem_reference_string.hpp | 32 ----- .../mem_reference_string.test.cpp | 33 ----- .../pippenger_reference_string.hpp | 52 ------- .../srs/reference_string/reference_string.hpp | 45 ------ .../commitment/pedersen/pedersen.bench.cpp | 2 +- .../stdlib/primitives/bool/bool.hpp | 8 +- .../stdlib/primitives/witness/witness.hpp | 3 +- .../verification_key/verification_key.hpp | 4 +- .../verification_key.test.cpp | 4 +- exports.json | 131 ++++------------- scripts/c_bind_files.txt | 2 +- ts/src/barretenberg_api/index.ts | 74 +++------- ts/src/crs/browser/cached_net_crs.ts | 1 + ts/src/crs/node/index.ts | 1 + ts/src/examples/simple.rawtest.ts | 7 +- ts/src/examples/simple.test.ts | 10 +- ts/src/main.ts | 48 +++++-- ts/src/serialize/serialize.ts | 2 +- ts/src/serialize/serialize.ts.bak | 132 ------------------ 100 files changed, 746 insertions(+), 824 deletions(-) create mode 100644 cpp/src/barretenberg/api/uint.hpp create mode 100644 cpp/src/barretenberg/srs/c_bind.cpp create mode 100644 cpp/src/barretenberg/srs/c_bind.hpp create mode 100644 cpp/src/barretenberg/srs/factories/crs_factory.hpp create mode 100644 cpp/src/barretenberg/srs/factories/file_crs_factory.cpp create mode 100644 cpp/src/barretenberg/srs/factories/file_crs_factory.hpp create mode 100644 cpp/src/barretenberg/srs/factories/mem_crs_factory.cpp create mode 100644 cpp/src/barretenberg/srs/factories/mem_crs_factory.hpp create mode 100644 cpp/src/barretenberg/srs/factories/mem_crs_factory.test.cpp create mode 100644 cpp/src/barretenberg/srs/global_crs.cpp create mode 100644 cpp/src/barretenberg/srs/global_crs.hpp delete mode 100644 cpp/src/barretenberg/srs/reference_string/file_reference_string.cpp delete mode 100644 cpp/src/barretenberg/srs/reference_string/file_reference_string.hpp delete mode 100644 cpp/src/barretenberg/srs/reference_string/mem_reference_string.cpp delete mode 100644 cpp/src/barretenberg/srs/reference_string/mem_reference_string.hpp delete mode 100644 cpp/src/barretenberg/srs/reference_string/mem_reference_string.test.cpp delete mode 100644 cpp/src/barretenberg/srs/reference_string/pippenger_reference_string.hpp delete mode 100644 cpp/src/barretenberg/srs/reference_string/reference_string.hpp delete mode 100644 ts/src/serialize/serialize.ts.bak diff --git a/cpp/src/barretenberg/api/uint.hpp b/cpp/src/barretenberg/api/uint.hpp new file mode 100644 index 0000000000..22f95afdcb --- /dev/null +++ b/cpp/src/barretenberg/api/uint.hpp @@ -0,0 +1,14 @@ + +namespace proof_system::plonk::stdlib { +template class uint_plookup; +} + +namespace barretenberg::api::plonk::ultra { + +class ct_witness { + + private: + proof_system::plonk::stdlib::uint_plookup* underlying +}; + +} // namespace barretenberg::api::plonk::ultra \ No newline at end of file diff --git a/cpp/src/barretenberg/benchmark/pippenger_bench/main.cpp b/cpp/src/barretenberg/benchmark/pippenger_bench/main.cpp index 40f2b15284..da6877b963 100644 --- a/cpp/src/barretenberg/benchmark/pippenger_bench/main.cpp +++ b/cpp/src/barretenberg/benchmark/pippenger_bench/main.cpp @@ -2,7 +2,7 @@ #include "barretenberg/common/assert.hpp" #include #include "barretenberg/ecc/curves/bn254/scalar_multiplication/scalar_multiplication.hpp" -#include "barretenberg/srs/reference_string/file_reference_string.hpp" +#include "barretenberg/srs/factories/file_crs_factory.hpp" #include "barretenberg/polynomials/polynomial_arithmetic.hpp" // #include @@ -41,7 +41,7 @@ constexpr size_t NUM_POINTS = 1 << 16; std::vector scalars; static barretenberg::evaluation_domain small_domain; static barretenberg::evaluation_domain large_domain; -auto reference_string = std::make_shared(NUM_POINTS, "../srs_db/ignition"); +auto reference_string = std::make_shared(NUM_POINTS, "../srs_db/ignition"); const auto init = []() { small_domain = barretenberg::evaluation_domain(NUM_POINTS); diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp index faa7dc8324..d97e4c665a 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp @@ -96,7 +96,7 @@ void create_circuit(Composer& composer, acir_format const& constraint_system) } Composer create_circuit(const acir_format& constraint_system, - std::shared_ptr const& crs_factory, + std::shared_ptr const& crs_factory, size_t size_hint) { if (constraint_system.public_inputs.size() > constraint_system.varnum) { @@ -188,7 +188,7 @@ Composer create_circuit(const acir_format& constraint_system, Composer create_circuit_with_witness(acir_format const& constraint_system, WitnessVector const& witness, - std::shared_ptr const& crs_factory) + std::shared_ptr const& crs_factory) { if (constraint_system.public_inputs.size() > constraint_system.varnum) { info("create_circuit_with_witness: too many public inputs!"); diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp index 8e296f79cc..b8dccde243 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp @@ -49,12 +49,12 @@ void read_witness(Composer& composer, std::vector const& witne void create_circuit(Composer& composer, const acir_format& constraint_system); Composer create_circuit(const acir_format& constraint_system, - std::shared_ptr const& crs_factory, + std::shared_ptr const& crs_factory, size_t size_hint = 0); Composer create_circuit_with_witness(const acir_format& constraint_system, WitnessVector const& witness, - std::shared_ptr const& crs_factory); + std::shared_ptr const& crs_factory); Composer create_circuit_with_witness(const acir_format& constraint_system, WitnessVector const& witness); diff --git a/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp b/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp index e2500a0ab0..7c63d5ba38 100644 --- a/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp @@ -136,7 +136,7 @@ TEST(ECDSASecp256k1, TestECDSACompilesForVerifier) .block_constraints = {}, .constraints = {}, }; - auto crs_factory = std::make_unique(); + auto crs_factory = std::make_unique(); auto composer = create_circuit(constraint_system, std::move(crs_factory)); } diff --git a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp index 0ef95d37ed..33b8e89389 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp @@ -4,20 +4,20 @@ #include "barretenberg/plonk/proof_system/proving_key/serialize.hpp" #include "barretenberg/dsl/acir_format/acir_format.hpp" #include "barretenberg/dsl/types.hpp" -#include "barretenberg/srs/reference_string/pippenger_reference_string.hpp" +#include "barretenberg/srs/factories/crs_factory.hpp" #include "barretenberg/plonk/proof_system/verification_key/sol_gen.hpp" -#include "barretenberg/srs/reference_string/reference_string.hpp" +#include "barretenberg/srs/factories/crs_factory.hpp" namespace acir_proofs { -AcirComposer::AcirComposer(std::shared_ptr const& crs_factory) +AcirComposer::AcirComposer(std::shared_ptr const& crs_factory) : crs_factory_(crs_factory) , composer_(0, 0, 0) {} -void AcirComposer::init_proving_key(acir_format::acir_format& constraint_system, size_t size_hint) +void AcirComposer::create_circuit(acir_format::acir_format& constraint_system, size_t size_hint) { - composer_ = create_circuit(constraint_system, crs_factory_, size_hint); + composer_ = acir_format::create_circuit(constraint_system, crs_factory_, size_hint); // We are done with the constraint system at this point, and we need the memory slab back. // constraint_system = acir_format::acir_format(); @@ -28,6 +28,11 @@ void AcirComposer::init_proving_key(acir_format::acir_format& constraint_system, total_circuit_size_ = composer_.get_total_circuit_size(); // Exact or total fed in here? circuit_subgroup_size_ = composer_.get_circuit_subgroup_size(exact_circuit_size_); +} + +void AcirComposer::init_proving_key(acir_format::acir_format& constraint_system, size_t size_hint) +{ + create_circuit(constraint_system, size_hint); proving_key_ = composer_.compute_proving_key(); } diff --git a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.hpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.hpp index d93a26802e..8e95542c1e 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.hpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.hpp @@ -9,7 +9,9 @@ namespace acir_proofs { class AcirComposer { public: - AcirComposer(std::shared_ptr const& crs_factory); + AcirComposer(std::shared_ptr const& crs_factory); + + void create_circuit(acir_format::acir_format& constraint_system, size_t size_hint = 0); void init_proving_key(acir_format::acir_format& constraint_system, size_t size_hint = 0); @@ -24,7 +26,7 @@ class AcirComposer { size_t get_total_circuit_size() { return total_circuit_size_; }; private: - std::shared_ptr crs_factory_; + std::shared_ptr crs_factory_; acir_format::Composer composer_; size_t exact_circuit_size_; size_t total_circuit_size_; diff --git a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp index 62baca99e0..81fb4adec9 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp @@ -7,14 +7,11 @@ #include "barretenberg/common/serialize.hpp" #include "barretenberg/common/slab_allocator.hpp" #include "barretenberg/dsl/acir_format/acir_format.hpp" -#include "barretenberg/srs/reference_string/pippenger_reference_string.hpp" +#include "barretenberg/srs/global_crs.hpp" -WASM_EXPORT void acir_new_acir_composer(in_ptr pippenger, uint8_t const* g2x_buf, out_ptr out) +WASM_EXPORT void acir_new_acir_composer(out_ptr out) { - auto g2x = from_buffer>(g2x_buf); - auto crs_factory = std::make_shared( - reinterpret_cast(*pippenger), g2x.data()); - *out = new acir_proofs::AcirComposer(crs_factory); + *out = new acir_proofs::AcirComposer(barretenberg::srs::get_crs_factory()); } WASM_EXPORT void acir_delete_acir_composer(in_ptr acir_composer_ptr) @@ -22,6 +19,19 @@ WASM_EXPORT void acir_delete_acir_composer(in_ptr acir_composer_ptr) delete reinterpret_cast(*acir_composer_ptr); } +WASM_EXPORT void acir_create_circuit(in_ptr acir_composer_ptr, + uint8_t const* constraint_system_buf, + uint32_t const* size_hint) +{ + auto acir_composer = reinterpret_cast(*acir_composer_ptr); + auto constraint_system = from_buffer(constraint_system_buf); + + // The binder would normally free the the constraint_system_buf, but we need the memory now. + free_mem_slab_raw((void*)constraint_system_buf); + + acir_composer->create_circuit(constraint_system, ntohl(*size_hint)); +} + WASM_EXPORT void acir_init_proving_key(in_ptr acir_composer_ptr, uint8_t const* constraint_system_buf, uint32_t const* size_hint) diff --git a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp index dc7efbdf3d..f0c1a5dd93 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp @@ -4,10 +4,14 @@ #include #include -WASM_EXPORT void acir_new_acir_composer(in_ptr pippenger, uint8_t const* g2x, out_ptr out); +WASM_EXPORT void acir_new_acir_composer(out_ptr out); WASM_EXPORT void acir_delete_acir_composer(in_ptr acir_composer_ptr); +WASM_EXPORT void acir_create_circuit(in_ptr acir_composer_ptr, + uint8_t const* constraint_system_buf, + uint32_t const* size_hint); + WASM_EXPORT void acir_init_proving_key(in_ptr acir_composer_ptr, uint8_t const* constraint_system_buf, uint32_t const* size_hint); diff --git a/cpp/src/barretenberg/ecc/fields/field2.hpp b/cpp/src/barretenberg/ecc/fields/field2.hpp index 630b25c1b4..5bb03c3690 100644 --- a/cpp/src/barretenberg/ecc/fields/field2.hpp +++ b/cpp/src/barretenberg/ecc/fields/field2.hpp @@ -126,6 +126,23 @@ template struct alignas(32) field2 { } }; +// Not working as expected. At least r.e. g2. +// template void read(B& it, field2& value) +// { +// using serialize::read; +// field2 result; +// read(it, result.c0); +// read(it, result.c1); +// value = result.to_montgomery_form(); +// } +// template void write(B& buf, field2 const& value) +// { +// using serialize::write; +// const auto input = value.from_montgomery_form(); +// write(buf, input.c0); +// write(buf, input.c1); +// } + } // namespace barretenberg #include "field2_impl.hpp" diff --git a/cpp/src/barretenberg/examples/c_bind.cpp b/cpp/src/barretenberg/examples/c_bind.cpp index eae7bedaac..cdc25c6b77 100644 --- a/cpp/src/barretenberg/examples/c_bind.cpp +++ b/cpp/src/barretenberg/examples/c_bind.cpp @@ -1,22 +1,13 @@ #include "c_bind.hpp" #include "simple/simple.hpp" -#include "barretenberg/srs/reference_string/pippenger_reference_string.hpp" - -extern "C" { +#include "barretenberg/srs/global_crs.hpp" using namespace proof_system::plonk::stdlib::types; -WASM_EXPORT void examples_simple_create_and_verify_proof(in_ptr pippenger, uint8_t const* g2x_buf, bool* valid) +WASM_EXPORT void examples_simple_create_and_verify_proof(bool* valid) { - auto g2x = from_buffer>(g2x_buf); - auto crs_factory = std::make_shared( - (scalar_multiplication::Pippenger*)(*pippenger), g2x.data()); - - auto* composer_ptr = examples::simple::create_composer(crs_factory); - + auto* composer_ptr = examples::simple::create_composer(barretenberg::srs::get_crs_factory()); auto proof = examples::simple::create_proof(composer_ptr); - *valid = examples::simple::verify_proof(composer_ptr, proof); examples::simple::delete_composer(composer_ptr); } -} diff --git a/cpp/src/barretenberg/examples/c_bind.hpp b/cpp/src/barretenberg/examples/c_bind.hpp index bf682c0f8e..37c6c6768b 100644 --- a/cpp/src/barretenberg/examples/c_bind.hpp +++ b/cpp/src/barretenberg/examples/c_bind.hpp @@ -2,7 +2,4 @@ #include #include "barretenberg/common/wasm_export.hpp" -extern "C" { - -WASM_EXPORT void examples_simple_create_and_verify_proof(in_ptr pippenger, uint8_t const* g2x, bool* valid); -} +WASM_EXPORT void examples_simple_create_and_verify_proof(bool* valid); diff --git a/cpp/src/barretenberg/examples/simple/simple.cpp b/cpp/src/barretenberg/examples/simple/simple.cpp index a331574a76..dc7cb6b33a 100644 --- a/cpp/src/barretenberg/examples/simple/simple.cpp +++ b/cpp/src/barretenberg/examples/simple/simple.cpp @@ -19,7 +19,7 @@ void build_circuit(Composer& composer) } } -Composer* create_composer(std::shared_ptr const& crs_factory) +Composer* create_composer(std::shared_ptr const& crs_factory) { // WARNING: Size hint is essential to perform 512k circuits! auto composer = std::make_unique(crs_factory, CIRCUIT_SIZE); diff --git a/cpp/src/barretenberg/examples/simple/simple.hpp b/cpp/src/barretenberg/examples/simple/simple.hpp index c9af42a966..a3695899f8 100644 --- a/cpp/src/barretenberg/examples/simple/simple.hpp +++ b/cpp/src/barretenberg/examples/simple/simple.hpp @@ -7,7 +7,7 @@ namespace examples::simple { using namespace proof_system::plonk; using namespace stdlib::types; -Composer* create_composer(std::shared_ptr const& crs_factory); +Composer* create_composer(std::shared_ptr const& crs_factory); proof create_proof(Composer* composer); diff --git a/cpp/src/barretenberg/examples/simple/simple.test.cpp b/cpp/src/barretenberg/examples/simple/simple.test.cpp index 2f6f2f5ba3..95fb679b2e 100644 --- a/cpp/src/barretenberg/examples/simple/simple.test.cpp +++ b/cpp/src/barretenberg/examples/simple/simple.test.cpp @@ -1,5 +1,5 @@ #include "simple.hpp" -#include +#include #include #include @@ -8,7 +8,7 @@ namespace examples::simple { TEST(examples_simple, create_proof) { auto srs_path = std::filesystem::absolute("../srs_db/ignition"); - auto crs_factory = std::make_shared(srs_path); + auto crs_factory = std::make_shared(srs_path); auto* composer = create_composer(crs_factory); auto proof = create_proof(composer); bool valid = verify_proof(composer, proof); diff --git a/cpp/src/barretenberg/honk/composer/composer_helper/standard_honk_composer_helper.cpp b/cpp/src/barretenberg/honk/composer/composer_helper/standard_honk_composer_helper.cpp index 1b8568779b..bbf96fadfb 100644 --- a/cpp/src/barretenberg/honk/composer/composer_helper/standard_honk_composer_helper.cpp +++ b/cpp/src/barretenberg/honk/composer/composer_helper/standard_honk_composer_helper.cpp @@ -3,7 +3,7 @@ #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/honk/pcs/commitment_key.hpp" #include "barretenberg/numeric/bitop/get_msb.hpp" -#include "barretenberg/srs/reference_string/reference_string.hpp" +#include "barretenberg/srs/factories/crs_factory.hpp" #include #include @@ -44,7 +44,7 @@ std::shared_ptr StandardHonkComposerHelp std::shared_ptr StandardHonkComposerHelper::compute_verification_key_base( std::shared_ptr const& proving_key, - std::shared_ptr const& vrs) + std::shared_ptr const& vrs) { auto key = std::make_shared( proving_key->circuit_size, proving_key->num_public_inputs, vrs, proving_key->composer_type); diff --git a/cpp/src/barretenberg/honk/composer/composer_helper/standard_honk_composer_helper.hpp b/cpp/src/barretenberg/honk/composer/composer_helper/standard_honk_composer_helper.hpp index 031ebb8115..42fdf9fe29 100644 --- a/cpp/src/barretenberg/honk/composer/composer_helper/standard_honk_composer_helper.hpp +++ b/cpp/src/barretenberg/honk/composer/composer_helper/standard_honk_composer_helper.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include "barretenberg/srs/reference_string/file_reference_string.hpp" +#include "barretenberg/srs/factories/file_crs_factory.hpp" #include "barretenberg/honk/proof_system/prover.hpp" #include "barretenberg/honk/proof_system/verifier.hpp" #include "barretenberg/proof_system/circuit_constructors/standard_circuit_constructor.hpp" @@ -25,18 +25,18 @@ class StandardHonkComposerHelper { std::shared_ptr verification_key; // TODO(#218)(kesha): we need to put this into the commitment key, so that the composer doesn't have to handle srs // at all - std::shared_ptr crs_factory_; + std::shared_ptr crs_factory_; bool computed_witness = false; // TODO(Luke): use make_shared StandardHonkComposerHelper() - : StandardHonkComposerHelper(std::shared_ptr( - new proof_system::FileReferenceStringFactory("../srs_db/ignition"))) + : StandardHonkComposerHelper(std::shared_ptr( + new barretenberg::srs::factories::FileCrsFactory("../srs_db/ignition"))) {} - StandardHonkComposerHelper(std::shared_ptr crs_factory) + StandardHonkComposerHelper(std::shared_ptr crs_factory) : crs_factory_(std::move(crs_factory)) {} - StandardHonkComposerHelper(std::unique_ptr&& crs_factory) + StandardHonkComposerHelper(std::unique_ptr&& crs_factory) : crs_factory_(std::move(crs_factory)) {} StandardHonkComposerHelper(std::shared_ptr p_key, std::shared_ptr v_key) @@ -63,7 +63,8 @@ class StandardHonkComposerHelper { // This needs to be static as it may be used only to compute the selector commitments. static std::shared_ptr compute_verification_key_base( - std::shared_ptr const& proving_key, std::shared_ptr const& vrs); + std::shared_ptr const& proving_key, + std::shared_ptr const& vrs); void compute_witness(const CircuitConstructor& circuit_constructor, const size_t minimum_circuit_size = 0); }; diff --git a/cpp/src/barretenberg/honk/composer/composer_helper/ultra_honk_composer_helper.hpp b/cpp/src/barretenberg/honk/composer/composer_helper/ultra_honk_composer_helper.hpp index cf14fea6f0..0e607184f1 100644 --- a/cpp/src/barretenberg/honk/composer/composer_helper/ultra_honk_composer_helper.hpp +++ b/cpp/src/barretenberg/honk/composer/composer_helper/ultra_honk_composer_helper.hpp @@ -2,7 +2,7 @@ #include "barretenberg/proof_system/composer/composer_helper_lib.hpp" #include "barretenberg/plonk/composer/splitting_tmp/composer_helper/composer_helper_lib.hpp" -#include "barretenberg/srs/reference_string/file_reference_string.hpp" +#include "barretenberg/srs/factories/file_crs_factory.hpp" #include "barretenberg/plonk/proof_system/proving_key/proving_key.hpp" #include "barretenberg/honk/proof_system/ultra_prover.hpp" #include "barretenberg/honk/proof_system/ultra_verifier.hpp" @@ -31,7 +31,7 @@ class UltraHonkComposerHelper { std::shared_ptr verification_key; // TODO(#218)(kesha): we need to put this into the commitment key, so that the composer doesn't have to handle srs // at all - std::shared_ptr crs_factory_; + std::shared_ptr crs_factory_; std::vector recursive_proof_public_input_indices; bool contains_recursive_proof = false; @@ -43,7 +43,7 @@ class UltraHonkComposerHelper { // vanishing_polynomial cannot be trivially fetched here, I am directly setting this to 4 - 1 = 3. static constexpr size_t s_randomness = 3; - explicit UltraHonkComposerHelper(std::shared_ptr crs_factory) + explicit UltraHonkComposerHelper(std::shared_ptr crs_factory) : crs_factory_(std::move(crs_factory)) {} diff --git a/cpp/src/barretenberg/honk/composer/standard_honk_composer.hpp b/cpp/src/barretenberg/honk/composer/standard_honk_composer.hpp index ea60cb6a2a..2fe53791ee 100644 --- a/cpp/src/barretenberg/honk/composer/standard_honk_composer.hpp +++ b/cpp/src/barretenberg/honk/composer/standard_honk_composer.hpp @@ -2,7 +2,7 @@ #include "composer_helper/standard_honk_composer_helper.hpp" #include "barretenberg/proof_system/circuit_constructors/standard_circuit_constructor.hpp" -#include "barretenberg/srs/reference_string/file_reference_string.hpp" +#include "barretenberg/srs/factories/file_crs_factory.hpp" #include "barretenberg/proof_system/types/merkle_hash_type.hpp" #include "barretenberg/proof_system/types/pedersen_commitment_type.hpp" @@ -46,18 +46,20 @@ class StandardHonkComposer { , variables(circuit_constructor.variables){}; StandardHonkComposer(std::string const& crs_path, const size_t size_hint = 0) - : StandardHonkComposer( - std::unique_ptr(new proof_system::FileReferenceStringFactory(crs_path)), - size_hint){}; + : StandardHonkComposer(std::unique_ptr( + new barretenberg::srs::factories::FileCrsFactory(crs_path)), + size_hint){}; - StandardHonkComposer(std::shared_ptr const& crs_factory, const size_t size_hint = 0) + StandardHonkComposer(std::shared_ptr const& crs_factory, + const size_t size_hint = 0) : circuit_constructor(size_hint) , composer_helper(crs_factory) , num_gates(circuit_constructor.num_gates) , variables(circuit_constructor.variables) {} - StandardHonkComposer(std::unique_ptr&& crs_factory, const size_t size_hint = 0) + StandardHonkComposer(std::unique_ptr&& crs_factory, + const size_t size_hint = 0) : circuit_constructor(size_hint) , composer_helper(std::move(crs_factory)) , num_gates(circuit_constructor.num_gates) diff --git a/cpp/src/barretenberg/honk/composer/ultra_honk_composer.hpp b/cpp/src/barretenberg/honk/composer/ultra_honk_composer.hpp index 1073ec7825..c85e57432c 100644 --- a/cpp/src/barretenberg/honk/composer/ultra_honk_composer.hpp +++ b/cpp/src/barretenberg/honk/composer/ultra_honk_composer.hpp @@ -28,10 +28,12 @@ class UltraHonkComposer { : UltraHonkComposer("../srs_db/ignition", 0){}; UltraHonkComposer(std::string const& crs_path, const size_t size_hint) - : UltraHonkComposer(std::unique_ptr(new FileReferenceStringFactory(crs_path)), + : UltraHonkComposer(std::unique_ptr( + new barretenberg::srs::factories::FileCrsFactory(crs_path)), size_hint){}; - UltraHonkComposer(std::shared_ptr const& crs_factory, const size_t size_hint) + UltraHonkComposer(std::shared_ptr const& crs_factory, + const size_t size_hint) : circuit_constructor(size_hint) , composer_helper(crs_factory) , num_gates(circuit_constructor.num_gates){}; diff --git a/cpp/src/barretenberg/honk/flavor/flavor.test.cpp b/cpp/src/barretenberg/honk/flavor/flavor.test.cpp index e820310f7e..d3c44be8bc 100644 --- a/cpp/src/barretenberg/honk/flavor/flavor.test.cpp +++ b/cpp/src/barretenberg/honk/flavor/flavor.test.cpp @@ -1,6 +1,6 @@ #include "barretenberg/honk/flavor/standard.hpp" #include "barretenberg/polynomials/polynomial.hpp" -#include "barretenberg/srs/reference_string/reference_string.hpp" +#include "barretenberg/srs/factories/crs_factory.hpp" #include #include @@ -15,7 +15,7 @@ TEST(Flavor, StandardGetters) using ProvingKey = typename Flavor::ProvingKey; ProvingKey proving_key = []() { - auto crs_factory = ReferenceStringFactory(); + auto crs_factory = barretenberg::srs::factories::CrsFactory(); auto crs = crs_factory.get_prover_crs(4); return Flavor::ProvingKey(/*circuit_size=*/4, /*num_public_inputs=*/0, crs, ComposerType::STANDARD); }(); @@ -121,7 +121,7 @@ TEST(Flavor, AllEntitiesSpecialMemberFunctions) using Flavor = proof_system::honk::flavor::Standard; using FF = Flavor::FF; using PartiallyEvaluatedMultivariates = Flavor::PartiallyEvaluatedMultivariates; - using Polynomial = Polynomial; + using Polynomial = barretenberg::Polynomial; PartiallyEvaluatedMultivariates polynomials_A; auto random_poly = Polynomial(10); diff --git a/cpp/src/barretenberg/honk/flavor/standard.hpp b/cpp/src/barretenberg/honk/flavor/standard.hpp index 1557fb8814..d3526c4526 100644 --- a/cpp/src/barretenberg/honk/flavor/standard.hpp +++ b/cpp/src/barretenberg/honk/flavor/standard.hpp @@ -17,7 +17,7 @@ #include "barretenberg/polynomials/evaluation_domain.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/proof_system/circuit_constructors/standard_circuit_constructor.hpp" -#include "barretenberg/srs/reference_string/reference_string.hpp" +#include "barretenberg/srs/factories/crs_factory.hpp" #include "barretenberg/proof_system/flavor/flavor.hpp" namespace proof_system::honk::flavor { diff --git a/cpp/src/barretenberg/honk/flavor/ultra.hpp b/cpp/src/barretenberg/honk/flavor/ultra.hpp index a3d016bd60..df0c9e6603 100644 --- a/cpp/src/barretenberg/honk/flavor/ultra.hpp +++ b/cpp/src/barretenberg/honk/flavor/ultra.hpp @@ -14,7 +14,7 @@ #include "barretenberg/polynomials/evaluation_domain.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/proof_system/circuit_constructors/ultra_circuit_constructor.hpp" -#include "barretenberg/srs/reference_string/reference_string.hpp" +#include "barretenberg/srs/factories/crs_factory.hpp" #include "barretenberg/proof_system/flavor/flavor.hpp" #include "barretenberg/honk/sumcheck/relations/ultra_arithmetic_relation.hpp" #include "barretenberg/honk/sumcheck/relations/ultra_arithmetic_relation_secondary.hpp" diff --git a/cpp/src/barretenberg/honk/pcs/commitment_key.hpp b/cpp/src/barretenberg/honk/pcs/commitment_key.hpp index 5d4e32c80d..3db3cbf6e0 100644 --- a/cpp/src/barretenberg/honk/pcs/commitment_key.hpp +++ b/cpp/src/barretenberg/honk/pcs/commitment_key.hpp @@ -7,7 +7,7 @@ #include "barretenberg/polynomials/polynomial_arithmetic.hpp" #include "barretenberg/polynomials/polynomial.hpp" -#include "barretenberg/srs/reference_string/file_reference_string.hpp" +#include "barretenberg/srs/factories/file_crs_factory.hpp" #include "barretenberg/ecc/curves/bn254/scalar_multiplication/scalar_multiplication.hpp" #include "barretenberg/ecc/curves/bn254/pairing.hpp" #include "barretenberg/numeric/bitop/pow.hpp" @@ -67,7 +67,7 @@ class CommitmentKey { private: barretenberg::scalar_multiplication::pippenger_runtime_state pippenger_runtime_state; - proof_system::FileReferenceString srs; + barretenberg::srs::factories::FileProverCrs srs; }; class VerificationKey { @@ -109,7 +109,7 @@ class VerificationKey { } private: - proof_system::VerifierFileReferenceString verifier_srs; + barretenberg::srs::factories::FileVerifierCrs verifier_srs; }; struct Params { @@ -244,7 +244,7 @@ class CommitmentKey { }; barretenberg::scalar_multiplication::pippenger_runtime_state pippenger_runtime_state; - proof_system::FileReferenceString srs; + barretenberg::srs::factories::FileProverCrs srs; }; class VerificationKey { @@ -269,7 +269,7 @@ class VerificationKey { {} barretenberg::scalar_multiplication::pippenger_runtime_state pippenger_runtime_state; - proof_system::FileReferenceString srs; + barretenberg::srs::factories::FileProverCrs srs; }; struct Params { diff --git a/cpp/src/barretenberg/honk/pcs/commitment_key.test.hpp b/cpp/src/barretenberg/honk/pcs/commitment_key.test.hpp index 991bc98386..dabfbf95aa 100644 --- a/cpp/src/barretenberg/honk/pcs/commitment_key.test.hpp +++ b/cpp/src/barretenberg/honk/pcs/commitment_key.test.hpp @@ -9,7 +9,7 @@ #include #include "barretenberg/polynomials/polynomial.hpp" -#include "barretenberg/srs/reference_string/file_reference_string.hpp" +#include "barretenberg/srs/factories/file_crs_factory.hpp" #include "barretenberg/ecc/curves/bn254/g1.hpp" #include "../oracle/oracle.hpp" diff --git a/cpp/src/barretenberg/honk/proof_system/composer_helper.lib.hpp b/cpp/src/barretenberg/honk/proof_system/composer_helper.lib.hpp index 24c89a3a06..d780f9f90d 100644 --- a/cpp/src/barretenberg/honk/proof_system/composer_helper.lib.hpp +++ b/cpp/src/barretenberg/honk/proof_system/composer_helper.lib.hpp @@ -18,7 +18,7 @@ namespace proof_system::honk { template std::shared_ptr compute_verification_key_common( std::shared_ptr const& proving_key, - std::shared_ptr const& vrs) + std::shared_ptr const& vrs) { auto verification_key = std::make_shared( proving_key->circuit_size, proving_key->num_public_inputs, vrs, proving_key->composer_type); diff --git a/cpp/src/barretenberg/honk/proof_system/prover_library.test.cpp b/cpp/src/barretenberg/honk/proof_system/prover_library.test.cpp index 74295a3255..88c9199622 100644 --- a/cpp/src/barretenberg/honk/proof_system/prover_library.test.cpp +++ b/cpp/src/barretenberg/honk/proof_system/prover_library.test.cpp @@ -5,7 +5,7 @@ #include "prover_library.hpp" #include "barretenberg/polynomials/polynomial.hpp" -#include "barretenberg/srs/reference_string/file_reference_string.hpp" +#include "barretenberg/srs/factories/file_crs_factory.hpp" #include #include #include @@ -56,7 +56,8 @@ template class ProverLibraryTests : public testing::Test { // Define some mock inputs for proving key constructor static const size_t num_gates = 8; static const size_t num_public_inputs = 0; - auto reference_string = std::make_shared(num_gates + 1, "../srs_db/ignition"); + auto reference_string = + std::make_shared(num_gates + 1, "../srs_db/ignition"); // Instatiate a proving_key and make a pointer to it. This will be used to instantiate a Prover. auto proving_key = std::make_shared( @@ -169,7 +170,8 @@ template class ProverLibraryTests : public testing::Test { // Define some mock inputs for proving key constructor static const size_t circuit_size = 8; static const size_t num_public_inputs = 0; - auto reference_string = std::make_shared(circuit_size + 1, "../srs_db/ignition"); + auto reference_string = + std::make_shared(circuit_size + 1, "../srs_db/ignition"); // Instatiate a proving_key and make a pointer to it. This will be used to instantiate a Prover. using Flavor = honk::flavor::Ultra; @@ -305,7 +307,8 @@ template class ProverLibraryTests : public testing::Test { // Construct a proving_key static const size_t circuit_size = 8; static const size_t num_public_inputs = 0; - auto reference_string = std::make_shared(circuit_size + 1, "../srs_db/ignition"); + auto reference_string = + std::make_shared(circuit_size + 1, "../srs_db/ignition"); using Flavor = honk::flavor::Ultra; auto proving_key = std::make_shared( circuit_size, num_public_inputs, reference_string, ComposerType::STANDARD_HONK); diff --git a/cpp/src/barretenberg/join_split_example/proofs/compute_circuit_data.hpp b/cpp/src/barretenberg/join_split_example/proofs/compute_circuit_data.hpp index a79d11c4de..2a55efb057 100644 --- a/cpp/src/barretenberg/join_split_example/proofs/compute_circuit_data.hpp +++ b/cpp/src/barretenberg/join_split_example/proofs/compute_circuit_data.hpp @@ -19,7 +19,7 @@ struct circuit_data { : num_gates(0) {} - std::shared_ptr srs; + std::shared_ptr srs; std::shared_ptr proving_key; std::shared_ptr verification_key; size_t num_gates; @@ -38,7 +38,7 @@ inline bool exists(std::string const& path) template circuit_data get_circuit_data(std::string const& name, std::string const& path_name, - std::shared_ptr const& srs, + std::shared_ptr const& srs, std::string const& key_path, bool compute, bool save, diff --git a/cpp/src/barretenberg/join_split_example/proofs/join_split/c_bind.cpp b/cpp/src/barretenberg/join_split_example/proofs/join_split/c_bind.cpp index 6be88c9280..49cb0e319c 100644 --- a/cpp/src/barretenberg/join_split_example/proofs/join_split/c_bind.cpp +++ b/cpp/src/barretenberg/join_split_example/proofs/join_split/c_bind.cpp @@ -9,7 +9,7 @@ #include "barretenberg/common/mem.hpp" #include "barretenberg/common/container.hpp" #include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp" -#include "barretenberg/srs/reference_string/pippenger_reference_string.hpp" +#include "barretenberg/srs/global_crs.hpp" #include "barretenberg/plonk/proof_system/proving_key/serialize.hpp" #include "barretenberg/join_split_example/types.hpp" @@ -22,15 +22,12 @@ extern "C" { WASM_EXPORT void join_split__init_proving_key(bool mock) { - // We know that we don't actually need any CRS to create a proving key, so just feed in a nothing. - // Hacky, but, right now it needs *something*. - auto crs_factory = std::make_shared(); - init_proving_key(crs_factory, mock); + init_proving_key(barretenberg::srs::get_crs_factory(), mock); } // WASM_EXPORT void join_split__init_proving_key_from_buffer(uint8_t const* pk_buf) // { -// std::shared_ptr crs; +// std::shared_ptr crs; // plonk::proving_key_data pk_data; // read(pk_buf, pk_data); // init_proving_key(crs, std::move(pk_data)); @@ -58,9 +55,7 @@ WASM_EXPORT uint32_t join_split__get_new_proving_key_data(uint8_t** output) WASM_EXPORT void join_split__init_verification_key(void* pippenger, uint8_t const* g2x) { - auto crs_factory = std::make_unique( - reinterpret_cast(pippenger), g2x); - init_verification_key(std::move(crs_factory)); + init_verification_key(barretenberg::srs::get_crs_factory()); } // WASM_EXPORT void join_split__init_verification_key_from_buffer(uint8_t const* vk_buf, uint8_t const* g2x) diff --git a/cpp/src/barretenberg/join_split_example/proofs/join_split/compute_circuit_data.cpp b/cpp/src/barretenberg/join_split_example/proofs/join_split/compute_circuit_data.cpp index 037799660b..402ac96af5 100644 --- a/cpp/src/barretenberg/join_split_example/proofs/join_split/compute_circuit_data.cpp +++ b/cpp/src/barretenberg/join_split_example/proofs/join_split/compute_circuit_data.cpp @@ -59,7 +59,7 @@ join_split_tx noop_tx() return tx; } -circuit_data get_circuit_data(std::shared_ptr const& srs, bool mock) +circuit_data get_circuit_data(std::shared_ptr const& srs, bool mock) { std::cerr << "Getting join-split circuit data..." << std::endl; diff --git a/cpp/src/barretenberg/join_split_example/proofs/join_split/compute_circuit_data.hpp b/cpp/src/barretenberg/join_split_example/proofs/join_split/compute_circuit_data.hpp index 6c01a5b144..05c7aa46d3 100644 --- a/cpp/src/barretenberg/join_split_example/proofs/join_split/compute_circuit_data.hpp +++ b/cpp/src/barretenberg/join_split_example/proofs/join_split/compute_circuit_data.hpp @@ -10,7 +10,7 @@ join_split_tx noop_tx(); using circuit_data = proofs::circuit_data; -circuit_data get_circuit_data(std::shared_ptr const& srs, bool mock = false); +circuit_data get_circuit_data(std::shared_ptr const& srs, bool mock = false); } // namespace join_split } // namespace proofs diff --git a/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.cpp b/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.cpp index 056f8df2fc..b561ba5429 100644 --- a/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.cpp +++ b/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.cpp @@ -14,7 +14,7 @@ using namespace proof_system::plonk::stdlib::merkle_tree; static std::shared_ptr proving_key; static std::shared_ptr verification_key; -void init_proving_key(std::shared_ptr const& crs_factory, bool mock) +void init_proving_key(std::shared_ptr const& crs_factory, bool mock) { if (proving_key) { return; @@ -41,7 +41,7 @@ void release_proving_key() proving_key.reset(); } -void init_verification_key(std::unique_ptr&& crs_factory) +void init_verification_key(std::shared_ptr const& crs_factory) { if (!proving_key) { std::abort(); diff --git a/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.hpp b/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.hpp index db529a7826..f836684aba 100644 --- a/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.hpp +++ b/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.hpp @@ -1,17 +1,17 @@ #pragma once #include "join_split_tx.hpp" -#include "barretenberg/srs/reference_string/mem_reference_string.hpp" +#include "barretenberg/srs/factories/crs_factory.hpp" #include "barretenberg/join_split_example/types.hpp" namespace join_split_example { namespace proofs { namespace join_split { -void init_proving_key(std::shared_ptr const& crs_factory, bool mock); +void init_proving_key(std::shared_ptr const& crs_factory, bool mock); void release_proving_key(); -void init_verification_key(std::unique_ptr&& crs_factory); +void init_verification_key(std::shared_ptr const& crs_factory); Prover new_join_split_prover(join_split_tx const& tx, bool mock); diff --git a/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.test.cpp b/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.test.cpp index 440b4a7af4..064b48fdf7 100644 --- a/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.test.cpp +++ b/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.test.cpp @@ -143,9 +143,9 @@ class join_split_tests : public ::testing::Test { static constexpr size_t ACCOUNT_INDEX = 14; static void SetUpTestCase() { - auto null_crs_factory = std::make_shared(); + auto null_crs_factory = std::make_shared(); init_proving_key(null_crs_factory, false); - auto crs_factory = std::make_unique("../srs_db/ignition"); + auto crs_factory = std::make_unique("../srs_db/ignition"); init_verification_key(std::move(crs_factory)); info("vk hash: ", get_verification_key()->sha256_hash()); } diff --git a/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_js_parity.test.cpp b/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_js_parity.test.cpp index 0294983f7c..4544bf1a27 100644 --- a/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_js_parity.test.cpp +++ b/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_js_parity.test.cpp @@ -25,9 +25,9 @@ class join_split_js_parity_tests : public ::testing::Test { protected: static void SetUpTestCase() { - auto null_crs_factory = std::make_shared(); + auto null_crs_factory = std::make_shared(); init_proving_key(null_crs_factory, false); - auto crs_factory = std::make_unique("../srs_db/ignition"); + auto crs_factory = std::make_unique("../srs_db/ignition"); init_verification_key(std::move(crs_factory)); info("vk hash: ", get_verification_key()->sha256_hash()); } diff --git a/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_tx.test.cpp b/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_tx.test.cpp index 60a83dcafd..a671dc164b 100644 --- a/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_tx.test.cpp +++ b/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_tx.test.cpp @@ -5,7 +5,6 @@ #include "barretenberg/common/streams.hpp" #include "barretenberg/crypto/schnorr/schnorr.hpp" #include "barretenberg/numeric/random/engine.hpp" -#include "barretenberg/srs/reference_string/pippenger_reference_string.hpp" #include "barretenberg/srs/io.hpp" #include diff --git a/cpp/src/barretenberg/join_split_example/proofs/verify.hpp b/cpp/src/barretenberg/join_split_example/proofs/verify.hpp index e87a3e0bee..4543522014 100644 --- a/cpp/src/barretenberg/join_split_example/proofs/verify.hpp +++ b/cpp/src/barretenberg/join_split_example/proofs/verify.hpp @@ -27,7 +27,7 @@ template struct verify_result { template inline bool pairing_check(plonk::stdlib::recursion::aggregation_state> aggregation_state, - std::shared_ptr const& srs) + std::shared_ptr const& srs) { g1::affine_element P[2]; P[0].x = barretenberg::fq(aggregation_state.P0.x.get_value().lo); diff --git a/cpp/src/barretenberg/plonk/composer/composer_base.cpp b/cpp/src/barretenberg/plonk/composer/composer_base.cpp index b4fdb7b130..71fccb746f 100644 --- a/cpp/src/barretenberg/plonk/composer/composer_base.cpp +++ b/cpp/src/barretenberg/plonk/composer/composer_base.cpp @@ -314,7 +314,8 @@ std::shared_ptr ComposerBase::compute_proving_key_base(const Compos * (2) sets the polynomial manifest using the data from proving key. */ std::shared_ptr ComposerBase::compute_verification_key_base( - std::shared_ptr const& proving_key, std::shared_ptr const& vrs) + std::shared_ptr const& proving_key, + std::shared_ptr const& vrs) { auto circuit_verification_key = std::make_shared( proving_key->circuit_size, proving_key->num_public_inputs, vrs, proving_key->composer_type); diff --git a/cpp/src/barretenberg/plonk/composer/composer_base.hpp b/cpp/src/barretenberg/plonk/composer/composer_base.hpp index ceed749b44..ccbbca2c31 100644 --- a/cpp/src/barretenberg/plonk/composer/composer_base.hpp +++ b/cpp/src/barretenberg/plonk/composer/composer_base.hpp @@ -5,7 +5,7 @@ #include "barretenberg/plonk/proof_system/prover/prover.hpp" #include "barretenberg/plonk/proof_system/verifier/verifier.hpp" #include "barretenberg/plonk/proof_system/types/prover_settings.hpp" -#include "barretenberg/srs/reference_string/file_reference_string.hpp" +#include "barretenberg/srs/factories/file_crs_factory.hpp" namespace proof_system::plonk { static constexpr uint32_t DUMMY_TAG = 0; @@ -52,9 +52,10 @@ class ComposerBase { }; ComposerBase() - : ComposerBase(std::shared_ptr(new FileReferenceStringFactory("../srs_db/ignition"))) + : ComposerBase(std::shared_ptr( + new barretenberg::srs::factories::FileCrsFactory("../srs_db/ignition"))) {} - ComposerBase(std::shared_ptr const& crs_factory, + ComposerBase(std::shared_ptr const& crs_factory, size_t num_selectors = 0, size_t size_hint = 0, std::vector selector_properties = {}) @@ -74,7 +75,7 @@ class ComposerBase { size_t size_hint = 0, std::vector selector_properties = {}) : num_gates(0) - , crs_factory_(std::make_unique("../srs_db/ignition")) + , crs_factory_(std::make_unique("../srs_db/ignition")) , num_selectors(num_selectors) , selectors(num_selectors) , selector_properties(selector_properties) @@ -116,7 +117,8 @@ class ComposerBase { const size_t num_reserved_gates = NUM_RESERVED_GATES); // This needs to be static as it may be used only to compute the selector commitments. static std::shared_ptr compute_verification_key_base( - std::shared_ptr const& proving_key, std::shared_ptr const& vrs); + std::shared_ptr const& proving_key, + std::shared_ptr const& vrs); virtual std::shared_ptr compute_proving_key() = 0; virtual std::shared_ptr compute_verification_key() = 0; virtual void compute_witness() = 0; @@ -317,7 +319,7 @@ class ComposerBase { bool computed_witness = false; - std::shared_ptr crs_factory_; + std::shared_ptr crs_factory_; size_t num_selectors; std::vector>> selectors; /** diff --git a/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/composer_helper_lib.cpp b/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/composer_helper_lib.cpp index 54b11e71db..f97e9cf2c0 100644 --- a/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/composer_helper_lib.cpp +++ b/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/composer_helper_lib.cpp @@ -44,7 +44,8 @@ void compute_monomial_and_coset_selector_forms(plonk::proving_key* circuit_provi * (2) sets the polynomial manifest using the data from proving key. */ std::shared_ptr compute_verification_key_common( - std::shared_ptr const& proving_key, std::shared_ptr const& vrs) + std::shared_ptr const& proving_key, + std::shared_ptr const& vrs) { auto circuit_verification_key = std::make_shared( proving_key->circuit_size, proving_key->num_public_inputs, vrs, proving_key->composer_type); diff --git a/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/composer_helper_lib.hpp b/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/composer_helper_lib.hpp index c704608a3a..21d32b8ad8 100644 --- a/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/composer_helper_lib.hpp +++ b/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/composer_helper_lib.hpp @@ -25,6 +25,7 @@ void compute_monomial_and_coset_selector_forms(plonk::proving_key* key, * (2) sets the polynomial manifest using the data from proving key. */ std::shared_ptr compute_verification_key_common( - std::shared_ptr const& proving_key, std::shared_ptr const& vrs); + std::shared_ptr const& proving_key, + std::shared_ptr const& vrs); } // namespace proof_system::plonk diff --git a/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/standard_plonk_composer_helper.hpp b/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/standard_plonk_composer_helper.hpp index 3c54be288c..c4438399c1 100644 --- a/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/standard_plonk_composer_helper.hpp +++ b/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/standard_plonk_composer_helper.hpp @@ -1,7 +1,7 @@ #pragma once #include "barretenberg/plonk/flavor/flavor.hpp" -#include "barretenberg/srs/reference_string/file_reference_string.hpp" +#include "barretenberg/srs/factories/file_crs_factory.hpp" #include "barretenberg/plonk/proof_system/proving_key/proving_key.hpp" #include "barretenberg/plonk/proof_system/prover/prover.hpp" #include "barretenberg/plonk/proof_system/verifier/verifier.hpp" @@ -23,21 +23,21 @@ class StandardPlonkComposerHelper { std::shared_ptr circuit_verification_key; // TODO(#218)(kesha): we need to put this into the commitment key, so that the composer doesn't have to handle srs // at all - std::shared_ptr crs_factory_; + std::shared_ptr crs_factory_; std::vector recursive_proof_public_input_indices; bool contains_recursive_proof = false; bool computed_witness = false; StandardPlonkComposerHelper() - : StandardPlonkComposerHelper(std::shared_ptr( - new proof_system::FileReferenceStringFactory("../srs_db/ignition"))) + : StandardPlonkComposerHelper(std::shared_ptr( + new barretenberg::srs::factories::FileCrsFactory("../srs_db/ignition"))) {} - StandardPlonkComposerHelper(std::shared_ptr crs_factory) + StandardPlonkComposerHelper(std::shared_ptr crs_factory) : crs_factory_(std::move(crs_factory)) {} - StandardPlonkComposerHelper(std::unique_ptr&& crs_factory) + StandardPlonkComposerHelper(std::unique_ptr&& crs_factory) : crs_factory_(std::move(crs_factory)) {} StandardPlonkComposerHelper(std::shared_ptr p_key, diff --git a/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/turbo_plonk_composer_helper.hpp b/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/turbo_plonk_composer_helper.hpp index de35b01e80..8695f60c0e 100644 --- a/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/turbo_plonk_composer_helper.hpp +++ b/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/turbo_plonk_composer_helper.hpp @@ -3,7 +3,7 @@ #include "barretenberg/plonk/flavor/flavor.hpp" #include "barretenberg/plonk/composer/splitting_tmp/composer_helper/composer_helper_lib.hpp" #include "barretenberg/proof_system/composer/composer_helper_lib.hpp" -#include "barretenberg/srs/reference_string/file_reference_string.hpp" +#include "barretenberg/srs/factories/file_crs_factory.hpp" #include "barretenberg/plonk/proof_system/proving_key/proving_key.hpp" #include "barretenberg/plonk/proof_system/prover/prover.hpp" #include "barretenberg/plonk/proof_system/verifier/verifier.hpp" @@ -22,21 +22,21 @@ class TurboPlonkComposerHelper { // TODO(#218)(kesha): we need to put this into the commitment key, so that the composer doesn't have to handle srs // at all - std::shared_ptr crs_factory_; + std::shared_ptr crs_factory_; std::vector recursive_proof_public_input_indices; bool contains_recursive_proof = false; bool computed_witness = false; TurboPlonkComposerHelper() - : TurboPlonkComposerHelper(std::shared_ptr( - new proof_system::FileReferenceStringFactory("../srs_db/ignition"))) + : TurboPlonkComposerHelper(std::shared_ptr( + new barretenberg::srs::factories::FileCrsFactory("../srs_db/ignition"))) {} - TurboPlonkComposerHelper(std::shared_ptr crs_factory) + TurboPlonkComposerHelper(std::shared_ptr crs_factory) : crs_factory_(std::move(crs_factory)) {} - TurboPlonkComposerHelper(std::unique_ptr&& crs_factory) + TurboPlonkComposerHelper(std::unique_ptr&& crs_factory) : crs_factory_(std::move(crs_factory)) {} TurboPlonkComposerHelper(std::shared_ptr p_key, std::shared_ptr v_key) diff --git a/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/ultra_plonk_composer_helper.hpp b/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/ultra_plonk_composer_helper.hpp index 2cef06fc50..63a4f5d73f 100644 --- a/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/ultra_plonk_composer_helper.hpp +++ b/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/ultra_plonk_composer_helper.hpp @@ -3,7 +3,7 @@ #include "barretenberg/plonk/flavor/flavor.hpp" #include "barretenberg/proof_system/composer/composer_helper_lib.hpp" #include "barretenberg/plonk/composer/splitting_tmp/composer_helper/composer_helper_lib.hpp" -#include "barretenberg/srs/reference_string/file_reference_string.hpp" +#include "barretenberg/srs/factories/file_crs_factory.hpp" #include "barretenberg/plonk/proof_system/proving_key/proving_key.hpp" #include "barretenberg/plonk/proof_system/prover/prover.hpp" #include "barretenberg/plonk/proof_system/verifier/verifier.hpp" @@ -29,7 +29,7 @@ class UltraPlonkComposerHelper { std::shared_ptr circuit_verification_key; // TODO(#218)(kesha): we need to put this into the commitment key, so that the composer doesn't have to handle srs // at all - std::shared_ptr crs_factory_; + std::shared_ptr crs_factory_; std::vector recursive_proof_public_input_indices; bool contains_recursive_proof = false; @@ -41,7 +41,7 @@ class UltraPlonkComposerHelper { // vanishing_polynomial cannot be trivially fetched here, I am directly setting this to 4 - 1 = 3. static constexpr size_t s_randomness = 3; - explicit UltraPlonkComposerHelper(std::shared_ptr crs_factory) + explicit UltraPlonkComposerHelper(std::shared_ptr crs_factory) : crs_factory_(std::move(crs_factory)) {} diff --git a/cpp/src/barretenberg/plonk/composer/splitting_tmp/standard_plonk_composer.hpp b/cpp/src/barretenberg/plonk/composer/splitting_tmp/standard_plonk_composer.hpp index 9dc96d2e2f..bd023af11d 100644 --- a/cpp/src/barretenberg/plonk/composer/splitting_tmp/standard_plonk_composer.hpp +++ b/cpp/src/barretenberg/plonk/composer/splitting_tmp/standard_plonk_composer.hpp @@ -2,7 +2,7 @@ #include "composer_helper/standard_plonk_composer_helper.hpp" #include "barretenberg/proof_system/circuit_constructors/standard_circuit_constructor.hpp" -#include "barretenberg/srs/reference_string/file_reference_string.hpp" +#include "barretenberg/srs/factories/file_crs_factory.hpp" #include "barretenberg/transcript/manifest.hpp" #include "barretenberg/proof_system/types/merkle_hash_type.hpp" #include "barretenberg/proof_system/types/pedersen_commitment_type.hpp" @@ -42,18 +42,20 @@ class StandardPlonkComposer { , variables(circuit_constructor.variables){}; StandardPlonkComposer(std::string const& crs_path, const size_t size_hint = 0) - : StandardPlonkComposer( - std::unique_ptr(new proof_system::FileReferenceStringFactory(crs_path)), - size_hint){}; + : StandardPlonkComposer(std::unique_ptr( + new barretenberg::srs::factories::FileCrsFactory(crs_path)), + size_hint){}; - StandardPlonkComposer(std::shared_ptr const& crs_factory, const size_t size_hint = 0) + StandardPlonkComposer(std::shared_ptr const& crs_factory, + const size_t size_hint = 0) : circuit_constructor(size_hint) , composer_helper(crs_factory) , num_gates(circuit_constructor.num_gates) , variables(circuit_constructor.variables) {} - StandardPlonkComposer(std::unique_ptr&& crs_factory, const size_t size_hint = 0) + StandardPlonkComposer(std::unique_ptr&& crs_factory, + const size_t size_hint = 0) : circuit_constructor(size_hint) , composer_helper(std::move(crs_factory)) , num_gates(circuit_constructor.num_gates) diff --git a/cpp/src/barretenberg/plonk/composer/splitting_tmp/standard_plonk_composer.test.cpp b/cpp/src/barretenberg/plonk/composer/splitting_tmp/standard_plonk_composer.test.cpp index f67d6622da..f3b6c908bb 100644 --- a/cpp/src/barretenberg/plonk/composer/splitting_tmp/standard_plonk_composer.test.cpp +++ b/cpp/src/barretenberg/plonk/composer/splitting_tmp/standard_plonk_composer.test.cpp @@ -36,7 +36,7 @@ TEST(standard_plonk_composer_splitting_tmp, composer_from_serialized_keys) auto pk_data = from_buffer(pk_buf); auto vk_data = from_buffer(vk_buf); - auto crs = std::make_unique("../srs_db/ignition"); + auto crs = std::make_unique("../srs_db/ignition"); auto proving_key = std::make_shared(std::move(pk_data), crs->get_prover_crs(pk_data.circuit_size + 1)); auto verification_key = std::make_shared(std::move(vk_data), crs->get_verifier_crs()); diff --git a/cpp/src/barretenberg/plonk/composer/splitting_tmp/turbo_plonk_composer.hpp b/cpp/src/barretenberg/plonk/composer/splitting_tmp/turbo_plonk_composer.hpp index 950163dae1..4dfa6c4e04 100644 --- a/cpp/src/barretenberg/plonk/composer/splitting_tmp/turbo_plonk_composer.hpp +++ b/cpp/src/barretenberg/plonk/composer/splitting_tmp/turbo_plonk_composer.hpp @@ -42,17 +42,19 @@ class TurboPlonkComposer { , variables(circuit_constructor.variables){}; TurboPlonkComposer(std::string const& crs_path, const size_t size_hint = 0) - : TurboPlonkComposer( - std::unique_ptr(new proof_system::FileReferenceStringFactory(crs_path)), - size_hint){}; + : TurboPlonkComposer(std::unique_ptr( + new barretenberg::srs::factories::FileCrsFactory(crs_path)), + size_hint){}; - TurboPlonkComposer(std::shared_ptr const& crs_factory, const size_t size_hint = 0) + TurboPlonkComposer(std::shared_ptr const& crs_factory, + const size_t size_hint = 0) : circuit_constructor(size_hint) , composer_helper(crs_factory) , num_gates(circuit_constructor.num_gates) , variables(circuit_constructor.variables){}; - TurboPlonkComposer(std::unique_ptr&& crs_factory, const size_t size_hint = 0) + TurboPlonkComposer(std::unique_ptr&& crs_factory, + const size_t size_hint = 0) : circuit_constructor(size_hint) , composer_helper(std::move(crs_factory)) , num_gates(circuit_constructor.num_gates) diff --git a/cpp/src/barretenberg/plonk/composer/splitting_tmp/turbo_plonk_composer.test.cpp b/cpp/src/barretenberg/plonk/composer/splitting_tmp/turbo_plonk_composer.test.cpp index d651b48bdf..e320a34022 100644 --- a/cpp/src/barretenberg/plonk/composer/splitting_tmp/turbo_plonk_composer.test.cpp +++ b/cpp/src/barretenberg/plonk/composer/splitting_tmp/turbo_plonk_composer.test.cpp @@ -39,7 +39,7 @@ TEST(turbo_plonk_composer_splitting_tmp, composer_from_serialized_keys) auto pk_data = from_buffer(pk_buf); auto vk_data = from_buffer(vk_buf); - auto crs = std::make_unique("../srs_db/ignition"); + auto crs = std::make_unique("../srs_db/ignition"); auto proving_key = std::make_shared(std::move(pk_data), crs->get_prover_crs(pk_data.circuit_size + 1)); auto verification_key = std::make_shared(std::move(vk_data), crs->get_verifier_crs()); diff --git a/cpp/src/barretenberg/plonk/composer/splitting_tmp/ultra_plonk_composer.hpp b/cpp/src/barretenberg/plonk/composer/splitting_tmp/ultra_plonk_composer.hpp index 703e037e64..7dad6f15bf 100644 --- a/cpp/src/barretenberg/plonk/composer/splitting_tmp/ultra_plonk_composer.hpp +++ b/cpp/src/barretenberg/plonk/composer/splitting_tmp/ultra_plonk_composer.hpp @@ -30,10 +30,12 @@ class UltraPlonkComposer { : UltraPlonkComposer("../srs_db/ignition", 0){}; UltraPlonkComposer(std::string const& crs_path, const size_t size_hint) - : UltraPlonkComposer(std::unique_ptr(new FileReferenceStringFactory(crs_path)), + : UltraPlonkComposer(std::unique_ptr( + new barretenberg::srs::factories::FileCrsFactory(crs_path)), size_hint){}; - UltraPlonkComposer(std::shared_ptr const& crs_factory, const size_t size_hint) + UltraPlonkComposer(std::shared_ptr const& crs_factory, + const size_t size_hint) : circuit_constructor(size_hint) , composer_helper(crs_factory) , num_gates(circuit_constructor.num_gates){}; diff --git a/cpp/src/barretenberg/plonk/composer/standard_composer.hpp b/cpp/src/barretenberg/plonk/composer/standard_composer.hpp index f4c59f71a5..58cac114d2 100644 --- a/cpp/src/barretenberg/plonk/composer/standard_composer.hpp +++ b/cpp/src/barretenberg/plonk/composer/standard_composer.hpp @@ -3,7 +3,7 @@ #include "barretenberg/proof_system/types/merkle_hash_type.hpp" #include "barretenberg/proof_system/types/pedersen_commitment_type.hpp" #include "barretenberg/transcript/manifest.hpp" -#include "barretenberg/srs/reference_string/file_reference_string.hpp" +#include "barretenberg/srs/factories/file_crs_factory.hpp" namespace proof_system::plonk { enum StandardSelectors { QM, QC, Q1, Q2, Q3, NUM }; @@ -44,10 +44,12 @@ class StandardComposer : public ComposerBase { }; StandardComposer(std::string const& crs_path, const size_t size_hint = 0) - : StandardComposer(std::unique_ptr(new FileReferenceStringFactory(crs_path)), + : StandardComposer(std::unique_ptr( + new barretenberg::srs::factories::FileCrsFactory(crs_path)), size_hint){}; - StandardComposer(std::shared_ptr const& crs_factory, const size_t size_hint = 0) + StandardComposer(std::shared_ptr const& crs_factory, + const size_t size_hint = 0) : ComposerBase(crs_factory, StandardSelectors::NUM, size_hint, standard_selector_properties()) { w_l.reserve(size_hint); @@ -57,7 +59,8 @@ class StandardComposer : public ComposerBase { zero_idx = put_constant_variable(fr::zero()); } - StandardComposer(std::unique_ptr&& crs_factory, const size_t size_hint = 0) + StandardComposer(std::unique_ptr&& crs_factory, + const size_t size_hint = 0) : ComposerBase(std::move(crs_factory), StandardSelectors::NUM, size_hint, standard_selector_properties()) { w_l.reserve(size_hint); diff --git a/cpp/src/barretenberg/plonk/composer/standard_composer.test.cpp b/cpp/src/barretenberg/plonk/composer/standard_composer.test.cpp index 71aec400e2..9d6c969c66 100644 --- a/cpp/src/barretenberg/plonk/composer/standard_composer.test.cpp +++ b/cpp/src/barretenberg/plonk/composer/standard_composer.test.cpp @@ -37,7 +37,7 @@ TEST(standard_composer, composer_from_serialized_keys) auto pk_data = from_buffer(pk_buf); auto vk_data = from_buffer(vk_buf); - auto crs = std::make_unique("../srs_db/ignition"); + auto crs = std::make_unique("../srs_db/ignition"); auto proving_key = std::make_shared(std::move(pk_data), crs->get_prover_crs(pk_data.circuit_size + 1)); auto verification_key = std::make_shared(std::move(vk_data), crs->get_verifier_crs()); diff --git a/cpp/src/barretenberg/plonk/composer/turbo_composer.cpp b/cpp/src/barretenberg/plonk/composer/turbo_composer.cpp index a002a7f8f1..1db1f3af05 100644 --- a/cpp/src/barretenberg/plonk/composer/turbo_composer.cpp +++ b/cpp/src/barretenberg/plonk/composer/turbo_composer.cpp @@ -9,7 +9,7 @@ #include "barretenberg/plonk/proof_system/commitment_scheme/kate_commitment_scheme.hpp" #include "../proof_system/widgets/transition_widgets/transition_widget.hpp" #include "../proof_system/widgets/transition_widgets/turbo_arithmetic_widget.hpp" -#include "barretenberg/srs/reference_string/file_reference_string.hpp" +#include "barretenberg/srs/factories/file_crs_factory.hpp" using namespace barretenberg; using namespace proof_system; @@ -55,7 +55,9 @@ TurboComposer::TurboComposer() * vectors during initialization. * */ TurboComposer::TurboComposer(std::string const& crs_path, const size_t size_hint) - : TurboComposer(std::shared_ptr(new FileReferenceStringFactory(crs_path)), size_hint){}; + : TurboComposer(std::shared_ptr( + new barretenberg::srs::factories::FileCrsFactory(crs_path)), + size_hint){}; /** * Turbo composer initialization, where you can specify the factory @@ -65,7 +67,8 @@ TurboComposer::TurboComposer(std::string const& crs_path, const size_t size_hint * @param size_hint Assumed number of gates. Used to allocate space for various member * vectors during initialization. * */ -TurboComposer::TurboComposer(std::shared_ptr const& crs_factory, const size_t size_hint) +TurboComposer::TurboComposer(std::shared_ptr const& crs_factory, + const size_t size_hint) : ComposerBase(crs_factory, TurboSelectors::NUM, size_hint, turbo_sel_props()) { w_l.reserve(size_hint); diff --git a/cpp/src/barretenberg/plonk/composer/turbo_composer.hpp b/cpp/src/barretenberg/plonk/composer/turbo_composer.hpp index 4500b89953..102897339a 100644 --- a/cpp/src/barretenberg/plonk/composer/turbo_composer.hpp +++ b/cpp/src/barretenberg/plonk/composer/turbo_composer.hpp @@ -14,7 +14,8 @@ class TurboComposer : public ComposerBase { TurboComposer(); TurboComposer(std::string const& crs_path, const size_t size_hint = 0); - TurboComposer(std::shared_ptr const& crs_factory, const size_t size_hint = 0); + TurboComposer(std::shared_ptr const& crs_factory, + const size_t size_hint = 0); TurboComposer(std::shared_ptr const& p_key, std::shared_ptr const& v_key, size_t size_hint = 0); diff --git a/cpp/src/barretenberg/plonk/composer/turbo_composer.test.cpp b/cpp/src/barretenberg/plonk/composer/turbo_composer.test.cpp index 5e9bc0b756..78dc181161 100644 --- a/cpp/src/barretenberg/plonk/composer/turbo_composer.test.cpp +++ b/cpp/src/barretenberg/plonk/composer/turbo_composer.test.cpp @@ -38,7 +38,7 @@ TEST(turbo_composer, composer_from_serialized_keys) auto pk_data = from_buffer(pk_buf); auto vk_data = from_buffer(vk_buf); - auto crs = std::make_unique("../srs_db/ignition"); + auto crs = std::make_unique("../srs_db/ignition"); auto proving_key = std::make_shared(std::move(pk_data), crs->get_prover_crs(pk_data.circuit_size + 1)); auto verification_key = std::make_shared(std::move(vk_data), crs->get_verifier_crs()); diff --git a/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp b/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp index bf13074fdf..02efa47c13 100644 --- a/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp +++ b/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp @@ -12,7 +12,7 @@ #include "barretenberg/plonk/proof_system/widgets/random_widgets/permutation_widget.hpp" #include "barretenberg/plonk/proof_system/widgets/random_widgets/plookup_widget.hpp" #include "barretenberg/plonk/proof_system/commitment_scheme/kate_commitment_scheme.hpp" -#include "barretenberg/srs/reference_string/file_reference_string.hpp" +#include "barretenberg/srs/factories/file_crs_factory.hpp" #include "barretenberg/proof_system/plookup_tables/types.hpp" #include "barretenberg/proof_system/plookup_tables/plookup_tables.hpp" @@ -68,9 +68,12 @@ UltraComposer::UltraComposer() {} UltraComposer::UltraComposer(std::string const& crs_path, const size_t size_hint) - : UltraComposer(std::unique_ptr(new FileReferenceStringFactory(crs_path)), size_hint){}; + : UltraComposer(std::unique_ptr( + new barretenberg::srs::factories::FileCrsFactory(crs_path)), + size_hint){}; -UltraComposer::UltraComposer(std::shared_ptr const& crs_factory, const size_t size_hint) +UltraComposer::UltraComposer(std::shared_ptr const& crs_factory, + const size_t size_hint) : ComposerBase(crs_factory, UltraSelectors::NUM, size_hint, ultra_selector_properties()) { w_l.reserve(size_hint); diff --git a/cpp/src/barretenberg/plonk/composer/ultra_composer.hpp b/cpp/src/barretenberg/plonk/composer/ultra_composer.hpp index eb0e5b0e92..693257677e 100644 --- a/cpp/src/barretenberg/plonk/composer/ultra_composer.hpp +++ b/cpp/src/barretenberg/plonk/composer/ultra_composer.hpp @@ -206,7 +206,8 @@ class UltraComposer : public ComposerBase { UltraComposer(); UltraComposer(std::string const& crs_path, const size_t size_hint = 0); - UltraComposer(std::shared_ptr const& crs_factory, const size_t size_hint = 0); + UltraComposer(std::shared_ptr const& crs_factory, + const size_t size_hint = 0); UltraComposer(std::shared_ptr const& p_key, std::shared_ptr const& v_key, size_t size_hint = 0); diff --git a/cpp/src/barretenberg/plonk/proof_system/commitment_scheme/commitment_scheme.test.cpp b/cpp/src/barretenberg/plonk/proof_system/commitment_scheme/commitment_scheme.test.cpp index 2b7f89ab0e..f4d015fbc4 100644 --- a/cpp/src/barretenberg/plonk/proof_system/commitment_scheme/commitment_scheme.test.cpp +++ b/cpp/src/barretenberg/plonk/proof_system/commitment_scheme/commitment_scheme.test.cpp @@ -10,7 +10,7 @@ #include "../../../proof_system/work_queue/work_queue.hpp" #include "../types/program_settings.hpp" #include "../../composer/composer_base.hpp" -#include "barretenberg/srs/reference_string/file_reference_string.hpp" +#include "barretenberg/srs/factories/file_crs_factory.hpp" #include "barretenberg/ecc/curves/bn254/fq12.hpp" #include "barretenberg/ecc/curves/bn254/pairing.hpp" @@ -36,8 +36,9 @@ TEST(commitment_scheme, kate_open) transcript::StandardTranscript inp_tx = transcript::StandardTranscript(transcript::Manifest()); plonk::KateCommitmentScheme newKate; - // std::shared_ptr crs_factory = (new FileReferenceStringFactory("../srs_db/ignition")); - auto file_crs = std::make_shared("../srs_db/ignition"); + // std::shared_ptr crs_factory = (new + // FileReferenceStringFactory("../srs_db/ignition")); + auto file_crs = std::make_shared("../srs_db/ignition"); auto crs = file_crs->get_prover_crs(n); auto circuit_proving_key = std::make_shared(n, 0, crs, ComposerType::STANDARD); work_queue queue(circuit_proving_key.get(), &inp_tx); @@ -94,7 +95,7 @@ TEST(commitment_scheme, kate_batch_open) transcript::StandardTranscript inp_tx = transcript::StandardTranscript(transcript::Manifest()); plonk::KateCommitmentScheme newKate; - auto file_crs = std::make_shared("../srs_db/ignition"); + auto file_crs = std::make_shared("../srs_db/ignition"); auto crs = file_crs->get_prover_crs(n); auto circuit_proving_key = std::make_shared(n, 0, crs, ComposerType::STANDARD); work_queue queue(circuit_proving_key.get(), &inp_tx); diff --git a/cpp/src/barretenberg/plonk/proof_system/prover/prover.test.cpp b/cpp/src/barretenberg/plonk/proof_system/prover/prover.test.cpp index 50a535f946..c110490e7a 100644 --- a/cpp/src/barretenberg/plonk/proof_system/prover/prover.test.cpp +++ b/cpp/src/barretenberg/plonk/proof_system/prover/prover.test.cpp @@ -4,7 +4,7 @@ #include "prover.hpp" #include -#include "barretenberg/srs/reference_string/file_reference_string.hpp" +#include "barretenberg/srs/factories/file_crs_factory.hpp" #include "barretenberg/polynomials/polynomial_arithmetic.hpp" #include "barretenberg/plonk/proof_system/commitment_scheme/kate_commitment_scheme.hpp" @@ -112,7 +112,7 @@ plonk::Prover generate_test_data(const size_t n) // even indices = mul gates, odd incides = add gates - auto reference_string = std::make_shared(n + 1, "../srs_db/ignition"); + auto reference_string = std::make_shared(n + 1, "../srs_db/ignition"); std::shared_ptr key = std::make_shared(n, 0, reference_string, ComposerType::STANDARD); polynomial w_l(n); diff --git a/cpp/src/barretenberg/plonk/proof_system/proving_key/proving_key.cpp b/cpp/src/barretenberg/plonk/proof_system/proving_key/proving_key.cpp index 4f2c5d533d..31033387f4 100644 --- a/cpp/src/barretenberg/plonk/proof_system/proving_key/proving_key.cpp +++ b/cpp/src/barretenberg/plonk/proof_system/proving_key/proving_key.cpp @@ -24,7 +24,7 @@ namespace proof_system::plonk { * */ proving_key::proving_key(const size_t num_gates, const size_t num_inputs, - std::shared_ptr const& crs, + std::shared_ptr const& crs, ComposerType type = ComposerType::STANDARD) // TODO(Cody): Don't use default for Honk : composer_type(type) , circuit_size(num_gates) @@ -44,7 +44,7 @@ proving_key::proving_key(const size_t num_gates, * @param data * @param crs */ -proving_key::proving_key(proving_key_data&& data, std::shared_ptr const& crs) +proving_key::proving_key(proving_key_data&& data, std::shared_ptr const& crs) : composer_type(data.composer_type) , circuit_size(data.circuit_size) , num_public_inputs(data.num_public_inputs) diff --git a/cpp/src/barretenberg/plonk/proof_system/proving_key/proving_key.hpp b/cpp/src/barretenberg/plonk/proof_system/proving_key/proving_key.hpp index 0714da1565..3a50731748 100644 --- a/cpp/src/barretenberg/plonk/proof_system/proving_key/proving_key.hpp +++ b/cpp/src/barretenberg/plonk/proof_system/proving_key/proving_key.hpp @@ -7,7 +7,7 @@ #include "barretenberg/proof_system/polynomial_store/polynomial_store.hpp" // #include "barretenberg/proof_system/polynomial_store/polynomial_store_wasm.hpp" // #include "barretenberg/proof_system/polynomial_store/polynomial_store_cache.hpp" -#include "barretenberg/srs/reference_string/reference_string.hpp" +#include "barretenberg/srs/factories/crs_factory.hpp" #include "barretenberg/plonk/proof_system/constants.hpp" #include "barretenberg/plonk/proof_system/types/polynomial_manifest.hpp" #include @@ -33,11 +33,11 @@ struct proving_key { RELATIVE_LOOKUP, }; - proving_key(proving_key_data&& data, std::shared_ptr const& crs); + proving_key(proving_key_data&& data, std::shared_ptr const& crs); proving_key(const size_t num_gates, const size_t num_inputs, - std::shared_ptr const& crs, + std::shared_ptr const& crs, ComposerType type); proving_key(std::ostream& is, std::string const& crs_path); @@ -60,7 +60,7 @@ struct proving_key { // The reference_string object contains the monomial SRS. We can access it using: // Monomial SRS: reference_string->get_monomial_points() - std::shared_ptr reference_string; + std::shared_ptr reference_string; barretenberg::polynomial quotient_polynomial_parts[plonk::NUM_QUOTIENT_PARTS]; diff --git a/cpp/src/barretenberg/plonk/proof_system/proving_key/proving_key.test.cpp b/cpp/src/barretenberg/plonk/proof_system/proving_key/proving_key.test.cpp index f620b33617..84d2c2365c 100644 --- a/cpp/src/barretenberg/plonk/proof_system/proving_key/proving_key.test.cpp +++ b/cpp/src/barretenberg/plonk/proof_system/proving_key/proving_key.test.cpp @@ -22,7 +22,7 @@ TEST(proving_key, proving_key_from_serialized_key) plonk::proving_key& p_key = *composer.compute_proving_key(); auto pk_buf = to_buffer(p_key); auto pk_data = from_buffer(pk_buf); - auto crs = std::make_unique("../srs_db/ignition"); + auto crs = std::make_unique("../srs_db/ignition"); auto proving_key = std::make_shared(std::move(pk_data), crs->get_prover_crs(pk_data.circuit_size + 1)); @@ -58,7 +58,7 @@ TEST(proving_key, proving_key_from_serialized_key_ultra) plonk::proving_key& p_key = *composer.compute_proving_key(); auto pk_buf = to_buffer(p_key); auto pk_data = from_buffer(pk_buf); - auto crs = std::make_unique("../srs_db/ignition"); + auto crs = std::make_unique("../srs_db/ignition"); auto proving_key = std::make_shared(std::move(pk_data), crs->get_prover_crs(pk_data.circuit_size + 1)); diff --git a/cpp/src/barretenberg/plonk/proof_system/verification_key/verification_key.cpp b/cpp/src/barretenberg/plonk/proof_system/verification_key/verification_key.cpp index 6e072abbb9..c51d941191 100644 --- a/cpp/src/barretenberg/plonk/proof_system/verification_key/verification_key.cpp +++ b/cpp/src/barretenberg/plonk/proof_system/verification_key/verification_key.cpp @@ -87,7 +87,7 @@ barretenberg::fr verification_key_data::compress_native(const size_t hash_index) verification_key::verification_key(const size_t num_gates, const size_t num_inputs, - std::shared_ptr const& crs, + std::shared_ptr const& crs, uint32_t composer_type_) : composer_type(composer_type_) , circuit_size(num_gates) @@ -98,7 +98,8 @@ verification_key::verification_key(const size_t num_gates, , polynomial_manifest(composer_type) {} -verification_key::verification_key(verification_key_data&& data, std::shared_ptr const& crs) +verification_key::verification_key(verification_key_data&& data, + std::shared_ptr const& crs) : composer_type(data.composer_type) , circuit_size(data.circuit_size) , log_circuit_size(numeric::get_msb(data.circuit_size)) diff --git a/cpp/src/barretenberg/plonk/proof_system/verification_key/verification_key.hpp b/cpp/src/barretenberg/plonk/proof_system/verification_key/verification_key.hpp index 8d0c3db094..cbac2cc4c8 100644 --- a/cpp/src/barretenberg/plonk/proof_system/verification_key/verification_key.hpp +++ b/cpp/src/barretenberg/plonk/proof_system/verification_key/verification_key.hpp @@ -1,7 +1,7 @@ #pragma once #include #include "barretenberg/common/streams.hpp" -#include "barretenberg/srs/reference_string/reference_string.hpp" +#include "barretenberg/srs/factories/crs_factory.hpp" #include "barretenberg/ecc/curves/bn254/fr.hpp" #include "barretenberg/polynomials/evaluation_domain.hpp" #include "barretenberg/crypto/sha256/sha256.hpp" @@ -59,10 +59,11 @@ inline bool operator==(verification_key_data const& lhs, verification_key_data c struct verification_key { // default constructor needed for msgpack unpack verification_key() = default; - verification_key(verification_key_data&& data, std::shared_ptr const& crs); + verification_key(verification_key_data&& data, + std::shared_ptr const& crs); verification_key(const size_t num_gates, const size_t num_inputs, - std::shared_ptr const& crs, + std::shared_ptr const& crs, uint32_t composer_type); verification_key(const verification_key& other); verification_key(verification_key&& other); @@ -79,7 +80,7 @@ struct verification_key { barretenberg::evaluation_domain domain; - std::shared_ptr reference_string; + std::shared_ptr reference_string; std::map commitments; diff --git a/cpp/src/barretenberg/plonk/proof_system/verifier/verifier.test.cpp b/cpp/src/barretenberg/plonk/proof_system/verifier/verifier.test.cpp index b61c4017f1..8ed2df86c3 100644 --- a/cpp/src/barretenberg/plonk/proof_system/verifier/verifier.test.cpp +++ b/cpp/src/barretenberg/plonk/proof_system/verifier/verifier.test.cpp @@ -7,7 +7,7 @@ #include "verifier.hpp" #include "barretenberg/ecc/curves/bn254/scalar_multiplication/scalar_multiplication.hpp" #include -#include "barretenberg/srs/reference_string/file_reference_string.hpp" +#include "barretenberg/srs/factories/file_crs_factory.hpp" #include "barretenberg/polynomials/polynomial_arithmetic.hpp" #include "barretenberg/plonk/proof_system/commitment_scheme/kate_commitment_scheme.hpp" @@ -40,7 +40,7 @@ plonk::Verifier generate_verifier(std::shared_ptr circuit_proving_k state)); } - auto crs = std::make_shared("../srs_db/ignition"); + auto crs = std::make_shared("../srs_db/ignition"); std::shared_ptr circuit_verification_key = std::make_shared(circuit_proving_key->circuit_size, circuit_proving_key->num_public_inputs, @@ -76,7 +76,7 @@ plonk::Prover generate_test_data(const size_t n) // even indices = mul gates, odd incides = add gates - auto crs = std::make_shared(n + 1, "../srs_db/ignition"); + auto crs = std::make_shared(n + 1, "../srs_db/ignition"); std::shared_ptr key = std::make_shared(n, 0, crs, ComposerType::STANDARD); polynomial w_l(n); diff --git a/cpp/src/barretenberg/proof_system/composer/composer_helper_lib.hpp b/cpp/src/barretenberg/proof_system/composer/composer_helper_lib.hpp index a5c432199f..176da27a55 100644 --- a/cpp/src/barretenberg/proof_system/composer/composer_helper_lib.hpp +++ b/cpp/src/barretenberg/proof_system/composer/composer_helper_lib.hpp @@ -2,6 +2,7 @@ #include #include "barretenberg/plonk/proof_system/proving_key/proving_key.hpp" #include "barretenberg/proof_system/flavor/flavor.hpp" +#include "barretenberg/srs/factories/crs_factory.hpp" namespace proof_system { @@ -19,7 +20,7 @@ namespace proof_system { template std::shared_ptr initialize_proving_key( const typename Flavor::CircuitConstructor& circuit_constructor, - ReferenceStringFactory* crs_factory, + barretenberg::srs::factories::CrsFactory* crs_factory, const size_t minimum_circuit_size, const size_t num_randomized_gates, ComposerType composer_type) diff --git a/cpp/src/barretenberg/proof_system/composer/composer_helper_lib.test.cpp b/cpp/src/barretenberg/proof_system/composer/composer_helper_lib.test.cpp index 720705b7f0..7ec2df661f 100644 --- a/cpp/src/barretenberg/proof_system/composer/composer_helper_lib.test.cpp +++ b/cpp/src/barretenberg/proof_system/composer/composer_helper_lib.test.cpp @@ -3,7 +3,7 @@ #include "barretenberg/honk/flavor/standard.hpp" // TODO: needed? #include "barretenberg/proof_system/composer/composer_helper_lib.hpp" #include "barretenberg/proof_system/types/composer_type.hpp" -#include "barretenberg/srs/reference_string/reference_string.hpp" +#include "barretenberg/srs/factories/crs_factory.hpp" namespace proof_system::test_composer_lib { @@ -13,7 +13,7 @@ class ComposerLibTests : public ::testing::Test { using FF = typename Flavor::FF; Flavor::CircuitConstructor circuit_constructor; Flavor::ProvingKey proving_key = []() { - auto crs_factory = ReferenceStringFactory(); + auto crs_factory = barretenberg::srs::factories::CrsFactory(); auto crs = crs_factory.get_prover_crs(4); return Flavor::ProvingKey(/*circuit_size=*/4, /*num_public_inputs=*/0, crs, ComposerType::STANDARD); }(); @@ -25,7 +25,7 @@ TEST_F(ComposerLibTests, InitializeProvingKey) EXPECT_EQ(circuit_constructor.get_circuit_subgroup_size(7), 8); - ReferenceStringFactory crs_factory; + barretenberg::srs::factories::CrsFactory crs_factory; auto pk = initialize_proving_key(circuit_constructor, &crs_factory, diff --git a/cpp/src/barretenberg/proof_system/composer/permutation_helper.test.cpp b/cpp/src/barretenberg/proof_system/composer/permutation_helper.test.cpp index 57103c69ae..1b9491b7b4 100644 --- a/cpp/src/barretenberg/proof_system/composer/permutation_helper.test.cpp +++ b/cpp/src/barretenberg/proof_system/composer/permutation_helper.test.cpp @@ -4,7 +4,7 @@ #include "barretenberg/proof_system/composer/composer_helper_lib.hpp" #include "barretenberg/proof_system/composer/permutation_helper.hpp" #include "barretenberg/proof_system/types/composer_type.hpp" -#include "barretenberg/srs/reference_string/reference_string.hpp" +#include "barretenberg/srs/factories/crs_factory.hpp" namespace proof_system::test_composer_lib { @@ -13,7 +13,7 @@ class PermutationHelperTests : public ::testing::Test { using Flavor = honk::flavor::Standard; using FF = typename Flavor::FF; Flavor::CircuitConstructor circuit_constructor; - ReferenceStringFactory crs_factory = ReferenceStringFactory(); + barretenberg::srs::factories::CrsFactory crs_factory = barretenberg::srs::factories::CrsFactory(); std::shared_ptr proving_key; virtual void SetUp() diff --git a/cpp/src/barretenberg/proof_system/flavor/flavor.hpp b/cpp/src/barretenberg/proof_system/flavor/flavor.hpp index d42e3c6c9a..db10d2f769 100644 --- a/cpp/src/barretenberg/proof_system/flavor/flavor.hpp +++ b/cpp/src/barretenberg/proof_system/flavor/flavor.hpp @@ -68,7 +68,7 @@ #include #include #include "barretenberg/honk/sumcheck/polynomials/barycentric_data.hpp" -#include "barretenberg/srs/reference_string/reference_string.hpp" +#include "barretenberg/srs/factories/crs_factory.hpp" #include "barretenberg/polynomials/evaluation_domain.hpp" #include "barretenberg/proof_system/types/composer_type.hpp" #include "barretenberg/honk/sumcheck/polynomials/univariate.hpp" @@ -143,13 +143,13 @@ class ProvingKey_ : public PrecomputedPolynomials, public WitnessPolynomials { bool contains_recursive_proof; std::vector recursive_proof_public_input_indices; - std::shared_ptr crs; + std::shared_ptr crs; barretenberg::EvaluationDomain evaluation_domain; ProvingKey_() = default; ProvingKey_(const size_t circuit_size, const size_t num_public_inputs, - std::shared_ptr const& crs, + std::shared_ptr const& crs, ComposerType composer_type) { this->crs = crs; @@ -176,12 +176,12 @@ class ProvingKey_ : public PrecomputedPolynomials, public WitnessPolynomials { */ template class VerificationKey_ : public PrecomputedCommitments { public: - std::shared_ptr vrs; + std::shared_ptr vrs; VerificationKey_() = default; VerificationKey_(const size_t circuit_size, const size_t num_public_inputs, - std::shared_ptr const& vrs, + std::shared_ptr const& vrs, ComposerType composer_type) { this->circuit_size = circuit_size; @@ -291,7 +291,7 @@ concept IsAnyOf = (std::same_as || ...); template concept IsPlonkFlavor = IsAnyOf; -template +template concept IsHonkFlavor = IsAnyOf; // clang-format on } // namespace proof_system diff --git a/cpp/src/barretenberg/srs/c_bind.cpp b/cpp/src/barretenberg/srs/c_bind.cpp new file mode 100644 index 0000000000..2542d3542a --- /dev/null +++ b/cpp/src/barretenberg/srs/c_bind.cpp @@ -0,0 +1,23 @@ +#include "c_bind.hpp" +#include "global_crs.hpp" +#include "./io.hpp" +#include +#include +#include + +using namespace barretenberg; + +/** + * WARNING: The SRS is not encoded the same way as all the read/write methods encode. + * Have to use the old school io functions to parse the buffers. + */ +WASM_EXPORT void srs_init_srs(uint8_t const* points_buf, uint32_t const* num_points, uint8_t const* g2_point_buf) +{ + auto points = std::vector(ntohl(*num_points)); + barretenberg::io::read_g1_elements_from_buffer(points.data(), (char*)points_buf, points.size() * 64); + + g2::affine_element g2_point; + io::read_g2_elements_from_buffer(&g2_point, (char*)g2_point_buf, 128); + + barretenberg::srs::init_crs_factory(points, g2_point); +} diff --git a/cpp/src/barretenberg/srs/c_bind.hpp b/cpp/src/barretenberg/srs/c_bind.hpp new file mode 100644 index 0000000000..a0e800aaa5 --- /dev/null +++ b/cpp/src/barretenberg/srs/c_bind.hpp @@ -0,0 +1,4 @@ +#include +#include + +WASM_EXPORT void srs_init_srs(uint8_t const* points_buf, uint32_t const* num_points, uint8_t const* g2_point_buf); diff --git a/cpp/src/barretenberg/srs/factories/crs_factory.hpp b/cpp/src/barretenberg/srs/factories/crs_factory.hpp new file mode 100644 index 0000000000..a849d7c392 --- /dev/null +++ b/cpp/src/barretenberg/srs/factories/crs_factory.hpp @@ -0,0 +1,51 @@ +#pragma once +#include "barretenberg/common/mem.hpp" +#include "barretenberg/ecc/curves/bn254/g1.hpp" +#include "barretenberg/ecc/curves/bn254/g2.hpp" +#include + +namespace barretenberg::pairing { +struct miller_lines; +} // namespace barretenberg::pairing + +namespace barretenberg::srs::factories { + +/** + * A prover crs representation. + */ +class ProverCrs { + public: + virtual ~ProverCrs() = default; + ; + + /** + * Returns the monomial points in a form to be consumed by scalar_multiplication pippenger algorithm. + */ + virtual barretenberg::g1::affine_element* get_monomial_points() = 0; + virtual size_t get_monomial_size() const = 0; +}; + +class VerifierCrs { + public: + virtual ~VerifierCrs() = default; + ; + + virtual barretenberg::g2::affine_element get_g2x() const = 0; + + virtual barretenberg::pairing::miller_lines const* get_precomputed_g2_lines() const = 0; +}; + +/** + * A factory class to return the prover crs and verifier crs on request. + * You can construct an empty placeholder factory, because composers need to be given a factory at construction time. + */ +class CrsFactory { + public: + CrsFactory() = default; + CrsFactory(CrsFactory&& other) = default; + virtual ~CrsFactory() = default; + virtual std::shared_ptr get_prover_crs(size_t) { return nullptr; } + virtual std::shared_ptr get_verifier_crs() { return nullptr; } +}; + +} // namespace barretenberg::srs::factories diff --git a/cpp/src/barretenberg/srs/factories/file_crs_factory.cpp b/cpp/src/barretenberg/srs/factories/file_crs_factory.cpp new file mode 100644 index 0000000000..649cff9f64 --- /dev/null +++ b/cpp/src/barretenberg/srs/factories/file_crs_factory.cpp @@ -0,0 +1,73 @@ +#include "file_crs_factory.hpp" +#include "../io.hpp" +#include "barretenberg/ecc/curves/bn254/g1.hpp" +#include "barretenberg/ecc/curves/bn254/pairing.hpp" +#include "barretenberg/ecc/curves/bn254/scalar_multiplication/pippenger.hpp" + +namespace barretenberg::srs::factories { + +FileProverCrs::FileProverCrs(const size_t num_points, std::string const& path) + : num_points(num_points) +{ + monomials_ = scalar_multiplication::point_table_alloc(num_points); + + io::read_transcript_g1(monomials_, num_points, path); + scalar_multiplication::generate_pippenger_point_table(monomials_, monomials_, num_points); +} + +g1::affine_element* FileProverCrs::get_monomial_points() +{ + return monomials_; +} + +size_t FileProverCrs::get_monomial_size() const +{ + return num_points; +} + +FileVerifierCrs::FileVerifierCrs(std::string const& path) + : precomputed_g2_lines( + (barretenberg::pairing::miller_lines*)(aligned_alloc(64, sizeof(barretenberg::pairing::miller_lines) * 2))) +{ + + barretenberg::io::read_transcript_g2(g2_x, path); + barretenberg::pairing::precompute_miller_lines(barretenberg::g2::one, precomputed_g2_lines[0]); + barretenberg::pairing::precompute_miller_lines(g2_x, precomputed_g2_lines[1]); +} + +FileVerifierCrs::~FileVerifierCrs() +{ + aligned_free(precomputed_g2_lines); +} + +g2::affine_element FileVerifierCrs::get_g2x() const +{ + return g2_x; +} + +pairing::miller_lines const* FileVerifierCrs::get_precomputed_g2_lines() const +{ + return precomputed_g2_lines; +} + +FileCrsFactory::FileCrsFactory(std::string path, size_t initial_degree) + : path_(std::move(path)) + , degree_(initial_degree) + , verifier_crs_(std::make_shared(path_)) +{} + +std::shared_ptr FileCrsFactory::get_prover_crs(size_t degree) +{ + if (degree != degree_ || !prover_crs_) { + prover_crs_ = std::make_shared(degree, path_); + degree_ = degree; + } + return prover_crs_; +} + +std::shared_ptr FileCrsFactory::get_verifier_crs() +{ + return verifier_crs_; +} + +} // namespace barretenberg::srs::factories \ No newline at end of file diff --git a/cpp/src/barretenberg/srs/factories/file_crs_factory.hpp b/cpp/src/barretenberg/srs/factories/file_crs_factory.hpp new file mode 100644 index 0000000000..96cc306e24 --- /dev/null +++ b/cpp/src/barretenberg/srs/factories/file_crs_factory.hpp @@ -0,0 +1,55 @@ +#pragma once +#include "crs_factory.hpp" +#include +#include + +namespace barretenberg::srs::factories { + +class FileProverCrs : public ProverCrs { + public: + FileProverCrs(const size_t num_points, std::string const& path); + + g1::affine_element* get_monomial_points() override; + + size_t get_monomial_size() const override; + + private: + size_t num_points; + g1::affine_element* monomials_; +}; + +class FileVerifierCrs : public VerifierCrs { + public: + FileVerifierCrs(std::string const& path); + + ~FileVerifierCrs(); + + g2::affine_element get_g2x() const override; + + pairing::miller_lines const* get_precomputed_g2_lines() const override; + + private: + g2::affine_element g2_x; + pairing::miller_lines* precomputed_g2_lines; +}; + +/** + * Create reference strings given a path to a directory of transcript files. + */ +class FileCrsFactory : public CrsFactory { + public: + FileCrsFactory(std::string path, size_t initial_degree = 0); + FileCrsFactory(FileCrsFactory&& other) = default; + + std::shared_ptr get_prover_crs(size_t degree) override; + + std::shared_ptr get_verifier_crs() override; + + private: + std::string path_; + size_t degree_; + std::shared_ptr prover_crs_; + std::shared_ptr verifier_crs_; +}; + +} // namespace barretenberg::srs::factories diff --git a/cpp/src/barretenberg/srs/factories/mem_crs_factory.cpp b/cpp/src/barretenberg/srs/factories/mem_crs_factory.cpp new file mode 100644 index 0000000000..8971551c7f --- /dev/null +++ b/cpp/src/barretenberg/srs/factories/mem_crs_factory.cpp @@ -0,0 +1,73 @@ +#include "mem_crs_factory.hpp" +#include "barretenberg/ecc/curves/bn254/g1.hpp" +#include "barretenberg/ecc/curves/bn254/pairing.hpp" +#include "barretenberg/ecc/curves/bn254/scalar_multiplication/pippenger.hpp" + +namespace { + +using namespace barretenberg; +using namespace barretenberg::srs::factories; + +class MemProverCrs : public ProverCrs { + public: + MemProverCrs(std::vector const& points) + : num_points(points.size()) + { + monomials_ = scalar_multiplication::point_table_alloc(num_points); + std::copy(points.begin(), points.end(), monomials_); + scalar_multiplication::generate_pippenger_point_table(monomials_, monomials_, num_points); + } + + ~MemProverCrs() { aligned_free(monomials_); } + + g1::affine_element* get_monomial_points() override { return monomials_; } + + size_t get_monomial_size() const override { return num_points; } + + private: + size_t num_points; + g1::affine_element* monomials_; +}; + +class MemVerifierCrs : public VerifierCrs { + public: + MemVerifierCrs(g2::affine_element const& g2_point) + : g2_x(g2_point) + { + precomputed_g2_lines = + (pairing::miller_lines*)(aligned_alloc(64, sizeof(barretenberg::pairing::miller_lines) * 2)); + barretenberg::pairing::precompute_miller_lines(barretenberg::g2::one, precomputed_g2_lines[0]); + barretenberg::pairing::precompute_miller_lines(g2_x, precomputed_g2_lines[1]); + } + + ~MemVerifierCrs() { aligned_free(precomputed_g2_lines); } + + g2::affine_element get_g2x() const override { return g2_x; } + + pairing::miller_lines const* get_precomputed_g2_lines() const override { return precomputed_g2_lines; } + + private: + g2::affine_element g2_x; + pairing::miller_lines* precomputed_g2_lines; +}; + +} // namespace + +namespace barretenberg::srs::factories { + +MemCrsFactory::MemCrsFactory(std::vector const& points, g2::affine_element const g2_point) + : prover_crs_(std::make_shared(points)) + , verifier_crs_(std::make_shared(g2_point)) +{} + +std::shared_ptr MemCrsFactory::get_prover_crs(size_t) +{ + return prover_crs_; +} + +std::shared_ptr MemCrsFactory::get_verifier_crs() +{ + return verifier_crs_; +} + +} // namespace barretenberg::srs::factories \ No newline at end of file diff --git a/cpp/src/barretenberg/srs/factories/mem_crs_factory.hpp b/cpp/src/barretenberg/srs/factories/mem_crs_factory.hpp new file mode 100644 index 0000000000..0cdcf16b20 --- /dev/null +++ b/cpp/src/barretenberg/srs/factories/mem_crs_factory.hpp @@ -0,0 +1,27 @@ +#pragma once +#include "crs_factory.hpp" +#include "barretenberg/ecc/curves/bn254/g1.hpp" +#include "barretenberg/ecc/curves/bn254/g2.hpp" +#include +#include + +namespace barretenberg::srs::factories { + +/** + * Create reference strings given pointers to in memory buffers. + */ +class MemCrsFactory : public CrsFactory { + public: + MemCrsFactory(std::vector const& points, g2::affine_element const g2_point); + MemCrsFactory(MemCrsFactory&& other) = default; + + std::shared_ptr get_prover_crs(size_t degree) override; + + std::shared_ptr get_verifier_crs() override; + + private: + std::shared_ptr prover_crs_; + std::shared_ptr verifier_crs_; +}; + +} // namespace barretenberg::srs::factories diff --git a/cpp/src/barretenberg/srs/factories/mem_crs_factory.test.cpp b/cpp/src/barretenberg/srs/factories/mem_crs_factory.test.cpp new file mode 100644 index 0000000000..6efcfe184e --- /dev/null +++ b/cpp/src/barretenberg/srs/factories/mem_crs_factory.test.cpp @@ -0,0 +1,44 @@ +#include "file_crs_factory.hpp" +#include "mem_crs_factory.hpp" +#include "../io.hpp" +#include "barretenberg/ecc/curves/bn254/pairing.hpp" +#include +#include + +using namespace barretenberg; +using namespace barretenberg::srs::factories; + +TEST(reference_string, mem_file_consistency) +{ + // Load 1024 from file. + auto file_crs = FileCrsFactory("../srs_db/ignition", 1024); + + // Use low level io lib to read 1024 from file. + std::vector points(1024); + io::read_transcript_g1(points.data(), 1024, "../srs_db/ignition"); + + g2::affine_element g2_point; + io::read_transcript_g2(g2_point, "../srs_db/ignition"); + + MemCrsFactory mem_crs(points, g2_point); + auto file_prover_crs = file_crs.get_prover_crs(1024); + auto mem_prover_crs = mem_crs.get_prover_crs(1024); + file_prover_crs->get_monomial_size(); + + EXPECT_EQ(mem_prover_crs->get_monomial_size(), file_prover_crs->get_monomial_size()); + + EXPECT_EQ(memcmp(mem_prover_crs->get_monomial_points(), + file_prover_crs->get_monomial_points(), + sizeof(g1::affine_element) * 1024 * 2), + 0); + + auto file_verifier_crs = file_crs.get_verifier_crs(); + auto mem_verifier_crs = file_crs.get_verifier_crs(); + + EXPECT_EQ(mem_verifier_crs->get_g2x(), file_verifier_crs->get_g2x()); + + EXPECT_EQ(memcmp(mem_verifier_crs->get_precomputed_g2_lines(), + file_verifier_crs->get_precomputed_g2_lines(), + sizeof(barretenberg::pairing::miller_lines) * 2), + 0); +} diff --git a/cpp/src/barretenberg/srs/global_crs.cpp b/cpp/src/barretenberg/srs/global_crs.cpp new file mode 100644 index 0000000000..d14b0ba140 --- /dev/null +++ b/cpp/src/barretenberg/srs/global_crs.cpp @@ -0,0 +1,23 @@ +#include "./global_crs.hpp" +#include "./factories/mem_crs_factory.hpp" +#include "barretenberg/common/throw_or_abort.hpp" + +namespace { +std::shared_ptr crs_factory; +} + +namespace barretenberg::srs { + +void init_crs_factory(std::vector const& points, g2::affine_element const g2_point) +{ + crs_factory = std::make_shared(points, g2_point); +} + +std::shared_ptr get_crs_factory() +{ + if (!crs_factory) { + throw_or_abort("You need to initalize the global CRS with a call to init_crs_factory(...)!"); + } + return crs_factory; +} +} // namespace barretenberg::srs \ No newline at end of file diff --git a/cpp/src/barretenberg/srs/global_crs.hpp b/cpp/src/barretenberg/srs/global_crs.hpp new file mode 100644 index 0000000000..68f657805a --- /dev/null +++ b/cpp/src/barretenberg/srs/global_crs.hpp @@ -0,0 +1,9 @@ +#include "./factories/crs_factory.hpp" + +namespace barretenberg::srs { + +void init_crs_factory(std::vector const& points, + barretenberg::g2::affine_element const g2_point); + +std::shared_ptr get_crs_factory(); +} // namespace barretenberg::srs \ No newline at end of file diff --git a/cpp/src/barretenberg/srs/reference_string/file_reference_string.cpp b/cpp/src/barretenberg/srs/reference_string/file_reference_string.cpp deleted file mode 100644 index 99f09c776c..0000000000 --- a/cpp/src/barretenberg/srs/reference_string/file_reference_string.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "file_reference_string.hpp" -#include "../io.hpp" - -#include "barretenberg/ecc/curves/bn254/pairing.hpp" - -namespace proof_system { - -VerifierFileReferenceString::VerifierFileReferenceString(std::string const& path) - : precomputed_g2_lines( - (barretenberg::pairing::miller_lines*)(aligned_alloc(64, sizeof(barretenberg::pairing::miller_lines) * 2))) -{ - - barretenberg::io::read_transcript_g2(g2_x, path); - barretenberg::pairing::precompute_miller_lines(barretenberg::g2::one, precomputed_g2_lines[0]); - barretenberg::pairing::precompute_miller_lines(g2_x, precomputed_g2_lines[1]); -} - -VerifierFileReferenceString::~VerifierFileReferenceString() -{ - aligned_free(precomputed_g2_lines); -} - -} // namespace proof_system diff --git a/cpp/src/barretenberg/srs/reference_string/file_reference_string.hpp b/cpp/src/barretenberg/srs/reference_string/file_reference_string.hpp deleted file mode 100644 index ef6bebfc0a..0000000000 --- a/cpp/src/barretenberg/srs/reference_string/file_reference_string.hpp +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Create reference strings given a path to a directory of transcript files. - */ -#pragma once -#include "reference_string.hpp" - -#include "barretenberg/ecc/curves/bn254/g1.hpp" -#include "barretenberg/ecc/curves/bn254/g2.hpp" -#include "barretenberg/ecc/curves/bn254/scalar_multiplication/pippenger.hpp" - -#include -#include - -namespace barretenberg::pairing { -struct miller_lines; -} // namespace barretenberg::pairing - -namespace proof_system { - -using namespace barretenberg; - -class VerifierFileReferenceString : public VerifierReferenceString { - public: - VerifierFileReferenceString(std::string const& path); - ~VerifierFileReferenceString(); - - g2::affine_element get_g2x() const override { return g2_x; } - - pairing::miller_lines const* get_precomputed_g2_lines() const override { return precomputed_g2_lines; } - - private: - g2::affine_element g2_x; - pairing::miller_lines* precomputed_g2_lines; -}; - -class FileReferenceString : public ProverReferenceString { - public: - FileReferenceString(const size_t num_points, std::string const& path) - : num_points(num_points) - , pippenger_(path, num_points) - {} - - g1::affine_element* get_monomial_points() override { return pippenger_.get_point_table(); } - - size_t get_monomial_size() const override { return num_points; } - - private: - size_t num_points; - scalar_multiplication::Pippenger pippenger_; -}; - -class FileReferenceStringFactory : public ReferenceStringFactory { - public: - FileReferenceStringFactory(std::string path) - : path_(std::move(path)) - {} - - FileReferenceStringFactory(FileReferenceStringFactory&& other) = default; - - std::shared_ptr get_prover_crs(size_t degree) override - { - return std::make_shared(degree, path_); - } - - std::shared_ptr get_verifier_crs() override - { - return std::make_shared(path_); - } - - private: - std::string path_; -}; - -class DynamicFileReferenceStringFactory : public ReferenceStringFactory { - public: - DynamicFileReferenceStringFactory(std::string path, size_t initial_degree = 0) - : path_(std::move(path)) - , degree_(initial_degree) - , verifier_crs_(std::make_shared(path_)) - {} - - DynamicFileReferenceStringFactory(DynamicFileReferenceStringFactory&& other) = default; - - std::shared_ptr get_prover_crs(size_t degree) override - { - if (degree != degree_) { - prover_crs_ = std::make_shared(degree, path_); - degree_ = degree; - } - return prover_crs_; - } - - std::shared_ptr get_verifier_crs() override { return verifier_crs_; } - - private: - std::string path_; - size_t degree_; - std::shared_ptr prover_crs_; - std::shared_ptr verifier_crs_; -}; - -} // namespace proof_system diff --git a/cpp/src/barretenberg/srs/reference_string/mem_reference_string.cpp b/cpp/src/barretenberg/srs/reference_string/mem_reference_string.cpp deleted file mode 100644 index 0a9c71b40a..0000000000 --- a/cpp/src/barretenberg/srs/reference_string/mem_reference_string.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "mem_reference_string.hpp" -#include "../io.hpp" - -#include "barretenberg/common/streams.hpp" -#include "barretenberg/ecc/curves/bn254/pairing.hpp" - -#include - -namespace proof_system { - -VerifierMemReferenceString::VerifierMemReferenceString(uint8_t const* g2x) - : precomputed_g2_lines( - (barretenberg::pairing::miller_lines*)(aligned_alloc(64, sizeof(barretenberg::pairing::miller_lines) * 2))) -{ - barretenberg::io::read_g2_elements_from_buffer(&g2_x, (char*)g2x, 128); - - barretenberg::pairing::precompute_miller_lines(barretenberg::g2::one, precomputed_g2_lines[0]); - barretenberg::pairing::precompute_miller_lines(g2_x, precomputed_g2_lines[1]); -} - -VerifierMemReferenceString::~VerifierMemReferenceString() -{ - aligned_free(precomputed_g2_lines); -} - -} // namespace proof_system diff --git a/cpp/src/barretenberg/srs/reference_string/mem_reference_string.hpp b/cpp/src/barretenberg/srs/reference_string/mem_reference_string.hpp deleted file mode 100644 index 608446fa77..0000000000 --- a/cpp/src/barretenberg/srs/reference_string/mem_reference_string.hpp +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Create reference strings given a buffer containing network formatted g1 or g2 points. - */ -#pragma once - -#include "reference_string.hpp" - -#include "barretenberg/ecc/curves/bn254/scalar_multiplication/pippenger.hpp" - -namespace barretenberg::pairing { -struct miller_lines; -} // namespace barretenberg::pairing - -namespace proof_system { - -using namespace barretenberg; - -class VerifierMemReferenceString : public VerifierReferenceString { - public: - VerifierMemReferenceString(uint8_t const* g2x); - ~VerifierMemReferenceString() override; - - g2::affine_element get_g2x() const override { return g2_x; } - - pairing::miller_lines const* get_precomputed_g2_lines() const override { return precomputed_g2_lines; } - - private: - g2::affine_element g2_x; - pairing::miller_lines* precomputed_g2_lines; -}; - -} // namespace proof_system diff --git a/cpp/src/barretenberg/srs/reference_string/mem_reference_string.test.cpp b/cpp/src/barretenberg/srs/reference_string/mem_reference_string.test.cpp deleted file mode 100644 index 18701cc537..0000000000 --- a/cpp/src/barretenberg/srs/reference_string/mem_reference_string.test.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "file_reference_string.hpp" -#include "mem_reference_string.hpp" - -#include "barretenberg/ecc/curves/bn254/pairing.hpp" - -#include - -#include - -TEST(reference_string, mem_file_consistency) -{ - std::ifstream transcript; - int NUM_POINTS_IN_TRANSCRIPT = 5040001; - transcript.open("../srs_db/ignition/monomial/transcript00.dat", std::ifstream::binary); - std::vector monomials(32768 * 64); - std::vector g2x(128); - transcript.seekg(28); - transcript.read((char*)monomials.data(), 32768 * 64); - transcript.seekg(28 + NUM_POINTS_IN_TRANSCRIPT * 64); - transcript.read((char*)g2x.data(), 128); - transcript.close(); - - auto mem_verifier = std::make_unique(g2x.data()); - - auto file_crs = std::make_unique("../srs_db/ignition"); - auto file_verifier = file_crs->get_verifier_crs(); - - EXPECT_EQ(mem_verifier->get_g2x(), file_verifier->get_g2x()); - EXPECT_EQ(memcmp(mem_verifier->get_precomputed_g2_lines(), - file_verifier->get_precomputed_g2_lines(), - sizeof(barretenberg::pairing::miller_lines) * 2), - 0); -} diff --git a/cpp/src/barretenberg/srs/reference_string/pippenger_reference_string.hpp b/cpp/src/barretenberg/srs/reference_string/pippenger_reference_string.hpp deleted file mode 100644 index 087b9f5956..0000000000 --- a/cpp/src/barretenberg/srs/reference_string/pippenger_reference_string.hpp +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Create reference strings given a Pippenger instance containing point table formatted monomials. - * Does not take ownership of the given buffer. - */ -#pragma once -#include "mem_reference_string.hpp" - -namespace barretenberg::pairing { -struct miller_lines; -} // namespace barretenberg::pairing - -namespace proof_system { - -using namespace barretenberg; - -class PippengerReferenceString : public ProverReferenceString { - public: - PippengerReferenceString(scalar_multiplication::Pippenger* pippenger) - : pippenger_(pippenger) - {} - - size_t get_monomial_size() const override { return pippenger_->get_num_points(); } - g1::affine_element* get_monomial_points() override { return pippenger_->get_point_table(); } - - private: - scalar_multiplication::Pippenger* pippenger_; -}; - -class PippengerReferenceStringFactory : public ReferenceStringFactory { - public: - PippengerReferenceStringFactory(scalar_multiplication::Pippenger* pippenger, uint8_t const* g2x) - : pippenger_(pippenger) - { - verifier_crs_ = std::make_shared(g2x); - } - - PippengerReferenceStringFactory(PippengerReferenceStringFactory&& other) = default; - - std::shared_ptr get_prover_crs(size_t degree) override - { - ASSERT(degree <= pippenger_->get_num_points()); - return std::make_shared(pippenger_); - } - - std::shared_ptr get_verifier_crs() override { return verifier_crs_; } - - private: - std::shared_ptr verifier_crs_; - scalar_multiplication::Pippenger* pippenger_; -}; - -} // namespace proof_system diff --git a/cpp/src/barretenberg/srs/reference_string/reference_string.hpp b/cpp/src/barretenberg/srs/reference_string/reference_string.hpp deleted file mode 100644 index c389a0819a..0000000000 --- a/cpp/src/barretenberg/srs/reference_string/reference_string.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include "barretenberg/common/mem.hpp" -#include "barretenberg/ecc/curves/bn254/g1.hpp" -#include "barretenberg/ecc/curves/bn254/g2.hpp" - -#include - -namespace barretenberg::pairing { -struct miller_lines; -} // namespace barretenberg::pairing - -namespace proof_system { - -class VerifierReferenceString { - public: - virtual ~VerifierReferenceString() = default; - ; - - virtual barretenberg::g2::affine_element get_g2x() const = 0; - - virtual barretenberg::pairing::miller_lines const* get_precomputed_g2_lines() const = 0; -}; - -class ProverReferenceString { - public: - virtual ~ProverReferenceString() = default; - ; - - virtual barretenberg::g1::affine_element* get_monomial_points() = 0; - virtual size_t get_monomial_size() const = 0; -}; - -// A placeholder factory. Exists because composers need to be given a factory at construction time. -// TODO: Refactor Composer code to only need CRS when actually needed. -class ReferenceStringFactory { - public: - ReferenceStringFactory() = default; - ReferenceStringFactory(ReferenceStringFactory&& other) = default; - virtual ~ReferenceStringFactory() = default; - virtual std::shared_ptr get_prover_crs(size_t) { return nullptr; } - virtual std::shared_ptr get_verifier_crs() { return nullptr; } -}; - -} // namespace proof_system diff --git a/cpp/src/barretenberg/stdlib/commitment/pedersen/pedersen.bench.cpp b/cpp/src/barretenberg/stdlib/commitment/pedersen/pedersen.bench.cpp index 8726b6ecc6..11847b6dbd 100644 --- a/cpp/src/barretenberg/stdlib/commitment/pedersen/pedersen.bench.cpp +++ b/cpp/src/barretenberg/stdlib/commitment/pedersen/pedersen.bench.cpp @@ -4,7 +4,7 @@ #include "barretenberg/ecc/curves/bn254/fr.hpp" #include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp" #include "barretenberg/plonk/composer/turbo_composer.hpp" -#include "barretenberg/srs/reference_string/file_reference_string.hpp" +#include "barretenberg/srs/factories/file_crs_factory.hpp" #include "barretenberg/stdlib/primitives/field/field.hpp" #define BARRETENBERG_SRS_PATH "../srs_db/ignition" diff --git a/cpp/src/barretenberg/stdlib/primitives/bool/bool.hpp b/cpp/src/barretenberg/stdlib/primitives/bool/bool.hpp index 40889aefec..86e98acf9e 100644 --- a/cpp/src/barretenberg/stdlib/primitives/bool/bool.hpp +++ b/cpp/src/barretenberg/stdlib/primitives/bool/bool.hpp @@ -1,10 +1,8 @@ #pragma once #include "../composers/composers_fwd.hpp" #include "../witness/witness.hpp" -#include "barretenberg/honk/composer/standard_honk_composer.hpp" -namespace proof_system::plonk { -namespace stdlib { +namespace proof_system::plonk::stdlib { template class bool_t { public: @@ -78,7 +76,5 @@ template inline std::ostream& operator<<(std::ostream& os, bool_t; -} // namespace stdlib -} // namespace proof_system::plonk +} // namespace proof_system::plonk::stdlib diff --git a/cpp/src/barretenberg/stdlib/primitives/witness/witness.hpp b/cpp/src/barretenberg/stdlib/primitives/witness/witness.hpp index a157c9022d..18e8ae164d 100644 --- a/cpp/src/barretenberg/stdlib/primitives/witness/witness.hpp +++ b/cpp/src/barretenberg/stdlib/primitives/witness/witness.hpp @@ -1,5 +1,6 @@ #pragma once -#include "barretenberg/plonk/composer/composer_base.hpp" +#include +#include #include "barretenberg/ecc/curves/bn254/fr.hpp" namespace proof_system::plonk { diff --git a/cpp/src/barretenberg/stdlib/recursion/verification_key/verification_key.hpp b/cpp/src/barretenberg/stdlib/recursion/verification_key/verification_key.hpp index 0c91945554..f8f21642d2 100644 --- a/cpp/src/barretenberg/stdlib/recursion/verification_key/verification_key.hpp +++ b/cpp/src/barretenberg/stdlib/recursion/verification_key/verification_key.hpp @@ -1,6 +1,6 @@ #pragma once #include -#include "barretenberg/srs/reference_string/reference_string.hpp" +#include "barretenberg/srs/factories/crs_factory.hpp" #include "barretenberg/polynomials/evaluation_domain.hpp" #include "barretenberg/plonk/proof_system/types/polynomial_manifest.hpp" @@ -390,7 +390,7 @@ template struct verification_key { // Native data: - std::shared_ptr reference_string; + std::shared_ptr reference_string; PolynomialManifest polynomial_manifest; diff --git a/cpp/src/barretenberg/stdlib/recursion/verification_key/verification_key.test.cpp b/cpp/src/barretenberg/stdlib/recursion/verification_key/verification_key.test.cpp index 755d751ff2..692b5425b9 100644 --- a/cpp/src/barretenberg/stdlib/recursion/verification_key/verification_key.test.cpp +++ b/cpp/src/barretenberg/stdlib/recursion/verification_key/verification_key.test.cpp @@ -56,7 +56,7 @@ TYPED_TEST(VerificationKeyFixture, vk_data_vs_recursion_compress_native) verification_key_data vk_data = TestFixture::rand_vk_data(); verification_key_data vk_data_copy = vk_data; - auto file_crs = std::make_unique("../srs_db/ignition"); + auto file_crs = std::make_unique("../srs_db/ignition"); auto file_verifier = file_crs->get_verifier_crs(); auto native_vk = std::make_shared(std::move(vk_data_copy), file_verifier); @@ -76,7 +76,7 @@ TYPED_TEST(VerificationKeyFixture, compress_vs_compress_native) verification_key_data vk_data = TestFixture::rand_vk_data(); - auto file_crs = std::make_unique("../srs_db/ignition"); + auto file_crs = std::make_unique("../srs_db/ignition"); auto file_verifier = file_crs->get_verifier_crs(); auto native_vk = std::make_shared(std::move(vk_data), file_verifier); diff --git a/exports.json b/exports.json index 2a9eb19970..4a9b66ce7c 100644 --- a/exports.json +++ b/exports.json @@ -463,116 +463,27 @@ "isAsync": false }, { - "functionName": "ecc_new_pippenger", + "functionName": "srs_init_srs", "inArgs": [ { - "name": "points", + "name": "points_buf", "type": "const uint8_t *" }, - { - "name": "num_points_buf", - "type": "const uint32_t *" - } - ], - "outArgs": [ - { - "name": "out", - "type": "out_ptr" - } - ], - "isAsync": false - }, - { - "functionName": "ecc_new_pippenger_mem_prealloced", - "inArgs": [ - { - "name": "points", - "type": "in_ptr" - }, { "name": "num_points", "type": "const uint32_t *" - } - ], - "outArgs": [ - { - "name": "out", - "type": "out_ptr" - } - ], - "isAsync": false - }, - { - "functionName": "ecc_delete_pippenger", - "inArgs": [ - { - "name": "pippenger", - "type": "in_ptr" - } - ], - "outArgs": [], - "isAsync": false - }, - { - "functionName": "ecc_pippenger_unsafe", - "inArgs": [ - { - "name": "pippenger_ptr", - "type": "in_ptr" - }, - { - "name": "scalars_ptr", - "type": "in_ptr" - }, - { - "name": "from", - "type": "const uint32_t *" }, { - "name": "range", - "type": "const uint32_t *" - } - ], - "outArgs": [ - { - "name": "result_ptr", - "type": "affine_element::out_buf" - } - ], - "isAsync": false - }, - { - "functionName": "ecc_g1_sum", - "inArgs": [ - { - "name": "points_ptr", - "type": "in_ptr" - }, - { - "name": "num_points", - "type": "const uint32_t *" - } - ], - "outArgs": [ - { - "name": "result_ptr", - "type": "affine_element::out_buf" + "name": "g2_point_buf", + "type": "const uint8_t *" } ], + "outArgs": [], "isAsync": false }, { "functionName": "examples_simple_create_and_verify_proof", - "inArgs": [ - { - "name": "pippenger", - "type": "in_ptr" - }, - { - "name": "g2x", - "type": "const uint8_t *" - } - ], + "inArgs": [], "outArgs": [ { "name": "valid", @@ -626,16 +537,7 @@ }, { "functionName": "acir_new_acir_composer", - "inArgs": [ - { - "name": "pippenger", - "type": "in_ptr" - }, - { - "name": "g2x", - "type": "const uint8_t *" - } - ], + "inArgs": [], "outArgs": [ { "name": "out", @@ -655,6 +557,25 @@ "outArgs": [], "isAsync": false }, + { + "functionName": "acir_create_circuit", + "inArgs": [ + { + "name": "acir_composer_ptr", + "type": "in_ptr" + }, + { + "name": "constraint_system_buf", + "type": "const uint8_t *" + }, + { + "name": "size_hint", + "type": "const uint32_t *" + } + ], + "outArgs": [], + "isAsync": false + }, { "functionName": "acir_init_proving_key", "inArgs": [ diff --git a/scripts/c_bind_files.txt b/scripts/c_bind_files.txt index 1672812fa7..a84057549b 100644 --- a/scripts/c_bind_files.txt +++ b/scripts/c_bind_files.txt @@ -2,7 +2,7 @@ ./cpp/src/barretenberg/crypto/pedersen_hash/c_bind.hpp ./cpp/src/barretenberg/crypto/blake2s/c_bind.hpp ./cpp/src/barretenberg/crypto/schnorr/c_bind.hpp -./cpp/src/barretenberg/ecc/c_bind.hpp +./cpp/src/barretenberg/srs/c_bind.hpp ./cpp/src/barretenberg/examples/c_bind.hpp ./cpp/src/barretenberg/common/c_bind.hpp ./cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp diff --git a/ts/src/barretenberg_api/index.ts b/ts/src/barretenberg_api/index.ts index 671251f927..c903f06213 100644 --- a/ts/src/barretenberg_api/index.ts +++ b/ts/src/barretenberg_api/index.ts @@ -136,33 +136,13 @@ export class BarretenbergApi { return result as any; } - async eccNewPippenger(points: Uint8Array, numPointsBuf: number): Promise { - const result = await this.binder.callWasmExport('ecc_new_pippenger', [points, numPointsBuf], [Ptr]); - return result[0]; - } - - async eccNewPippengerMemPrealloced(points: Ptr, numPoints: number): Promise { - const result = await this.binder.callWasmExport('ecc_new_pippenger_mem_prealloced', [points, numPoints], [Ptr]); - return result[0]; - } - - async eccDeletePippenger(pippenger: Ptr): Promise { - const result = await this.binder.callWasmExport('ecc_delete_pippenger', [pippenger], []); + async srsInitSrs(pointsBuf: Uint8Array, numPoints: number, g2PointBuf: Uint8Array): Promise { + const result = await this.binder.callWasmExport('srs_init_srs', [pointsBuf, numPoints, g2PointBuf], []); return; } - async eccPippengerUnsafe(pippengerPtr: Ptr, scalarsPtr: Ptr, from: number, range: number): Promise { - const result = await this.binder.callWasmExport('ecc_pippenger_unsafe', [pippengerPtr, scalarsPtr, from, range], [Point]); - return result[0]; - } - - async eccG1Sum(pointsPtr: Ptr, numPoints: number): Promise { - const result = await this.binder.callWasmExport('ecc_g1_sum', [pointsPtr, numPoints], [Point]); - return result[0]; - } - - async examplesSimpleCreateAndVerifyProof(pippenger: Ptr, g2x: Uint8Array): Promise { - const result = await this.binder.callWasmExport('examples_simple_create_and_verify_proof', [pippenger, g2x], [BoolDeserializer()]); + async examplesSimpleCreateAndVerifyProof(): Promise { + const result = await this.binder.callWasmExport('examples_simple_create_and_verify_proof', [], [BoolDeserializer()]); return result[0]; } @@ -186,8 +166,8 @@ export class BarretenbergApi { return; } - async acirNewAcirComposer(pippenger: Ptr, g2x: Uint8Array): Promise { - const result = await this.binder.callWasmExport('acir_new_acir_composer', [pippenger, g2x], [Ptr]); + async acirNewAcirComposer(): Promise { + const result = await this.binder.callWasmExport('acir_new_acir_composer', [], [Ptr]); return result[0]; } @@ -196,6 +176,11 @@ export class BarretenbergApi { return; } + async acirCreateCircuit(acirComposerPtr: Ptr, constraintSystemBuf: Uint8Array, sizeHint: number): Promise { + const result = await this.binder.callWasmExport('acir_create_circuit', [acirComposerPtr, constraintSystemBuf, sizeHint], []); + return; + } + async acirInitProvingKey(acirComposerPtr: Ptr, constraintSystemBuf: Uint8Array, sizeHint: number): Promise { const result = await this.binder.callWasmExport('acir_init_proving_key', [acirComposerPtr, constraintSystemBuf, sizeHint], []); return; @@ -369,33 +354,13 @@ export class BarretenbergApiSync { return result as any; } - eccNewPippenger(points: Uint8Array, numPointsBuf: number): Ptr { - const result = this.binder.callWasmExport('ecc_new_pippenger', [points, numPointsBuf], [Ptr]); - return result[0]; - } - - eccNewPippengerMemPrealloced(points: Ptr, numPoints: number): Ptr { - const result = this.binder.callWasmExport('ecc_new_pippenger_mem_prealloced', [points, numPoints], [Ptr]); - return result[0]; - } - - eccDeletePippenger(pippenger: Ptr): void { - const result = this.binder.callWasmExport('ecc_delete_pippenger', [pippenger], []); + srsInitSrs(pointsBuf: Uint8Array, numPoints: number, g2PointBuf: Uint8Array): void { + const result = this.binder.callWasmExport('srs_init_srs', [pointsBuf, numPoints, g2PointBuf], []); return; } - eccPippengerUnsafe(pippengerPtr: Ptr, scalarsPtr: Ptr, from: number, range: number): Point { - const result = this.binder.callWasmExport('ecc_pippenger_unsafe', [pippengerPtr, scalarsPtr, from, range], [Point]); - return result[0]; - } - - eccG1Sum(pointsPtr: Ptr, numPoints: number): Point { - const result = this.binder.callWasmExport('ecc_g1_sum', [pointsPtr, numPoints], [Point]); - return result[0]; - } - - examplesSimpleCreateAndVerifyProof(pippenger: Ptr, g2x: Uint8Array): boolean { - const result = this.binder.callWasmExport('examples_simple_create_and_verify_proof', [pippenger, g2x], [BoolDeserializer()]); + examplesSimpleCreateAndVerifyProof(): boolean { + const result = this.binder.callWasmExport('examples_simple_create_and_verify_proof', [], [BoolDeserializer()]); return result[0]; } @@ -419,8 +384,8 @@ export class BarretenbergApiSync { return; } - acirNewAcirComposer(pippenger: Ptr, g2x: Uint8Array): Ptr { - const result = this.binder.callWasmExport('acir_new_acir_composer', [pippenger, g2x], [Ptr]); + acirNewAcirComposer(): Ptr { + const result = this.binder.callWasmExport('acir_new_acir_composer', [], [Ptr]); return result[0]; } @@ -429,6 +394,11 @@ export class BarretenbergApiSync { return; } + acirCreateCircuit(acirComposerPtr: Ptr, constraintSystemBuf: Uint8Array, sizeHint: number): void { + const result = this.binder.callWasmExport('acir_create_circuit', [acirComposerPtr, constraintSystemBuf, sizeHint], []); + return; + } + acirInitProvingKey(acirComposerPtr: Ptr, constraintSystemBuf: Uint8Array, sizeHint: number): void { const result = this.binder.callWasmExport('acir_init_proving_key', [acirComposerPtr, constraintSystemBuf, sizeHint], []); return; diff --git a/ts/src/crs/browser/cached_net_crs.ts b/ts/src/crs/browser/cached_net_crs.ts index 3152933d3b..d2822d68a2 100644 --- a/ts/src/crs/browser/cached_net_crs.ts +++ b/ts/src/crs/browser/cached_net_crs.ts @@ -1,3 +1,4 @@ +import { concatenateUint8Arrays, numToUInt32BE } from '../../serialize/index.js'; import { NetCrs } from '../net_crs.js'; import { get, set } from 'idb-keyval'; diff --git a/ts/src/crs/node/index.ts b/ts/src/crs/node/index.ts index 7598b10148..f66646c96b 100644 --- a/ts/src/crs/node/index.ts +++ b/ts/src/crs/node/index.ts @@ -1,3 +1,4 @@ +import { concatenateUint8Arrays, numToUInt32BE } from '../../serialize/serialize.js'; import { NetCrs } from '../net_crs.js'; import { FileCrs } from './file_crs.js'; diff --git a/ts/src/examples/simple.rawtest.ts b/ts/src/examples/simple.rawtest.ts index e7f0ce8325..5998376f23 100644 --- a/ts/src/examples/simple.rawtest.ts +++ b/ts/src/examples/simple.rawtest.ts @@ -1,6 +1,7 @@ import { Crs } from '../crs/index.js'; import createDebug from 'debug'; import { newBarretenbergApiAsync } from '../factory/index.js'; +import { RawBuffer } from '../types/index.js'; createDebug.enable('*'); const debug = createDebug('simple_test'); @@ -11,16 +12,16 @@ async function main() { debug('starting test...'); const api = await newBarretenbergApiAsync(); - // Import to init slab allocator as first thing, to ensure maximum memory efficiency. + // Important to init slab allocator as first thing, to ensure maximum memory efficiency. await api.commonInitSlabAllocator(CIRCUIT_SIZE); // Plus 1 needed! const crs = await Crs.new(CIRCUIT_SIZE + 1); - const pippengerPtr = await api.eccNewPippenger(crs.getG1Data(), crs.numPoints); + await api.srsInitSrs(new RawBuffer(crs.getG1Data()), crs.numPoints, new RawBuffer(crs.getG2Data())); for (let i = 0; i < 10; ++i) { debug(`iteration ${i} starting...`); - await api.examplesSimpleCreateAndVerifyProof(pippengerPtr, crs.getG2Data()); + await api.examplesSimpleCreateAndVerifyProof(); } await api.destroy(); diff --git a/ts/src/examples/simple.test.ts b/ts/src/examples/simple.test.ts index 45f6489a13..c32496fdfc 100644 --- a/ts/src/examples/simple.test.ts +++ b/ts/src/examples/simple.test.ts @@ -1,5 +1,6 @@ import { Crs } from '../index.js'; import { BarretenbergApiAsync, newBarretenbergApiAsync } from '../factory/index.js'; +import { RawBuffer } from '../types/index.js'; describe('simple', () => { let api: BarretenbergApiAsync; @@ -7,9 +8,12 @@ describe('simple', () => { beforeAll(async () => { api = await newBarretenbergApiAsync(); - // Import to init slab allocator as first thing, to ensure maximum memory efficiency. + // Important to init slab allocator as first thing, to ensure maximum memory efficiency. const CIRCUIT_SIZE = 2 ** 19; await api.commonInitSlabAllocator(CIRCUIT_SIZE); + + const crs = await Crs.new(2 ** 19 + 1); + await api.srsInitSrs(new RawBuffer(crs.getG1Data()), crs.numPoints, new RawBuffer(crs.getG2Data())); }, 20000); afterAll(async () => { @@ -17,9 +21,7 @@ describe('simple', () => { }); it('should construct 512k gate proof', async () => { - const crs = await Crs.new(2 ** 19 + 1); - const pippengerPtr = await api.eccNewPippenger(crs.getG1Data(), crs.numPoints); - const valid = await api.examplesSimpleCreateAndVerifyProof(pippengerPtr, crs.getG2Data()); + const valid = await api.examplesSimpleCreateAndVerifyProof(); expect(valid).toBe(true); }, 60000); }); diff --git a/ts/src/main.ts b/ts/src/main.ts index 98779ee0ed..c5a04d06cd 100755 --- a/ts/src/main.ts +++ b/ts/src/main.ts @@ -5,12 +5,12 @@ import { newBarretenbergApiAsync } from './factory/index.js'; import { readFileSync, writeFileSync } from 'fs'; import { gunzipSync } from 'zlib'; import { RawBuffer } from './types/index.js'; -import { numToInt32BE } from './serialize/serialize.js'; +import { numToUInt32BE } from './serialize/serialize.js'; import { Command } from 'commander'; createDebug.log = console.error.bind(console); const debug = createDebug('bb.js'); -createDebug.enable('*'); +// createDebug.enable('*'); // Maximum we support. const CIRCUIT_SIZE = 2 ** 19; @@ -25,7 +25,7 @@ function getBytecode(jsonPath: string) { function getWitness(witnessPath: string) { const data = readFileSync(witnessPath); - return Buffer.concat([numToInt32BE(data.length / 32), data]); + return Buffer.concat([numToUInt32BE(data.length / 32), data]); } async function init() { @@ -37,8 +37,11 @@ async function init() { // Import to init slab allocator as first thing, to ensure maximum memory efficiency. await api.commonInitSlabAllocator(CIRCUIT_SIZE); - const pippengerPtr = await api.eccNewPippenger(crs.getG1Data(), crs.numPoints); - const acirComposer = await api.acirNewAcirComposer(pippengerPtr, crs.getG2Data()); + // Load CRS into wasm global CRS state. + // TODO: Make RawBuffer be default behaviour, and have a specific Vector type for when wanting length prefixed. + await api.srsInitSrs(new RawBuffer(crs.getG1Data()), crs.numPoints, new RawBuffer(crs.getG2Data())); + + const acirComposer = await api.acirNewAcirComposer(); return { api, acirComposer }; } @@ -61,7 +64,7 @@ export async function proveAndVerify(jsonPath: string, witnessPath: string) { const proof = await api.acirCreateProof(acirComposer, new RawBuffer(bytecode), new RawBuffer(witness)); const verified = await api.acirVerifyProof(acirComposer, proof); - debug(`verified: ${verified}`); + console.log(`verified: ${verified}`); return verified; } finally { await api.destroy(); @@ -83,7 +86,20 @@ export async function prove(jsonPath: string, witnessPath: string, outputPath: s const proof = await api.acirCreateProof(acirComposer, new RawBuffer(bytecode), new RawBuffer(witness)); writeFileSync(outputPath, proof); - debug('done.'); + console.log(`proof written to: ${outputPath}`); + } finally { + await api.destroy(); + } +} + +export async function gateCount(jsonPath: string) { + const { api, acirComposer } = await init(); + try { + const bytecode = getBytecode(jsonPath); + await api.acirCreateCircuit(acirComposer, new RawBuffer(bytecode), CIRCUIT_SIZE); + + const gates = await api.acirGetTotalCircuitSize(acirComposer); + console.log(`${gates}`); } finally { await api.destroy(); } @@ -100,7 +116,7 @@ export async function verify(jsonPath: string, proofPath: string) { await api.acirInitVerificationKey(acirComposer); const verified = await api.acirVerifyProof(acirComposer, readFileSync(proofPath)); - debug(`verified: ${verified}`); + console.log(`verified: ${verified}`); return verified; } finally { await api.destroy(); @@ -122,7 +138,7 @@ export async function contract(jsonPath: string, outputPath: string) { console.log(contract); } else { writeFileSync(outputPath, contract); - debug(`contract written to: ${outputPath}`); + console.log(`contract written to: ${outputPath}`); } } finally { await api.destroy(); @@ -142,7 +158,7 @@ export async function writeVk(jsonPath: string, outputPath: string) { process.stdout.write(vk); } else { writeFileSync(outputPath, vk); - debug(`vk written to: ${outputPath}`); + console.log(`vk written to: ${outputPath}`); } } finally { await api.destroy(); @@ -181,6 +197,14 @@ program await prove(jsonPath, witnessPath, outputDir + '/' + name); }); +program + .command('gates') + .description('Print gate count to standard output.') + .option('-j, --json-path ', 'Specify the JSON path', './target/main.json') + .action(async ({ jsonPath }) => { + await gateCount(jsonPath); + }); + program .command('verify') .description('Verify a proof. Process exists with success or failure code.') @@ -194,7 +218,7 @@ program .command('contract') .description('Output solidity verification key contract.') .option('-j, --json-path ', 'Specify the JSON path', './target/main.json') - .requiredOption('-o, --output-path ', 'Specify the path to write the contract') + .option('-o, --output-path ', 'Specify the path to write the contract', '-') .action(async ({ jsonPath, outputPath }) => { await contract(jsonPath, outputPath); }); @@ -208,4 +232,4 @@ program await writeVk(jsonPath, outputPath); }); -program.parse(process.argv); +program.name('bb.js').parse(process.argv); diff --git a/ts/src/serialize/serialize.ts b/ts/src/serialize/serialize.ts index 29613d7fc9..aa3634cc73 100644 --- a/ts/src/serialize/serialize.ts +++ b/ts/src/serialize/serialize.ts @@ -35,7 +35,7 @@ export function numToUInt8(n: number) { return buf; } -function concatenateUint8Arrays(arrayOfUint8Arrays: Uint8Array[]) { +export function concatenateUint8Arrays(arrayOfUint8Arrays: Uint8Array[]) { const totalLength = arrayOfUint8Arrays.reduce((prev, curr) => prev + curr.length, 0); const result = new Uint8Array(totalLength); let length = 0; diff --git a/ts/src/serialize/serialize.ts.bak b/ts/src/serialize/serialize.ts.bak deleted file mode 100644 index bb5e3d677f..0000000000 --- a/ts/src/serialize/serialize.ts.bak +++ /dev/null @@ -1,132 +0,0 @@ -import { toBigIntBE, toBufferBE } from 'bigint-buffer'; - -// For serializing bool. -export function boolToBuffer(b: boolean) { - const buf = Buffer.alloc(1); - buf.writeUInt8(b ? 1 : 0); - return buf; -} - -// For serializing numbers to 32 bit little-endian form. -export function numToUInt32LE(n: number, bufferSize = 4) { - const buf = Buffer.alloc(bufferSize); - buf.writeUInt32LE(n, bufferSize - 4); - return buf; -} - -// For serializing numbers to 32 bit big-endian form. -export function numToUInt32BE(n: number, bufferSize = 4) { - const buf = Buffer.alloc(bufferSize); - buf.writeUInt32BE(n, bufferSize - 4); - return buf; -} - -// For serializing signed numbers to 32 bit big-endian form. -export function numToInt32BE(n: number, bufferSize = 4) { - const buf = Buffer.alloc(bufferSize); - buf.writeInt32BE(n, bufferSize - 4); - return buf; -} - -// For serializing numbers to 32 bit big-endian form. -export function numToUInt8(n: number) { - const bufferSize = 1; - const buf = Buffer.alloc(bufferSize); - buf.writeUInt8(n, 0); - return buf; -} - -// For serializing a buffer as a vector. -export function serializeBufferToVector(buf: Buffer) { - const lengthBuf = Buffer.alloc(4); - lengthBuf.writeUInt32BE(buf.length, 0); - return Buffer.concat([lengthBuf, buf]); -} - -export function serializeBigInt(n: bigint, width = 32) { - return toBufferBE(n, width); -} - -export function deserializeBigInt(buf: Buffer, offset = 0, width = 32) { - return { elem: toBigIntBE(buf.slice(offset, offset + width)), adv: width }; -} - -export function serializeDate(date: Date) { - return serializeBigInt(BigInt(date.getTime()), 8); -} - -export function deserializeBufferFromVector(vector: Buffer, offset = 0) { - const length = vector.readUInt32BE(offset); - const adv = 4 + length; - return { elem: vector.slice(offset + 4, offset + adv), adv }; -} - -export function deserializeBool(buf: Buffer, offset = 0) { - const adv = 1; - return { elem: buf.readUInt8(offset), adv }; -} - -export function deserializeUInt32(buf: Buffer, offset = 0) { - const adv = 4; - return { elem: buf.readUInt32BE(offset), adv }; -} - -export function deserializeInt32(buf: Buffer, offset = 0) { - const adv = 4; - return { elem: buf.readInt32BE(offset), adv }; -} - -export function deserializeField(buf: Buffer, offset = 0) { - const adv = 32; - return { elem: buf.slice(offset, offset + adv), adv }; -} - -// For serializing an array of fixed length elements. -export function serializeBufferArrayToVector(arr: Buffer[]) { - const lengthBuf = Buffer.alloc(4); - lengthBuf.writeUInt32BE(arr.length, 0); - return Buffer.concat([lengthBuf, ...arr]); -} - -export function deserializeArrayFromVector( - deserialize: (buf: Buffer, offset: number) => { elem: T; adv: number }, - vector: Buffer, - offset = 0, -) { - let pos = offset; - const size = vector.readUInt32BE(pos); - pos += 4; - const arr = new Array(size); - for (let i = 0; i < size; ++i) { - const { elem, adv } = deserialize(vector, pos); - pos += adv; - arr[i] = elem; - } - return { elem: arr, adv: pos - offset }; -} - -/** A type that can be written to a buffer. */ -export type Bufferable = boolean | Buffer | number | string | { toBuffer: () => Buffer } | Bufferable[]; - -/** - * Serializes a list of objects contiguously for calling into wasm. - * @param objs - Objects to serialize. - * @returns A buffer list with the concatenation of all fields. - */ -export function serializeBufferable(obj: Bufferable): Buffer { - if (Array.isArray(obj)) { - return serializeBufferArrayToVector(obj.map(serializeBufferable)); - } else if (Buffer.isBuffer(obj)) { - return serializeBufferToVector(obj); - } else if (typeof obj === 'boolean') { - return boolToBuffer(obj); - } else if (typeof obj === 'number') { - return numToUInt32BE(obj); - } else if (typeof obj === 'bigint') { - return serializeBigInt(obj); - } else if (typeof obj === 'string') { - return serializeBufferToVector(Buffer.from(obj)); - } else { - return obj.toBuffer(); - } -} From 97a2fdf673f6a779a3a79970b57cdb6992def7b1 Mon Sep 17 00:00:00 2001 From: Charlie Lye Date: Sat, 27 May 2023 02:09:45 +0000 Subject: [PATCH 26/29] Add back vk serialization for a3 --- .../verification_key/verification_key.cpp | 2 +- .../verification_key/verification_key.hpp | 87 ++++++++++++++++--- cpp/src/barretenberg/srs/global_crs.cpp | 5 ++ 3 files changed, 79 insertions(+), 15 deletions(-) diff --git a/cpp/src/barretenberg/plonk/proof_system/verification_key/verification_key.cpp b/cpp/src/barretenberg/plonk/proof_system/verification_key/verification_key.cpp index c51d941191..e60160615a 100644 --- a/cpp/src/barretenberg/plonk/proof_system/verification_key/verification_key.cpp +++ b/cpp/src/barretenberg/plonk/proof_system/verification_key/verification_key.cpp @@ -49,7 +49,7 @@ barretenberg::fr compress_native_evaluation_domain(barretenberg::evaluation_doma * @param hash_index generator index to use during pedersen compression * @returns a field containing the compression */ -barretenberg::fr verification_key_data::compress_native(const size_t hash_index) +barretenberg::fr verification_key_data::compress_native(const size_t hash_index) const { barretenberg::evaluation_domain eval_domain = barretenberg::evaluation_domain(circuit_size); diff --git a/cpp/src/barretenberg/plonk/proof_system/verification_key/verification_key.hpp b/cpp/src/barretenberg/plonk/proof_system/verification_key/verification_key.hpp index cbac2cc4c8..4b2d756d8d 100644 --- a/cpp/src/barretenberg/plonk/proof_system/verification_key/verification_key.hpp +++ b/cpp/src/barretenberg/plonk/proof_system/verification_key/verification_key.hpp @@ -1,7 +1,7 @@ #pragma once #include #include "barretenberg/common/streams.hpp" -#include "barretenberg/srs/factories/crs_factory.hpp" +#include "barretenberg/srs/global_crs.hpp" #include "barretenberg/ecc/curves/bn254/fr.hpp" #include "barretenberg/polynomials/evaluation_domain.hpp" #include "barretenberg/crypto/sha256/sha256.hpp" @@ -25,7 +25,7 @@ struct verification_key_data { commitments, contains_recursive_proof, recursive_proof_public_input_indices); - barretenberg::fr compress_native(size_t const hash_index = 0); + barretenberg::fr compress_native(size_t const hash_index = 0) const; }; template inline void read(B& buf, verification_key_data& key) @@ -50,6 +50,16 @@ template inline void write(B& buf, verification_key_data const& key write(buf, key.recursive_proof_public_input_indices); } +inline std::ostream& operator<<(std::ostream& os, verification_key_data const& key) +{ + return os << "key.composer_type: " << key.composer_type << "\n" + << "key.circuit_size: " << static_cast(key.circuit_size) << "\n" + << "key.num_public_inputs: " << static_cast(key.num_public_inputs) << "\n" + << "key.commitments: " << key.commitments << "\n" + << "key.contains_recursive_proof: " << key.contains_recursive_proof << "\n" + << "key.recursive_proof_public_input_indices: " << key.recursive_proof_public_input_indices << "\n"; +}; + inline bool operator==(verification_key_data const& lhs, verification_key_data const& rhs) { return lhs.composer_type == rhs.composer_type && lhs.circuit_size == rhs.circuit_size && @@ -73,6 +83,18 @@ struct verification_key { sha256::hash sha256_hash(); + verification_key_data as_data() const + { + return { + .composer_type = composer_type, + .circuit_size = (uint32_t)circuit_size, + .num_public_inputs = (uint32_t)num_public_inputs, + .commitments = commitments, + .contains_recursive_proof = contains_recursive_proof, + .recursive_proof_public_input_indices = recursive_proof_public_input_indices, + }; + } + uint32_t composer_type; size_t circuit_size; size_t log_circuit_size; @@ -93,27 +115,64 @@ struct verification_key { bool contains_recursive_proof = false; std::vector recursive_proof_public_input_indices; size_t program_width = 3; + + // for serialization: update with new fields + void msgpack_pack(auto& packer) const + { + verification_key_data data = { composer_type, + static_cast(circuit_size), + static_cast(num_public_inputs), + commitments, + contains_recursive_proof, + recursive_proof_public_input_indices }; + packer.pack(data); + } + void msgpack_unpack(auto obj) + { + verification_key_data data = obj; + *this = verification_key{ std::move(data), barretenberg::srs::get_crs_factory()->get_verifier_crs() }; + } }; +// specialize schema serialization +inline void msgpack_schema(auto& packer, proof_system::plonk::verification_key const&) +{ + packer.pack_schema(proof_system::plonk::verification_key_data{}); +} + +template inline void read(B& buf, verification_key& key) +{ + using serialize::read; + verification_key_data vk_data; + read(buf, vk_data); + key = verification_key{ std::move(vk_data), barretenberg::srs::get_crs_factory()->get_verifier_crs() }; +} + +template inline void read(B& buf, std::shared_ptr& key) +{ + using serialize::read; + verification_key_data vk_data; + read(buf, vk_data); + key = std::make_shared(std::move(vk_data), + barretenberg::srs::get_crs_factory()->get_verifier_crs()); +} + template inline void write(B& buf, verification_key const& key) { using serialize::write; - write(buf, key.composer_type); - write(buf, static_cast(key.circuit_size)); - write(buf, static_cast(key.num_public_inputs)); - write(buf, key.commitments); - write(buf, key.contains_recursive_proof); - write(buf, key.recursive_proof_public_input_indices); + write(buf, key.as_data()); } inline std::ostream& operator<<(std::ostream& os, verification_key const& key) { - return os << "key.composer_type: " << key.composer_type << "\n" - << "key.circuit_size: " << static_cast(key.circuit_size) << "\n" - << "key.num_public_inputs: " << static_cast(key.num_public_inputs) << "\n" - << "key.commitments: " << key.commitments << "\n" - << "key.contains_recursive_proof: " << key.contains_recursive_proof << "\n" - << "key.recursive_proof_public_input_indices: " << key.recursive_proof_public_input_indices << "\n"; + return os << key.as_data(); }; } // namespace proof_system::plonk + +// help our msgpack schema compiler with this struct +// Alias verification_key as verification_key_data +inline void msgpack_schema_pack(auto& packer, proof_system::plonk::verification_key const&) +{ + msgpack_schema_pack(packer, proof_system::plonk::verification_key_data{}); +} \ No newline at end of file diff --git a/cpp/src/barretenberg/srs/global_crs.cpp b/cpp/src/barretenberg/srs/global_crs.cpp index d14b0ba140..f86cf924d3 100644 --- a/cpp/src/barretenberg/srs/global_crs.cpp +++ b/cpp/src/barretenberg/srs/global_crs.cpp @@ -1,5 +1,6 @@ #include "./global_crs.hpp" #include "./factories/mem_crs_factory.hpp" +#include "./factories/file_crs_factory.hpp" #include "barretenberg/common/throw_or_abort.hpp" namespace { @@ -16,7 +17,11 @@ void init_crs_factory(std::vector const& points, g2::affine_ std::shared_ptr get_crs_factory() { if (!crs_factory) { +#ifdef __wasm__ throw_or_abort("You need to initalize the global CRS with a call to init_crs_factory(...)!"); +#else + crs_factory = std::make_shared("../srs_db/ignition"); +#endif } return crs_factory; } From 04b60248992875d0bffd65c906df2051c8677f70 Mon Sep 17 00:00:00 2001 From: Charlie Lye Date: Sat, 27 May 2023 02:26:06 +0000 Subject: [PATCH 27/29] Clean --- cpp/src/barretenberg/api/uint.hpp | 14 -------------- .../barretenberg/dsl/acir_proofs/acir_composer.cpp | 3 +-- cpp/src/barretenberg/ecc/fields/field2.hpp | 1 - 3 files changed, 1 insertion(+), 17 deletions(-) delete mode 100644 cpp/src/barretenberg/api/uint.hpp diff --git a/cpp/src/barretenberg/api/uint.hpp b/cpp/src/barretenberg/api/uint.hpp deleted file mode 100644 index 22f95afdcb..0000000000 --- a/cpp/src/barretenberg/api/uint.hpp +++ /dev/null @@ -1,14 +0,0 @@ - -namespace proof_system::plonk::stdlib { -template class uint_plookup; -} - -namespace barretenberg::api::plonk::ultra { - -class ct_witness { - - private: - proof_system::plonk::stdlib::uint_plookup* underlying -}; - -} // namespace barretenberg::api::plonk::ultra \ No newline at end of file diff --git a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp index 33b8e89389..12fe771c25 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp @@ -26,8 +26,7 @@ void AcirComposer::create_circuit(acir_format::acir_format& constraint_system, s exact_circuit_size_ = composer_.get_num_gates(); total_circuit_size_ = composer_.get_total_circuit_size(); - // Exact or total fed in here? - circuit_subgroup_size_ = composer_.get_circuit_subgroup_size(exact_circuit_size_); + circuit_subgroup_size_ = composer_.get_circuit_subgroup_size(total_circuit_size_); } void AcirComposer::init_proving_key(acir_format::acir_format& constraint_system, size_t size_hint) diff --git a/cpp/src/barretenberg/ecc/fields/field2.hpp b/cpp/src/barretenberg/ecc/fields/field2.hpp index 5bb03c3690..32be96eab9 100644 --- a/cpp/src/barretenberg/ecc/fields/field2.hpp +++ b/cpp/src/barretenberg/ecc/fields/field2.hpp @@ -126,7 +126,6 @@ template struct alignas(32) field2 { } }; -// Not working as expected. At least r.e. g2. // template void read(B& it, field2& value) // { // using serialize::read; From 7cfc53a78a2897b66305f898af05ab38f50b9680 Mon Sep 17 00:00:00 2001 From: Charlie Lye Date: Sat, 27 May 2023 17:25:15 +0000 Subject: [PATCH 28/29] Exclude env from lib. --- cpp/src/CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cpp/src/CMakeLists.txt b/cpp/src/CMakeLists.txt index 565146e1a3..9d1bf92925 100644 --- a/cpp/src/CMakeLists.txt +++ b/cpp/src/CMakeLists.txt @@ -73,8 +73,10 @@ endif() include(GNUInstallDirs) -# For this library we include everything but the wasi module, as it is the responsibility of the +# For this library we include everything but the env and wasi modules, as it is the responsibility of the # consumer of this library to define how and in what environment its artefact will run. +# libbarretenberg + libwasi = a wasi "reactor" that implements it's own env (e.g. logstr), e.g. barretenberg.wasm. +# libbarretenberg + env = a wasi "command" that expects a full wasi runtime (e.g. wasmtime), e.g. test binaries. message(STATUS "Compiling all-in-one barretenberg archive") add_library( barretenberg @@ -111,7 +113,6 @@ add_library( $ $ $ - $ ) # Small library to provide necessary primitives for rust crate. From 3683800e5a18e07b0ec29d83d245aab692c9c52c Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Thu, 1 Jun 2023 12:26:04 +0100 Subject: [PATCH 29/29] feat(dsl)!: DSL recursion changes w/ bb.js (#485) * Added recursion constraint into dsl + tests * fix dsl ecdsa constraint. Added ecdsa dsl tests * changed dsl recursion to pass proof/key as witnesses * recursive verification key no longer encapsulates a native key recursive verification key no longer encapsulates a reference string (neither were fundamentally needed!) * added serialization test for acir_proofs * Added serialization methods into dsl for recursive proof composition Added passing serialization tests Fixed format of RecursionConstraint to be compatible with existing ACIR formatting * added verificaiton key hash into RecursionConstraint Can be used by backend to force recursive verification key to be a specific value (it is represented via witnesses and therefore is not by-default constraint to represent a specific circuit) * fixed compiler errors in stdlib_recursion_tests * feat(dsl)!: Noir recursion updates (#379) * merge master in zw/noir-recursion * add dsl files to commit * namespace stuff and debugging * c bind functions * constraint test and comment removal * revert some changes to RecursionConstraint while debugging serialization issues * dispaly error when trying to use create_circuit_with_witness * is_recursive flag as part of new_proof and verify_proof, new RecursiveProver type in dsl, and serialization changes for recursion acir_proofs methods * remove debug output from TestSerializationWithRecursion * master merge conflicts * EnvReferenceString undefined reference to error workaround * add missing recursion_constraint field from acir_format tests * add recursion_constraints field back in acir_proofs.test inner circuit * fix inner circuit in RecursionConstraint.TestRecursionConstraint * Empty-Commit * add verify_recursive_proof method for simulating recursive verification in the ACVM * add ecc module to env package to fix linking of ennv_load_prover_crs and env_load_verifier_crs * add back reference strinng to stdlib recursion key to pass sol verifier generation tests * remove prints from recursive verifier test * fix dirty free for when serializing vk to fields, was working on macbook so not caught earlier, but need more clarity on ubuntu * fix ecdsa tests after master merge * missing keccak constraints fields in acir format and proofs tests * one more missing keccak constraint * mismatched acir format structs for gcc build * missing block constraints in acir tests * feat(dsl)!: Arbitrary depth recursion (#433) * merge conflicts and small updates to get acir_proofs test passing with arbitrary depth cahnges * inline with mv/noir-recursion and working double recursion acir_proofs serialization test * cleanup and working towards supporting full nested proofs, still some bugs in acir_proofs test * full recursive composition test working in acir_proofs * use two public inptus for inner circuit * delete commented out unnecessary acir proofs method * made dummy transcript points unique to prevent point collisions * handle nested proofs when exporting dummy transcript, export recursive proof indices when init vkey, fix full recursive comp test in acir_proofs * update bindings on verify_recursive_proof to accept num public inputs * missing acir_format field in tests * missing one more correct acir_format struct in recursion constraint test * cleanup and additional comment for recursion_constraint * fix up comment in recursion_constraint * remove unnecesary comments when we were including proof outputs as public inputs in the recursion constraint --------- Co-authored-by: zac-williamson * move export key into dsl package * chore: remove unused export key in recursion format from main proof system classes * pr review: moved from_witness comment and renamed from_field_pt_vector * moved export transcript in recursion format to DSL package * move order of acir functions * remove ecc bb_module declaration in env package * chore: remove usage of magic numbers when slicing g1::affine_element into barretenberg::fr * introduce NUM_AGGREGATION_ELEMENTS constant and use it through recursion constraint * nit ASSERT(result != -1) in get_public_input_index * remove unused found var * cast -1 * fix up verify_recursive_proof and add a test for it * moved from tempalte for has_valid_witness_assignments to a flag * chore: add comments to AcirProofs.TestVerifyRecursiveProofPass * update prove and verify exports to handle is_recursive * remove install state * remove debug output and use total_circuit_size * remove verify_recursive_proof as we might not need it for simulation * switch how we do is_recursive * remove acir recursive simulation method * changed wasi stubs and removed cout from acir_init_proving_key * removed cout outs getting runtime error for func definition * working recursion format funcs, but strangely getting errors about trying to invert zero in the field for dummy transcript and key * most recent debug output, hitting bad alloc in compute_proving_key_base * delete old comment * bb.js cmd changes * Lint and default fixes. * cleanup info and debug comments * add comment to recursion serialization methods * match package.json on cl/acir_cbinds * don't remove EventEmitter from bb_wasm.ts * delete empty exports file * use process.exit * log * add comment for why CIRCUIT_SIZE is 2**18 * mising keccak var constraints in new acir format tests * Cleanup some serialization. * Cleanup for publishing. README. --------- Co-authored-by: zac-williamson Co-authored-by: Charlie Lye --- .../barretenberg/common/slab_allocator.cpp | 4 +- .../barretenberg/common/slab_allocator.hpp | 2 +- .../dsl/acir_format/acir_format.cpp | 76 + .../dsl/acir_format/acir_format.hpp | 4 + .../dsl/acir_format/acir_format.test.cpp | 48 + .../dsl/acir_format/block_constraint.test.cpp | 1 + .../dsl/acir_format/ecdsa_secp256k1.test.cpp | 3 + .../dsl/acir_format/recursion_constraint.cpp | 352 + .../dsl/acir_format/recursion_constraint.hpp | 110 + .../acir_format/recursion_constraint.test.cpp | 303 + .../dsl/acir_proofs/acir_composer.cpp | 99 +- .../dsl/acir_proofs/acir_composer.hpp | 24 +- .../barretenberg/dsl/acir_proofs/c_bind.cpp | 73 +- .../barretenberg/dsl/acir_proofs/c_bind.hpp | 24 +- cpp/src/barretenberg/dsl/types.hpp | 13 +- .../plonk/composer/composer_base.hpp | 13 + .../plonk/composer/ultra_composer.cpp | 1 - .../plonk/composer/ultra_composer.hpp | 17 + .../types/polynomial_manifest.hpp | 2 +- .../verification_key/verification_key.hpp | 1 + .../solidity_helpers/CMakeLists.txt | 2 +- .../circuits/recursive_circuit.hpp | 1 + .../recursion/transcript/transcript.hpp | 48 + .../verification_key/verification_key.hpp | 89 +- .../stdlib/recursion/verifier/verifier.hpp | 59 +- exports.json | 69 +- ts/README.md | 117 +- ts/bb.js-dev | 6 + ts/package-lock.json | 11910 ---------------- ts/package.json | 25 +- ts/src/barretenberg_api/index.ts | 56 +- ts/src/barretenberg_wasm/barretenberg_wasm.ts | 4 +- ts/src/index.ts | 2 + ts/src/main-dev.ts | 2 - ts/src/main.ts | 209 +- ts/src/serialize/serialize.ts | 4 + ts/src/types/fields.ts | 4 +- ts/yarn.lock | 356 +- 38 files changed, 1840 insertions(+), 12293 deletions(-) create mode 100644 cpp/src/barretenberg/dsl/acir_format/recursion_constraint.cpp create mode 100644 cpp/src/barretenberg/dsl/acir_format/recursion_constraint.hpp create mode 100644 cpp/src/barretenberg/dsl/acir_format/recursion_constraint.test.cpp create mode 100755 ts/bb.js-dev delete mode 100644 ts/package-lock.json delete mode 100755 ts/src/main-dev.ts diff --git a/cpp/src/barretenberg/common/slab_allocator.cpp b/cpp/src/barretenberg/common/slab_allocator.cpp index 89597d8cce..96be5d7426 100644 --- a/cpp/src/barretenberg/common/slab_allocator.cpp +++ b/cpp/src/barretenberg/common/slab_allocator.cpp @@ -195,9 +195,9 @@ SlabAllocator allocator; } // namespace namespace barretenberg { -void init_slab_allocator(size_t circuit_size) +void init_slab_allocator(size_t circuit_subgroup_size) { - allocator.init(circuit_size); + allocator.init(circuit_subgroup_size); } // auto init = ([]() { diff --git a/cpp/src/barretenberg/common/slab_allocator.hpp b/cpp/src/barretenberg/common/slab_allocator.hpp index 2db615b00b..be5ef6ea1b 100644 --- a/cpp/src/barretenberg/common/slab_allocator.hpp +++ b/cpp/src/barretenberg/common/slab_allocator.hpp @@ -25,7 +25,7 @@ namespace barretenberg { * TODO: De-globalise. Init the allocator and pass around. Use a PolynomialFactory (PolynomialStore?). * TODO: Consider removing, but once due-dilligence has been done that we no longer have memory limitations. */ -void init_slab_allocator(size_t circuit_size); +void init_slab_allocator(size_t circuit_subgroup_size); /** * Returns a slab from the preallocated pool of slabs, or fallback to a new heap allocation (32 byte aligned). diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp index ee3e683dd0..63d6c6791a 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp @@ -96,6 +96,21 @@ void create_circuit(Composer& composer, acir_format const& constraint_system) for (const auto& constraint : constraint_system.block_constraints) { create_block_constraints(composer, constraint); } + + // Add recursion constraints + for (size_t i = 0; i < constraint_system.recursion_constraints.size(); ++i) { + auto& constraint = constraint_system.recursion_constraints[i]; + create_recursion_constraints(composer, constraint); + + // make sure the verification key records the public input indices of the final recursion output + // (N.B. up to the ACIR description to make sure that the final output aggregation object wires are public + // inputs!) + if (i == constraint_system.recursion_constraints.size() - 1) { + std::vector proof_output_witness_indices(constraint.output_aggregation_object.begin(), + constraint.output_aggregation_object.end()); + composer.set_recursive_proof(proof_output_witness_indices); + } + } } Composer create_circuit(const acir_format& constraint_system, @@ -120,6 +135,7 @@ Composer create_circuit(const acir_format& constraint_system, composer.add_variable(0); } } + // Add arithmetic gates for (const auto& constraint : constraint_system.constraints) { composer.create_poly_gate(constraint); @@ -189,6 +205,21 @@ Composer create_circuit(const acir_format& constraint_system, create_block_constraints(composer, constraint); } + // Add recursion constraints + for (size_t i = 0; i < constraint_system.recursion_constraints.size(); ++i) { + auto& constraint = constraint_system.recursion_constraints[i]; + create_recursion_constraints(composer, constraint); + + // make sure the verification key records the public input indices of the final recursion output + // (N.B. up to the ACIR description to make sure that the final output aggregation object wires are public + // inputs!) + if (i == constraint_system.recursion_constraints.size() - 1) { + std::vector proof_output_witness_indices(constraint.output_aggregation_object.begin(), + constraint.output_aggregation_object.end()); + composer.set_recursive_proof(proof_output_witness_indices); + } + } + return composer; } @@ -286,6 +317,21 @@ Composer create_circuit_with_witness(acir_format const& constraint_system, create_block_constraints(composer, constraint); } + // Add recursion constraints + for (size_t i = 0; i < constraint_system.recursion_constraints.size(); ++i) { + auto& constraint = constraint_system.recursion_constraints[i]; + create_recursion_constraints(composer, constraint, true); + + // make sure the verification key records the public input indices of the final recursion output + // (N.B. up to the ACIR description to make sure that the final output aggregation object wires are public + // inputs!) + if (i == constraint_system.recursion_constraints.size() - 1) { + std::vector proof_output_witness_indices(constraint.output_aggregation_object.begin(), + constraint.output_aggregation_object.end()); + composer.set_recursive_proof(proof_output_witness_indices); + } + } + return composer; } Composer create_circuit_with_witness(const acir_format& constraint_system, WitnessVector const& witness) @@ -380,6 +426,21 @@ Composer create_circuit_with_witness(const acir_format& constraint_system, Witne create_block_constraints(composer, constraint); } + // Add recursion constraints + for (size_t i = 0; i < constraint_system.recursion_constraints.size(); ++i) { + auto& constraint = constraint_system.recursion_constraints[i]; + create_recursion_constraints(composer, constraint, true); + + // make sure the verification key records the public input indices of the final recursion output + // (N.B. up to the ACIR description to make sure that the final output aggregation object wires are public + // inputs!) + if (i == constraint_system.recursion_constraints.size() - 1) { + std::vector proof_output_witness_indices(constraint.output_aggregation_object.begin(), + constraint.output_aggregation_object.end()); + composer.set_recursive_proof(proof_output_witness_indices); + } + } + return composer; } void create_circuit_with_witness(Composer& composer, acir_format const& constraint_system, WitnessVector const& witness) @@ -471,6 +532,21 @@ void create_circuit_with_witness(Composer& composer, acir_format const& constrai for (const auto& constraint : constraint_system.block_constraints) { create_block_constraints(composer, constraint); } + + // Add recursion constraints + for (size_t i = 0; i < constraint_system.recursion_constraints.size(); ++i) { + auto& constraint = constraint_system.recursion_constraints[i]; + create_recursion_constraints(composer, constraint, true); + + // make sure the verification key records the public input indices of the final recursion output + // (N.B. up to the ACIR description to make sure that the final output aggregation object wires are public + // inputs!) + if (i == constraint_system.recursion_constraints.size() - 1) { + std::vector proof_output_witness_indices(constraint.output_aggregation_object.begin(), + constraint.output_aggregation_object.end()); + composer.set_recursive_proof(proof_output_witness_indices); + } + } } } // namespace acir_format diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp index 5a42a593ab..6dc5e8dd1b 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp @@ -9,6 +9,7 @@ #include "schnorr_verify.hpp" #include "ecdsa_secp256k1.hpp" #include "compute_merkle_root_constraint.hpp" +#include "recursion_constraint.hpp" #include "block_constraint.hpp" #include "pedersen.hpp" #include "hash_to_field.hpp" @@ -35,6 +36,7 @@ struct acir_format { std::vector pedersen_constraints; std::vector compute_merkle_root_constraints; std::vector block_constraints; + std::vector recursion_constraints; // A standard plonk arithmetic constraint, as defined in the poly_triple struct, consists of selector values // for q_M,q_L,q_R,q_O,q_C and indices of three variables taking the role of left, right and output wire // This could be a large vector so use slab allocator, we don't expect the blackbox implementations to be so large. @@ -81,6 +83,7 @@ template inline void read(B& buf, acir_format& data) read(buf, data.pedersen_constraints); read(buf, data.hash_to_field_constraints); read(buf, data.fixed_base_scalar_mul_constraints); + read(buf, data.recursion_constraints); read(buf, data.constraints); read(buf, data.block_constraints); } @@ -102,6 +105,7 @@ template inline void write(B& buf, acir_format const& data) write(buf, data.pedersen_constraints); write(buf, data.hash_to_field_constraints); write(buf, data.fixed_base_scalar_mul_constraints); + write(buf, data.recursion_constraints); write(buf, data.constraints); write(buf, data.block_constraints); } diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp index 87ec0e45be..96c067805a 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp @@ -5,6 +5,51 @@ #include "barretenberg/common/streams.hpp" #include "barretenberg/serialize/test_helper.hpp" #include "ecdsa_secp256k1.hpp" + +TEST(acir_format, test_a_single_constraint_no_pub_inputs) +{ + + poly_triple constraint{ + .a = 1, + .b = 2, + .c = 3, + .q_m = 0, + .q_l = 1, + .q_r = 1, + .q_o = -1, + .q_c = 0, + }; + + acir_format::acir_format constraint_system{ + .varnum = 4, + .public_inputs = {}, + .fixed_base_scalar_mul_constraints = {}, + .logic_constraints = {}, + .range_constraints = {}, + .schnorr_constraints = {}, + .ecdsa_constraints = {}, + .sha256_constraints = {}, + .blake2s_constraints = {}, + .keccak_constraints = {}, + .keccak_var_constraints = {}, + .hash_to_field_constraints = {}, + .pedersen_constraints = {}, + .compute_merkle_root_constraints = {}, + .block_constraints = {}, + .recursion_constraints = {}, + .constraints = { constraint }, + }; + + auto composer = acir_format::create_circuit_with_witness(constraint_system, { 0, 0, 1 }); + + auto prover = composer.create_ultra_with_keccak_prover(); + auto proof = prover.construct_proof(); + + auto verifier = composer.create_ultra_with_keccak_verifier(); + + EXPECT_EQ(verifier.verify_proof(proof), false); +} + TEST(acir_format, msgpack_logic_constraint) { auto [actual, expected] = msgpack_roundtrip(acir_format::LogicConstraint{}); @@ -97,6 +142,7 @@ TEST(acir_format, test_logic_gate_from_noir_circuit) .pedersen_constraints = {}, .compute_merkle_root_constraints = {}, .block_constraints = {}, + .recursion_constraints = {}, .constraints = { expr_a, expr_b, expr_c, expr_d }, }; @@ -162,6 +208,7 @@ TEST(acir_format, test_schnorr_verify_pass) .pedersen_constraints = {}, .compute_merkle_root_constraints = {}, .block_constraints = {}, + .recursion_constraints = {}, .constraints = { poly_triple{ .a = schnorr_constraint.result, .b = schnorr_constraint.result, @@ -234,6 +281,7 @@ TEST(acir_format, test_schnorr_verify_small_range) .pedersen_constraints = {}, .compute_merkle_root_constraints = {}, .block_constraints = {}, + .recursion_constraints = {}, .constraints = { poly_triple{ .a = schnorr_constraint.result, .b = schnorr_constraint.result, diff --git a/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp b/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp index 2fdc25c2a5..de75643564 100644 --- a/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp @@ -118,6 +118,7 @@ TEST(up_ram, TestBlockConstraint) .pedersen_constraints = {}, .compute_merkle_root_constraints = {}, .block_constraints = { block }, + .recursion_constraints = {}, .constraints = {}, }; diff --git a/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp b/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp index a34a3a0cbe..d82de5a870 100644 --- a/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp @@ -99,6 +99,7 @@ TEST(ECDSASecp256k1, TestECDSAConstraintSucceed) .pedersen_constraints = {}, .compute_merkle_root_constraints = {}, .block_constraints = {}, + .recursion_constraints = {}, .constraints = {}, }; @@ -136,6 +137,7 @@ TEST(ECDSASecp256k1, TestECDSACompilesForVerifier) .pedersen_constraints = {}, .compute_merkle_root_constraints = {}, .block_constraints = {}, + .recursion_constraints = {}, .constraints = {}, }; auto crs_factory = std::make_unique(); @@ -170,6 +172,7 @@ TEST(ECDSASecp256k1, TestECDSAConstraintFail) .pedersen_constraints = {}, .compute_merkle_root_constraints = {}, .block_constraints = {}, + .recursion_constraints = {}, .constraints = {}, }; diff --git a/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.cpp b/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.cpp new file mode 100644 index 0000000000..f5064788cb --- /dev/null +++ b/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.cpp @@ -0,0 +1,352 @@ +#include "recursion_constraint.hpp" +#include "barretenberg/plonk/proof_system/verification_key/verification_key.hpp" +#include "barretenberg/stdlib/recursion/aggregation_state/aggregation_state.hpp" +#include "barretenberg/stdlib/recursion/verifier/verifier.hpp" +#include "barretenberg/transcript/transcript_wrappers.hpp" + +namespace acir_format { + +using namespace proof_system::plonk; + +// `NUM_LIMB_BITS_IN_FIELD_SIMULATION` is the limb size when simulating a non-native field using the bigfield class +// A aggregation object is two acir_format::g1_ct types where each coordinate in a point is a non-native field. +// Each field is represented as four limbs. We split those limbs in half when serializing to/from buffer. +static constexpr uint64_t TWO_LIMBS_BITS_IN_FIELD_SIMULATION = NUM_LIMB_BITS_IN_FIELD_SIMULATION * 2; +static constexpr uint64_t FOUR_LIMBS_BITS_IN_FIELD_SIMULATION = NUM_LIMB_BITS_IN_FIELD_SIMULATION * 4; + +void generate_dummy_proof() {} +/** + * @brief Add constraints required to recursively verify an UltraPlonk proof + * + * @param composer + * @param input + * @tparam has_valid_witness_assignment. Do we have witnesses or are we just generating keys? + * @tparam inner_proof_contains_recursive_proof. Do we expect the inner proof to also have performed recursive + * verification? We need to know this at circuit-compile time. + * + * @note We currently only support RecursionConstraint where inner_proof_contains_recursive_proof = false. + * We would either need a separate ACIR opcode where inner_proof_contains_recursive_proof = true, + * or we need non-witness data to be provided as metadata in the ACIR opcode + */ +void create_recursion_constraints(Composer& composer, + const RecursionConstraint& input, + bool has_valid_witness_assignments) +{ + const auto& nested_aggregation_indices = input.nested_aggregation_object; + bool nested_aggregation_indices_all_zero = true; + for (const auto& idx : nested_aggregation_indices) { + nested_aggregation_indices_all_zero &= (idx == 0); + } + const bool inner_proof_contains_recursive_proof = !nested_aggregation_indices_all_zero; + + // If we do not have a witness, we must ensure that our dummy witness will not trigger + // on-curve errors and inverting-zero errors + { + // get a fake key/proof that satisfies on-curve + inversion-zero checks + const std::vector dummy_key = export_dummy_key_in_recursion_format(PolynomialManifest(Composer::type), + inner_proof_contains_recursive_proof); + const auto manifest = Composer::create_unrolled_manifest(input.public_inputs.size()); + const std::vector dummy_proof = + export_dummy_transcript_in_recursion_format(manifest, inner_proof_contains_recursive_proof); + for (size_t i = 0; i < input.proof.size(); ++i) { + const auto proof_field_idx = input.proof[i]; + // if we do NOT have a witness assignment (i.e. are just building the proving/verification keys), + // we add our dummy proof values as Composer variables. + // if we DO have a valid witness assignment, we use the real witness assignment + barretenberg::fr dummy_field = + has_valid_witness_assignments ? composer.get_variable(proof_field_idx) : dummy_proof[i]; + // Create a copy constraint between our dummy field and the witness index provided by RecursionConstraint. + // This will make the RecursionConstraint idx equal to `dummy_field`. + // In the case of a valid witness assignment, this does nothing (as dummy_field = real value) + // In the case of no valid witness assignment, this makes sure that the RecursionConstraint witness indices + // will not trigger basic errors (check inputs are on-curve, check we are not inverting 0) + composer.assert_equal(composer.add_variable(dummy_field), proof_field_idx); + } + for (size_t i = 0; i < input.key.size(); ++i) { + const auto key_field_idx = input.key[i]; + barretenberg::fr dummy_field = + has_valid_witness_assignments ? composer.get_variable(key_field_idx) : dummy_key[i]; + composer.assert_equal(composer.add_variable(dummy_field), key_field_idx); + } + } + + // Construct an in-circuit representation of the verification key. + // For now, the v-key is a circuit constant and is fixed for the circuit. + // (We may need a separate recursion opcode for this to vary, or add more config witnesses to this opcode) + const auto& aggregation_input = input.input_aggregation_object; + aggregation_state_ct previous_aggregation; + + // If we have previously recursively verified proofs, `is_aggregation_object_nonzero = true` + // For now this is a complile-time constant i.e. whether this is true/false is fixed for the circuit! + bool inner_aggregation_indices_all_zero = true; + for (const auto& idx : aggregation_input) { + inner_aggregation_indices_all_zero &= (idx == 0); + } + + if (!inner_aggregation_indices_all_zero) { + std::array aggregation_elements; + for (size_t i = 0; i < 4; ++i) { + aggregation_elements[i] = + bn254::fq_ct(field_ct::from_witness_index(&composer, aggregation_input[4 * i]), + field_ct::from_witness_index(&composer, aggregation_input[4 * i + 1]), + field_ct::from_witness_index(&composer, aggregation_input[4 * i + 2]), + field_ct::from_witness_index(&composer, aggregation_input[4 * i + 3])); + aggregation_elements[i].assert_is_in_field(); + } + // If we have a previous aggregation object, assign it to `previous_aggregation` so that it is included + // in stdlib::recursion::verify_proof + previous_aggregation.P0 = bn254::g1_ct(aggregation_elements[0], aggregation_elements[1]); + previous_aggregation.P1 = bn254::g1_ct(aggregation_elements[2], aggregation_elements[3]); + previous_aggregation.has_data = true; + } else { + previous_aggregation.has_data = false; + } + + transcript::Manifest manifest = Composer::create_unrolled_manifest(input.public_inputs.size()); + + std::vector key_fields; + key_fields.reserve(input.key.size()); + for (const auto& idx : input.key) { + auto field = field_ct::from_witness_index(&composer, idx); + key_fields.emplace_back(field); + } + + std::vector proof_fields; + proof_fields.reserve(input.proof.size()); + for (const auto& idx : input.proof) { + auto field = field_ct::from_witness_index(&composer, idx); + proof_fields.emplace_back(field); + } + + // recursively verify the proof + std::shared_ptr vkey = verification_key_ct::from_field_elements( + &composer, key_fields, inner_proof_contains_recursive_proof, nested_aggregation_indices); + vkey->program_width = noir_recursive_settings::program_width; + Transcript_ct transcript(&composer, manifest, proof_fields, input.public_inputs.size()); + aggregation_state_ct result = proof_system::plonk::stdlib::recursion::verify_proof_( + &composer, vkey, transcript, previous_aggregation); + + // Assign correct witness value to the verification key hash + vkey->compress().assert_equal(field_ct::from_witness_index(&composer, input.key_hash)); + + ASSERT(result.public_inputs.size() == input.public_inputs.size()); + + // Assign the `public_input` field to the public input of the inner proof + for (size_t i = 0; i < input.public_inputs.size(); ++i) { + result.public_inputs[i].assert_equal(field_ct::from_witness_index(&composer, input.public_inputs[i])); + } + + // Assign the recursive proof outputs to `output_aggregation_object` + for (size_t i = 0; i < result.proof_witness_indices.size(); ++i) { + const auto lhs = field_ct::from_witness_index(&composer, result.proof_witness_indices[i]); + const auto rhs = field_ct::from_witness_index(&composer, input.output_aggregation_object[i]); + lhs.assert_equal(rhs); + } +} + +/** + * @brief When recursively verifying proofs, we represent the verification key using field elements. + * This method exports the key formatted in the manner our recursive verifier expects. + * NOTE: only used by the dsl at the moment. Might be cleaner to make this a dsl function? + * + * @return std::vector + */ +std::vector export_key_in_recursion_format(std::shared_ptr const& vkey) +{ + std::vector output; + output.emplace_back(vkey->domain.root); + output.emplace_back(vkey->domain.domain); + output.emplace_back(vkey->domain.generator); + output.emplace_back(vkey->circuit_size); + output.emplace_back(vkey->num_public_inputs); + output.emplace_back(vkey->contains_recursive_proof); + for (size_t i = 0; i < RecursionConstraint::AGGREGATION_OBJECT_SIZE; ++i) { + if (vkey->recursive_proof_public_input_indices.size() > i) { + output.emplace_back(vkey->recursive_proof_public_input_indices[i]); + } else { + output.emplace_back(0); + ASSERT(vkey->contains_recursive_proof == false); + } + } + for (const auto& descriptor : vkey->polynomial_manifest.get()) { + if (descriptor.source == PolynomialSource::SELECTOR || descriptor.source == PolynomialSource::PERMUTATION) { + const auto element = vkey->commitments.at(std::string(descriptor.commitment_label)); + auto g1_as_fields = export_g1_affine_element_as_fields(element); + output.emplace_back(g1_as_fields.x_lo); + output.emplace_back(g1_as_fields.x_hi); + output.emplace_back(g1_as_fields.y_lo); + output.emplace_back(g1_as_fields.y_hi); + } + } + + verification_key_data vkey_data{ + .composer_type = vkey->composer_type, + .circuit_size = static_cast(vkey->circuit_size), + .num_public_inputs = static_cast(vkey->num_public_inputs), + .commitments = vkey->commitments, + .contains_recursive_proof = vkey->contains_recursive_proof, + .recursive_proof_public_input_indices = vkey->recursive_proof_public_input_indices, + }; + output.emplace_back(vkey_data.compress_native(0)); // key_hash + return output; +} + +/** + * @brief When recursively verifying proofs, we represent the verification key using field elements. + * This method exports the key formatted in the manner our recursive verifier expects. + * A dummy key is used when building a circuit without a valid witness assignment. + * We want the transcript to contain valid G1 points to prevent on-curve errors being thrown. + * We want a non-zero circuit size as this element will be inverted by the circuit + * and we do not want an "inverting 0" error thrown + * + * @return std::vector + */ +std::vector export_dummy_key_in_recursion_format(const PolynomialManifest& polynomial_manifest, + const bool contains_recursive_proof) +{ + std::vector output; + output.emplace_back(1); // domain.domain (will be inverted) + output.emplace_back(1); // domain.root (will be inverted) + output.emplace_back(1); // domain.generator (will be inverted) + + output.emplace_back(1); // circuit size + output.emplace_back(1); // num public inputs + + output.emplace_back(contains_recursive_proof); // contains_recursive_proof + for (size_t i = 0; i < RecursionConstraint::AGGREGATION_OBJECT_SIZE; ++i) { + output.emplace_back(0); // recursive_proof_public_input_indices + } + + for (const auto& descriptor : polynomial_manifest.get()) { + if (descriptor.source == PolynomialSource::SELECTOR || descriptor.source == PolynomialSource::PERMUTATION) { + // the std::biggroup class creates unsatisfiable constraints when identical points are added/subtracted. + // (when verifying zk proofs this is acceptable as we make sure verification key points are not identical. + // And prover points should contain randomness for an honest Prover). + // This check can also trigger a runtime error due to causing 0 to be inverted. + // When creating dummy verification key points we must be mindful of the above and make sure that each + // transcript point is unique. + auto scalar = barretenberg::fr::random_element(); + const auto element = barretenberg::g1::affine_element(barretenberg::g1::one * scalar); + auto g1_as_fields = export_g1_affine_element_as_fields(element); + output.emplace_back(g1_as_fields.x_lo); + output.emplace_back(g1_as_fields.x_hi); + output.emplace_back(g1_as_fields.y_lo); + output.emplace_back(g1_as_fields.y_hi); + } + } + + output.emplace_back(0); // key_hash + + return output; +} + +/** + * @brief Returns transcript represented as a vector of barretenberg::fr. + * Used to represent recursive proofs (i.e. proof represented as circuit-native field elements) + * + * @return std::vector + */ +std::vector export_transcript_in_recursion_format(const transcript::StandardTranscript& transcript) +{ + std::vector fields; + const auto num_rounds = transcript.get_manifest().get_num_rounds(); + for (size_t i = 0; i < num_rounds; ++i) { + for (const auto& manifest_element : transcript.get_manifest().get_round_manifest(i).elements) { + if (!manifest_element.derived_by_verifier) { + if (manifest_element.num_bytes == 32 && manifest_element.name != "public_inputs") { + fields.emplace_back(transcript.get_field_element(manifest_element.name)); + } else if (manifest_element.num_bytes == 64 && manifest_element.name != "public_inputs") { + const auto group_element = transcript.get_group_element(manifest_element.name); + auto g1_as_fields = export_g1_affine_element_as_fields(group_element); + fields.emplace_back(g1_as_fields.x_lo); + fields.emplace_back(g1_as_fields.x_hi); + fields.emplace_back(g1_as_fields.y_lo); + fields.emplace_back(g1_as_fields.y_hi); + } else { + ASSERT(manifest_element.name == "public_inputs"); + const auto public_inputs_vector = transcript.get_field_element_vector(manifest_element.name); + for (const auto& ele : public_inputs_vector) { + fields.emplace_back(ele); + } + } + } + } + } + return fields; +} + +/** + * @brief Get a dummy fake proof for recursion. All elliptic curve group elements are still valid points to prevent + * errors being thrown. + * + * @param manifest + * @return std::vector + */ +std::vector export_dummy_transcript_in_recursion_format(const transcript::Manifest& manifest, + const bool contains_recursive_proof) +{ + std::vector fields; + const auto num_rounds = manifest.get_num_rounds(); + for (size_t i = 0; i < num_rounds; ++i) { + for (const auto& manifest_element : manifest.get_round_manifest(i).elements) { + if (!manifest_element.derived_by_verifier) { + if (manifest_element.num_bytes == 32 && manifest_element.name != "public_inputs") { + // auto scalar = barretenberg::fr::random_element(); + fields.emplace_back(0); + } else if (manifest_element.num_bytes == 64 && manifest_element.name != "public_inputs") { + // the std::biggroup class creates unsatisfiable constraints when identical points are + // added/subtracted. + // (when verifying zk proofs this is acceptable as we make sure verification key points are not + // identical. And prover points should contain randomness for an honest Prover). This check can + // also trigger a runtime error due to causing 0 to be inverted. When creating dummy proof + // points we must be mindful of the above and make sure that each point is unique. + auto scalar = barretenberg::fr::random_element(); + const auto group_element = barretenberg::g1::affine_element(barretenberg::g1::one * scalar); + auto g1_as_fields = export_g1_affine_element_as_fields(group_element); + fields.emplace_back(g1_as_fields.x_lo); + fields.emplace_back(g1_as_fields.x_hi); + fields.emplace_back(g1_as_fields.y_lo); + fields.emplace_back(g1_as_fields.y_hi); + } else { + ASSERT(manifest_element.name == "public_inputs"); + const size_t num_public_inputs = manifest_element.num_bytes / 32; + // If we have a recursive proofs the public inputs must describe an aggregation object that + // is composed of two valid G1 points on the curve. Without this conditional we will get a + // runtime error that we are attempting to invert 0. + if (contains_recursive_proof) { + ASSERT(num_public_inputs == RecursionConstraint::AGGREGATION_OBJECT_SIZE); + for (size_t k = 0; k < RecursionConstraint::NUM_AGGREGATION_ELEMENTS; ++k) { + auto scalar = barretenberg::fr::random_element(); + const auto group_element = barretenberg::g1::affine_element(barretenberg::g1::one * scalar); + auto g1_as_fields = export_g1_affine_element_as_fields(group_element); + fields.emplace_back(g1_as_fields.x_lo); + fields.emplace_back(g1_as_fields.x_hi); + fields.emplace_back(g1_as_fields.y_lo); + fields.emplace_back(g1_as_fields.y_hi); + } + } else { + for (size_t j = 0; j < num_public_inputs; ++j) { + // auto scalar = barretenberg::fr::random_element(); + fields.emplace_back(0); + } + } + } + } + } + } + return fields; +} + +G1AsFields export_g1_affine_element_as_fields(const barretenberg::g1::affine_element& group_element) +{ + const uint256_t x = group_element.x; + const uint256_t y = group_element.y; + const barretenberg::fr x_lo = x.slice(0, TWO_LIMBS_BITS_IN_FIELD_SIMULATION); + const barretenberg::fr x_hi = x.slice(TWO_LIMBS_BITS_IN_FIELD_SIMULATION, FOUR_LIMBS_BITS_IN_FIELD_SIMULATION); + const barretenberg::fr y_lo = y.slice(0, TWO_LIMBS_BITS_IN_FIELD_SIMULATION); + const barretenberg::fr y_hi = y.slice(TWO_LIMBS_BITS_IN_FIELD_SIMULATION, FOUR_LIMBS_BITS_IN_FIELD_SIMULATION); + + return G1AsFields{ x_lo, x_hi, y_lo, y_hi }; +} + +} // namespace acir_format diff --git a/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.hpp b/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.hpp new file mode 100644 index 0000000000..f99dc21230 --- /dev/null +++ b/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.hpp @@ -0,0 +1,110 @@ +#pragma once +#include +#include "barretenberg/dsl/types.hpp" +#include "barretenberg/plonk/proof_system/verification_key/verification_key.hpp" + +namespace acir_format { + +using namespace proof_system::plonk; + +/** + * @brief RecursionConstraint struct contains information required to recursively verify a proof! + * + * @details The recursive verifier algorithm produces an 'aggregation object' representing 2 G1 points, expressed as 16 + * witness values. The smart contract Verifier must be aware of this aggregation object in order to complete the full + * recursive verification. If the circuit verifies more than 1 proof, the recursion algorithm will update a pre-existing + * aggregation object (`input_aggregation_object`). + * + * @details We currently require that the inner circuit being verified only has a single public input. If more are + * required, the outer circuit can hash them down to 1 input. + * + * @param verification_key_data The inner circuit vkey. Is converted into circuit witness values (internal to the + * backend) + * @param proof The plonk proof. Is converted into circuit witness values (internal to the backend) + * @param is_aggregation_object_nonzero A flag to tell us whether the circuit has already recursively verified proofs + * (and therefore an aggregation object is present) + * @param public_input The index of the single public input + * @param input_aggregation_object Witness indices of pre-existing aggregation object (if it exists) + * @param output_aggregation_object Witness indices of the aggregation object produced by recursive verification + * @param nested_aggregation_object Public input indices of an aggregation object inside the proof. + * + * @note If input_aggregation_object witness indices are all zero, we interpret this to mean that the inner proof does + * NOT contain a previously recursively verified proof + * @note nested_aggregation_object is used for cases where the proof being verified contains an aggregation object in + * its public inputs! If this is the case, we record the public input locations in `nested_aggregation_object`. If the + * inner proof is of a circuit that does not have a nested aggregation object, these values are all zero. + * + * To outline the interaction between the input_aggergation_object and the nested_aggregation_object take the following + * example: If we have a circuit that verifies 2 proofs A and B, the recursion constraint for B will have an + * input_aggregation_object that points to the aggregation output produced by verifying A. If circuit B also verifies a + * proof, in the above example the recursion constraint for verifying B will have a nested object that describes the + * aggregation object in B’s public inputs as well as an input aggregation object that points to the object produced by + * the previous recursion constraint in the circuit (the one that verifies A) + * + */ +struct RecursionConstraint { + // An aggregation state is represented by two G1 affine elements. Each G1 point has + // two field element coordinates (x, y). Thus, four field elements + static constexpr size_t NUM_AGGREGATION_ELEMENTS = 4; + // Four limbs are used when simulating a non-native field using the bigfield class + static constexpr size_t AGGREGATION_OBJECT_SIZE = + NUM_AGGREGATION_ELEMENTS * NUM_QUOTIENT_PARTS; // 16 field elements + std::vector key; + std::vector proof; + std::vector public_inputs; + uint32_t key_hash; + std::array input_aggregation_object; + std::array output_aggregation_object; + std::array nested_aggregation_object; + + friend bool operator==(RecursionConstraint const& lhs, RecursionConstraint const& rhs) = default; +}; + +void create_recursion_constraints(Composer& composer, + const RecursionConstraint& input, + bool has_valid_witness_assignments = false); + +std::vector export_key_in_recursion_format(std::shared_ptr const& vkey); +std::vector export_dummy_key_in_recursion_format(const PolynomialManifest& polynomial_manifest, + bool contains_recursive_proof = 0); + +std::vector export_transcript_in_recursion_format(const transcript::StandardTranscript& transcript); +std::vector export_dummy_transcript_in_recursion_format(const transcript::Manifest& manifest, + const bool contains_recursive_proof); + +// In order to interact with a recursive aggregation state inside of a circuit, we need to represent its internal G1 +// elements as field elements. This happens in multiple locations when creating a recursion constraint. The struct and +// method below export a g1 affine element as fields to use as part of the recursive circuit. +struct G1AsFields { + barretenberg::fr x_lo; + barretenberg::fr x_hi; + barretenberg::fr y_lo; + barretenberg::fr y_hi; +}; +G1AsFields export_g1_affine_element_as_fields(const barretenberg::g1::affine_element& group_element); + +template inline void read(B& buf, RecursionConstraint& constraint) +{ + using serialize::read; + read(buf, constraint.key); + read(buf, constraint.proof); + read(buf, constraint.public_inputs); + read(buf, constraint.key_hash); + read(buf, constraint.input_aggregation_object); + read(buf, constraint.output_aggregation_object); + read(buf, constraint.nested_aggregation_object); +} + +template inline void write(B& buf, RecursionConstraint const& constraint) +{ + using serialize::write; + write(buf, constraint.key); + write(buf, constraint.proof); + write(buf, constraint.public_inputs); + write(buf, constraint.key_hash); + write(buf, constraint.input_aggregation_object); + write(buf, constraint.output_aggregation_object); + write(buf, constraint.nested_aggregation_object); +} + +} // namespace acir_format diff --git a/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.test.cpp b/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.test.cpp new file mode 100644 index 0000000000..0117b4f0a5 --- /dev/null +++ b/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.test.cpp @@ -0,0 +1,303 @@ +#include "acir_format.hpp" +#include "recursion_constraint.hpp" +#include "barretenberg/plonk/proof_system/types/proof.hpp" +#include "barretenberg/plonk/proof_system/verification_key/verification_key.hpp" + +#include +#include + +using namespace proof_system::plonk; + +acir_format::Composer create_inner_circuit() +{ + /** + * constraints produced by Noir program: + * fn main(x : u32, y : pub u32) { + * let z = x ^ y; + * + * constrain z != 10; + * } + **/ + acir_format::RangeConstraint range_a{ + .witness = 1, + .num_bits = 32, + }; + acir_format::RangeConstraint range_b{ + .witness = 2, + .num_bits = 32, + }; + + acir_format::LogicConstraint logic_constraint{ + .a = 1, + .b = 2, + .result = 3, + .num_bits = 32, + .is_xor_gate = 1, + }; + poly_triple expr_a{ + .a = 3, + .b = 4, + .c = 0, + .q_m = 0, + .q_l = 1, + .q_r = -1, + .q_o = 0, + .q_c = -10, + }; + poly_triple expr_b{ + .a = 4, + .b = 5, + .c = 6, + .q_m = 1, + .q_l = 0, + .q_r = 0, + .q_o = -1, + .q_c = 0, + }; + poly_triple expr_c{ + .a = 4, + .b = 6, + .c = 4, + .q_m = 1, + .q_l = 0, + .q_r = 0, + .q_o = -1, + .q_c = 0, + + }; + poly_triple expr_d{ + .a = 6, + .b = 0, + .c = 0, + .q_m = 0, + .q_l = -1, + .q_r = 0, + .q_o = 0, + .q_c = 1, + }; + + acir_format::acir_format constraint_system{ + .varnum = 7, + .public_inputs = { 2, 3 }, + .fixed_base_scalar_mul_constraints = {}, + .logic_constraints = { logic_constraint }, + .range_constraints = { range_a, range_b }, + .schnorr_constraints = {}, + .ecdsa_constraints = {}, + .sha256_constraints = {}, + .blake2s_constraints = {}, + .keccak_constraints = {}, + .keccak_var_constraints = {}, + .hash_to_field_constraints = {}, + .pedersen_constraints = {}, + .compute_merkle_root_constraints = {}, + .block_constraints = {}, + .recursion_constraints = {}, + .constraints = { expr_a, expr_b, expr_c, expr_d }, + }; + + uint256_t inverse_of_five = fr(5).invert(); + auto composer = acir_format::create_circuit_with_witness(constraint_system, + { + 5, + 10, + 15, + 5, + inverse_of_five, + 1, + }); + + return composer; +} + +/** + * @brief Create a circuit that recursively verifies one or more inner circuits + * + * @param inner_composers + * @return acir_format::Composer + */ +acir_format::Composer create_outer_circuit(std::vector& inner_composers) +{ + std::vector recursion_constraints; + + // witness count starts at 1 (Composer reserves 1st witness to be the zero-valued zero_idx) + size_t witness_offset = 1; + std::array output_aggregation_object; + std::vector> witness; + + for (size_t i = 0; i < inner_composers.size(); ++i) { + const bool has_input_aggregation_object = i > 0; + + auto& inner_composer = inner_composers[i]; + auto inner_prover = inner_composer.create_prover(); + auto inner_proof = inner_prover.construct_proof(); + auto inner_verifier = inner_composer.create_verifier(); + + const bool has_nested_proof = inner_verifier.key->contains_recursive_proof; + const size_t num_inner_public_inputs = inner_composer.get_num_public_inputs(); + + transcript::StandardTranscript transcript(inner_proof.proof_data, + acir_format::Composer::create_manifest(num_inner_public_inputs), + transcript::HashType::PlookupPedersenBlake3s, + 16); + + const std::vector proof_witnesses = + acir_format::export_transcript_in_recursion_format(transcript); + const std::vector key_witnesses = + acir_format::export_key_in_recursion_format(inner_verifier.key); + + const uint32_t key_hash_start_idx = static_cast(witness_offset); + const uint32_t public_input_start_idx = key_hash_start_idx + 1; + const uint32_t output_aggregation_object_start_idx = + static_cast(public_input_start_idx + num_inner_public_inputs + (has_nested_proof ? 16 : 0)); + const uint32_t proof_indices_start_idx = output_aggregation_object_start_idx + 16; + const uint32_t key_indices_start_idx = static_cast(proof_indices_start_idx + proof_witnesses.size()); + + std::vector proof_indices; + std::vector key_indices; + std::vector inner_public_inputs; + std::array input_aggregation_object = {}; + std::array nested_aggregation_object = {}; + if (has_input_aggregation_object) { + input_aggregation_object = output_aggregation_object; + } + for (size_t i = 0; i < 16; ++i) { + output_aggregation_object[i] = (static_cast(i + output_aggregation_object_start_idx)); + } + if (has_nested_proof) { + for (size_t i = 0; i < 16; ++i) { + nested_aggregation_object[i] = inner_composer.recursive_proof_public_input_indices[i]; + } + } + for (size_t i = 0; i < proof_witnesses.size(); ++i) { + proof_indices.emplace_back(static_cast(i + proof_indices_start_idx)); + } + const size_t key_size = key_witnesses.size(); + for (size_t i = 0; i < key_size; ++i) { + key_indices.emplace_back(static_cast(i + key_indices_start_idx)); + } + for (size_t i = 0; i < num_inner_public_inputs; ++i) { + inner_public_inputs.push_back(static_cast(i + public_input_start_idx)); + } + + acir_format::RecursionConstraint recursion_constraint{ + .key = key_indices, + .proof = proof_indices, + .public_inputs = inner_public_inputs, + .key_hash = key_hash_start_idx, + .input_aggregation_object = input_aggregation_object, + .output_aggregation_object = output_aggregation_object, + .nested_aggregation_object = nested_aggregation_object, + }; + recursion_constraints.push_back(recursion_constraint); + for (size_t i = 0; i < proof_indices_start_idx - witness_offset; ++i) { + witness.emplace_back(0); + } + for (const auto& wit : proof_witnesses) { + witness.emplace_back(wit); + } + for (const auto& wit : key_witnesses) { + witness.emplace_back(wit); + } + witness_offset = key_indices_start_idx + key_witnesses.size(); + } + + std::vector public_inputs(output_aggregation_object.begin(), output_aggregation_object.end()); + + acir_format::acir_format constraint_system{ + .varnum = static_cast(witness.size() + 1), + .public_inputs = public_inputs, + .fixed_base_scalar_mul_constraints = {}, + .logic_constraints = {}, + .range_constraints = {}, + .schnorr_constraints = {}, + .ecdsa_constraints = {}, + .sha256_constraints = {}, + .blake2s_constraints = {}, + .keccak_constraints = {}, + .keccak_var_constraints = {}, + .hash_to_field_constraints = {}, + .pedersen_constraints = {}, + .compute_merkle_root_constraints = {}, + .block_constraints = {}, + .recursion_constraints = recursion_constraints, + .constraints = {}, + }; + + auto composer = acir_format::create_circuit_with_witness(constraint_system, witness); + + return composer; +} + +TEST(RecursionConstraint, TestBasicDoubleRecursionConstraints) +{ + std::vector layer_1_composers; + layer_1_composers.push_back(create_inner_circuit()); + + layer_1_composers.push_back(create_inner_circuit()); + + auto layer_2_composer = create_outer_circuit(layer_1_composers); + + std::cout << "composer gates = " << layer_2_composer.get_num_gates() << std::endl; + auto prover = layer_2_composer.create_ultra_with_keccak_prover(); + std::cout << "prover gates = " << prover.circuit_size << std::endl; + auto proof = prover.construct_proof(); + auto verifier = layer_2_composer.create_ultra_with_keccak_verifier(); + EXPECT_EQ(verifier.verify_proof(proof), true); +} + +TEST(RecursionConstraint, TestFullRecursionConstraints) +{ + /** + * We want to test the following: + * 1. circuit that verifies a proof of another circuit + * 2. the above, but the inner circuit contains a recursive proof output that we have to aggregate + * 3. the above, but the outer circuit verifies 2 proofs, the aggregation outputs from the 2 proofs (+ the recursive + * proof output from 2) are aggregated together + * + * A = basic circuit + * B = circuit that verifies proof of A + * C = circuit that verifies proof of B and a proof of A + * + * Layer 1 = proof of A + * Layer 2 = verifies proof of A and proof of B + * Layer 3 = verifies proof of C + * + * Attempt at a visual graphic + * =========================== + * + * C + * ^ + * | + * | - B + * ^ ^ + * | | + * | -A + * | + * - A + * + * =========================== + * + * Final aggregation object contains aggregated proofs for 2 instances of A and 1 instance of B + */ + std::vector layer_1_composers; + layer_1_composers.push_back(create_inner_circuit()); + std::cout << "created first inner circuit\n"; + std::vector layer_2_composers; + + layer_2_composers.push_back(create_inner_circuit()); + std::cout << "created second inner circuit\n"; + + layer_2_composers.push_back(create_outer_circuit(layer_1_composers)); + std::cout << "created first outer circuit\n"; + + auto layer_3_composer = create_outer_circuit(layer_2_composers); + std::cout << "created second outer circuit\n"; + + std::cout << "composer gates = " << layer_3_composer.get_num_gates() << std::endl; + auto prover = layer_3_composer.create_ultra_with_keccak_prover(); + std::cout << "prover gates = " << prover.circuit_size << std::endl; + auto proof = prover.construct_proof(); + auto verifier = layer_3_composer.create_ultra_with_keccak_verifier(); + EXPECT_EQ(verifier.verify_proof(proof), true); +} diff --git a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp index 12fe771c25..0dc392c284 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp @@ -4,23 +4,22 @@ #include "barretenberg/plonk/proof_system/proving_key/serialize.hpp" #include "barretenberg/dsl/acir_format/acir_format.hpp" #include "barretenberg/dsl/types.hpp" +#include "barretenberg/plonk/proof_system/verification_key/verification_key.hpp" #include "barretenberg/srs/factories/crs_factory.hpp" #include "barretenberg/plonk/proof_system/verification_key/sol_gen.hpp" #include "barretenberg/srs/factories/crs_factory.hpp" namespace acir_proofs { -AcirComposer::AcirComposer(std::shared_ptr const& crs_factory) - : crs_factory_(crs_factory) - , composer_(0, 0, 0) +AcirComposer::AcirComposer() + : composer_(0, 0, 0) {} -void AcirComposer::create_circuit(acir_format::acir_format& constraint_system, size_t size_hint) +void AcirComposer::create_circuit(acir_format::acir_format& constraint_system) { - composer_ = acir_format::create_circuit(constraint_system, crs_factory_, size_hint); + composer_ = acir_format::create_circuit(constraint_system, nullptr); // We are done with the constraint system at this point, and we need the memory slab back. - // constraint_system = acir_format::acir_format(); constraint_system.constraints.clear(); constraint_system.constraints.shrink_to_fit(); @@ -29,18 +28,32 @@ void AcirComposer::create_circuit(acir_format::acir_format& constraint_system, s circuit_subgroup_size_ = composer_.get_circuit_subgroup_size(total_circuit_size_); } -void AcirComposer::init_proving_key(acir_format::acir_format& constraint_system, size_t size_hint) +void AcirComposer::init_proving_key(std::shared_ptr const& crs_factory, + acir_format::acir_format& constraint_system, + size_t size_hint) { - create_circuit(constraint_system, size_hint); + composer_ = acir_format::create_circuit(constraint_system, crs_factory, size_hint); + + // We are done with the constraint system at this point, and we need the memory slab back. + constraint_system.constraints.clear(); + constraint_system.constraints.shrink_to_fit(); + + exact_circuit_size_ = composer_.get_num_gates(); + total_circuit_size_ = composer_.get_total_circuit_size(); + circuit_subgroup_size_ = composer_.get_circuit_subgroup_size(total_circuit_size_); + proving_key_ = composer_.compute_proving_key(); } -std::vector AcirComposer::create_proof(acir_format::acir_format& constraint_system, - acir_format::WitnessVector& witness) +std::vector AcirComposer::create_proof( + std::shared_ptr const& crs_factory, + acir_format::acir_format& constraint_system, + acir_format::WitnessVector& witness, + bool is_recursive) { composer_ = acir_format::Composer(proving_key_, verification_key_, circuit_subgroup_size_); // You can't produce the verification key unless you manually set the crs. Which seems like a bug. - composer_.crs_factory_ = crs_factory_; + composer_.crs_factory_ = crs_factory; create_circuit_with_witness(composer_, constraint_system, witness); @@ -50,8 +63,14 @@ std::vector AcirComposer::create_proof(acir_format::acir_format& constr witness.clear(); witness.shrink_to_fit(); - auto prover = composer_.create_ultra_with_keccak_prover(); - auto proof = prover.construct_proof().proof_data; + std::vector proof; + if (is_recursive) { + auto prover = composer_.create_prover(); + proof = prover.construct_proof().proof_data; + } else { + auto prover = composer_.create_ultra_with_keccak_prover(); + proof = prover.construct_proof().proof_data; + } return proof; } @@ -60,10 +79,26 @@ std::shared_ptr AcirComposer::init_verifi return verification_key_ = composer_.compute_verification_key(); } -bool AcirComposer::verify_proof(std::vector const& proof) +void AcirComposer::load_verification_key(std::shared_ptr const& crs_factory, + proof_system::plonk::verification_key_data&& data) { - auto verifier = composer_.create_ultra_with_keccak_verifier(); - return verifier.verify_proof({ proof }); + verification_key_ = + std::make_shared(std::move(data), crs_factory->get_verifier_crs()); + composer_ = acir_format::Composer(proving_key_, verification_key_, circuit_subgroup_size_); +} + +bool AcirComposer::verify_proof(std::vector const& proof, bool is_recursive) +{ + // Hack. Shouldn't need to do this. 2144 is size with no public inputs. + composer_.public_inputs.resize((proof.size() - 2144) / 32); + + if (is_recursive) { + auto verifier = composer_.create_verifier(); + return verifier.verify_proof({ proof }); + } else { + auto verifier = composer_.create_ultra_with_keccak_verifier(); + return verifier.verify_proof({ proof }); + } } std::string AcirComposer::get_solidity_verifier() @@ -73,4 +108,36 @@ std::string AcirComposer::get_solidity_verifier() return stream.str(); } +/** + * @brief Takes in a proof buffer and converts into a vector of field elements. + * The Recursion opcode requires the proof serialized as a vector of witnesses. + * Use this method to get the witness values! + * + * @param proof + * @param num_inner_public_inputs - number of public inputs on the proof being serialized + */ +std::vector AcirComposer::serialize_proof_into_fields(std::vector const& proof, + size_t num_inner_public_inputs) +{ + transcript::StandardTranscript transcript(proof, + acir_format::Composer::create_manifest(num_inner_public_inputs), + transcript::HashType::PlookupPedersenBlake3s, + 16); + + std::vector output = acir_format::export_transcript_in_recursion_format(transcript); + return output; +} + +/** + * @brief Takes in a verification key buffer and converts into a vector of field elements. + * The Recursion opcode requires the vk serialized as a vector of witnesses. + * Use this method to get the witness values! + * The composer should already have a verification key initialized. + */ +std::vector AcirComposer::serialize_verification_key_into_fields() +{ + std::vector output = acir_format::export_key_in_recursion_format(verification_key_); + return output; +} + } // namespace acir_proofs diff --git a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.hpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.hpp index 8e95542c1e..c6de53c205 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.hpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.hpp @@ -9,24 +9,36 @@ namespace acir_proofs { class AcirComposer { public: - AcirComposer(std::shared_ptr const& crs_factory); + AcirComposer(); - void create_circuit(acir_format::acir_format& constraint_system, size_t size_hint = 0); + void create_circuit(acir_format::acir_format& constraint_system); - void init_proving_key(acir_format::acir_format& constraint_system, size_t size_hint = 0); + void init_proving_key(std::shared_ptr const& crs_factory, + acir_format::acir_format& constraint_system, + size_t size_hint = 0); - std::vector create_proof(acir_format::acir_format& constraint_system, acir_format::WitnessVector& witness); + std::vector create_proof(std::shared_ptr const& crs_factory, + acir_format::acir_format& constraint_system, + acir_format::WitnessVector& witness, + bool is_recursive); + + void load_verification_key(std::shared_ptr const& crs_factory, + proof_system::plonk::verification_key_data&& data); std::shared_ptr init_verification_key(); - bool verify_proof(std::vector const& proof); + bool verify_proof(std::vector const& proof, bool is_recursive); std::string get_solidity_verifier(); size_t get_exact_circuit_size() { return exact_circuit_size_; }; size_t get_total_circuit_size() { return total_circuit_size_; }; + std::vector serialize_proof_into_fields(std::vector const& proof, + size_t num_inner_public_inputs); + + std::vector serialize_verification_key_into_fields(); + private: - std::shared_ptr crs_factory_; acir_format::Composer composer_; size_t exact_circuit_size_; size_t total_circuit_size_; diff --git a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp index 81fb4adec9..8cce085b72 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp @@ -7,29 +7,30 @@ #include "barretenberg/common/serialize.hpp" #include "barretenberg/common/slab_allocator.hpp" #include "barretenberg/dsl/acir_format/acir_format.hpp" +#include "barretenberg/plonk/proof_system/verification_key/verification_key.hpp" #include "barretenberg/srs/global_crs.hpp" -WASM_EXPORT void acir_new_acir_composer(out_ptr out) +WASM_EXPORT void acir_get_circuit_sizes(uint8_t const* constraint_system_buf, + uint32_t* exact, + uint32_t* total, + uint32_t* subgroup) { - *out = new acir_proofs::AcirComposer(barretenberg::srs::get_crs_factory()); + auto constraint_system = from_buffer(constraint_system_buf); + free_mem_slab_raw((void*)constraint_system_buf); + auto composer = acir_format::create_circuit(constraint_system, nullptr, 1 << 19); + *exact = htonl((uint32_t)composer.get_num_gates()); + *total = htonl((uint32_t)composer.get_total_circuit_size()); + *subgroup = htonl((uint32_t)composer.get_circuit_subgroup_size(composer.get_total_circuit_size())); } -WASM_EXPORT void acir_delete_acir_composer(in_ptr acir_composer_ptr) +WASM_EXPORT void acir_new_acir_composer(out_ptr out) { - delete reinterpret_cast(*acir_composer_ptr); + *out = new acir_proofs::AcirComposer(); } -WASM_EXPORT void acir_create_circuit(in_ptr acir_composer_ptr, - uint8_t const* constraint_system_buf, - uint32_t const* size_hint) +WASM_EXPORT void acir_delete_acir_composer(in_ptr acir_composer_ptr) { - auto acir_composer = reinterpret_cast(*acir_composer_ptr); - auto constraint_system = from_buffer(constraint_system_buf); - - // The binder would normally free the the constraint_system_buf, but we need the memory now. - free_mem_slab_raw((void*)constraint_system_buf); - - acir_composer->create_circuit(constraint_system, ntohl(*size_hint)); + delete reinterpret_cast(*acir_composer_ptr); } WASM_EXPORT void acir_init_proving_key(in_ptr acir_composer_ptr, @@ -42,12 +43,13 @@ WASM_EXPORT void acir_init_proving_key(in_ptr acir_composer_ptr, // The binder would normally free the the constraint_system_buf, but we need the memory now. free_mem_slab_raw((void*)constraint_system_buf); - acir_composer->init_proving_key(constraint_system, ntohl(*size_hint)); + acir_composer->init_proving_key(barretenberg::srs::get_crs_factory(), constraint_system, ntohl(*size_hint)); } WASM_EXPORT void acir_create_proof(in_ptr acir_composer_ptr, uint8_t const* constraint_system_buf, uint8_t const* witness_buf, + bool const* is_recursive, uint8_t** out) { auto acir_composer = reinterpret_cast(*acir_composer_ptr); @@ -58,10 +60,18 @@ WASM_EXPORT void acir_create_proof(in_ptr acir_composer_ptr, free_mem_slab_raw((void*)constraint_system_buf); free_mem_slab_raw((void*)witness_buf); - auto proof_data = acir_composer->create_proof(constraint_system, witness); + auto proof_data = + acir_composer->create_proof(barretenberg::srs::get_crs_factory(), constraint_system, witness, *is_recursive); *out = to_heap_buffer(proof_data); } +WASM_EXPORT void acir_load_verification_key(in_ptr acir_composer_ptr, uint8_t const* vk_buf) +{ + auto acir_composer = reinterpret_cast(*acir_composer_ptr); + auto vk_data = from_buffer(vk_buf); + acir_composer->load_verification_key(barretenberg::srs::get_crs_factory(), std::move(vk_data)); +} + WASM_EXPORT void acir_init_verification_key(in_ptr acir_composer_ptr) { auto acir_composer = reinterpret_cast(*acir_composer_ptr); @@ -78,11 +88,14 @@ WASM_EXPORT void acir_get_verification_key(in_ptr acir_composer_ptr, uint8_t** o *out = to_heap_buffer(to_buffer(*vk)); } -WASM_EXPORT void acir_verify_proof(in_ptr acir_composer_ptr, uint8_t const* proof_buf, bool* result) +WASM_EXPORT void acir_verify_proof(in_ptr acir_composer_ptr, + uint8_t const* proof_buf, + bool const* is_recursive, + bool* result) { auto acir_composer = reinterpret_cast(*acir_composer_ptr); auto proof = from_buffer>(proof_buf); - *result = acir_composer->verify_proof(proof); + *result = acir_composer->verify_proof(proof, *is_recursive); } WASM_EXPORT void acir_get_solidity_verifier(in_ptr acir_composer_ptr, out_str_buf out) @@ -92,14 +105,28 @@ WASM_EXPORT void acir_get_solidity_verifier(in_ptr acir_composer_ptr, out_str_bu *out = to_heap_buffer(str); } -WASM_EXPORT void acir_get_exact_circuit_size(in_ptr acir_composer_ptr, uint32_t* out) +WASM_EXPORT void acir_serialize_proof_into_fields(in_ptr acir_composer_ptr, + uint8_t const* proof_buf, + uint32_t const* num_inner_public_inputs, + fr::vec_out_buf out) { auto acir_composer = reinterpret_cast(*acir_composer_ptr); - *out = htonl((uint32_t)acir_composer->get_exact_circuit_size()); + auto proof = from_buffer>(proof_buf); + auto proof_as_fields = acir_composer->serialize_proof_into_fields(proof, ntohl(*num_inner_public_inputs)); + + *out = to_heap_buffer(proof_as_fields); } -WASM_EXPORT void acir_get_total_circuit_size(in_ptr acir_composer_ptr, uint32_t* out) +WASM_EXPORT void acir_serialize_verification_key_into_fields(in_ptr acir_composer_ptr, + fr::vec_out_buf out_vkey, + fr::out_buf out_key_hash) { auto acir_composer = reinterpret_cast(*acir_composer_ptr); - *out = htonl((uint32_t)acir_composer->get_total_circuit_size()); -} \ No newline at end of file + + auto vkey_as_fields = acir_composer->serialize_verification_key_into_fields(); + auto vk_hash = vkey_as_fields.back(); + vkey_as_fields.pop_back(); + + *out_vkey = to_heap_buffer(vkey_as_fields); + write(out_key_hash, vk_hash); +} diff --git a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp index f0c1a5dd93..9fbd0be14a 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp @@ -4,6 +4,13 @@ #include #include +using namespace barretenberg; + +WASM_EXPORT void acir_get_circuit_sizes(uint8_t const* constraint_system_buf, + uint32_t* exact, + uint32_t* total, + uint32_t* subgroup); + WASM_EXPORT void acir_new_acir_composer(out_ptr out); WASM_EXPORT void acir_delete_acir_composer(in_ptr acir_composer_ptr); @@ -24,16 +31,27 @@ WASM_EXPORT void acir_init_proving_key(in_ptr acir_composer_ptr, WASM_EXPORT void acir_create_proof(in_ptr acir_composer_ptr, uint8_t const* constraint_system_buf, uint8_t const* witness_buf, + bool const* is_recursive, uint8_t** out); +WASM_EXPORT void acir_load_verification_key(in_ptr acir_composer_ptr, uint8_t const* vk_buf); + WASM_EXPORT void acir_init_verification_key(in_ptr acir_composer_ptr); WASM_EXPORT void acir_get_verification_key(in_ptr acir_composer_ptr, uint8_t** out); -WASM_EXPORT void acir_verify_proof(in_ptr acir_composer_ptr, uint8_t const* proof_buf, bool* result); +WASM_EXPORT void acir_verify_proof(in_ptr acir_composer_ptr, + uint8_t const* proof_buf, + bool const* is_recursive, + bool* result); WASM_EXPORT void acir_get_solidity_verifier(in_ptr acir_composer_ptr, out_str_buf out); -WASM_EXPORT void acir_get_exact_circuit_size(in_ptr acir_composer_ptr, uint32_t* out); +WASM_EXPORT void acir_serialize_proof_into_fields(in_ptr acir_composer_ptr, + uint8_t const* proof_buf, + uint32_t const* num_inner_public_inputs, + fr::vec_out_buf out); -WASM_EXPORT void acir_get_total_circuit_size(in_ptr acir_composer_ptr, uint32_t* out); \ No newline at end of file +WASM_EXPORT void acir_serialize_verification_key_into_fields(in_ptr acir_composer_ptr, + fr::vec_out_buf out_vkey, + fr::out_buf out_key_hash); \ No newline at end of file diff --git a/cpp/src/barretenberg/dsl/types.hpp b/cpp/src/barretenberg/dsl/types.hpp index e5277faf2d..f9823984bf 100644 --- a/cpp/src/barretenberg/dsl/types.hpp +++ b/cpp/src/barretenberg/dsl/types.hpp @@ -20,6 +20,10 @@ #include "barretenberg/stdlib/primitives/curves/secp256k1.hpp" #include "barretenberg/stdlib/primitives/memory/rom_table.hpp" #include "barretenberg/stdlib/primitives/memory/ram_table.hpp" +#include "barretenberg/stdlib/recursion/verifier/program_settings.hpp" +#include "barretenberg/stdlib/recursion/verification_key/verification_key.hpp" +#include "barretenberg/stdlib/recursion/aggregation_state/aggregation_state.hpp" + namespace acir_format { using Composer = plonk::UltraComposer; @@ -34,6 +38,8 @@ using Verifier = std::conditional_t< plonk::UltraWithKeccakVerifier, std::conditional_t, plonk::TurboVerifier, plonk::Verifier>>; +using RecursiveProver = plonk::UltraProver; + using witness_ct = proof_system::plonk::stdlib::witness_t; using public_witness_ct = proof_system::plonk::stdlib::public_witness_t; using bool_ct = proof_system::plonk::stdlib::bool_t; @@ -58,8 +64,13 @@ using hash_path_ct = proof_system::plonk::stdlib::merkle_tree::hash_path; -// Ultra-composer specific typesv +// Ultra-composer specific types using rom_table_ct = proof_system::plonk::stdlib::rom_table; using ram_table_ct = proof_system::plonk::stdlib::ram_table; +using verification_key_ct = proof_system::plonk::stdlib::recursion::verification_key; +using aggregation_state_ct = proof_system::plonk::stdlib::recursion::aggregation_state; +using noir_recursive_settings = proof_system::plonk::stdlib::recursion::recursive_ultra_verifier_settings; +using Transcript_ct = proof_system::plonk::stdlib::recursion::Transcript; + } // namespace acir_format diff --git a/cpp/src/barretenberg/plonk/composer/composer_base.hpp b/cpp/src/barretenberg/plonk/composer/composer_base.hpp index ccbbca2c31..29330b085f 100644 --- a/cpp/src/barretenberg/plonk/composer/composer_base.hpp +++ b/cpp/src/barretenberg/plonk/composer/composer_base.hpp @@ -189,6 +189,19 @@ class ComposerBase { barretenberg::fr get_public_input(const uint32_t index) const { return get_variable(public_inputs[index]); } + uint32_t get_public_input_index(const uint32_t witness_index) const + { + uint32_t result = static_cast(-1); + for (size_t i = 0; i < public_inputs.size(); ++i) { + if (real_variable_index[public_inputs[i]] == real_variable_index[witness_index]) { + result = static_cast(i); + break; + } + } + ASSERT(result != static_cast(-1)); + return result; + } + std::vector get_public_inputs() const { std::vector result; diff --git a/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp b/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp index 02efa47c13..a56a3af717 100644 --- a/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp +++ b/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp @@ -568,7 +568,6 @@ std::shared_ptr UltraComposer::compute_proving_key() // Compute selector polynomials and appropriate fft versions and put them in the proving key ComposerBase::compute_proving_key_base(type, tables_size + lookups_size, NUM_RESERVED_GATES); - const size_t subgroup_size = circuit_proving_key->circuit_size; polynomial poly_q_table_column_1(subgroup_size); diff --git a/cpp/src/barretenberg/plonk/composer/ultra_composer.hpp b/cpp/src/barretenberg/plonk/composer/ultra_composer.hpp index 693257677e..c7e82be144 100644 --- a/cpp/src/barretenberg/plonk/composer/ultra_composer.hpp +++ b/cpp/src/barretenberg/plonk/composer/ultra_composer.hpp @@ -255,6 +255,23 @@ class UltraComposer : public ComposerBase { } } + /** + * @brief Update recursive_proof_public_input_indices with existing public inputs that represent a recursive proof + * + * @param proof_output_witness_indices + */ + void set_recursive_proof(const std::vector& proof_output_witness_indices) + { + if (contains_recursive_proof) { + failure("added recursive proof when one already exists"); + } + contains_recursive_proof = true; + for (size_t i = 0; i < proof_output_witness_indices.size(); ++i) { + recursive_proof_public_input_indices.push_back( + get_public_input_index(real_variable_index[proof_output_witness_indices[i]])); + } + } + void create_new_range_constraint(const uint32_t variable_index, const uint64_t target_range, std::string const msg = "create_new_range_constraint"); diff --git a/cpp/src/barretenberg/plonk/proof_system/types/polynomial_manifest.hpp b/cpp/src/barretenberg/plonk/proof_system/types/polynomial_manifest.hpp index c16aeaafdf..e2b4cc6e10 100644 --- a/cpp/src/barretenberg/plonk/proof_system/types/polynomial_manifest.hpp +++ b/cpp/src/barretenberg/plonk/proof_system/types/polynomial_manifest.hpp @@ -200,7 +200,7 @@ class PolynomialManifest { }; } - const std::vector& get() { return manifest; }; + const std::vector& get() const { return manifest; }; size_t size() const { return manifest.size(); } diff --git a/cpp/src/barretenberg/plonk/proof_system/verification_key/verification_key.hpp b/cpp/src/barretenberg/plonk/proof_system/verification_key/verification_key.hpp index 4b2d756d8d..d56909181c 100644 --- a/cpp/src/barretenberg/plonk/proof_system/verification_key/verification_key.hpp +++ b/cpp/src/barretenberg/plonk/proof_system/verification_key/verification_key.hpp @@ -75,6 +75,7 @@ struct verification_key { const size_t num_inputs, std::shared_ptr const& crs, uint32_t composer_type); + verification_key(const verification_key& other); verification_key(verification_key&& other); verification_key& operator=(verification_key&& other); diff --git a/cpp/src/barretenberg/solidity_helpers/CMakeLists.txt b/cpp/src/barretenberg/solidity_helpers/CMakeLists.txt index 0dbb3b2d5e..bf448229a8 100644 --- a/cpp/src/barretenberg/solidity_helpers/CMakeLists.txt +++ b/cpp/src/barretenberg/solidity_helpers/CMakeLists.txt @@ -1,4 +1,4 @@ -barretenberg_module(stdlib_solidity_helpers plonk proof_system transcript crypto_pedersen_commitment polynomials crypto_sha256 ecc crypto_blake3s stdlib_primitives stdlib_pedersen_commitment stdlib_blake3s stdlib_blake2s) +barretenberg_module(stdlib_solidity_helpers plonk proof_system transcript crypto_pedersen_commitment polynomials crypto_sha256 ecc crypto_blake3s stdlib_primitives stdlib_pedersen_commitment stdlib_blake3s stdlib_blake2s srs) add_executable(solidity_key_gen key_gen.cpp) diff --git a/cpp/src/barretenberg/solidity_helpers/circuits/recursive_circuit.hpp b/cpp/src/barretenberg/solidity_helpers/circuits/recursive_circuit.hpp index 7274600b84..693418182f 100644 --- a/cpp/src/barretenberg/solidity_helpers/circuits/recursive_circuit.hpp +++ b/cpp/src/barretenberg/solidity_helpers/circuits/recursive_circuit.hpp @@ -110,6 +110,7 @@ template class RecursiveCircuit { OuterComposer outer_composer = OuterComposer(srs_path); create_inner_circuit_no_tables(inner_composer, inputs); + auto circuit_output = create_outer_circuit(inner_composer, outer_composer); g1::affine_element P[2]; diff --git a/cpp/src/barretenberg/stdlib/recursion/transcript/transcript.hpp b/cpp/src/barretenberg/stdlib/recursion/transcript/transcript.hpp index 9db2f12dc9..87e55977d0 100644 --- a/cpp/src/barretenberg/stdlib/recursion/transcript/transcript.hpp +++ b/cpp/src/barretenberg/stdlib/recursion/transcript/transcript.hpp @@ -49,6 +49,54 @@ template class Transcript { // } } + /** + * @brief Construct a new Transcript object using a proof represented as a field_pt vector + * + * N.B. If proof is represented as a uint8_t vector, Transcript will convert into witnesses in-situ. + * Use this constructor method if the proof is *already present* as circuit witnesses! + * @param in_context + * @param input_manifest + * @param field_buffer + * @param num_public_inputs + */ + Transcript(Composer* in_context, + const transcript::Manifest input_manifest, + const std::vector& field_buffer, + const size_t num_public_inputs) + : context(in_context) + , transcript_base(input_manifest, transcript::HashType::PlookupPedersenBlake3s, 16) + , current_challenge(in_context) + { + size_t count = 0; + + const auto num_rounds = input_manifest.get_num_rounds(); + for (size_t i = 0; i < num_rounds; ++i) { + for (auto manifest_element : input_manifest.get_round_manifest(i).elements) { + if (!manifest_element.derived_by_verifier) { + if (manifest_element.num_bytes == 32 && manifest_element.name != "public_inputs") { + add_field_element(manifest_element.name, field_buffer[count++]); + } else if (manifest_element.num_bytes == 64 && manifest_element.name != "public_inputs") { + const auto x_lo = field_buffer[count++]; + const auto x_hi = field_buffer[count++]; + const auto y_lo = field_buffer[count++]; + const auto y_hi = field_buffer[count++]; + fq_pt x(x_lo, x_hi); + fq_pt y(y_lo, y_hi); + group_pt element(x, y); + add_group_element(manifest_element.name, element); + } else { + ASSERT(manifest_element.name == "public_inputs"); + std::vector public_inputs; + for (size_t i = 0; i < num_public_inputs; ++i) { + public_inputs.emplace_back(field_buffer[count++]); + } + add_field_element_vector(manifest_element.name, public_inputs); + } + } + } + } + } + transcript::Manifest get_manifest() const { return transcript_base.get_manifest(); } int check_field_element_cache(const std::string& element_name) const diff --git a/cpp/src/barretenberg/stdlib/recursion/verification_key/verification_key.hpp b/cpp/src/barretenberg/stdlib/recursion/verification_key/verification_key.hpp index f8f21642d2..3d05b572a6 100644 --- a/cpp/src/barretenberg/stdlib/recursion/verification_key/verification_key.hpp +++ b/cpp/src/barretenberg/stdlib/recursion/verification_key/verification_key.hpp @@ -178,6 +178,20 @@ template struct PedersenPreimage }; template struct evaluation_domain { + static evaluation_domain from_field_elements(const std::vector>& fields) + { + evaluation_domain domain; + domain.root = fields[0]; + + domain.root_inverse = domain.root.invert(); + domain.domain = fields[1]; + domain.domain_inverse = domain.domain.invert(); + domain.generator = fields[2]; + domain.generator_inverse = domain.generator.invert(); + domain.size = domain.domain; + return domain; + } + static evaluation_domain from_witness(Composer* ctx, const barretenberg::evaluation_domain& input) { evaluation_domain domain; @@ -213,20 +227,63 @@ template struct evaluation_domain { uint32 size; }; -/** - * @brief Converts a 'native' verification key into a standard library type, instantiating the `input_key` parameter as - * circuit variables. This allows the recursive verifier to accept arbitrary verification keys, where the circuit being - * verified is not fixed as part of the recursive circuit. - */ template struct verification_key { using Composer = typename Curve::Composer; + + static std::shared_ptr from_field_elements( + Composer* ctx, + const std::vector>& fields, + bool inner_proof_contains_recursive_proof = false, + std::array recursive_proof_public_input_indices = {}) + { + std::vector fields_raw; + std::shared_ptr key = std::make_shared(); + key->context = ctx; + + key->polynomial_manifest = PolynomialManifest(Composer::type); + key->domain = evaluation_domain::from_field_elements({ fields[0], fields[1], fields[2] }); + + key->n = fields[3]; + key->num_public_inputs = fields[4]; + + // NOTE: For now `contains_recursive_proof` and `recursive_proof_public_input_indices` need to be circuit + // constants! + key->contains_recursive_proof = inner_proof_contains_recursive_proof; + for (size_t i = 0; i < 16; ++i) { + auto x = recursive_proof_public_input_indices[i]; + key->recursive_proof_public_input_indices.emplace_back(x); + } + + size_t count = 22; + for (const auto& descriptor : key->polynomial_manifest.get()) { + if (descriptor.source == PolynomialSource::SELECTOR || descriptor.source == PolynomialSource::PERMUTATION) { + + const auto x_lo = fields[count++]; + const auto x_hi = fields[count++]; + const auto y_lo = fields[count++]; + const auto y_hi = fields[count++]; + const typename Curve::fq_ct x(x_lo, x_hi); + const typename Curve::fq_ct y(y_lo, y_hi); + const typename Curve::g1_ct element(x, y); + + key->commitments.insert({ std::string(descriptor.commitment_label), element }); + } + } + + return key; + } + + /** + * @brief Converts a 'native' verification key into a standard library type, instantiating the `input_key` parameter + * as circuit variables. This allows the recursive verifier to accept arbitrary verification keys, where the circuit + * being verified is not fixed as part of the recursive circuit. + */ static std::shared_ptr from_witness(Composer* ctx, const std::shared_ptr& input_key) { std::shared_ptr key = std::make_shared(); // Native data: key->context = ctx; - key->base_key = input_key; key->reference_string = input_key->reference_string; key->polynomial_manifest = input_key->polynomial_manifest; @@ -234,7 +291,8 @@ template struct verification_key { key->n = witness_t(ctx, barretenberg::fr(input_key->circuit_size)); key->num_public_inputs = witness_t(ctx, input_key->num_public_inputs); key->domain = evaluation_domain::from_witness(ctx, input_key->domain); - key->contains_recursive_proof = witness_t(ctx, input_key->contains_recursive_proof); + key->contains_recursive_proof = input_key->contains_recursive_proof; + key->recursive_proof_public_input_indices = input_key->recursive_proof_public_input_indices; for (const auto& [tag, value] : input_key->commitments) { // We do not perform on_curve() circuit checks when constructing the Curve::g1_ct element. // The assumption is that the circuit creator is honest and that the verification key hash (or some other @@ -254,19 +312,18 @@ template struct verification_key { { std::shared_ptr key = std::make_shared(); key->context = ctx; - key->base_key = input_key; key->n = field_t(ctx, input_key->circuit_size); key->num_public_inputs = field_t(ctx, input_key->num_public_inputs); - key->contains_recursive_proof = bool_t(ctx, input_key->contains_recursive_proof); + key->contains_recursive_proof = input_key->contains_recursive_proof; + key->recursive_proof_public_input_indices = input_key->recursive_proof_public_input_indices; key->domain = evaluation_domain::from_constants(ctx, input_key->domain); - key->reference_string = input_key->reference_string; - for (const auto& [tag, value] : input_key->commitments) { key->commitments.insert({ tag, typename Curve::g1_ct(value) }); } + key->reference_string = input_key->reference_string; key->polynomial_manifest = input_key->polynomial_manifest; return key; @@ -380,10 +437,6 @@ template struct verification_key { field_t num_public_inputs; field_t z_pow_n; - // NOTE: This does not strictly need to be a circuit type. It can be used to check in the circuit - // if a proof contains any aggregated state. - bool_t contains_recursive_proof; - evaluation_domain domain; std::map commitments; @@ -393,10 +446,10 @@ template struct verification_key { std::shared_ptr reference_string; PolynomialManifest polynomial_manifest; - + // Used to check in the circuit if a proof contains any aggregated state. + bool contains_recursive_proof = false; + std::vector recursive_proof_public_input_indices; size_t program_width = 4; - - std::shared_ptr base_key; Composer* context; }; diff --git a/cpp/src/barretenberg/stdlib/recursion/verifier/verifier.hpp b/cpp/src/barretenberg/stdlib/recursion/verifier/verifier.hpp index 009e732b20..244aa0950c 100644 --- a/cpp/src/barretenberg/stdlib/recursion/verifier/verifier.hpp +++ b/cpp/src/barretenberg/stdlib/recursion/verifier/verifier.hpp @@ -181,6 +181,25 @@ aggregation_state verify_proof(typename Curve::Composer* context, const transcript::Manifest& manifest, const plonk::proof& proof, const aggregation_state previous_output = aggregation_state()) +{ + using Composer = typename Curve::Composer; + + key->program_width = program_settings::program_width; + + Transcript transcript = Transcript(context, proof.proof_data, manifest); + + return verify_proof_(context, key, transcript, previous_output); +} + +/** + * Refer to src/barretenberg/plonk/proof_system/verifier/verifier.cpp verify_proof() for the native implementation, + * which includes detailed comments. + */ +template +aggregation_state verify_proof_(typename Curve::Composer* context, + std::shared_ptr> key, + Transcript& transcript, + const aggregation_state previous_output = aggregation_state()) { using fr_ct = typename Curve::fr_ct; using fq_ct = typename Curve::fq_ct; @@ -189,7 +208,6 @@ aggregation_state verify_proof(typename Curve::Composer* context, key->program_width = program_settings::program_width; - Transcript transcript = Transcript(context, proof.proof_data, manifest); std::map kate_g1_elements; std::map kate_fr_elements_at_zeta; std::map kate_fr_elements_at_zeta_large; @@ -231,6 +249,7 @@ aggregation_state verify_proof(typename Curve::Composer* context, fr_ct u = transcript.get_challenge_field_element("separator", 0); fr_ct batch_opening_scalar; + populate_kate_element_map, program_settings>(context, key.get(), transcript, @@ -311,10 +330,6 @@ aggregation_state verify_proof(typename Curve::Composer* context, rhs_scalars.push_back(random_separator); } - // Check if recursive proof information is correctly set. - key->contains_recursive_proof.assert_equal(key->base_key->contains_recursive_proof, - "contains_recursive_proof is incorrectly set"); - /** * N.B. if this key contains a recursive proof, then ALL potential verification keys being verified by the outer *circuit must ALSO contain a recursive proof (this is not a concern if the key is being generated from circuit @@ -322,7 +337,7 @@ aggregation_state verify_proof(typename Curve::Composer* context, *code path should be used with extreme caution if the verification key is not being generated from circuit *constants **/ - if (key->base_key->contains_recursive_proof) { + if (key->contains_recursive_proof) { const auto public_inputs = transcript.get_field_element_vector("public_inputs"); const auto recover_fq_from_public_inputs = [&public_inputs](const size_t idx0, const size_t idx1, const size_t idx2, const size_t idx3) { @@ -339,22 +354,22 @@ aggregation_state verify_proof(typename Curve::Composer* context, fr_ct recursion_separator_challenge = transcript.get_challenge_field_element("separator", 2); - const auto x0 = recover_fq_from_public_inputs(key->base_key->recursive_proof_public_input_indices[0], - key->base_key->recursive_proof_public_input_indices[1], - key->base_key->recursive_proof_public_input_indices[2], - key->base_key->recursive_proof_public_input_indices[3]); - const auto y0 = recover_fq_from_public_inputs(key->base_key->recursive_proof_public_input_indices[4], - key->base_key->recursive_proof_public_input_indices[5], - key->base_key->recursive_proof_public_input_indices[6], - key->base_key->recursive_proof_public_input_indices[7]); - const auto x1 = recover_fq_from_public_inputs(key->base_key->recursive_proof_public_input_indices[8], - key->base_key->recursive_proof_public_input_indices[9], - key->base_key->recursive_proof_public_input_indices[10], - key->base_key->recursive_proof_public_input_indices[11]); - const auto y1 = recover_fq_from_public_inputs(key->base_key->recursive_proof_public_input_indices[12], - key->base_key->recursive_proof_public_input_indices[13], - key->base_key->recursive_proof_public_input_indices[14], - key->base_key->recursive_proof_public_input_indices[15]); + const auto x0 = recover_fq_from_public_inputs(key->recursive_proof_public_input_indices[0], + key->recursive_proof_public_input_indices[1], + key->recursive_proof_public_input_indices[2], + key->recursive_proof_public_input_indices[3]); + const auto y0 = recover_fq_from_public_inputs(key->recursive_proof_public_input_indices[4], + key->recursive_proof_public_input_indices[5], + key->recursive_proof_public_input_indices[6], + key->recursive_proof_public_input_indices[7]); + const auto x1 = recover_fq_from_public_inputs(key->recursive_proof_public_input_indices[8], + key->recursive_proof_public_input_indices[9], + key->recursive_proof_public_input_indices[10], + key->recursive_proof_public_input_indices[11]); + const auto y1 = recover_fq_from_public_inputs(key->recursive_proof_public_input_indices[12], + key->recursive_proof_public_input_indices[13], + key->recursive_proof_public_input_indices[14], + key->recursive_proof_public_input_indices[15]); opening_elements.push_back(g1_ct(x0, y0)); opening_scalars.push_back(recursion_separator_challenge); diff --git a/exports.json b/exports.json index 4a9b66ce7c..60fb981dd1 100644 --- a/exports.json +++ b/exports.json @@ -535,6 +535,30 @@ "outArgs": [], "isAsync": false }, + { + "functionName": "acir_get_circuit_sizes", + "inArgs": [ + { + "name": "constraint_system_buf", + "type": "const uint8_t *" + } + ], + "outArgs": [ + { + "name": "exact", + "type": "uint32_t *" + }, + { + "name": "total", + "type": "uint32_t *" + }, + { + "name": "subgroup", + "type": "uint32_t *" + } + ], + "isAsync": false + }, { "functionName": "acir_new_acir_composer", "inArgs": [], @@ -609,6 +633,10 @@ { "name": "witness_buf", "type": "const uint8_t *" + }, + { + "name": "is_recursive", + "type": "const bool *" } ], "outArgs": [ @@ -619,6 +647,21 @@ ], "isAsync": false }, + { + "functionName": "acir_load_verification_key", + "inArgs": [ + { + "name": "acir_composer_ptr", + "type": "in_ptr" + }, + { + "name": "vk_buf", + "type": "const uint8_t *" + } + ], + "outArgs": [], + "isAsync": false + }, { "functionName": "acir_init_verification_key", "inArgs": [ @@ -656,6 +699,10 @@ { "name": "proof_buf", "type": "const uint8_t *" + }, + { + "name": "is_recursive", + "type": "const bool *" } ], "outArgs": [ @@ -683,23 +730,31 @@ "isAsync": false }, { - "functionName": "acir_get_exact_circuit_size", + "functionName": "acir_serialize_proof_into_fields", "inArgs": [ { "name": "acir_composer_ptr", "type": "in_ptr" + }, + { + "name": "proof_buf", + "type": "const uint8_t *" + }, + { + "name": "num_inner_public_inputs", + "type": "const uint32_t *" } ], "outArgs": [ { "name": "out", - "type": "uint32_t *" + "type": "fr::vec_out_buf" } ], "isAsync": false }, { - "functionName": "acir_get_total_circuit_size", + "functionName": "acir_serialize_verification_key_into_fields", "inArgs": [ { "name": "acir_composer_ptr", @@ -708,8 +763,12 @@ ], "outArgs": [ { - "name": "out", - "type": "uint32_t *" + "name": "out_vkey", + "type": "fr::vec_out_buf" + }, + { + "name": "out_key_hash", + "type": "fr::out_buf" } ], "isAsync": false diff --git a/ts/README.md b/ts/README.md index c25f356420..a65bad3250 100644 --- a/ts/README.md +++ b/ts/README.md @@ -1,3 +1,116 @@ -# Barretenberg.js +# bb.js -Javascript bindings for barretenberg WASM. +Prover/verifier executable and API for barretenberg. Default cli arguments are appropriate for running within Noir +project structures. + +## Performance and limitations + +Max circuit size is 2^19 gates (524,288). This is due to the underlying WASM 4GB memory limit. This should improve +with future proving systems, and/or introduction of wasm64. + +If running from terminal, or within browser where you can set shared memory CORS headers, multithreading is enabled. +Note there are two independent WASM builds, one with threading enabled and one without. This is because the shared +memory flag is set within the WASM itself. If you're running in a context where you can't have shared memory, we want +to fallback to single threaded performance. + +Performance for 2^19: + +- 16 core x86: ~13s. +- 10 core M1 Mac Pro: ~18s. + +Linear scaling was observed up to 32 cores, however we limit to 16 as 2^19 runs out of memory with 32 cores. +This maybe resolvable. + +## Using as a standalone binary + +### Installing + +To install the package globally for running as a terminal application: + +``` +npm install -g @aztec/bb.js@alpha +``` + +This will install `bb.js` into your path. + +### Usage + +Run `bb.js` for further usage information, you'll see e.g. + +``` +% bb.js +Usage: bb.js [options] [command] + +Options: + -v, --verbose enable verbose logging (default: false) + -h, --help display help for command + +Commands: + prove_and_verify [options] Generate a proof and verify it. Process exits with success or failure code. + prove [options] Generate a proof and write it to a file. + gates [options] Print gate count to standard output. + verify [options] Verify a proof. Process exists with success or failure code. + contract [options] Output solidity verification key contract. + write_vk [options] Output verification key. + proof_as_fields [options] Return the proof as fields elements + vk_as_fields [options] Return the verifiation key represented as fields elements. Also return the verification key hash. + help [command] display help for command +``` + +## Using as a library + +### Installing + +To install as a package to be used as a library: + +``` +npm install @aztec/bb.js@alpha +``` + +or with yarn + +``` +yarn add @aztec/bb.js@alpha +``` + +### Usage + +To create a multithreaded version of the API: + +```typescript +const api = await newBarretenbergApiAsync(/* num_threads */); +// Use. +const input = Buffer.from('hello world!'); +const result = await api.blake2s(input); +await api.destroy(); +``` + +All methods are asynchronous. If no threads are specified, will default to number of cores with a maximum of 16. +If `1` is specified, fallback to non multi-threaded wasm that doesn't need shared memory. + +You can also create a synchronous version of the api that also has no multi-threading. This is only useful in the +browser if you don't call any multi-threaded functions. It's probably best to just always use async version of the api +unless you're really trying to avoid the small overhead of worker communication. + +```typescript +const api = await newBarretenbergApiSync(); +// Use. +const input = Buffer.from('hello world!'); +const result = api.blake2s(input); +await api.destroy(); +``` + +See `src/main.ts` for one example of how to use. + +## Development + +Create a symlink to the root script `bb.js-dev` in your path. You can now run the current state of the code from +anywhere in your filesystem with no `yarn build` required. + +If you change the C++ code run `yarn build:wasm`. + +To run the tests run `yarn test`. + +To run a continuous "stress tests" run `yarn simple_test` to do 10 full pk/proof/vk iterations. + +To run the same test in the browser run `yarn serve`, navigate to appropriate URL and open the console. diff --git a/ts/bb.js-dev b/ts/bb.js-dev new file mode 100755 index 0000000000..5255fe4b37 --- /dev/null +++ b/ts/bb.js-dev @@ -0,0 +1,6 @@ +#!/bin/sh +# Add a symlink to this somewhere in your path. +# Now you can run bb.js-dev anywhere to execute latest code, no 'yarn build' required. +SCRIPT_PATH=$(dirname $(realpath $0)) +export TS_NODE_PROJECT="$SCRIPT_PATH/tsconfig.json" +NODE_OPTIONS="--loader $SCRIPT_PATH/node_modules/ts-node/esm/transpile-only.mjs --no-warnings" node $SCRIPT_PATH/src/main.ts $@ diff --git a/ts/package-lock.json b/ts/package-lock.json deleted file mode 100644 index 2b533c549f..0000000000 --- a/ts/package-lock.json +++ /dev/null @@ -1,11910 +0,0 @@ -{ - "name": "@aztec/barretenberg.js", - "version": "0.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "@aztec/barretenberg.js", - "version": "0.0.0", - "dependencies": { - "bigint-buffer": "^1.1.5", - "commander": "^10.0.1", - "tslib": "^2.4.0" - }, - "bin": { - "bb.js": "dest/main.js", - "bb.js-dev": "src/main-dev.ts" - }, - "devDependencies": { - "@jest/globals": "^29.4.3", - "@types/debug": "^4.1.7", - "@types/detect-node": "^2.0.0", - "@types/jest": "^29.4.0", - "@types/node": "^18.7.23", - "@types/source-map-support": "^0.5.6", - "@typescript-eslint/eslint-plugin": "^5.54.1", - "@typescript-eslint/parser": "^5.54.1", - "buffer": "^6.0.3", - "comlink": "^4.4.1", - "copy-webpack-plugin": "^11.0.0", - "debug": "^4.3.4", - "eslint": "^8.35.0", - "eslint-config-prettier": "^8.8.0", - "html-webpack-plugin": "^5.5.1", - "idb-keyval": "^6.2.1", - "jest": "^29.5.0", - "prettier": "^2.8.4", - "resolve-typescript-plugin": "^2.0.1", - "ts-jest": "^29.1.0", - "ts-loader": "^9.4.2", - "ts-node": "^10.9.1", - "typescript": "^5.0.4", - "webpack": "^5.82.1", - "webpack-cli": "^5.1.1", - "webpack-dev-server": "^4.15.0" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.2.1", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.21.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/highlight": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.21.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.21.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.4", - "@babel/helper-compilation-targets": "^7.21.4", - "@babel/helper-module-transforms": "^7.21.2", - "@babel/helpers": "^7.21.0", - "@babel/parser": "^7.21.4", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.4", - "@babel/types": "^7.21.4", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.0", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.21.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.21.4", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.21.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.21.4", - "@babel/helper-validator-option": "^7.21.0", - "browserslist": "^4.21.3", - "lru-cache": "^5.1.1", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { - "version": "5.1.1", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.0", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { - "version": "3.1.1", - "dev": true, - "license": "ISC" - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.9", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.21.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.21.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.21.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.21.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.2", - "@babel/types": "^7.21.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.20.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.20.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.19.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.21.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.21.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.0", - "@babel/types": "^7.21.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.18.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.21.4", - "dev": true, - "license": "MIT", - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.21.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.21.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/template": { - "version": "7.20.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.21.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.4", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.4", - "@babel/types": "^7.21.4", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/types": { - "version": "7.21.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "dev": true, - "license": "MIT" - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.5.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.5.1", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.12.6", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@eslint/js": { - "version": "8.38.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.8", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "dev": true, - "license": "ISC", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/core": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^29.5.0", - "@jest/reporters": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.5.0", - "jest-config": "^29.5.0", - "jest-haste-map": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-resolve-dependencies": "^29.5.0", - "jest-runner": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "jest-watcher": "^29.5.0", - "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/environment": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/fake-timers": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "jest-mock": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/expect": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "expect": "^29.5.0", - "jest-snapshot": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/expect-utils": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-get-type": "^29.4.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/fake-timers": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.5.0", - "@sinonjs/fake-timers": "^10.0.2", - "@types/node": "*", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-util": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/globals": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/expect": "^29.5.0", - "@jest/types": "^29.5.0", - "jest-mock": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/reporters": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@jridgewell/trace-mapping": "^0.3.15", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "v8-to-istanbul": "^9.0.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/schemas": { - "version": "29.4.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.25.16" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/source-map": { - "version": "29.4.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.15", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/test-result": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/test-result": "^29.5.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.5.0", - "@jridgewell/trace-mapping": "^0.3.15", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/transform/node_modules/convert-source-map": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/@jest/types": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.4.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } - }, - "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "dev": true, - "license": "MIT" - }, - "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.4", - "dev": true, - "license": "MIT" - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@sinclair/typebox": { - "version": "0.25.24", - "dev": true, - "license": "MIT" - }, - "node_modules/@sinonjs/commons": { - "version": "2.0.0", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "10.0.2", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^2.0.0" - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.3", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/babel__core": { - "version": "7.20.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.18.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.3.0" - } - }, - "node_modules/@types/body-parser": { - "version": "1.19.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/bonjour": { - "version": "3.5.10", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.35", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect-history-api-fallback": { - "version": "1.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, - "node_modules/@types/debug": { - "version": "4.1.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/detect-node": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/eslint": { - "version": "8.37.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/express": { - "version": "4.17.17", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.34", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/html-minifier-terser": { - "version": "6.1.0", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/http-proxy": { - "version": "1.17.11", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.4", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.11", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/mime": { - "version": "1.3.2", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/ms": { - "version": "0.7.31", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "18.15.11", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/prettier": { - "version": "2.7.2", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/qs": { - "version": "6.9.7", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/range-parser": { - "version": "1.2.4", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/retry": { - "version": "0.12.0", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/semver": { - "version": "7.3.13", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/send": { - "version": "0.17.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/serve-index": { - "version": "1.9.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/mime": "*", - "@types/node": "*" - } - }, - "node_modules/@types/serve-static/node_modules/@types/mime": { - "version": "3.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/sockjs": { - "version": "0.3.33", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/source-map-support": { - "version": "0.5.6", - "dev": true, - "license": "MIT", - "dependencies": { - "source-map": "^0.6.0" - } - }, - "node_modules/@types/stack-utils": { - "version": "2.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/ws": { - "version": "8.5.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/yargs": { - "version": "17.0.24", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.57.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.57.1", - "@typescript-eslint/type-utils": "5.57.1", - "@typescript-eslint/utils": "5.57.1", - "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "5.57.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "5.57.1", - "@typescript-eslint/types": "5.57.1", - "@typescript-eslint/typescript-estree": "5.57.1", - "debug": "^4.3.4" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.57.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "5.57.1", - "@typescript-eslint/visitor-keys": "5.57.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.57.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "5.57.1", - "@typescript-eslint/utils": "5.57.1", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "5.57.1", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.57.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "5.57.1", - "@typescript-eslint/visitor-keys": "5.57.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "5.57.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.57.1", - "@typescript-eslint/types": "5.57.1", - "@typescript-eslint/typescript-estree": "5.57.1", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.57.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "5.57.1", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.11.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "dev": true, - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "dev": true, - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.6", - "dev": true, - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "dev": true, - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "dev": true, - "license": "MIT" - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-opt": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6", - "@webassemblyjs/wast-printer": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webpack-cli/configtest": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "node_modules/@webpack-cli/info": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "node_modules/@webpack-cli/serve": { - "version": "2.0.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - }, - "peerDependenciesMeta": { - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/accepts": { - "version": "1.3.8", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.8.2", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^8" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ajv": { - "version": "8.12.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-keywords": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/ajv/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-html-community": { - "version": "0.0.8", - "dev": true, - "engines": [ - "node >= 0.8.0" - ], - "license": "Apache-2.0", - "bin": { - "ansi-html": "bin/ansi-html" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/argparse": { - "version": "1.0.10", - "dev": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/array-flatten": { - "version": "2.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/array-union": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-jest": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/transform": "^29.5.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.5.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-plugin-jest-hoist": "^29.5.0", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "dev": true, - "license": "MIT" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/batch": { - "version": "0.6.1", - "dev": true, - "license": "MIT" - }, - "node_modules/bigint-buffer": { - "version": "1.1.5", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "bindings": "^1.3.0" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "license": "MIT", - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/body-parser": { - "version": "1.20.1", - "dev": true, - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/bonjour-service": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "array-flatten": "^2.1.2", - "dns-equal": "^1.0.0", - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.21.5", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bs-logger": { - "version": "0.2.6", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-json-stable-stringify": "2.x" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/buffer": { - "version": "6.0.3", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/bytes": { - "version": "3.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camel-case": { - "version": "4.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001476", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/chalk": { - "version": "4.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0" - } - }, - "node_modules/ci-info": { - "version": "3.8.0", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cjs-module-lexer": { - "version": "1.2.2", - "dev": true, - "license": "MIT" - }, - "node_modules/clean-css": { - "version": "5.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 10.0" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/co": { - "version": "4.6.0", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/color-convert": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "dev": true, - "license": "MIT" - }, - "node_modules/colorette": { - "version": "2.0.20", - "dev": true, - "license": "MIT" - }, - "node_modules/comlink": { - "version": "4.4.1", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/commander": { - "version": "10.0.1", - "license": "MIT", - "engines": { - "node": ">=14" - } - }, - "node_modules/compressible": { - "version": "2.0.18", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compression": { - "version": "1.7.4", - "dev": true, - "license": "MIT", - "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/compression/node_modules/bytes": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/connect-history-api-fallback": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "dev": true, - "license": "MIT" - }, - "node_modules/cookie": { - "version": "0.5.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "dev": true, - "license": "MIT" - }, - "node_modules/copy-webpack-plugin": { - "version": "11.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-glob": "^3.2.11", - "glob-parent": "^6.0.1", - "globby": "^13.1.1", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - } - }, - "node_modules/copy-webpack-plugin/node_modules/globby": { - "version": "13.1.4", - "dev": true, - "license": "MIT", - "dependencies": { - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.11", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/copy-webpack-plugin/node_modules/slash": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "dev": true, - "license": "MIT" - }, - "node_modules/create-require": { - "version": "1.1.1", - "dev": true, - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/css-select": { - "version": "4.3.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/dedent": { - "version": "0.7.0", - "dev": true, - "license": "MIT" - }, - "node_modules/deep-is": { - "version": "0.1.4", - "dev": true, - "license": "MIT" - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-gateway": { - "version": "6.0.3", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/define-lazy-prop": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/detect-newline": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/detect-node": { - "version": "2.1.0", - "dev": true, - "license": "MIT" - }, - "node_modules/diff": { - "version": "4.0.2", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/diff-sequences": { - "version": "29.4.3", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dns-equal": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/dns-packet": { - "version": "5.6.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@leichtgewicht/ip-codec": "^2.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dom-converter": { - "version": "0.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "utila": "~0.4" - } - }, - "node_modules/dom-serializer": { - "version": "1.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "BSD-2-Clause" - }, - "node_modules/domhandler": { - "version": "4.3.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "2.8.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dot-case": { - "version": "3.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "dev": true, - "license": "MIT" - }, - "node_modules/electron-to-chromium": { - "version": "1.4.356", - "dev": true, - "license": "ISC" - }, - "node_modules/emittery": { - "version": "0.13.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.14.0", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/entities": { - "version": "2.2.0", - "dev": true, - "license": "BSD-2-Clause", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/envinfo": { - "version": "7.8.1", - "dev": true, - "license": "MIT", - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-module-lexer": { - "version": "1.2.1", - "dev": true, - "license": "MIT" - }, - "node_modules/escalade": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "dev": true, - "license": "MIT" - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/eslint": { - "version": "8.38.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.2", - "@eslint/js": "8.38.0", - "@humanwhocodes/config-array": "^0.11.8", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-visitor-keys": "^3.4.0", - "espree": "^9.5.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-prettier": { - "version": "8.8.0", - "dev": true, - "license": "MIT", - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-scope/node_modules/estraverse": { - "version": "4.3.0", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.0", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/ajv": { - "version": "6.12.6", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.1.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint/node_modules/find-up": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/locate-path": { - "version": "6.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-locate": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/espree": { - "version": "9.5.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "dev": true, - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "dev": true, - "license": "MIT" - }, - "node_modules/events": { - "version": "3.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expect": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/expect-utils": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/express": { - "version": "4.18.2", - "dev": true, - "license": "MIT", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/array-flatten": { - "version": "1.1.1", - "dev": true, - "license": "MIT" - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-glob": { - "version": "3.2.12", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "dev": true, - "license": "MIT" - }, - "node_modules/fastest-levenshtein": { - "version": "1.0.16", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.9.1" - } - }, - "node_modules/fastq": { - "version": "1.15.0", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "bser": "2.1.1" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/fill-range": { - "version": "7.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/find-up": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.2.7", - "dev": true, - "license": "ISC" - }, - "node_modules/follow-redirects": { - "version": "1.15.2", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs-monkey": { - "version": "1.0.3", - "dev": true, - "license": "Unlicense" - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/function-bind": { - "version": "1.1.1", - "dev": true, - "license": "MIT" - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "dev": true, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/globals": { - "version": "13.20.0", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "dev": true, - "license": "ISC" - }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "dev": true, - "license": "MIT" - }, - "node_modules/handle-thing": { - "version": "2.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/has": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/he": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "bin": { - "he": "bin/he" - } - }, - "node_modules/hpack.js": { - "version": "2.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, - "node_modules/hpack.js/node_modules/readable-stream": { - "version": "2.3.8", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/hpack.js/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/hpack.js/node_modules/string_decoder": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/html-entities": { - "version": "2.3.3", - "dev": true, - "license": "MIT" - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "dev": true, - "license": "MIT" - }, - "node_modules/html-minifier-terser": { - "version": "6.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/html-minifier-terser/node_modules/commander": { - "version": "8.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "node_modules/html-webpack-plugin": { - "version": "5.5.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/html-webpack-plugin" - }, - "peerDependencies": { - "webpack": "^5.20.0" - } - }, - "node_modules/htmlparser2": { - "version": "6.1.0", - "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - }, - "node_modules/http-deceiver": { - "version": "1.2.7", - "dev": true, - "license": "MIT" - }, - "node_modules/http-errors": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-parser-js": { - "version": "0.5.8", - "dev": true, - "license": "MIT" - }, - "node_modules/http-proxy": { - "version": "1.18.1", - "dev": true, - "license": "MIT", - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/http-proxy-middleware": { - "version": "2.0.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } - } - }, - "node_modules/human-signals": { - "version": "2.1.0", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/idb-keyval": { - "version": "6.2.1", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/ieee754": { - "version": "1.2.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/ignore": { - "version": "5.2.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/import-local": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "dev": true, - "license": "ISC" - }, - "node_modules/interpret": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "dev": true, - "license": "MIT" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-core-module": { - "version": "2.11.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "dev": true, - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/isobject": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.5", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/core": "^29.5.0", - "@jest/types": "^29.5.0", - "import-local": "^3.0.2", - "jest-cli": "^29.5.0" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-changed-files": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "execa": "^5.0.0", - "p-limit": "^3.1.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-circus": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/expect": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^29.5.0", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", - "p-limit": "^3.1.0", - "pretty-format": "^29.5.0", - "pure-rand": "^6.0.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-cli": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/core": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "prompts": "^2.0.1", - "yargs": "^17.3.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-config": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.5.0", - "@jest/types": "^29.5.0", - "babel-jest": "^29.5.0", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^29.5.0", - "jest-environment-node": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-runner": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^29.5.0", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@types/node": "*", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-diff": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.4.3", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-docblock": { - "version": "29.4.3", - "dev": true, - "license": "MIT", - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-each": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.5.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.4.3", - "jest-util": "^29.5.0", - "pretty-format": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-environment-node": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/fake-timers": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "jest-mock": "^29.5.0", - "jest-util": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-get-type": { - "version": "29.4.3", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.5.0", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "node_modules/jest-leak-detector": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-matcher-utils": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-message-util": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.5.0", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-mock": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "jest-util": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-regex-util": { - "version": "29.4.3", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-resolve": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "resolve": "^1.20.0", - "resolve.exports": "^2.0.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-regex-util": "^29.4.3", - "jest-snapshot": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-runner": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^29.5.0", - "@jest/environment": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^29.4.3", - "jest-environment-node": "^29.5.0", - "jest-haste-map": "^29.5.0", - "jest-leak-detector": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-resolve": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-util": "^29.5.0", - "jest-watcher": "^29.5.0", - "jest-worker": "^29.5.0", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-runner/node_modules/source-map-support": { - "version": "0.5.13", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/jest-runtime": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/fake-timers": "^29.5.0", - "@jest/globals": "^29.5.0", - "@jest/source-map": "^29.4.3", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-snapshot": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/babel__traverse": "^7.0.6", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.5.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.5.0", - "semver": "^7.3.5" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-util": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-validate": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.5.0", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.4.3", - "leven": "^3.1.0", - "pretty-format": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-watcher": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "jest-util": "^29.5.0", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-util": "^29.5.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/js-sdsl": { - "version": "4.4.0", - "dev": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/js-yaml/node_modules/argparse": { - "version": "2.0.1", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/jsesc": { - "version": "2.5.2", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "dev": true, - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/json5": { - "version": "2.2.3", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/launch-editor": { - "version": "2.6.0", - "dev": true, - "license": "MIT", - "dependencies": { - "picocolors": "^1.0.0", - "shell-quote": "^1.7.3" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "dev": true, - "license": "MIT" - }, - "node_modules/loader-runner": { - "version": "4.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.11.5" - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "dev": true, - "license": "MIT" - }, - "node_modules/lower-case": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "dev": true, - "license": "ISC" - }, - "node_modules/makeerror": { - "version": "1.0.12", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tmpl": "1.0.5" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memfs": { - "version": "3.5.1", - "dev": true, - "license": "Unlicense", - "dependencies": { - "fs-monkey": "^1.0.3" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/merge2": { - "version": "1.4.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromatch": { - "version": "4.0.5", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "dev": true, - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "dev": true, - "license": "ISC" - }, - "node_modules/minimatch": { - "version": "3.1.2", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/multicast-dns": { - "version": "7.2.5", - "dev": true, - "license": "MIT", - "dependencies": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - }, - "bin": { - "multicast-dns": "cli.js" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/negotiator": { - "version": "0.6.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "dev": true, - "license": "MIT" - }, - "node_modules/no-case": { - "version": "3.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node_modules/node-forge": { - "version": "1.3.1", - "dev": true, - "license": "(BSD-3-Clause OR GPL-2.0)", - "engines": { - "node": ">= 6.13.0" - } - }, - "node_modules/node-int64": { - "version": "0.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/node-releases": { - "version": "2.0.10", - "dev": true, - "license": "MIT" - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nth-check": { - "version": "2.1.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/object-inspect": { - "version": "1.12.3", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/obuf": { - "version": "1.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/on-finished": { - "version": "2.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/open": { - "version": "8.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.1", - "dev": true, - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-locate/node_modules/p-limit": { - "version": "2.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-retry": { - "version": "4.6.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/retry": "0.12.0", - "retry": "^0.13.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-retry/node_modules/retry": { - "version": "0.13.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/param-case": { - "version": "3.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/pascal-case": { - "version": "3.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "dev": true, - "license": "MIT" - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "dev": true, - "license": "MIT" - }, - "node_modules/path-type": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/picocolors": { - "version": "1.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pirates": { - "version": "4.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "2.8.7", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/pretty-error": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" - } - }, - "node_modules/pretty-format": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.4.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/prompts": { - "version": "2.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "dev": true, - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/punycode": { - "version": "2.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/pure-rand": { - "version": "6.0.1", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ], - "license": "MIT" - }, - "node_modules/qs": { - "version": "6.11.0", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/randombytes": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.1", - "dev": true, - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/react-is": { - "version": "18.2.0", - "dev": true, - "license": "MIT" - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/rechoir": { - "version": "0.8.0", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve": "^1.20.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/relateurl": { - "version": "0.2.7", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/renderkid": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/resolve": { - "version": "1.22.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.11.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-typescript-plugin": { - "version": "2.0.1", - "dev": true, - "license": "ISC", - "dependencies": { - "tslib": "2.5.0" - }, - "engines": { - "node": "^14 || ^16 || >=18" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/resolve.exports": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/schema-utils": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/select-hose": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/selfsigned": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "node-forge": "^1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver": { - "version": "7.3.8", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/send": { - "version": "0.18.0", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/serialize-javascript": { - "version": "6.0.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/serve-index": { - "version": "1.9.1", - "dev": true, - "license": "MIT", - "dependencies": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serve-index/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/serve-index/node_modules/depd": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "dev": true, - "license": "ISC" - }, - "node_modules/serve-index/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "dev": true, - "license": "ISC" - }, - "node_modules/serve-index/node_modules/statuses": { - "version": "1.5.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-static": { - "version": "1.15.0", - "dev": true, - "license": "MIT", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "dev": true, - "license": "ISC" - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/shell-quote": { - "version": "1.8.1", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "dev": true, - "license": "ISC" - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "dev": true, - "license": "MIT" - }, - "node_modules/slash": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/sockjs": { - "version": "0.3.24", - "dev": true, - "license": "MIT", - "dependencies": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/spdy": { - "version": "4.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/spdy-transport": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/stack-utils": { - "version": "2.0.6", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-length": { - "version": "4.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/tapable": { - "version": "2.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/terser": { - "version": "5.17.3", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.17", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.16.8" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/terser-webpack-plugin/node_modules/ajv": { - "version": "6.12.6", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { - "version": "3.5.2", - "dev": true, - "license": "MIT", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/terser-webpack-plugin/node_modules/jest-worker": { - "version": "27.5.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/terser-webpack-plugin/node_modules/supports-color": { - "version": "8.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "dev": true, - "license": "MIT" - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "dev": true, - "license": "MIT" - }, - "node_modules/thunky": { - "version": "1.1.0", - "dev": true, - "license": "MIT" - }, - "node_modules/tmpl": { - "version": "1.0.5", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/ts-jest": { - "version": "29.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^29.0.0", - "json5": "^2.2.3", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "^21.0.1" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": ">=7.0.0-beta.0 <8", - "@jest/types": "^29.0.0", - "babel-jest": "^29.0.0", - "jest": "^29.0.0", - "typescript": ">=4.3 <6" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@jest/types": { - "optional": true - }, - "babel-jest": { - "optional": true - }, - "esbuild": { - "optional": true - } - } - }, - "node_modules/ts-loader": { - "version": "9.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "typescript": "*", - "webpack": "^5.0.0" - } - }, - "node_modules/ts-loader/node_modules/semver": { - "version": "7.5.0", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ts-node": { - "version": "10.9.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/tslib": { - "version": "2.5.0", - "license": "0BSD" - }, - "node_modules/tsutils": { - "version": "3.21.0", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "dev": true, - "license": "0BSD" - }, - "node_modules/type-check": { - "version": "0.4.0", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "dev": true, - "license": "MIT", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typescript": { - "version": "5.0.4", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=12.20" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.10", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "browserslist-lint": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "dev": true, - "license": "MIT" - }, - "node_modules/utila": { - "version": "0.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "dev": true, - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/v8-to-istanbul": { - "version": "9.1.0", - "dev": true, - "license": "ISC", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/walker": { - "version": "1.0.8", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/watchpack": { - "version": "2.4.0", - "dev": true, - "license": "MIT", - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/wbuf": { - "version": "1.7.3", - "dev": true, - "license": "MIT", - "dependencies": { - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/webpack": { - "version": "5.82.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.0", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.14.0", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.2", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.7", - "watchpack": "^2.4.0", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-cli": { - "version": "5.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.1.0", - "@webpack-cli/info": "^2.0.1", - "@webpack-cli/serve": "^2.0.4", - "colorette": "^2.0.14", - "commander": "^10.0.1", - "cross-spawn": "^7.0.3", - "envinfo": "^7.7.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^3.1.1", - "rechoir": "^0.8.0", - "webpack-merge": "^5.7.3" - }, - "bin": { - "webpack-cli": "bin/cli.js" - }, - "engines": { - "node": ">=14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "5.x.x" - }, - "peerDependenciesMeta": { - "@webpack-cli/generators": { - "optional": true - }, - "webpack-bundle-analyzer": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/webpack-dev-middleware": { - "version": "5.3.3", - "dev": true, - "license": "MIT", - "dependencies": { - "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/webpack-dev-server": { - "version": "4.15.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.1", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "launch-editor": "^2.6.0", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.1.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.1", - "ws": "^8.13.0" - }, - "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.37.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - }, - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-dev-server/node_modules/ipaddr.js": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/webpack-merge": { - "version": "5.8.0", - "dev": true, - "license": "MIT", - "dependencies": { - "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack/node_modules/ajv": { - "version": "6.12.6", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack/node_modules/ajv-keywords": { - "version": "3.5.2", - "dev": true, - "license": "MIT", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/webpack/node_modules/schema-utils": { - "version": "3.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wildcard": { - "version": "2.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "dev": true, - "license": "ISC" - }, - "node_modules/write-file-atomic": { - "version": "4.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/ws": { - "version": "8.13.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/yargs": { - "version": "17.7.1", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - }, - "dependencies": { - "@ampproject/remapping": { - "version": "2.2.1", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@babel/code-frame": { - "version": "7.21.4", - "dev": true, - "requires": { - "@babel/highlight": "^7.18.6" - } - }, - "@babel/compat-data": { - "version": "7.21.4", - "dev": true - }, - "@babel/core": { - "version": "7.21.4", - "dev": true, - "requires": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.4", - "@babel/helper-compilation-targets": "^7.21.4", - "@babel/helper-module-transforms": "^7.21.2", - "@babel/helpers": "^7.21.0", - "@babel/parser": "^7.21.4", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.4", - "@babel/types": "^7.21.4", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.21.4", - "dev": true, - "requires": { - "@babel/types": "^7.21.4", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.21.4", - "dev": true, - "requires": { - "@babel/compat-data": "^7.21.4", - "@babel/helper-validator-option": "^7.21.0", - "browserslist": "^4.21.3", - "lru-cache": "^5.1.1", - "semver": "^6.3.0" - }, - "dependencies": { - "lru-cache": { - "version": "5.1.1", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "semver": { - "version": "6.3.0", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "dev": true - } - } - }, - "@babel/helper-environment-visitor": { - "version": "7.18.9", - "dev": true - }, - "@babel/helper-function-name": { - "version": "7.21.0", - "dev": true, - "requires": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.18.6", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-module-imports": { - "version": "7.21.4", - "dev": true, - "requires": { - "@babel/types": "^7.21.4" - } - }, - "@babel/helper-module-transforms": { - "version": "7.21.2", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.2", - "@babel/types": "^7.21.2" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.20.2", - "dev": true - }, - "@babel/helper-simple-access": { - "version": "7.20.2", - "dev": true, - "requires": { - "@babel/types": "^7.20.2" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.18.6", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-string-parser": { - "version": "7.19.4", - "dev": true - }, - "@babel/helper-validator-identifier": { - "version": "7.19.1", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.21.0", - "dev": true - }, - "@babel/helpers": { - "version": "7.21.0", - "dev": true, - "requires": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.0", - "@babel/types": "^7.21.0" - } - }, - "@babel/highlight": { - "version": "7.18.6", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.21.4", - "dev": true - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.21.4", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.20.2" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-typescript": { - "version": "7.21.4", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.20.2" - } - }, - "@babel/template": { - "version": "7.20.7", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" - } - }, - "@babel/traverse": { - "version": "7.21.4", - "dev": true, - "requires": { - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.4", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.4", - "@babel/types": "^7.21.4", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "globals": { - "version": "11.12.0", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.21.4", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", - "to-fast-properties": "^2.0.0" - } - }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "dev": true - }, - "@cspotcode/source-map-support": { - "version": "0.8.1", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "dependencies": { - "@jridgewell/resolve-uri": { - "version": "3.1.1", - "dev": true - }, - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - } - } - }, - "@discoveryjs/json-ext": { - "version": "0.5.7", - "dev": true - }, - "@eslint-community/eslint-utils": { - "version": "4.4.0", - "dev": true, - "requires": { - "eslint-visitor-keys": "^3.3.0" - } - }, - "@eslint-community/regexpp": { - "version": "4.5.0", - "dev": true - }, - "@eslint/eslintrc": { - "version": "2.0.2", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.5.1", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - } - } - }, - "@eslint/js": { - "version": "8.38.0", - "dev": true - }, - "@humanwhocodes/config-array": { - "version": "0.11.8", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - } - }, - "@humanwhocodes/module-importer": { - "version": "1.0.1", - "dev": true - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "dev": true - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "js-yaml": { - "version": "3.14.1", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - } - } - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "dev": true - }, - "@jest/console": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "slash": "^3.0.0" - } - }, - "@jest/core": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/console": "^29.5.0", - "@jest/reporters": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.5.0", - "jest-config": "^29.5.0", - "jest-haste-map": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-resolve-dependencies": "^29.5.0", - "jest-runner": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "jest-watcher": "^29.5.0", - "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "@jest/environment": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/fake-timers": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "jest-mock": "^29.5.0" - } - }, - "@jest/expect": { - "version": "29.5.0", - "dev": true, - "requires": { - "expect": "^29.5.0", - "jest-snapshot": "^29.5.0" - } - }, - "@jest/expect-utils": { - "version": "29.5.0", - "dev": true, - "requires": { - "jest-get-type": "^29.4.3" - } - }, - "@jest/fake-timers": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "@sinonjs/fake-timers": "^10.0.2", - "@types/node": "*", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-util": "^29.5.0" - } - }, - "@jest/globals": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/environment": "^29.5.0", - "@jest/expect": "^29.5.0", - "@jest/types": "^29.5.0", - "jest-mock": "^29.5.0" - } - }, - "@jest/reporters": { - "version": "29.5.0", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@jridgewell/trace-mapping": "^0.3.15", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "v8-to-istanbul": "^9.0.1" - } - }, - "@jest/schemas": { - "version": "29.4.3", - "dev": true, - "requires": { - "@sinclair/typebox": "^0.25.16" - } - }, - "@jest/source-map": { - "version": "29.4.3", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.15", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - } - }, - "@jest/test-result": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/console": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/test-result": "^29.5.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "slash": "^3.0.0" - } - }, - "@jest/transform": { - "version": "29.5.0", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.5.0", - "@jridgewell/trace-mapping": "^0.3.15", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" - }, - "dependencies": { - "convert-source-map": { - "version": "2.0.0", - "dev": true - } - } - }, - "@jest/types": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/schemas": "^29.4.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@jridgewell/gen-mapping": { - "version": "0.3.3", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.0", - "dev": true - }, - "@jridgewell/set-array": { - "version": "1.1.2", - "dev": true - }, - "@jridgewell/source-map": { - "version": "0.3.3", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "dev": true - }, - "@jridgewell/trace-mapping": { - "version": "0.3.18", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - }, - "dependencies": { - "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "dev": true - } - } - }, - "@leichtgewicht/ip-codec": { - "version": "2.0.4", - "dev": true - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@sinclair/typebox": { - "version": "0.25.24", - "dev": true - }, - "@sinonjs/commons": { - "version": "2.0.0", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "10.0.2", - "dev": true, - "requires": { - "@sinonjs/commons": "^2.0.0" - } - }, - "@tsconfig/node10": { - "version": "1.0.9", - "dev": true - }, - "@tsconfig/node12": { - "version": "1.0.11", - "dev": true - }, - "@tsconfig/node14": { - "version": "1.0.3", - "dev": true - }, - "@tsconfig/node16": { - "version": "1.0.3", - "dev": true - }, - "@types/babel__core": { - "version": "7.20.0", - "dev": true, - "requires": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.4", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.4.1", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.18.3", - "dev": true, - "requires": { - "@babel/types": "^7.3.0" - } - }, - "@types/body-parser": { - "version": "1.19.2", - "dev": true, - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "@types/bonjour": { - "version": "3.5.10", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/connect": { - "version": "3.4.35", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/connect-history-api-fallback": { - "version": "1.5.0", - "dev": true, - "requires": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, - "@types/debug": { - "version": "4.1.7", - "dev": true, - "requires": { - "@types/ms": "*" - } - }, - "@types/detect-node": { - "version": "2.0.0", - "dev": true - }, - "@types/eslint": { - "version": "8.37.0", - "dev": true, - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.4", - "dev": true, - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "@types/estree": { - "version": "1.0.1", - "dev": true - }, - "@types/express": { - "version": "4.17.17", - "dev": true, - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "@types/express-serve-static-core": { - "version": "4.17.34", - "dev": true, - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "@types/graceful-fs": { - "version": "4.1.6", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/html-minifier-terser": { - "version": "6.1.0", - "dev": true - }, - "@types/http-proxy": { - "version": "1.17.11", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.4", - "dev": true - }, - "@types/istanbul-lib-report": { - "version": "3.0.0", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/jest": { - "version": "29.5.0", - "dev": true, - "requires": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" - } - }, - "@types/json-schema": { - "version": "7.0.11", - "dev": true - }, - "@types/mime": { - "version": "1.3.2", - "dev": true - }, - "@types/ms": { - "version": "0.7.31", - "dev": true - }, - "@types/node": { - "version": "18.15.11", - "dev": true - }, - "@types/prettier": { - "version": "2.7.2", - "dev": true - }, - "@types/qs": { - "version": "6.9.7", - "dev": true - }, - "@types/range-parser": { - "version": "1.2.4", - "dev": true - }, - "@types/retry": { - "version": "0.12.0", - "dev": true - }, - "@types/semver": { - "version": "7.3.13", - "dev": true - }, - "@types/send": { - "version": "0.17.1", - "dev": true, - "requires": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "@types/serve-index": { - "version": "1.9.1", - "dev": true, - "requires": { - "@types/express": "*" - } - }, - "@types/serve-static": { - "version": "1.15.1", - "dev": true, - "requires": { - "@types/mime": "*", - "@types/node": "*" - }, - "dependencies": { - "@types/mime": { - "version": "3.0.1", - "dev": true - } - } - }, - "@types/sockjs": { - "version": "0.3.33", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/source-map-support": { - "version": "0.5.6", - "dev": true, - "requires": { - "source-map": "^0.6.0" - } - }, - "@types/stack-utils": { - "version": "2.0.1", - "dev": true - }, - "@types/ws": { - "version": "8.5.4", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/yargs": { - "version": "17.0.24", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "21.0.0", - "dev": true - }, - "@typescript-eslint/eslint-plugin": { - "version": "5.57.1", - "dev": true, - "requires": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.57.1", - "@typescript-eslint/type-utils": "5.57.1", - "@typescript-eslint/utils": "5.57.1", - "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/parser": { - "version": "5.57.1", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "5.57.1", - "@typescript-eslint/types": "5.57.1", - "@typescript-eslint/typescript-estree": "5.57.1", - "debug": "^4.3.4" - } - }, - "@typescript-eslint/scope-manager": { - "version": "5.57.1", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.57.1", - "@typescript-eslint/visitor-keys": "5.57.1" - } - }, - "@typescript-eslint/type-utils": { - "version": "5.57.1", - "dev": true, - "requires": { - "@typescript-eslint/typescript-estree": "5.57.1", - "@typescript-eslint/utils": "5.57.1", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/types": { - "version": "5.57.1", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.57.1", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.57.1", - "@typescript-eslint/visitor-keys": "5.57.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/utils": { - "version": "5.57.1", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.57.1", - "@typescript-eslint/types": "5.57.1", - "@typescript-eslint/typescript-estree": "5.57.1", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.57.1", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.57.1", - "eslint-visitor-keys": "^3.3.0" - } - }, - "@webassemblyjs/ast": { - "version": "1.11.6", - "dev": true, - "requires": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.11.6", - "dev": true - }, - "@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "dev": true, - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.11.6", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.11.6", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.11.6", - "dev": true, - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.11.6", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.11.6", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-opt": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6", - "@webassemblyjs/wast-printer": "1.11.6" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.11.6", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.11.6", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.11.6", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.11.6", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "@webpack-cli/configtest": { - "version": "2.1.0", - "dev": true, - "requires": {} - }, - "@webpack-cli/info": { - "version": "2.0.1", - "dev": true, - "requires": {} - }, - "@webpack-cli/serve": { - "version": "2.0.4", - "dev": true, - "requires": {} - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.2", - "dev": true - }, - "accepts": { - "version": "1.3.8", - "dev": true, - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, - "acorn": { - "version": "8.8.2", - "dev": true - }, - "acorn-import-assertions": { - "version": "1.9.0", - "dev": true, - "requires": {} - }, - "acorn-jsx": { - "version": "5.3.2", - "dev": true, - "requires": {} - }, - "acorn-walk": { - "version": "8.2.0", - "dev": true - }, - "ajv": { - "version": "8.12.0", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "dependencies": { - "json-schema-traverse": { - "version": "1.0.0", - "dev": true - } - } - }, - "ajv-formats": { - "version": "2.1.1", - "dev": true, - "requires": { - "ajv": "^8.0.0" - } - }, - "ajv-keywords": { - "version": "5.1.0", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.3" - } - }, - "ansi-escapes": { - "version": "4.3.2", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - }, - "dependencies": { - "type-fest": { - "version": "0.21.3", - "dev": true - } - } - }, - "ansi-html-community": { - "version": "0.0.8", - "dev": true - }, - "ansi-regex": { - "version": "5.0.1", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.3", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "arg": { - "version": "4.1.3", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "array-flatten": { - "version": "2.1.2", - "dev": true - }, - "array-union": { - "version": "2.1.0", - "dev": true - }, - "babel-jest": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/transform": "^29.5.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.5.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - } - }, - "babel-plugin-istanbul": { - "version": "6.1.1", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - } - }, - "babel-plugin-jest-hoist": { - "version": "29.5.0", - "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-preset-current-node-syntax": { - "version": "1.0.1", - "dev": true, - "requires": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - } - }, - "babel-preset-jest": { - "version": "29.5.0", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^29.5.0", - "babel-preset-current-node-syntax": "^1.0.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "dev": true - }, - "base64-js": { - "version": "1.5.1", - "dev": true - }, - "batch": { - "version": "0.6.1", - "dev": true - }, - "bigint-buffer": { - "version": "1.1.5", - "requires": { - "bindings": "^1.3.0" - } - }, - "binary-extensions": { - "version": "2.2.0", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "body-parser": { - "version": "1.20.1", - "dev": true, - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "dev": true - } - } - }, - "bonjour-service": { - "version": "1.1.1", - "dev": true, - "requires": { - "array-flatten": "^2.1.2", - "dns-equal": "^1.0.0", - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" - } - }, - "boolbase": { - "version": "1.0.0", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "browserslist": { - "version": "4.21.5", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" - } - }, - "bs-logger": { - "version": "0.2.6", - "dev": true, - "requires": { - "fast-json-stable-stringify": "2.x" - } - }, - "bser": { - "version": "2.1.1", - "dev": true, - "requires": { - "node-int64": "^0.4.0" - } - }, - "buffer": { - "version": "6.0.3", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "buffer-from": { - "version": "1.1.2", - "dev": true - }, - "bytes": { - "version": "3.1.2", - "dev": true - }, - "call-bind": { - "version": "1.0.2", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "dev": true - }, - "camel-case": { - "version": "4.1.2", - "dev": true, - "requires": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "camelcase": { - "version": "5.3.1", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001476", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "char-regex": { - "version": "1.0.2", - "dev": true - }, - "chokidar": { - "version": "3.5.3", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "chrome-trace-event": { - "version": "1.0.3", - "dev": true - }, - "ci-info": { - "version": "3.8.0", - "dev": true - }, - "cjs-module-lexer": { - "version": "1.2.2", - "dev": true - }, - "clean-css": { - "version": "5.3.2", - "dev": true, - "requires": { - "source-map": "~0.6.0" - } - }, - "cliui": { - "version": "8.0.1", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - } - }, - "clone-deep": { - "version": "4.0.1", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } - }, - "co": { - "version": "4.6.0", - "dev": true - }, - "collect-v8-coverage": { - "version": "1.0.1", - "dev": true - }, - "color-convert": { - "version": "2.0.1", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "dev": true - }, - "colorette": { - "version": "2.0.20", - "dev": true - }, - "comlink": { - "version": "4.4.1", - "dev": true - }, - "commander": { - "version": "10.0.1" - }, - "compressible": { - "version": "2.0.18", - "dev": true, - "requires": { - "mime-db": ">= 1.43.0 < 2" - } - }, - "compression": { - "version": "1.7.4", - "dev": true, - "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "dependencies": { - "bytes": { - "version": "3.0.0", - "dev": true - }, - "debug": { - "version": "2.6.9", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "dev": true - } - } - }, - "concat-map": { - "version": "0.0.1", - "dev": true - }, - "connect-history-api-fallback": { - "version": "2.0.0", - "dev": true - }, - "content-disposition": { - "version": "0.5.4", - "dev": true, - "requires": { - "safe-buffer": "5.2.1" - } - }, - "content-type": { - "version": "1.0.5", - "dev": true - }, - "convert-source-map": { - "version": "1.9.0", - "dev": true - }, - "cookie": { - "version": "0.5.0", - "dev": true - }, - "cookie-signature": { - "version": "1.0.6", - "dev": true - }, - "copy-webpack-plugin": { - "version": "11.0.0", - "dev": true, - "requires": { - "fast-glob": "^3.2.11", - "glob-parent": "^6.0.1", - "globby": "^13.1.1", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0" - }, - "dependencies": { - "globby": { - "version": "13.1.4", - "dev": true, - "requires": { - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.11", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^4.0.0" - } - }, - "slash": { - "version": "4.0.0", - "dev": true - } - } - }, - "core-util-is": { - "version": "1.0.3", - "dev": true - }, - "create-require": { - "version": "1.1.1", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "css-select": { - "version": "4.3.0", - "dev": true, - "requires": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - } - }, - "css-what": { - "version": "6.1.0", - "dev": true - }, - "debug": { - "version": "4.3.4", - "dev": true, - "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "dev": true - } - } - }, - "dedent": { - "version": "0.7.0", - "dev": true - }, - "deep-is": { - "version": "0.1.4", - "dev": true - }, - "deepmerge": { - "version": "4.3.1", - "dev": true - }, - "default-gateway": { - "version": "6.0.3", - "dev": true, - "requires": { - "execa": "^5.0.0" - } - }, - "define-lazy-prop": { - "version": "2.0.0", - "dev": true - }, - "depd": { - "version": "2.0.0", - "dev": true - }, - "destroy": { - "version": "1.2.0", - "dev": true - }, - "detect-newline": { - "version": "3.1.0", - "dev": true - }, - "detect-node": { - "version": "2.1.0", - "dev": true - }, - "diff": { - "version": "4.0.2", - "dev": true - }, - "diff-sequences": { - "version": "29.4.3", - "dev": true - }, - "dir-glob": { - "version": "3.0.1", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "dns-equal": { - "version": "1.0.0", - "dev": true - }, - "dns-packet": { - "version": "5.6.0", - "dev": true, - "requires": { - "@leichtgewicht/ip-codec": "^2.0.1" - } - }, - "doctrine": { - "version": "3.0.0", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "dom-converter": { - "version": "0.2.0", - "dev": true, - "requires": { - "utila": "~0.4" - } - }, - "dom-serializer": { - "version": "1.4.1", - "dev": true, - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - } - }, - "domelementtype": { - "version": "2.3.0", - "dev": true - }, - "domhandler": { - "version": "4.3.1", - "dev": true, - "requires": { - "domelementtype": "^2.2.0" - } - }, - "domutils": { - "version": "2.8.0", - "dev": true, - "requires": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - } - }, - "dot-case": { - "version": "3.0.4", - "dev": true, - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "ee-first": { - "version": "1.1.1", - "dev": true - }, - "electron-to-chromium": { - "version": "1.4.356", - "dev": true - }, - "emittery": { - "version": "0.13.1", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "dev": true - }, - "enhanced-resolve": { - "version": "5.14.0", - "dev": true, - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - }, - "entities": { - "version": "2.2.0", - "dev": true - }, - "envinfo": { - "version": "7.8.1", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-module-lexer": { - "version": "1.2.1", - "dev": true - }, - "escalade": { - "version": "3.1.1", - "dev": true - }, - "escape-html": { - "version": "1.0.3", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "dev": true - }, - "eslint": { - "version": "8.38.0", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.2", - "@eslint/js": "8.38.0", - "@humanwhocodes/config-array": "^0.11.8", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-visitor-keys": "^3.4.0", - "espree": "^9.5.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "escape-string-regexp": { - "version": "4.0.0", - "dev": true - }, - "eslint-scope": { - "version": "7.1.1", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "find-up": { - "version": "5.0.0", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "6.0.0", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "p-locate": { - "version": "5.0.0", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - } - } - }, - "eslint-config-prettier": { - "version": "8.8.0", - "dev": true, - "requires": {} - }, - "eslint-scope": { - "version": "5.1.1", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "dependencies": { - "estraverse": { - "version": "4.3.0", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "3.4.0", - "dev": true - }, - "espree": { - "version": "9.5.1", - "dev": true, - "requires": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.0" - } - }, - "esprima": { - "version": "4.0.1", - "dev": true - }, - "esquery": { - "version": "1.5.0", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - } - }, - "esrecurse": { - "version": "4.3.0", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "dev": true - }, - "etag": { - "version": "1.8.1", - "dev": true - }, - "eventemitter3": { - "version": "4.0.7", - "dev": true - }, - "events": { - "version": "3.3.0", - "dev": true - }, - "execa": { - "version": "5.1.1", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "exit": { - "version": "0.1.2", - "dev": true - }, - "expect": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/expect-utils": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0" - } - }, - "express": { - "version": "4.18.2", - "dev": true, - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "array-flatten": { - "version": "1.1.1", - "dev": true - }, - "debug": { - "version": "2.6.9", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "dev": true - } - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "dev": true - }, - "fast-glob": { - "version": "3.2.12", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "dev": true - }, - "fastest-levenshtein": { - "version": "1.0.16", - "dev": true - }, - "fastq": { - "version": "1.15.0", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "faye-websocket": { - "version": "0.11.4", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "fb-watchman": { - "version": "2.0.2", - "dev": true, - "requires": { - "bser": "2.1.1" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "file-uri-to-path": { - "version": "1.0.0" - }, - "fill-range": { - "version": "7.0.1", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "finalhandler": { - "version": "1.2.0", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "dev": true - } - } - }, - "find-up": { - "version": "4.1.0", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "flat-cache": { - "version": "3.0.4", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.7", - "dev": true - }, - "follow-redirects": { - "version": "1.15.2", - "dev": true - }, - "forwarded": { - "version": "0.2.0", - "dev": true - }, - "fresh": { - "version": "0.5.2", - "dev": true - }, - "fs-monkey": { - "version": "1.0.3", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "dev": true - }, - "gensync": { - "version": "1.0.0-beta.2", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "dev": true - }, - "get-intrinsic": { - "version": "1.2.0", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - } - }, - "get-package-type": { - "version": "0.1.0", - "dev": true - }, - "get-stream": { - "version": "6.0.1", - "dev": true - }, - "glob": { - "version": "7.2.3", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "6.0.2", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "glob-to-regexp": { - "version": "0.4.1", - "dev": true - }, - "globals": { - "version": "13.20.0", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globby": { - "version": "11.1.0", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.11", - "dev": true - }, - "grapheme-splitter": { - "version": "1.0.4", - "dev": true - }, - "handle-thing": { - "version": "2.0.1", - "dev": true - }, - "has": { - "version": "1.0.3", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "4.0.0", - "dev": true - }, - "has-symbols": { - "version": "1.0.3", - "dev": true - }, - "he": { - "version": "1.2.0", - "dev": true - }, - "hpack.js": { - "version": "2.1.6", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.8", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "html-entities": { - "version": "2.3.3", - "dev": true - }, - "html-escaper": { - "version": "2.0.2", - "dev": true - }, - "html-minifier-terser": { - "version": "6.1.0", - "dev": true, - "requires": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - }, - "dependencies": { - "commander": { - "version": "8.3.0", - "dev": true - } - } - }, - "html-webpack-plugin": { - "version": "5.5.1", - "dev": true, - "requires": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" - } - }, - "htmlparser2": { - "version": "6.1.0", - "dev": true, - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - }, - "http-deceiver": { - "version": "1.2.7", - "dev": true - }, - "http-errors": { - "version": "2.0.0", - "dev": true, - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - } - }, - "http-parser-js": { - "version": "0.5.8", - "dev": true - }, - "http-proxy": { - "version": "1.18.1", - "dev": true, - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "http-proxy-middleware": { - "version": "2.0.6", - "dev": true, - "requires": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - } - }, - "human-signals": { - "version": "2.1.0", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "idb-keyval": { - "version": "6.2.1", - "dev": true - }, - "ieee754": { - "version": "1.2.1", - "dev": true - }, - "ignore": { - "version": "5.2.4", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "4.0.0", - "dev": true - } - } - }, - "import-local": { - "version": "3.1.0", - "dev": true, - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "dev": true - }, - "interpret": { - "version": "3.1.1", - "dev": true - }, - "ipaddr.js": { - "version": "1.9.1", - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "dev": true - }, - "is-binary-path": { - "version": "2.1.0", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-core-module": { - "version": "2.11.0", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-docker": { - "version": "2.2.1", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true - }, - "is-generator-fn": { - "version": "2.1.0", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "dev": true - }, - "is-path-inside": { - "version": "3.0.3", - "dev": true - }, - "is-plain-obj": { - "version": "3.0.0", - "dev": true - }, - "is-plain-object": { - "version": "2.0.4", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-stream": { - "version": "2.0.1", - "dev": true - }, - "is-wsl": { - "version": "2.2.0", - "dev": true, - "requires": { - "is-docker": "^2.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "dev": true - }, - "istanbul-lib-coverage": { - "version": "3.2.0", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "5.2.1", - "dev": true, - "requires": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "dev": true - } - } - }, - "istanbul-lib-report": { - "version": "3.0.0", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.1", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - } - }, - "istanbul-reports": { - "version": "3.1.5", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "jest": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/core": "^29.5.0", - "@jest/types": "^29.5.0", - "import-local": "^3.0.2", - "jest-cli": "^29.5.0" - } - }, - "jest-changed-files": { - "version": "29.5.0", - "dev": true, - "requires": { - "execa": "^5.0.0", - "p-limit": "^3.1.0" - } - }, - "jest-circus": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/environment": "^29.5.0", - "@jest/expect": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^29.5.0", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", - "p-limit": "^3.1.0", - "pretty-format": "^29.5.0", - "pure-rand": "^6.0.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-cli": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/core": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "prompts": "^2.0.1", - "yargs": "^17.3.1" - } - }, - "jest-config": { - "version": "29.5.0", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.5.0", - "@jest/types": "^29.5.0", - "babel-jest": "^29.5.0", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^29.5.0", - "jest-environment-node": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-runner": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^29.5.0", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - } - }, - "jest-diff": { - "version": "29.5.0", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^29.4.3", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" - } - }, - "jest-docblock": { - "version": "29.4.3", - "dev": true, - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-each": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.4.3", - "jest-util": "^29.5.0", - "pretty-format": "^29.5.0" - } - }, - "jest-environment-node": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/environment": "^29.5.0", - "@jest/fake-timers": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "jest-mock": "^29.5.0", - "jest-util": "^29.5.0" - } - }, - "jest-get-type": { - "version": "29.4.3", - "dev": true - }, - "jest-haste-map": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - } - }, - "jest-leak-detector": { - "version": "29.5.0", - "dev": true, - "requires": { - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" - } - }, - "jest-matcher-utils": { - "version": "29.5.0", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" - } - }, - "jest-message-util": { - "version": "29.5.0", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.5.0", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-mock": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "jest-util": "^29.5.0" - } - }, - "jest-pnp-resolver": { - "version": "1.2.3", - "dev": true, - "requires": {} - }, - "jest-regex-util": { - "version": "29.4.3", - "dev": true - }, - "jest-resolve": { - "version": "29.5.0", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "resolve": "^1.20.0", - "resolve.exports": "^2.0.0", - "slash": "^3.0.0" - } - }, - "jest-resolve-dependencies": { - "version": "29.5.0", - "dev": true, - "requires": { - "jest-regex-util": "^29.4.3", - "jest-snapshot": "^29.5.0" - } - }, - "jest-runner": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/console": "^29.5.0", - "@jest/environment": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^29.4.3", - "jest-environment-node": "^29.5.0", - "jest-haste-map": "^29.5.0", - "jest-leak-detector": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-resolve": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-util": "^29.5.0", - "jest-watcher": "^29.5.0", - "jest-worker": "^29.5.0", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" - }, - "dependencies": { - "source-map-support": { - "version": "0.5.13", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - } - } - }, - "jest-runtime": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/environment": "^29.5.0", - "@jest/fake-timers": "^29.5.0", - "@jest/globals": "^29.5.0", - "@jest/source-map": "^29.4.3", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - } - }, - "jest-snapshot": { - "version": "29.5.0", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/babel__traverse": "^7.0.6", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.5.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.5.0", - "semver": "^7.3.5" - } - }, - "jest-util": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, - "jest-validate": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.4.3", - "leven": "^3.1.0", - "pretty-format": "^29.5.0" - }, - "dependencies": { - "camelcase": { - "version": "6.3.0", - "dev": true - } - } - }, - "jest-watcher": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "jest-util": "^29.5.0", - "string-length": "^4.0.1" - } - }, - "jest-worker": { - "version": "29.5.0", - "dev": true, - "requires": { - "@types/node": "*", - "jest-util": "^29.5.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "dependencies": { - "supports-color": { - "version": "8.1.1", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "js-sdsl": { - "version": "4.4.0", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "dev": true, - "requires": { - "argparse": "^2.0.1" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "dev": true - } - } - }, - "jsesc": { - "version": "2.5.2", - "dev": true - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "dev": true - }, - "json5": { - "version": "2.2.3", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "dev": true - }, - "kleur": { - "version": "3.0.3", - "dev": true - }, - "launch-editor": { - "version": "2.6.0", - "dev": true, - "requires": { - "picocolors": "^1.0.0", - "shell-quote": "^1.7.3" - } - }, - "leven": { - "version": "3.1.0", - "dev": true - }, - "levn": { - "version": "0.4.1", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lines-and-columns": { - "version": "1.2.4", - "dev": true - }, - "loader-runner": { - "version": "4.3.0", - "dev": true - }, - "locate-path": { - "version": "5.0.0", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "lodash": { - "version": "4.17.21", - "dev": true - }, - "lodash.memoize": { - "version": "4.1.2", - "dev": true - }, - "lodash.merge": { - "version": "4.6.2", - "dev": true - }, - "lower-case": { - "version": "2.0.2", - "dev": true, - "requires": { - "tslib": "^2.0.3" - } - }, - "lru-cache": { - "version": "6.0.0", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "make-dir": { - "version": "3.1.0", - "dev": true, - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.6", - "dev": true - }, - "makeerror": { - "version": "1.0.12", - "dev": true, - "requires": { - "tmpl": "1.0.5" - } - }, - "media-typer": { - "version": "0.3.0", - "dev": true - }, - "memfs": { - "version": "3.5.1", - "dev": true, - "requires": { - "fs-monkey": "^1.0.3" - } - }, - "merge-descriptors": { - "version": "1.0.1", - "dev": true - }, - "merge-stream": { - "version": "2.0.0", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "dev": true - }, - "methods": { - "version": "1.1.2", - "dev": true - }, - "micromatch": { - "version": "4.0.5", - "dev": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - }, - "mime": { - "version": "1.6.0", - "dev": true - }, - "mime-db": { - "version": "1.52.0", - "dev": true - }, - "mime-types": { - "version": "2.1.35", - "dev": true, - "requires": { - "mime-db": "1.52.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "dev": true - }, - "minimalistic-assert": { - "version": "1.0.1", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "ms": { - "version": "2.1.3", - "dev": true - }, - "multicast-dns": { - "version": "7.2.5", - "dev": true, - "requires": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - } - }, - "natural-compare": { - "version": "1.4.0", - "dev": true - }, - "natural-compare-lite": { - "version": "1.4.0", - "dev": true - }, - "negotiator": { - "version": "0.6.3", - "dev": true - }, - "neo-async": { - "version": "2.6.2", - "dev": true - }, - "no-case": { - "version": "3.0.4", - "dev": true, - "requires": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node-forge": { - "version": "1.3.1", - "dev": true - }, - "node-int64": { - "version": "0.4.0", - "dev": true - }, - "node-releases": { - "version": "2.0.10", - "dev": true - }, - "normalize-path": { - "version": "3.0.0", - "dev": true - }, - "npm-run-path": { - "version": "4.0.1", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "nth-check": { - "version": "2.1.1", - "dev": true, - "requires": { - "boolbase": "^1.0.0" - } - }, - "object-inspect": { - "version": "1.12.3", - "dev": true - }, - "obuf": { - "version": "1.1.2", - "dev": true - }, - "on-finished": { - "version": "2.4.1", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.2", - "dev": true - }, - "once": { - "version": "1.4.0", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "open": { - "version": "8.4.2", - "dev": true, - "requires": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - } - }, - "optionator": { - "version": "0.9.1", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "p-limit": { - "version": "3.1.0", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "4.1.0", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - }, - "dependencies": { - "p-limit": { - "version": "2.3.0", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - } - } - }, - "p-retry": { - "version": "4.6.2", - "dev": true, - "requires": { - "@types/retry": "0.12.0", - "retry": "^0.13.1" - }, - "dependencies": { - "retry": { - "version": "0.13.1", - "dev": true - } - } - }, - "p-try": { - "version": "2.2.0", - "dev": true - }, - "param-case": { - "version": "3.0.4", - "dev": true, - "requires": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "parent-module": { - "version": "1.0.1", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-json": { - "version": "5.2.0", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "parseurl": { - "version": "1.3.3", - "dev": true - }, - "pascal-case": { - "version": "3.1.2", - "dev": true, - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "path-exists": { - "version": "4.0.0", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "dev": true - }, - "path-to-regexp": { - "version": "0.1.7", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "dev": true - }, - "picocolors": { - "version": "1.0.0", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "dev": true - }, - "pirates": { - "version": "4.0.5", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - }, - "prelude-ls": { - "version": "1.2.1", - "dev": true - }, - "prettier": { - "version": "2.8.7", - "dev": true - }, - "pretty-error": { - "version": "4.0.0", - "dev": true, - "requires": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" - } - }, - "pretty-format": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/schemas": "^29.4.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "dev": true - } - } - }, - "process-nextick-args": { - "version": "2.0.1", - "dev": true - }, - "prompts": { - "version": "2.4.2", - "dev": true, - "requires": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - } - }, - "proxy-addr": { - "version": "2.0.7", - "dev": true, - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - } - }, - "punycode": { - "version": "2.3.0", - "dev": true - }, - "pure-rand": { - "version": "6.0.1", - "dev": true - }, - "qs": { - "version": "6.11.0", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - }, - "queue-microtask": { - "version": "1.2.3", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "dev": true - }, - "raw-body": { - "version": "2.5.1", - "dev": true, - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "react-is": { - "version": "18.2.0", - "dev": true - }, - "readable-stream": { - "version": "3.6.2", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.6.0", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "rechoir": { - "version": "0.8.0", - "dev": true, - "requires": { - "resolve": "^1.20.0" - } - }, - "relateurl": { - "version": "0.2.7", - "dev": true - }, - "renderkid": { - "version": "3.0.0", - "dev": true, - "requires": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" - } - }, - "require-directory": { - "version": "2.1.1", - "dev": true - }, - "require-from-string": { - "version": "2.0.2", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "dev": true - }, - "resolve": { - "version": "1.22.2", - "dev": true, - "requires": { - "is-core-module": "^2.11.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-cwd": { - "version": "3.0.0", - "dev": true, - "requires": { - "resolve-from": "^5.0.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "dev": true - }, - "resolve-typescript-plugin": { - "version": "2.0.1", - "dev": true, - "requires": { - "tslib": "2.5.0" - } - }, - "resolve.exports": { - "version": "2.0.2", - "dev": true - }, - "reusify": { - "version": "1.0.4", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "run-parallel": { - "version": "1.2.0", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "safe-buffer": { - "version": "5.2.1", - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "dev": true - }, - "schema-utils": { - "version": "4.0.1", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - } - }, - "select-hose": { - "version": "2.0.0", - "dev": true - }, - "selfsigned": { - "version": "2.1.1", - "dev": true, - "requires": { - "node-forge": "^1" - } - }, - "semver": { - "version": "7.3.8", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "send": { - "version": "0.18.0", - "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "dev": true - } - } - } - } - }, - "serialize-javascript": { - "version": "6.0.1", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "serve-index": { - "version": "1.9.1", - "dev": true, - "requires": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "depd": { - "version": "1.1.2", - "dev": true - }, - "http-errors": { - "version": "1.6.3", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "inherits": { - "version": "2.0.3", - "dev": true - }, - "ms": { - "version": "2.0.0", - "dev": true - }, - "setprototypeof": { - "version": "1.1.0", - "dev": true - }, - "statuses": { - "version": "1.5.0", - "dev": true - } - } - }, - "serve-static": { - "version": "1.15.0", - "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - } - }, - "setprototypeof": { - "version": "1.2.0", - "dev": true - }, - "shallow-clone": { - "version": "3.0.1", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - } - }, - "shebang-command": { - "version": "2.0.0", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "dev": true - }, - "shell-quote": { - "version": "1.8.1", - "dev": true - }, - "side-channel": { - "version": "1.0.4", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "signal-exit": { - "version": "3.0.7", - "dev": true - }, - "sisteransi": { - "version": "1.0.5", - "dev": true - }, - "slash": { - "version": "3.0.0", - "dev": true - }, - "sockjs": { - "version": "0.3.24", - "dev": true, - "requires": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - } - }, - "source-map": { - "version": "0.6.1", - "dev": true - }, - "source-map-support": { - "version": "0.5.21", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "spdy": { - "version": "4.0.2", - "dev": true, - "requires": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - } - }, - "spdy-transport": { - "version": "3.0.0", - "dev": true, - "requires": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - } - }, - "sprintf-js": { - "version": "1.0.3", - "dev": true - }, - "stack-utils": { - "version": "2.0.6", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "dev": true - } - } - }, - "statuses": { - "version": "2.0.1", - "dev": true - }, - "string_decoder": { - "version": "1.3.0", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "string-length": { - "version": "4.0.2", - "dev": true, - "requires": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - } - }, - "string-width": { - "version": "4.2.3", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-bom": { - "version": "4.0.0", - "dev": true - }, - "strip-final-newline": { - "version": "2.0.0", - "dev": true - }, - "strip-json-comments": { - "version": "3.1.1", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "dev": true - }, - "tapable": { - "version": "2.2.1", - "dev": true - }, - "terser": { - "version": "5.17.3", - "dev": true, - "requires": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "5.3.8", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.17", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.16.8" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "dev": true, - "requires": {} - }, - "jest-worker": { - "version": "27.5.1", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - } - }, - "schema-utils": { - "version": "3.1.2", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, - "supports-color": { - "version": "8.1.1", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "test-exclude": { - "version": "6.0.0", - "dev": true, - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - } - }, - "text-table": { - "version": "0.2.0", - "dev": true - }, - "thunky": { - "version": "1.1.0", - "dev": true - }, - "tmpl": { - "version": "1.0.5", - "dev": true - }, - "to-fast-properties": { - "version": "2.0.0", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "toidentifier": { - "version": "1.0.1", - "dev": true - }, - "ts-jest": { - "version": "29.1.0", - "dev": true, - "requires": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^29.0.0", - "json5": "^2.2.3", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "^21.0.1" - } - }, - "ts-loader": { - "version": "9.4.2", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4" - }, - "dependencies": { - "semver": { - "version": "7.5.0", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, - "ts-node": { - "version": "10.9.1", - "dev": true, - "requires": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - } - }, - "tslib": { - "version": "2.5.0" - }, - "tsutils": { - "version": "3.21.0", - "dev": true, - "requires": { - "tslib": "^1.8.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "dev": true - } - } - }, - "type-check": { - "version": "0.4.0", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-detect": { - "version": "4.0.8", - "dev": true - }, - "type-fest": { - "version": "0.20.2", - "dev": true - }, - "type-is": { - "version": "1.6.18", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typescript": { - "version": "5.0.4", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "dev": true - }, - "update-browserslist-db": { - "version": "1.0.10", - "dev": true, - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - } - }, - "uri-js": { - "version": "4.4.1", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "dev": true - }, - "utila": { - "version": "0.4.0", - "dev": true - }, - "utils-merge": { - "version": "1.0.1", - "dev": true - }, - "uuid": { - "version": "8.3.2", - "dev": true - }, - "v8-compile-cache-lib": { - "version": "3.0.1", - "dev": true - }, - "v8-to-istanbul": { - "version": "9.1.0", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0" - } - }, - "vary": { - "version": "1.1.2", - "dev": true - }, - "walker": { - "version": "1.0.8", - "dev": true, - "requires": { - "makeerror": "1.0.12" - } - }, - "watchpack": { - "version": "2.4.0", - "dev": true, - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - } - }, - "wbuf": { - "version": "1.7.3", - "dev": true, - "requires": { - "minimalistic-assert": "^1.0.0" - } - }, - "webpack": { - "version": "5.82.1", - "dev": true, - "requires": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.0", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.14.0", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.2", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.7", - "watchpack": "^2.4.0", - "webpack-sources": "^3.2.3" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "dev": true, - "requires": {} - }, - "schema-utils": { - "version": "3.1.2", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } - } - }, - "webpack-cli": { - "version": "5.1.1", - "dev": true, - "requires": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.1.0", - "@webpack-cli/info": "^2.0.1", - "@webpack-cli/serve": "^2.0.4", - "colorette": "^2.0.14", - "commander": "^10.0.1", - "cross-spawn": "^7.0.3", - "envinfo": "^7.7.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^3.1.1", - "rechoir": "^0.8.0", - "webpack-merge": "^5.7.3" - } - }, - "webpack-dev-middleware": { - "version": "5.3.3", - "dev": true, - "requires": { - "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - } - }, - "webpack-dev-server": { - "version": "4.15.0", - "dev": true, - "requires": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.1", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "launch-editor": "^2.6.0", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.1.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.1", - "ws": "^8.13.0" - }, - "dependencies": { - "ipaddr.js": { - "version": "2.0.1", - "dev": true - } - } - }, - "webpack-merge": { - "version": "5.8.0", - "dev": true, - "requires": { - "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" - } - }, - "webpack-sources": { - "version": "3.2.3", - "dev": true - }, - "websocket-driver": { - "version": "0.7.4", - "dev": true, - "requires": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.4", - "dev": true - }, - "which": { - "version": "2.0.2", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wildcard": { - "version": "2.0.1", - "dev": true - }, - "word-wrap": { - "version": "1.2.3", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "dev": true - }, - "write-file-atomic": { - "version": "4.0.2", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - } - }, - "ws": { - "version": "8.13.0", - "dev": true, - "requires": {} - }, - "y18n": { - "version": "5.0.8", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "dev": true - }, - "yargs": { - "version": "17.7.1", - "dev": true, - "requires": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - } - }, - "yargs-parser": { - "version": "21.1.1", - "dev": true - }, - "yn": { - "version": "3.1.1", - "dev": true - }, - "yocto-queue": { - "version": "0.1.0", - "dev": true - } - } -} diff --git a/ts/package.json b/ts/package.json index e8bb1dc842..6bcbcd5dff 100644 --- a/ts/package.json +++ b/ts/package.json @@ -1,21 +1,23 @@ { - "name": "@aztec/barretenberg.js", - "version": "0.0.0", + "name": "@aztec/bb.js", + "version": "0.0.1-alpha.1", "type": "module", "typedoc": { "entryPoint": "./src/index.ts", - "displayName": "Barretenberg.js", + "displayName": "bb.js", "tsconfig": "./tsconfig.json" }, - "bin": { - "bb.js": "./dest/main.js", - "bb.js-dev": "./src/main-dev.ts" - }, + "bin": "./dest/main.js", + "files": [ + "src/", + "dest/", + "README.md" + ], "scripts": { "clean": "rm -rf ./dest .tsbuildinfo", "build": "yarn clean && yarn build:wasm && tsc -b && webpack && chmod +x ./dest/main.js", "build:dev": "tsc -b --watch", - "build:wasm": "cd ../cpp && cmake --preset wasm-threads && cmake --build --preset wasm-threads", + "build:wasm": "cd ../cpp && cmake --preset wasm-threads && cmake --build --preset wasm-threads && cmake --preset wasm && cmake --build --preset wasm", "serve": "webpack serve", "formatting": "prettier --check ./src && eslint --max-warnings 0 ./src", "formatting:fix": "prettier -w ./src", @@ -40,8 +42,10 @@ "rootDir": "./src" }, "dependencies": { - "bigint-buffer": "^1.1.5", + "comlink": "^4.4.1", "commander": "^10.0.1", + "debug": "^4.3.4", + "ts-node": "^10.9.1", "tslib": "^2.4.0" }, "devDependencies": { @@ -54,9 +58,7 @@ "@typescript-eslint/eslint-plugin": "^5.54.1", "@typescript-eslint/parser": "^5.54.1", "buffer": "^6.0.3", - "comlink": "^4.4.1", "copy-webpack-plugin": "^11.0.0", - "debug": "^4.3.4", "eslint": "^8.35.0", "eslint-config-prettier": "^8.8.0", "html-webpack-plugin": "^5.5.1", @@ -66,7 +68,6 @@ "resolve-typescript-plugin": "^2.0.1", "ts-jest": "^29.1.0", "ts-loader": "^9.4.2", - "ts-node": "^10.9.1", "typescript": "^5.0.4", "webpack": "^5.82.1", "webpack-cli": "^5.1.1", diff --git a/ts/src/barretenberg_api/index.ts b/ts/src/barretenberg_api/index.ts index c903f06213..3e27fe74ae 100644 --- a/ts/src/barretenberg_api/index.ts +++ b/ts/src/barretenberg_api/index.ts @@ -166,6 +166,11 @@ export class BarretenbergApi { return; } + async acirGetCircuitSizes(constraintSystemBuf: Uint8Array): Promise<[number, number, number]> { + const result = await this.binder.callWasmExport('acir_get_circuit_sizes', [constraintSystemBuf], [NumberDeserializer(), NumberDeserializer(), NumberDeserializer()]); + return result as any; + } + async acirNewAcirComposer(): Promise { const result = await this.binder.callWasmExport('acir_new_acir_composer', [], [Ptr]); return result[0]; @@ -186,11 +191,16 @@ export class BarretenbergApi { return; } - async acirCreateProof(acirComposerPtr: Ptr, constraintSystemBuf: Uint8Array, witnessBuf: Uint8Array): Promise { - const result = await this.binder.callWasmExport('acir_create_proof', [acirComposerPtr, constraintSystemBuf, witnessBuf], [BufferDeserializer()]); + async acirCreateProof(acirComposerPtr: Ptr, constraintSystemBuf: Uint8Array, witnessBuf: Uint8Array, isRecursive: boolean): Promise { + const result = await this.binder.callWasmExport('acir_create_proof', [acirComposerPtr, constraintSystemBuf, witnessBuf, isRecursive], [BufferDeserializer()]); return result[0]; } + async acirLoadVerificationKey(acirComposerPtr: Ptr, vkBuf: Uint8Array): Promise { + const result = await this.binder.callWasmExport('acir_load_verification_key', [acirComposerPtr, vkBuf], []); + return; + } + async acirInitVerificationKey(acirComposerPtr: Ptr): Promise { const result = await this.binder.callWasmExport('acir_init_verification_key', [acirComposerPtr], []); return; @@ -201,8 +211,8 @@ export class BarretenbergApi { return result[0]; } - async acirVerifyProof(acirComposerPtr: Ptr, proofBuf: Uint8Array): Promise { - const result = await this.binder.callWasmExport('acir_verify_proof', [acirComposerPtr, proofBuf], [BoolDeserializer()]); + async acirVerifyProof(acirComposerPtr: Ptr, proofBuf: Uint8Array, isRecursive: boolean): Promise { + const result = await this.binder.callWasmExport('acir_verify_proof', [acirComposerPtr, proofBuf, isRecursive], [BoolDeserializer()]); return result[0]; } @@ -211,14 +221,14 @@ export class BarretenbergApi { return result[0]; } - async acirGetExactCircuitSize(acirComposerPtr: Ptr): Promise { - const result = await this.binder.callWasmExport('acir_get_exact_circuit_size', [acirComposerPtr], [NumberDeserializer()]); + async acirSerializeProofIntoFields(acirComposerPtr: Ptr, proofBuf: Uint8Array, numInnerPublicInputs: number): Promise { + const result = await this.binder.callWasmExport('acir_serialize_proof_into_fields', [acirComposerPtr, proofBuf, numInnerPublicInputs], [VectorDeserializer(Fr)]); return result[0]; } - async acirGetTotalCircuitSize(acirComposerPtr: Ptr): Promise { - const result = await this.binder.callWasmExport('acir_get_total_circuit_size', [acirComposerPtr], [NumberDeserializer()]); - return result[0]; + async acirSerializeVerificationKeyIntoFields(acirComposerPtr: Ptr): Promise<[Fr[], Fr]> { + const result = await this.binder.callWasmExport('acir_serialize_verification_key_into_fields', [acirComposerPtr], [VectorDeserializer(Fr), Fr]); + return result as any; } } @@ -384,6 +394,11 @@ export class BarretenbergApiSync { return; } + acirGetCircuitSizes(constraintSystemBuf: Uint8Array): [number, number, number] { + const result = this.binder.callWasmExport('acir_get_circuit_sizes', [constraintSystemBuf], [NumberDeserializer(), NumberDeserializer(), NumberDeserializer()]); + return result as any; + } + acirNewAcirComposer(): Ptr { const result = this.binder.callWasmExport('acir_new_acir_composer', [], [Ptr]); return result[0]; @@ -404,11 +419,16 @@ export class BarretenbergApiSync { return; } - acirCreateProof(acirComposerPtr: Ptr, constraintSystemBuf: Uint8Array, witnessBuf: Uint8Array): Uint8Array { - const result = this.binder.callWasmExport('acir_create_proof', [acirComposerPtr, constraintSystemBuf, witnessBuf], [BufferDeserializer()]); + acirCreateProof(acirComposerPtr: Ptr, constraintSystemBuf: Uint8Array, witnessBuf: Uint8Array, isRecursive: boolean): Uint8Array { + const result = this.binder.callWasmExport('acir_create_proof', [acirComposerPtr, constraintSystemBuf, witnessBuf, isRecursive], [BufferDeserializer()]); return result[0]; } + acirLoadVerificationKey(acirComposerPtr: Ptr, vkBuf: Uint8Array): void { + const result = this.binder.callWasmExport('acir_load_verification_key', [acirComposerPtr, vkBuf], []); + return; + } + acirInitVerificationKey(acirComposerPtr: Ptr): void { const result = this.binder.callWasmExport('acir_init_verification_key', [acirComposerPtr], []); return; @@ -419,8 +439,8 @@ export class BarretenbergApiSync { return result[0]; } - acirVerifyProof(acirComposerPtr: Ptr, proofBuf: Uint8Array): boolean { - const result = this.binder.callWasmExport('acir_verify_proof', [acirComposerPtr, proofBuf], [BoolDeserializer()]); + acirVerifyProof(acirComposerPtr: Ptr, proofBuf: Uint8Array, isRecursive: boolean): boolean { + const result = this.binder.callWasmExport('acir_verify_proof', [acirComposerPtr, proofBuf, isRecursive], [BoolDeserializer()]); return result[0]; } @@ -429,13 +449,13 @@ export class BarretenbergApiSync { return result[0]; } - acirGetExactCircuitSize(acirComposerPtr: Ptr): number { - const result = this.binder.callWasmExport('acir_get_exact_circuit_size', [acirComposerPtr], [NumberDeserializer()]); + acirSerializeProofIntoFields(acirComposerPtr: Ptr, proofBuf: Uint8Array, numInnerPublicInputs: number): Fr[] { + const result = this.binder.callWasmExport('acir_serialize_proof_into_fields', [acirComposerPtr, proofBuf, numInnerPublicInputs], [VectorDeserializer(Fr)]); return result[0]; } - acirGetTotalCircuitSize(acirComposerPtr: Ptr): number { - const result = this.binder.callWasmExport('acir_get_total_circuit_size', [acirComposerPtr], [NumberDeserializer()]); - return result[0]; + acirSerializeVerificationKeyIntoFields(acirComposerPtr: Ptr): [Fr[], Fr] { + const result = this.binder.callWasmExport('acir_serialize_verification_key_into_fields', [acirComposerPtr], [VectorDeserializer(Fr), Fr]); + return result as any; } } diff --git a/ts/src/barretenberg_wasm/barretenberg_wasm.ts b/ts/src/barretenberg_wasm/barretenberg_wasm.ts index a597f89812..d94b32f989 100644 --- a/ts/src/barretenberg_wasm/barretenberg_wasm.ts +++ b/ts/src/barretenberg_wasm/barretenberg_wasm.ts @@ -8,7 +8,7 @@ import { randomBytes } from '../random/index.js'; import { fetchCode, getNumCpu, createWorker, getRemoteBarretenbergWasm, threadLogger, killSelf } from './node/index.js'; // import { fetchCode, getNumCpu, createWorker, randomBytes } from './browser/index.js'; -const debug = createDebug('wasm'); +const debug = createDebug('bb.js:wasm'); EventEmitter.defaultMaxListeners = 30; @@ -65,6 +65,8 @@ export class BarretenbergWasm { this.memory = new WebAssembly.Memory({ initial, maximum, shared: threads > 1 }); + // Annoyingly the wasm declares if it's memory is shared or not. So now we need two wasms if we want to be + // able to fallback on "non shared memory" situations. const code = await fetchCode(threads > 1 ? 'barretenberg-threads.wasm' : 'barretenberg.wasm'); const { instance, module } = await WebAssembly.instantiate(code, this.getImportObj(this.memory)); diff --git a/ts/src/index.ts b/ts/src/index.ts index b6df75a32a..686cf4af06 100644 --- a/ts/src/index.ts +++ b/ts/src/index.ts @@ -1,3 +1,5 @@ export * from './crs/index.js'; export * from './barretenberg_wasm/index.js'; export * from './barretenberg_api/index.js'; +export * from './factory/index.js'; +export { RawBuffer } from './types/index.js'; diff --git a/ts/src/main-dev.ts b/ts/src/main-dev.ts deleted file mode 100755 index 8c090cb92d..0000000000 --- a/ts/src/main-dev.ts +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env -S node --loader ts-node/esm --no-warnings -import './main.js'; diff --git a/ts/src/main.ts b/ts/src/main.ts index c5a04d06cd..dc8c5c50cd 100755 --- a/ts/src/main.ts +++ b/ts/src/main.ts @@ -1,19 +1,16 @@ #!/usr/bin/env -S node --no-warnings -import { Crs } from './crs/index.js'; +import { Crs, BarretenbergApiAsync, newBarretenbergApiAsync, RawBuffer } from './index.js'; import createDebug from 'debug'; -import { newBarretenbergApiAsync } from './factory/index.js'; import { readFileSync, writeFileSync } from 'fs'; import { gunzipSync } from 'zlib'; -import { RawBuffer } from './types/index.js'; import { numToUInt32BE } from './serialize/serialize.js'; import { Command } from 'commander'; createDebug.log = console.error.bind(console); const debug = createDebug('bb.js'); -// createDebug.enable('*'); // Maximum we support. -const CIRCUIT_SIZE = 2 ** 19; +const MAX_CIRCUIT_SIZE = 2 ** 19; function getBytecode(jsonPath: string) { const json = readFileSync(jsonPath, 'utf-8'); @@ -28,42 +25,69 @@ function getWitness(witnessPath: string) { return Buffer.concat([numToUInt32BE(data.length / 32), data]); } -async function init() { - // Plus 1 needed! - const crs = await Crs.new(CIRCUIT_SIZE + 1); +async function getCircuitSize(jsonPath: string, api: BarretenbergApiAsync) { + const bytecode = getBytecode(jsonPath); + const [exact, total, subgroup] = await api.acirGetCircuitSizes(new RawBuffer(bytecode)); + return { exact, total, subgroup }; +} +async function init(jsonPath: string) { const api = await newBarretenbergApiAsync(); - // Import to init slab allocator as first thing, to ensure maximum memory efficiency. - await api.commonInitSlabAllocator(CIRCUIT_SIZE); + // First compute circuit size. + const circuitSizes = await getCircuitSize(jsonPath, api); + debug(`circuit size: ${circuitSizes.total}`); + + if (circuitSizes.subgroup > MAX_CIRCUIT_SIZE) { + throw new Error(`Circuit size of ${circuitSizes.subgroup} exceeds max supported of ${MAX_CIRCUIT_SIZE}`); + } + + // Plus 1 needed! (Move +1 into Crs?) + const crs = await Crs.new(circuitSizes.subgroup + 1); + + // Important to init slab allocator as first thing, to ensure maximum memory efficiency. + await api.commonInitSlabAllocator(circuitSizes.subgroup); // Load CRS into wasm global CRS state. // TODO: Make RawBuffer be default behaviour, and have a specific Vector type for when wanting length prefixed. await api.srsInitSrs(new RawBuffer(crs.getG1Data()), crs.numPoints, new RawBuffer(crs.getG2Data())); const acirComposer = await api.acirNewAcirComposer(); + return { api, acirComposer, circuitSize: circuitSizes.subgroup }; +} + +async function initLite() { + const api = await newBarretenbergApiAsync(1); + // Plus 1 needed! (Move +1 into Crs?) + const crs = await Crs.new(1); + + // Load CRS into wasm global CRS state. + await api.srsInitSrs(new RawBuffer(crs.getG1Data()), crs.numPoints, new RawBuffer(crs.getG2Data())); + + const acirComposer = await api.acirNewAcirComposer(); return { api, acirComposer }; } -export async function proveAndVerify(jsonPath: string, witnessPath: string) { - const { api, acirComposer } = await init(); +export async function proveAndVerify(jsonPath: string, witnessPath: string, isRecursive: boolean) { + const { api, acirComposer, circuitSize } = await init(jsonPath); try { debug('initing proving key...'); const bytecode = getBytecode(jsonPath); - await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), CIRCUIT_SIZE); + await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), circuitSize); - const exactCircuitSize = await api.acirGetExactCircuitSize(acirComposer); - debug(`circuit size: ${exactCircuitSize}`); + // const circuitSize = await api.acirGetExactCircuitSize(acirComposer); + // debug(`circuit size: ${circuitSize}`); debug('initing verification key...'); await api.acirInitVerificationKey(acirComposer); debug(`creating proof...`); const witness = getWitness(witnessPath); - const proof = await api.acirCreateProof(acirComposer, new RawBuffer(bytecode), new RawBuffer(witness)); + const proof = await api.acirCreateProof(acirComposer, new RawBuffer(bytecode), new RawBuffer(witness), isRecursive); + debug(`done.`); - const verified = await api.acirVerifyProof(acirComposer, proof); + const verified = await api.acirVerifyProof(acirComposer, proof, isRecursive); console.log(`verified: ${verified}`); return verified; } finally { @@ -71,19 +95,20 @@ export async function proveAndVerify(jsonPath: string, witnessPath: string) { } } -export async function prove(jsonPath: string, witnessPath: string, outputPath: string) { - const { api, acirComposer } = await init(); +export async function prove(jsonPath: string, witnessPath: string, isRecursive: boolean, outputPath: string) { + const { api, acirComposer, circuitSize } = await init(jsonPath); try { debug('initing proving key...'); const bytecode = getBytecode(jsonPath); - await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), CIRCUIT_SIZE); + await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), circuitSize); - const exactCircuitSize = await api.acirGetExactCircuitSize(acirComposer); - debug(`circuit size: ${exactCircuitSize}`); + // const circuitSize = await api.acirGetExactCircuitSize(acirComposer); + // debug(`circuit size: ${circuitSize}`); debug(`creating proof...`); const witness = getWitness(witnessPath); - const proof = await api.acirCreateProof(acirComposer, new RawBuffer(bytecode), new RawBuffer(witness)); + const proof = await api.acirCreateProof(acirComposer, new RawBuffer(bytecode), new RawBuffer(witness), isRecursive); + debug(`done.`); writeFileSync(outputPath, proof); console.log(`proof written to: ${outputPath}`); @@ -93,42 +118,51 @@ export async function prove(jsonPath: string, witnessPath: string, outputPath: s } export async function gateCount(jsonPath: string) { - const { api, acirComposer } = await init(); + const api = await newBarretenbergApiAsync(1); try { - const bytecode = getBytecode(jsonPath); - await api.acirCreateCircuit(acirComposer, new RawBuffer(bytecode), CIRCUIT_SIZE); - - const gates = await api.acirGetTotalCircuitSize(acirComposer); - console.log(`${gates}`); + const circuitSizes = await getCircuitSize(jsonPath, api); + console.log(`${circuitSizes.exact}`); } finally { await api.destroy(); } } -export async function verify(jsonPath: string, proofPath: string) { - const { api, acirComposer } = await init(); - try { - debug('initing proving key...'); - const bytecode = getBytecode(jsonPath); - await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), CIRCUIT_SIZE); - - debug('initing verification key...'); - await api.acirInitVerificationKey(acirComposer); - - const verified = await api.acirVerifyProof(acirComposer, readFileSync(proofPath)); - console.log(`verified: ${verified}`); - return verified; - } finally { - await api.destroy(); +export async function verify(jsonPath: string, proofPath: string, isRecursive: boolean, vkPath?: string) { + if (vkPath) { + const { api, acirComposer } = await initLite(); + try { + await api.acirLoadVerificationKey(acirComposer, new RawBuffer(readFileSync(vkPath))); + const verified = await api.acirVerifyProof(acirComposer, readFileSync(proofPath), isRecursive); + console.log(`verified: ${verified}`); + return verified; + } finally { + await api.destroy(); + } + } else { + const { api, acirComposer, circuitSize } = await init(jsonPath); + try { + debug('initing proving key...'); + const bytecode = getBytecode(jsonPath); + await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), circuitSize); + + debug('initing verification key...'); + await api.acirInitVerificationKey(acirComposer); + + const verified = await api.acirVerifyProof(acirComposer, readFileSync(proofPath), isRecursive); + console.log(`verified: ${verified}`); + return verified; + } finally { + await api.destroy(); + } } } export async function contract(jsonPath: string, outputPath: string) { - const { api, acirComposer } = await init(); + const { api, acirComposer, circuitSize } = await init(jsonPath); try { debug('initing proving key...'); const bytecode = getBytecode(jsonPath); - await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), CIRCUIT_SIZE); + await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), circuitSize); debug('initing verification key...'); await api.acirInitVerificationKey(acirComposer); @@ -146,11 +180,11 @@ export async function contract(jsonPath: string, outputPath: string) { } export async function writeVk(jsonPath: string, outputPath: string) { - const { api, acirComposer } = await init(); + const { api, acirComposer, circuitSize } = await init(jsonPath); try { debug('initing proving key...'); const bytecode = getBytecode(jsonPath); - await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), CIRCUIT_SIZE); + await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), circuitSize); debug('initing verification key...'); const vk = await api.acirGetVerificationKey(acirComposer); @@ -164,6 +198,40 @@ export async function writeVk(jsonPath: string, outputPath: string) { await api.destroy(); } } + +export async function proofAsFields(proofPath: string, numInnerPublicInputs: number, outputPath: string) { + const { api, acirComposer } = await initLite(); + + try { + debug('serializing proof byte array into field elements'); + const proofAsFields = await api.acirSerializeProofIntoFields( + acirComposer, + readFileSync(proofPath), + numInnerPublicInputs, + ); + + writeFileSync(outputPath, JSON.stringify(proofAsFields.map(f => f.toString()))); + debug('done.'); + } finally { + await api.destroy(); + } +} + +export async function vkAsFields(vkPath: string, vkeyOutputPath: string) { + const { api, acirComposer } = await initLite(); + + try { + debug('serializing vk byte array into field elements'); + await api.acirLoadVerificationKey(acirComposer, new RawBuffer(readFileSync(vkPath))); + const [vkAsFields, vkHash] = await api.acirSerializeVerificationKeyIntoFields(acirComposer); + const output = [vkHash, ...vkAsFields].map(f => f.toString()); + writeFileSync(vkeyOutputPath, JSON.stringify(output)); + debug('done.'); + } finally { + await api.destroy(); + } +} + // nargo use bb.js: backend -> bb.js // backend prove --data-dir data --witness /foo/bar/witness.tr --json /foo/bar/main.json // backend verify ... @@ -176,13 +244,23 @@ export async function writeVk(jsonPath: string, outputPath: string) { const program = new Command(); +program.option('-v, --verbose', 'enable verbose logging', false); + +function handleGlobalOptions() { + if (program.opts().verbose) { + createDebug.enable('bb.js*'); + } +} + program .command('prove_and_verify') .description('Generate a proof and verify it. Process exits with success or failure code.') .option('-j, --json-path ', 'Specify the JSON path', './target/main.json') .option('-w, --witness-path ', 'Specify the witness path', './target/witness.tr') - .action(async ({ jsonPath, witnessPath }) => { - const result = await proveAndVerify(jsonPath, witnessPath); + .option('-r, --recursive', 'prove and verify using recursive prover and verifier', false) + .action(async ({ jsonPath, witnessPath, recursive }) => { + handleGlobalOptions(); + const result = await proveAndVerify(jsonPath, witnessPath, recursive); process.exit(result ? 0 : 1); }); @@ -191,10 +269,12 @@ program .description('Generate a proof and write it to a file.') .option('-j, --json-path ', 'Specify the JSON path', './target/main.json') .option('-w, --witness-path ', 'Specify the witness path', './target/witness.tr') + .option('-r, --recursive', 'prove using recursive prover', false) .option('-o, --output-dir ', 'Specify the proof output dir', './proofs') .requiredOption('-n, --name ', 'Output file name.') - .action(async ({ jsonPath, witnessPath, outputDir, name }) => { - await prove(jsonPath, witnessPath, outputDir + '/' + name); + .action(async ({ jsonPath, witnessPath, recursive, outputDir, name }) => { + handleGlobalOptions(); + await prove(jsonPath, witnessPath, recursive, outputDir + '/' + name); }); program @@ -210,8 +290,10 @@ program .description('Verify a proof. Process exists with success or failure code.') .option('-j, --json-path ', 'Specify the JSON path', './target/main.json') .requiredOption('-p, --proof-path ', 'Specify the path to the proof') - .action(async ({ jsonPath, proofPath }) => { - await verify(jsonPath, proofPath); + .option('-r, --recursive', 'prove using recursive prover', false) + .option('-k, --vk ', 'path to a verification key. avoids recomputation.') + .action(async ({ jsonPath, proofPath, recursive, vk }) => { + await verify(jsonPath, proofPath, recursive, vk); }); program @@ -232,4 +314,23 @@ program await writeVk(jsonPath, outputPath); }); +program + .command('proof_as_fields') + .description('Return the proof as fields elements') + .requiredOption('-p, --proof-path ', 'Specify the proof path') + .requiredOption('-n, --num-public-inputs ', 'Specify the number of public inputs') + .requiredOption('-o, --output-path ', 'Specify the JSON path to write the proof fields') + .action(async ({ proofPath, numPublicInputs, outputPath }) => { + await proofAsFields(proofPath, numPublicInputs, outputPath); + }); + +program + .command('vk_as_fields') + .description('Return the verifiation key represented as fields elements. Also return the verification key hash.') + .requiredOption('-i, --input-path ', 'Specifies the vk path (output from write_vk)') + .requiredOption('-o, --output-path ', 'Specify the JSON path to write the verification key fields and key hash') + .action(async ({ inputPath, outputPath }) => { + await vkAsFields(inputPath, outputPath); + }); + program.name('bb.js').parse(process.argv); diff --git a/ts/src/serialize/serialize.ts b/ts/src/serialize/serialize.ts index aa3634cc73..b09caac6b0 100644 --- a/ts/src/serialize/serialize.ts +++ b/ts/src/serialize/serialize.ts @@ -46,6 +46,10 @@ export function concatenateUint8Arrays(arrayOfUint8Arrays: Uint8Array[]) { return result; } +export function uint8ArrayToHexString(uint8Array: Uint8Array) { + return uint8Array.reduce((accumulator, byte) => accumulator + byte.toString(16).padStart(2, '0'), ''); +} + // For serializing a buffer as a vector. export function serializeBufferToVector(buf: Uint8Array) { return concatenateUint8Arrays([numToInt32BE(buf.length), buf]); diff --git a/ts/src/types/fields.ts b/ts/src/types/fields.ts index b1ac2ef438..a0b095813d 100644 --- a/ts/src/types/fields.ts +++ b/ts/src/types/fields.ts @@ -1,6 +1,6 @@ import { randomBytes } from '../random/index.js'; import { toBigIntBE, toBufferBE } from '../bigint-array/index.js'; -import { BufferReader } from '../serialize/index.js'; +import { BufferReader, uint8ArrayToHexString } from '../serialize/index.js'; export class Fr { static ZERO = new Fr(0n); @@ -38,7 +38,7 @@ export class Fr { } toString() { - return '0x' + this.value.toString(16); + return '0x' + uint8ArrayToHexString(this.toBuffer()); } equals(rhs: Fr) { diff --git a/ts/yarn.lock b/ts/yarn.lock index 56f0530fc7..0b068d22d7 100644 --- a/ts/yarn.lock +++ b/ts/yarn.lock @@ -15,9 +15,9 @@ __metadata: languageName: node linkType: hard -"@aztec/barretenberg.js@workspace:.": +"@aztec/bb.js@workspace:.": version: 0.0.0-use.local - resolution: "@aztec/barretenberg.js@workspace:." + resolution: "@aztec/bb.js@workspace:." dependencies: "@jest/globals": ^29.4.3 "@types/debug": ^4.1.7 @@ -27,7 +27,6 @@ __metadata: "@types/source-map-support": ^0.5.6 "@typescript-eslint/eslint-plugin": ^5.54.1 "@typescript-eslint/parser": ^5.54.1 - bigint-buffer: ^1.1.5 buffer: ^6.0.3 comlink: ^4.4.1 commander: ^10.0.1 @@ -50,7 +49,6 @@ __metadata: webpack-dev-server: ^4.15.0 bin: bb.js: ./dest/main.js - bb.js-dev: ./src/main-dev.ts languageName: unknown linkType: soft @@ -63,67 +61,67 @@ __metadata: languageName: node linkType: hard -"@babel/compat-data@npm:^7.21.5": - version: 7.21.9 - resolution: "@babel/compat-data@npm:7.21.9" - checksum: df97be04955c0801f5a23846f79a100660aa98f9433cfd1fad8f53ecd9f3454538e78522e86275939aa8aa7d6f9e32f23f94bc04ae843f7246b7cd4bffe3a175 +"@babel/compat-data@npm:^7.22.0": + version: 7.22.3 + resolution: "@babel/compat-data@npm:7.22.3" + checksum: eb001646f41459f42ccb0d39ee8bb3c3c495bc297234817044c0002689c625e3159a6678c53fd31bd98cf21f31472b73506f350fc6906e3bdfa49cb706e2af8d languageName: node linkType: hard "@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3": - version: 7.21.8 - resolution: "@babel/core@npm:7.21.8" + version: 7.22.1 + resolution: "@babel/core@npm:7.22.1" dependencies: "@ampproject/remapping": ^2.2.0 "@babel/code-frame": ^7.21.4 - "@babel/generator": ^7.21.5 - "@babel/helper-compilation-targets": ^7.21.5 - "@babel/helper-module-transforms": ^7.21.5 - "@babel/helpers": ^7.21.5 - "@babel/parser": ^7.21.8 - "@babel/template": ^7.20.7 - "@babel/traverse": ^7.21.5 - "@babel/types": ^7.21.5 + "@babel/generator": ^7.22.0 + "@babel/helper-compilation-targets": ^7.22.1 + "@babel/helper-module-transforms": ^7.22.1 + "@babel/helpers": ^7.22.0 + "@babel/parser": ^7.22.0 + "@babel/template": ^7.21.9 + "@babel/traverse": ^7.22.1 + "@babel/types": ^7.22.0 convert-source-map: ^1.7.0 debug: ^4.1.0 gensync: ^1.0.0-beta.2 json5: ^2.2.2 semver: ^6.3.0 - checksum: f28118447355af2a90bd340e2e60699f94c8020517eba9b71bf8ebff62fa9e00d63f076e033f9dfb97548053ad62ada45fafb0d96584b1a90e8aef5a3b8241b1 + checksum: bbe45e791f223a7e692d2ea6597a73f48050abd24b119c85c48ac6504c30ce63343a2ea3f79b5847bf4b409ddd8a68b6cdc4f0272ded1d2ef6f6b1e9663432f0 languageName: node linkType: hard -"@babel/generator@npm:^7.21.5, @babel/generator@npm:^7.7.2": - version: 7.21.9 - resolution: "@babel/generator@npm:7.21.9" +"@babel/generator@npm:^7.22.0, @babel/generator@npm:^7.22.3, @babel/generator@npm:^7.7.2": + version: 7.22.3 + resolution: "@babel/generator@npm:7.22.3" dependencies: - "@babel/types": ^7.21.5 + "@babel/types": ^7.22.3 "@jridgewell/gen-mapping": ^0.3.2 "@jridgewell/trace-mapping": ^0.3.17 jsesc: ^2.5.1 - checksum: 5bd10334ebdf7f2a30eb4a1fd99d369a57703aa2234527784449187512c254a1174fa739c9d4c31bcbb6018732012a0664bec7c314f12b5ec2458737ddbb01c7 + checksum: ccb6426ca5b5a38f0d47a3ac9628e223d2aaaa489cbf90ffab41468795c22afe86855f68a58667f0f2673949f1810d4d5a57b826c17984eab3e28fdb34a909e6 languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.21.5": - version: 7.21.5 - resolution: "@babel/helper-compilation-targets@npm:7.21.5" +"@babel/helper-compilation-targets@npm:^7.22.1": + version: 7.22.1 + resolution: "@babel/helper-compilation-targets@npm:7.22.1" dependencies: - "@babel/compat-data": ^7.21.5 + "@babel/compat-data": ^7.22.0 "@babel/helper-validator-option": ^7.21.0 browserslist: ^4.21.3 lru-cache: ^5.1.1 semver: ^6.3.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: 0edecb9c970ddc22ebda1163e77a7f314121bef9e483e0e0d9a5802540eed90d5855b6bf9bce03419b35b2e07c323e62d0353b153fa1ca34f17dbba897a83c25 + checksum: a686a01bd3288cf95ca26faa27958d34c04e2501c4b0858c3a6558776dec20317b5635f33d64c5a635b6fbdfe462a85c30d4bfa0ae7e7ffe3467e4d06442d7c8 languageName: node linkType: hard -"@babel/helper-environment-visitor@npm:^7.21.5": - version: 7.21.5 - resolution: "@babel/helper-environment-visitor@npm:7.21.5" - checksum: e436af7b62956e919066448013a3f7e2cd0b51010c26c50f790124dcd350be81d5597b4e6ed0a4a42d098a27de1e38561cd7998a116a42e7899161192deac9a6 +"@babel/helper-environment-visitor@npm:^7.22.1": + version: 7.22.1 + resolution: "@babel/helper-environment-visitor@npm:7.22.1" + checksum: a6b4bb5505453bff95518d361ac1de393f0029aeb8b690c70540f4317934c53c43cc4afcda8c752ffa8c272e63ed6b929a56eca28e4978424177b24238b21bf9 languageName: node linkType: hard @@ -155,19 +153,19 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.21.5": - version: 7.21.5 - resolution: "@babel/helper-module-transforms@npm:7.21.5" +"@babel/helper-module-transforms@npm:^7.22.1": + version: 7.22.1 + resolution: "@babel/helper-module-transforms@npm:7.22.1" dependencies: - "@babel/helper-environment-visitor": ^7.21.5 + "@babel/helper-environment-visitor": ^7.22.1 "@babel/helper-module-imports": ^7.21.4 "@babel/helper-simple-access": ^7.21.5 "@babel/helper-split-export-declaration": ^7.18.6 "@babel/helper-validator-identifier": ^7.19.1 - "@babel/template": ^7.20.7 - "@babel/traverse": ^7.21.5 - "@babel/types": ^7.21.5 - checksum: 1ccfc88830675a5d485d198e918498f9683cdd46f973fdd4fe1c85b99648fb70f87fca07756c7a05dc201bd9b248c74ced06ea80c9991926ac889f53c3659675 + "@babel/template": ^7.21.9 + "@babel/traverse": ^7.22.1 + "@babel/types": ^7.22.0 + checksum: dfa084211a93c9f0174ab07385fdbf7831bbf5c1ff3d4f984effc489f48670825ad8b817b9e9d2ec6492fde37ed6518c15944e9dd7a60b43a3d9874c9250f5f8 languageName: node linkType: hard @@ -217,14 +215,14 @@ __metadata: languageName: node linkType: hard -"@babel/helpers@npm:^7.21.5": - version: 7.21.5 - resolution: "@babel/helpers@npm:7.21.5" +"@babel/helpers@npm:^7.22.0": + version: 7.22.3 + resolution: "@babel/helpers@npm:7.22.3" dependencies: - "@babel/template": ^7.20.7 - "@babel/traverse": ^7.21.5 - "@babel/types": ^7.21.5 - checksum: a6f74b8579713988e7f5adf1a986d8b5255757632ba65b2552f0f609ead5476edb784044c7e4b18f3681ee4818ca9d08c41feb9bd4e828648c25a00deaa1f9e4 + "@babel/template": ^7.21.9 + "@babel/traverse": ^7.22.1 + "@babel/types": ^7.22.3 + checksum: 385289ee8b87cf9af448bbb9fcf747f6e67600db5f7f64eb4ad97761ee387819bf2212b6a757008286c6bfacf4f3fc0b6de88686f2e517a70fb59996bdfbd1e9 languageName: node linkType: hard @@ -239,12 +237,12 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.21.5, @babel/parser@npm:^7.21.8, @babel/parser@npm:^7.21.9": - version: 7.21.9 - resolution: "@babel/parser@npm:7.21.9" +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.21.9, @babel/parser@npm:^7.22.0, @babel/parser@npm:^7.22.4": + version: 7.22.4 + resolution: "@babel/parser@npm:7.22.4" bin: parser: ./bin/babel-parser.js - checksum: 985ccc311eb286a320331fd21ff54d94935df76e081abdb304cd4591ea2051a6c799c6b0d8e26d09a9dd041797d9a91ebadeb0c50699d0101bd39fc565082d5c + checksum: 0ca6d3a2d9aae2504ba1bc494704b64a83140884f7379f609de69bd39b60adb58a4f8ec692fe53fef8657dd82705d01b7e6efb65e18296326bdd66f71d52d9a9 languageName: node linkType: hard @@ -402,7 +400,7 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:^7.20.7, @babel/template@npm:^7.3.3": +"@babel/template@npm:^7.20.7, @babel/template@npm:^7.21.9, @babel/template@npm:^7.3.3": version: 7.21.9 resolution: "@babel/template@npm:7.21.9" dependencies: @@ -413,32 +411,32 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.21.5, @babel/traverse@npm:^7.7.2": - version: 7.21.5 - resolution: "@babel/traverse@npm:7.21.5" +"@babel/traverse@npm:^7.22.1, @babel/traverse@npm:^7.7.2": + version: 7.22.4 + resolution: "@babel/traverse@npm:7.22.4" dependencies: "@babel/code-frame": ^7.21.4 - "@babel/generator": ^7.21.5 - "@babel/helper-environment-visitor": ^7.21.5 + "@babel/generator": ^7.22.3 + "@babel/helper-environment-visitor": ^7.22.1 "@babel/helper-function-name": ^7.21.0 "@babel/helper-hoist-variables": ^7.18.6 "@babel/helper-split-export-declaration": ^7.18.6 - "@babel/parser": ^7.21.5 - "@babel/types": ^7.21.5 + "@babel/parser": ^7.22.4 + "@babel/types": ^7.22.4 debug: ^4.1.0 globals: ^11.1.0 - checksum: b403733fa7d858f0c8e224f0434a6ade641bc469a4f92975363391e796629d5bf53e544761dfe85039aab92d5389ebe7721edb309d7a5bb7df2bf74f37bf9f47 + checksum: 9560ae22092d5a7c52849145dd3e5aed2ffb73d61255e70e19e3fbd06bcbafbbdecea28df40a42ee3b60b01e85a42224ec841df93e867547e329091cc2f2bb6f languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.6, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.0, @babel/types@npm:^7.21.4, @babel/types@npm:^7.21.5, @babel/types@npm:^7.3.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.8.3": - version: 7.21.5 - resolution: "@babel/types@npm:7.21.5" +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.6, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.0, @babel/types@npm:^7.21.4, @babel/types@npm:^7.21.5, @babel/types@npm:^7.22.0, @babel/types@npm:^7.22.3, @babel/types@npm:^7.22.4, @babel/types@npm:^7.3.3, @babel/types@npm:^7.8.3": + version: 7.22.4 + resolution: "@babel/types@npm:7.22.4" dependencies: "@babel/helper-string-parser": ^7.21.5 "@babel/helper-validator-identifier": ^7.19.1 to-fast-properties: ^2.0.0 - checksum: 43242a99c612d13285ee4af46cc0f1066bcb6ffd38307daef7a76e8c70f36cfc3255eb9e75c8e768b40e761176c313aec4d5c0b9d97a21e494d49d5fd123a9f7 + checksum: ffe36bb4f4a99ad13c426a98c3b508d70736036cae4e471d9c862e3a579847ed4f480686af0fce2633f6f7c0f0d3bf02da73da36e7edd3fde0b2061951dcba9a languageName: node linkType: hard @@ -980,15 +978,15 @@ __metadata: linkType: hard "@types/babel__core@npm:^7.1.14": - version: 7.20.0 - resolution: "@types/babel__core@npm:7.20.0" + version: 7.20.1 + resolution: "@types/babel__core@npm:7.20.1" dependencies: "@babel/parser": ^7.20.7 "@babel/types": ^7.20.7 "@types/babel__generator": "*" "@types/babel__template": "*" "@types/babel__traverse": "*" - checksum: 49b601a0a7637f1f387442c8156bd086cfd10ff4b82b0e1994e73a6396643b5435366fb33d6b604eade8467cca594ef97adcbc412aede90bb112ebe88d0ad6df + checksum: 9fcd9691a33074802d9057ff70b0e3ff3778f52470475b68698a0f6714fbe2ccb36c16b43dc924eb978cd8a81c1f845e5ff4699e7a47606043b539eb8c6331a8 languageName: node linkType: hard @@ -1012,11 +1010,11 @@ __metadata: linkType: hard "@types/babel__traverse@npm:*, @types/babel__traverse@npm:^7.0.6": - version: 7.18.5 - resolution: "@types/babel__traverse@npm:7.18.5" + version: 7.20.0 + resolution: "@types/babel__traverse@npm:7.20.0" dependencies: - "@babel/types": ^7.3.0 - checksum: b9e7f39eb84626cc8f83ebf75a621d47f04b53cb085a3ea738a9633d57cf65208e503b1830db91aa5e297bc2ba761681ac0b0cbfb7a3d56afcfb2296212668ef + "@babel/types": ^7.20.7 + checksum: 030d647a61baa70aff5bc1193227694098191578e45e18720db3a14614f1827664d609630a668ad75cddffd7b80cd14a55455364239d1f14ea55f1f4d7d2c9ef languageName: node linkType: hard @@ -1176,19 +1174,19 @@ __metadata: linkType: hard "@types/jest@npm:^29.4.0": - version: 29.5.1 - resolution: "@types/jest@npm:29.5.1" + version: 29.5.2 + resolution: "@types/jest@npm:29.5.2" dependencies: expect: ^29.0.0 pretty-format: ^29.0.0 - checksum: 0a22491dec86333c0e92b897be2c809c922a7b2b0aa5604ac369810d6b2360908b4a3f2c6892e8a237a54fa1f10ecefe0e823ec5fcb7915195af4dfe88d2197e + checksum: 7d205599ea3cccc262bad5cc173d3242d6bf8138c99458509230e4ecef07a52d6ddcde5a1dbd49ace655c0af51d2dbadef3748697292ea4d86da19d9e03e19c0 languageName: node linkType: hard "@types/json-schema@npm:*, @types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9": - version: 7.0.11 - resolution: "@types/json-schema@npm:7.0.11" - checksum: 527bddfe62db9012fccd7627794bd4c71beb77601861055d87e3ee464f2217c85fca7a4b56ae677478367bbd248dbde13553312b7d4dbc702a2f2bbf60c4018d + version: 7.0.12 + resolution: "@types/json-schema@npm:7.0.12" + checksum: 00239e97234eeb5ceefb0c1875d98ade6e922bfec39dd365ec6bd360b5c2f825e612ac4f6e5f1d13601b8b30f378f15e6faa805a3a732f4a1bbe61915163d293 languageName: node linkType: hard @@ -1214,23 +1212,23 @@ __metadata: linkType: hard "@types/node@npm:*": - version: 20.2.3 - resolution: "@types/node@npm:20.2.3" - checksum: 576065e8fc1fa45798c8f59a6bf809169582d04abc2e25fab1a048ffc734975b9992ae31be0d960cf705a21fb37112f7fcde11aa322beddf7491e73d5a5a988c + version: 20.2.5 + resolution: "@types/node@npm:20.2.5" + checksum: 38ce7c7e9d76880dc632f71d71e0d5914fcda9d5e9a7095d6c339abda55ca4affb0f2a882aeb29398f8e09d2c5151f0b6586c81c8ccdfe529c34b1ea3337425e languageName: node linkType: hard "@types/node@npm:^18.7.23": - version: 18.16.14 - resolution: "@types/node@npm:18.16.14" - checksum: c11cb3c787236414efe58240ae71854971592554d82ff9d201876ce7cafd51c37aaa001c63602d002e8238614d7331bd6d48ac4c1c0caa826799980b6846fb08 + version: 18.16.16 + resolution: "@types/node@npm:18.16.16" + checksum: 0efad726dd1e0bef71c392c708fc5d78c5b39c46b0ac5186fee74de4ccb1b2e847b3fa468da67d62812f56569da721b15bf31bdc795e6c69b56c73a45079ed2d languageName: node linkType: hard "@types/prettier@npm:^2.1.5": - version: 2.7.2 - resolution: "@types/prettier@npm:2.7.2" - checksum: b47d76a5252265f8d25dd2fe2a5a61dc43ba0e6a96ffdd00c594cb4fd74c1982c2e346497e3472805d97915407a09423804cc2110a0b8e1b22cffcab246479b7 + version: 2.7.3 + resolution: "@types/prettier@npm:2.7.3" + checksum: 705384209cea6d1433ff6c187c80dcc0b95d99d5c5ce21a46a9a58060c527973506822e428789d842761e0280d25e3359300f017fbe77b9755bc772ab3dc2f83 languageName: node linkType: hard @@ -1342,13 +1340,13 @@ __metadata: linkType: hard "@typescript-eslint/eslint-plugin@npm:^5.54.1": - version: 5.59.7 - resolution: "@typescript-eslint/eslint-plugin@npm:5.59.7" + version: 5.59.8 + resolution: "@typescript-eslint/eslint-plugin@npm:5.59.8" dependencies: "@eslint-community/regexpp": ^4.4.0 - "@typescript-eslint/scope-manager": 5.59.7 - "@typescript-eslint/type-utils": 5.59.7 - "@typescript-eslint/utils": 5.59.7 + "@typescript-eslint/scope-manager": 5.59.8 + "@typescript-eslint/type-utils": 5.59.8 + "@typescript-eslint/utils": 5.59.8 debug: ^4.3.4 grapheme-splitter: ^1.0.4 ignore: ^5.2.0 @@ -1361,43 +1359,43 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10d28bac7a5af9e41767be0bb9c270ee3dcdfeaa38d1b036c6822e7260b88821c460699ba943664eb1ef272d00de6a81b99d7d955332044ea87b624e7ead84a1 + checksum: 3e05cd06149ec3741c3c2fb638e2d19a55687b4614a5c8820433db82997687650297e51c17828d320162ccf4241798cf5712c405561e7605cb17e984a6967f7b languageName: node linkType: hard "@typescript-eslint/parser@npm:^5.54.1": - version: 5.59.7 - resolution: "@typescript-eslint/parser@npm:5.59.7" + version: 5.59.8 + resolution: "@typescript-eslint/parser@npm:5.59.8" dependencies: - "@typescript-eslint/scope-manager": 5.59.7 - "@typescript-eslint/types": 5.59.7 - "@typescript-eslint/typescript-estree": 5.59.7 + "@typescript-eslint/scope-manager": 5.59.8 + "@typescript-eslint/types": 5.59.8 + "@typescript-eslint/typescript-estree": 5.59.8 debug: ^4.3.4 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: bc44f37a11a44f84ae5f0156213f3e2e49aef2ecac94d9e161a0c721acd29462e288f306ad4648095ac1c0e5a5f62b78280c1735883cf39f79ee3afcba312119 + checksum: bac9f09d8552086ceb882a7b87ce4d98dfaa41579249216c75d97e3fc07af33cddc4cbbd07a127a5823c826a258882643aaf658bec19cb2a434002b55c5f0d12 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:5.59.7": - version: 5.59.7 - resolution: "@typescript-eslint/scope-manager@npm:5.59.7" +"@typescript-eslint/scope-manager@npm:5.59.8": + version: 5.59.8 + resolution: "@typescript-eslint/scope-manager@npm:5.59.8" dependencies: - "@typescript-eslint/types": 5.59.7 - "@typescript-eslint/visitor-keys": 5.59.7 - checksum: 43f7ea93fddbe2902122a41050677fe3eff2ea468f435b981592510cfc6136e8c28ac7d3a3e05fb332c0b3078a29bd0c91c35b2b1f4e788b4eb9aaeb70e21583 + "@typescript-eslint/types": 5.59.8 + "@typescript-eslint/visitor-keys": 5.59.8 + checksum: e1e810ee991cfeb433330b04ee949bb6784abe4dbdb7d9480aa7a7536671b4fec914b7803edf662516c8ecb1b31dcff126797f9923270a529c26e2b00b0ea96f languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:5.59.7": - version: 5.59.7 - resolution: "@typescript-eslint/type-utils@npm:5.59.7" +"@typescript-eslint/type-utils@npm:5.59.8": + version: 5.59.8 + resolution: "@typescript-eslint/type-utils@npm:5.59.8" dependencies: - "@typescript-eslint/typescript-estree": 5.59.7 - "@typescript-eslint/utils": 5.59.7 + "@typescript-eslint/typescript-estree": 5.59.8 + "@typescript-eslint/utils": 5.59.8 debug: ^4.3.4 tsutils: ^3.21.0 peerDependencies: @@ -1405,23 +1403,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 9cbeffad27b145b478e4cbbab2b44c5b246a9b922f01fd06d401ea4c41a4fa6dc8ba75d13a6409b3b4474ccaf2018770a4c6c599172e22ec2004110e00f4e721 + checksum: d9fde31397da0f0e62a5568f64bad99d06bcd324b7e3aac7fd997a3d045a0fe4c084b2e85d440e0a39645acd2269ad6593f196399c2c0f880d293417fec894e3 languageName: node linkType: hard -"@typescript-eslint/types@npm:5.59.7": - version: 5.59.7 - resolution: "@typescript-eslint/types@npm:5.59.7" - checksum: 52eccec9e2d631eb2808e48b5dc33a837b5e242fa9eddace89fc707c9f2283b5364f1d38b33d418a08d64f45f6c22f051800898e1881a912f8aac0c3ae300d0a +"@typescript-eslint/types@npm:5.59.8": + version: 5.59.8 + resolution: "@typescript-eslint/types@npm:5.59.8" + checksum: 559473d5601c849eb0da1874a2ac67c753480beed484ad6f6cda62fa6023273f2c3005c7f2864d9c2afb7c6356412d0d304b57db10c53597207f18a7f6cd4f18 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:5.59.7": - version: 5.59.7 - resolution: "@typescript-eslint/typescript-estree@npm:5.59.7" +"@typescript-eslint/typescript-estree@npm:5.59.8": + version: 5.59.8 + resolution: "@typescript-eslint/typescript-estree@npm:5.59.8" dependencies: - "@typescript-eslint/types": 5.59.7 - "@typescript-eslint/visitor-keys": 5.59.7 + "@typescript-eslint/types": 5.59.8 + "@typescript-eslint/visitor-keys": 5.59.8 debug: ^4.3.4 globby: ^11.1.0 is-glob: ^4.0.3 @@ -1430,35 +1428,35 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: eefe82eedf9ee2e14463c3f2b5b18df084c1328a859b245ee897a9a7075acce7cca0216a21fd7968b75aa64189daa008bfde1e2f9afbcc336f3dfe856e7f342e + checksum: d93371cc866f573a6a1ddc0eb10d498a8e59f36763a99ce21da0737fff2b4c942eef1587216aad273f8d896ebc0b19003677cba63a27d2646aa2c087638963eb languageName: node linkType: hard -"@typescript-eslint/utils@npm:5.59.7": - version: 5.59.7 - resolution: "@typescript-eslint/utils@npm:5.59.7" +"@typescript-eslint/utils@npm:5.59.8": + version: 5.59.8 + resolution: "@typescript-eslint/utils@npm:5.59.8" dependencies: "@eslint-community/eslint-utils": ^4.2.0 "@types/json-schema": ^7.0.9 "@types/semver": ^7.3.12 - "@typescript-eslint/scope-manager": 5.59.7 - "@typescript-eslint/types": 5.59.7 - "@typescript-eslint/typescript-estree": 5.59.7 + "@typescript-eslint/scope-manager": 5.59.8 + "@typescript-eslint/types": 5.59.8 + "@typescript-eslint/typescript-estree": 5.59.8 eslint-scope: ^5.1.1 semver: ^7.3.7 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: d8682700187ca94cc6441480cb6b87d0514a9748103c15dd93206c5b1c6fefa59063662f27a4103e16abbcfb654a61d479bc55af8f23d96f342431b87f31bb4e + checksum: cbaa057485c7f52c45d0dfb4f5a8e9273abccb1c52dcb4426a79f9e71d2c1062cf2525bad6d4aca5ec42db3fe723d749843bcade5a323bde7fbe4b5d5b5d5c3b languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:5.59.7": - version: 5.59.7 - resolution: "@typescript-eslint/visitor-keys@npm:5.59.7" +"@typescript-eslint/visitor-keys@npm:5.59.8": + version: 5.59.8 + resolution: "@typescript-eslint/visitor-keys@npm:5.59.8" dependencies: - "@typescript-eslint/types": 5.59.7 + "@typescript-eslint/types": 5.59.8 eslint-visitor-keys: ^3.3.0 - checksum: 4367f2ea68dd96a0520485434ad11e1bd26239eeeb3a2150bee7478a0f1df3c2099a39f96486722932be0456bcb7a47a483b452876d1d30bdeb9b81d354eef3d + checksum: 6bfa7918dbb0e08d8a7404aeeef7bcd1a85736dc8d01614d267c0c5ec10f94d2746b50a945bf5c82c54fda67926e8deaeba8565c919da17f725fc11209ef8987 languageName: node linkType: hard @@ -1677,7 +1675,7 @@ __metadata: languageName: node linkType: hard -"acorn-import-assertions@npm:^1.7.6": +"acorn-import-assertions@npm:^1.9.0": version: 1.9.0 resolution: "acorn-import-assertions@npm:1.9.0" peerDependencies: @@ -2017,16 +2015,6 @@ __metadata: languageName: node linkType: hard -"bigint-buffer@npm:^1.1.5": - version: 1.1.5 - resolution: "bigint-buffer@npm:1.1.5" - dependencies: - bindings: ^1.3.0 - node-gyp: latest - checksum: d010c9f57758bcdaccb435d88b483ffcc95fe8bbc6e7fb3a44fb5221f29c894ffaf4a3c5a4a530e0e7d6608203c2cde9b79ee4f2386cd6d4462d1070bc8c9f4e - languageName: node - linkType: hard - "binary-extensions@npm:^2.0.0": version: 2.2.0 resolution: "binary-extensions@npm:2.2.0" @@ -2034,15 +2022,6 @@ __metadata: languageName: node linkType: hard -"bindings@npm:^1.3.0": - version: 1.5.0 - resolution: "bindings@npm:1.5.0" - dependencies: - file-uri-to-path: 1.0.0 - checksum: 65b6b48095717c2e6105a021a7da4ea435aa8d3d3cd085cb9e85bcb6e5773cf318c4745c3f7c504412855940b585bdf9b918236612a1c7a7942491de176f1ae7 - languageName: node - linkType: hard - "body-parser@npm:1.20.1": version: 1.20.1 resolution: "body-parser@npm:1.20.1" @@ -2111,16 +2090,16 @@ __metadata: linkType: hard "browserslist@npm:^4.14.5, browserslist@npm:^4.21.3": - version: 4.21.5 - resolution: "browserslist@npm:4.21.5" + version: 4.21.7 + resolution: "browserslist@npm:4.21.7" dependencies: - caniuse-lite: ^1.0.30001449 - electron-to-chromium: ^1.4.284 - node-releases: ^2.0.8 - update-browserslist-db: ^1.0.10 + caniuse-lite: ^1.0.30001489 + electron-to-chromium: ^1.4.411 + node-releases: ^2.0.12 + update-browserslist-db: ^1.0.11 bin: browserslist: cli.js - checksum: 9755986b22e73a6a1497fd8797aedd88e04270be33ce66ed5d85a1c8a798292a65e222b0f251bafa1c2522261e237d73b08b58689d4920a607e5a53d56dc4706 + checksum: 3d0d025e6d381c4db5e71b538258952660ba574c060832095f182a9877ca798836fa550736269e669a2080e486f0cfdf5d3bcf2769b9f7cf123f6c6b8c005f8f languageName: node linkType: hard @@ -2240,10 +2219,10 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001449": - version: 1.0.30001489 - resolution: "caniuse-lite@npm:1.0.30001489" - checksum: 94585a351fd7661b855c83eace474db0ee5a617159b46f2eff1f6fe4b85d7a205418471fdec8cf5cd647a7f79958706d5e664c0bbf3c7c09118b35db9bb95a1b +"caniuse-lite@npm:^1.0.30001489": + version: 1.0.30001492 + resolution: "caniuse-lite@npm:1.0.30001492" + checksum: 261869f910ec905ab6aa5a754e4ae57da8c5c33f3b723db2fa21840da307667bff61057aef3abaca32091c1561c254dd3a807c0fdb054cdc9e7e3ba495a55e20 languageName: node linkType: hard @@ -2812,10 +2791,10 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.4.284": - version: 1.4.405 - resolution: "electron-to-chromium@npm:1.4.405" - checksum: d1cf421eaf63dbd5481bcc4296a94e5db5cf831bdc5cbdad283b4b0d53d8fd87254b64fa6cda88f1cb4789eab012f078c1eed4cbb01c5a34bd0ce657dcfe08c8 +"electron-to-chromium@npm:^1.4.411": + version: 1.4.416 + resolution: "electron-to-chromium@npm:1.4.416" + checksum: a1804fe6f1955b3b80519bf2feb69d5e2111914e824cdacdff85545dba48da44d16f43d5fb702ff4cfc9148f7d0be7cd2669cb5e939b0ed13ee9772cae3edfd4 languageName: node linkType: hard @@ -2849,13 +2828,13 @@ __metadata: languageName: node linkType: hard -"enhanced-resolve@npm:^5.0.0, enhanced-resolve@npm:^5.14.0": - version: 5.14.0 - resolution: "enhanced-resolve@npm:5.14.0" +"enhanced-resolve@npm:^5.0.0, enhanced-resolve@npm:^5.14.1": + version: 5.14.1 + resolution: "enhanced-resolve@npm:5.14.1" dependencies: graceful-fs: ^4.2.4 tapable: ^2.2.0 - checksum: fff1aaebbf376371e5df4502e111967f6247c37611ad3550e4e7fca657f6dcb29ef7ffe88bf14e5010b78997f1ddd984a8db97af87ee0a5477771398fd326f5b + checksum: ad2a31928b6649eed40d364838449587f731baa63863e83d2629bebaa8be1eabac18b90f89c1784bc805b0818363e99b22547159edd485d7e5ccf18cdc640642 languageName: node linkType: hard @@ -3261,13 +3240,6 @@ __metadata: languageName: node linkType: hard -"file-uri-to-path@npm:1.0.0": - version: 1.0.0 - resolution: "file-uri-to-path@npm:1.0.0" - checksum: b648580bdd893a008c92c7ecc96c3ee57a5e7b6c4c18a9a09b44fb5d36d79146f8e442578bc0e173dc027adf3987e254ba1dfd6e3ec998b7c282873010502144 - languageName: node - linkType: hard - "fill-range@npm:^7.0.1": version: 7.0.1 resolution: "fill-range@npm:7.0.1" @@ -3363,9 +3335,9 @@ __metadata: linkType: hard "fs-monkey@npm:^1.0.3": - version: 1.0.3 - resolution: "fs-monkey@npm:1.0.3" - checksum: cf50804833f9b88a476911ae911fe50f61a98d986df52f890bd97e7262796d023698cb2309fa9b74fdd8974f04315b648748a0a8ee059e7d5257b293bfc409c0 + version: 1.0.4 + resolution: "fs-monkey@npm:1.0.4" + checksum: 8b254c982905c0b7e028eab22b410dc35a5c0019c1c860456f5f54ae6a61666e1cb8c6b700d6c88cc873694c00953c935847b9959cc4dcf274aacb8673c1e8bf languageName: node linkType: hard @@ -3944,9 +3916,9 @@ __metadata: linkType: hard "ipaddr.js@npm:^2.0.1": - version: 2.0.1 - resolution: "ipaddr.js@npm:2.0.1" - checksum: dd194a394a843d470f88d17191b0948f383ed1c8e320813f850c336a0fcb5e9215d97ec26ca35ab4fbbd31392c8b3467f3e8344628029ed3710b2ff6b5d1034e + version: 2.1.0 + resolution: "ipaddr.js@npm:2.1.0" + checksum: 807a054f2bd720c4d97ee479d6c9e865c233bea21f139fb8dabd5a35c4226d2621c42e07b4ad94ff3f82add926a607d8d9d37c625ad0319f0e08f9f2bd1968e2 languageName: node linkType: hard @@ -5148,7 +5120,7 @@ __metadata: languageName: node linkType: hard -"node-releases@npm:^2.0.8": +"node-releases@npm:^2.0.12": version: 2.0.12 resolution: "node-releases@npm:2.0.12" checksum: b8c56db82c4642a0f443332b331a4396dae452a2ac5a65c8dbd93ef89ecb2fbb0da9d42ac5366d4764973febadca816cf7587dad492dce18d2a6b2af59cda260 @@ -6576,7 +6548,7 @@ __metadata: languageName: node linkType: hard -"update-browserslist-db@npm:^1.0.10": +"update-browserslist-db@npm:^1.0.11": version: 1.0.11 resolution: "update-browserslist-db@npm:1.0.11" dependencies: @@ -6794,8 +6766,8 @@ __metadata: linkType: hard "webpack@npm:^5.82.1": - version: 5.83.1 - resolution: "webpack@npm:5.83.1" + version: 5.85.0 + resolution: "webpack@npm:5.85.0" dependencies: "@types/eslint-scope": ^3.7.3 "@types/estree": ^1.0.0 @@ -6803,10 +6775,10 @@ __metadata: "@webassemblyjs/wasm-edit": ^1.11.5 "@webassemblyjs/wasm-parser": ^1.11.5 acorn: ^8.7.1 - acorn-import-assertions: ^1.7.6 + acorn-import-assertions: ^1.9.0 browserslist: ^4.14.5 chrome-trace-event: ^1.0.2 - enhanced-resolve: ^5.14.0 + enhanced-resolve: ^5.14.1 es-module-lexer: ^1.2.1 eslint-scope: 5.1.1 events: ^3.2.0 @@ -6826,7 +6798,7 @@ __metadata: optional: true bin: webpack: bin/webpack.js - checksum: 219d5ef50380bc0fd3702ed17feddf13819d8173b78f7a5b857dc74ac177e63d1f79c050792754411cc088bbc02e0971b989efddadbb8e393cf27d64c0ad9ff8 + checksum: b013be9fbc7f6810d1f229f570c70710ddbc7290f817411acffe4214b2b6c783a041ab1f2005d9e1109f4ab21c136f0f8d8c067a5fb64f20a82dcbc1ee0d3f42 languageName: node linkType: hard