From 30a67aa1d080b71d83119ef63e3884044fd1b6fc Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Wed, 1 Feb 2023 18:07:25 +0000 Subject: [PATCH 1/5] Several changes to UltraPlonk to make proofs more amenable to be verified by a smart contract. Linearisation trick has been removed from base UltraPlonk. Adds unnecessary complexity TurboPlonk fixed-base Pedersen gate has been removed from UltraPlonk. We only added it for backwards-compatibility with TurboPlonk in case we upgraded Aztec Connect to UP. Given that is redundant, the gate adds unnecessary complexity. Ideally we move forward by standardising on the (much simpler) UltraPlonk Pedersen hash UltraPlonk uses plookup Pedersen by default, but remains backwards-compatible with TurboPlonk Pedersen hash by using StandardComposer's fallback methods for create_fixed_group_add_gate, create_fixed_group_add_gate_init, create_fixed_group_add_gate_final. These methods have been moved out of StandardComposer and into a stdlib::pedersen_gates class to prevent code duplication. Copied @dbanks12 barretenberg CMake changes from PR [REPLACED] Move README.md into cpp and add a simple top-level one #56 (to more easily build key/proof generation scripts in aztec-verifier-contract-tests) Added code to generate UltraPlonk verification keys --- cpp/src/aztec/CMakeLists.txt | 78 ++++- .../plonk/composer/standard_composer.cpp | 240 ------------- .../plonk/composer/standard_composer.hpp | 5 - .../aztec/plonk/composer/ultra_composer.cpp | 107 +----- .../aztec/plonk/composer/ultra_composer.hpp | 115 ++----- .../proof_system/types/program_settings.hpp | 13 +- .../proof_system/types/prover_settings.hpp | 2 +- .../plookup_arithmetic_widget.hpp | 2 +- .../types/polynomial_manifest.hpp | 63 ++-- .../proof_system/verification_key/sol_gen.hpp | 108 +++++- .../aztec/stdlib/hash/pedersen/pedersen.cpp | 23 +- .../stdlib/hash/pedersen/pedersen_gates.hpp | 315 ++++++++++++++++++ .../aztec/stdlib/primitives/group/group.hpp | 6 +- .../stdlib/primitives/memory/ram_table.cpp | 7 +- cpp/src/aztec/stdlib/types/types.hpp | 7 +- 15 files changed, 566 insertions(+), 525 deletions(-) create mode 100644 cpp/src/aztec/stdlib/hash/pedersen/pedersen_gates.hpp diff --git a/cpp/src/aztec/CMakeLists.txt b/cpp/src/aztec/CMakeLists.txt index 88dffca2cf..fb7d27505b 100644 --- a/cpp/src/aztec/CMakeLists.txt +++ b/cpp/src/aztec/CMakeLists.txt @@ -1,20 +1,10 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -# Enable the following warnings project wide. -# If any compilation issues arise in the future, they should not be silenced here but rather in the -# module's own CMakeLists.txt by adding conditional compilation flags like the following -# ``` -# if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") -# target_compile_options(crypto_blake3s_full_objects PRIVATE -Wno-error=shorten-64-to-32) -# endif() -# ``` -# Specifying `-Wno-${ERROR_NAME}` will silence the error completely. -# To preserve the warning, but prevent them from causing the build to fail, -# use the flag `-Wno-error=${ERROR_NAME}` -add_compile_options(-Werror -Wall -Wextra -Wconversion -Wsign-conversion -Wfatal-errors) +add_compile_options(-Werror -Wall -Wextra -Wconversion -Wsign-conversion -Wno-deprecated -Wno-tautological-compare -Wfatal-errors) if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") - add_compile_options(-fconstexpr-steps=100000000) + add_compile_options(-Wno-unguarded-availability-new -Wno-c99-extensions -fconstexpr-steps=100000000) if(MEMORY_CHECKS) message(STATUS "Compiling with memory checks.") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") @@ -22,7 +12,7 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") endif() if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") - add_compile_options(-fconstexpr-ops-limit=100000000) + add_compile_options(-Wno-deprecated-copy -fconstexpr-ops-limit=100000000) endif() include_directories(${CMAKE_CURRENT_SOURCE_DIR}) @@ -67,7 +57,6 @@ if(WASM) $ $ $ - $ $ $ $ @@ -78,7 +67,7 @@ if(WASM) $ $ $ - $ + # TODO: remove all except those needed for testing (join_split) $ $ $ @@ -108,5 +97,60 @@ if(WASM) barretenberg.wasm DEPENDS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/barretenberg.wasm ) + # For use when compiling dependent cpp projects for WASM + message(STATUS "Compiling all-in-one barretenberg WASM archive") + add_library( + barretenberg + STATIC + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + ) -endif() +else() + # For use when compiling dependent cpp projects + message(STATUS "Compiling all-in-one barretenberg archive") + add_library( + barretenberg + STATIC + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + ) +endif() \ No newline at end of file diff --git a/cpp/src/aztec/plonk/composer/standard_composer.cpp b/cpp/src/aztec/plonk/composer/standard_composer.cpp index 04668e0ba2..aa666da7ad 100644 --- a/cpp/src/aztec/plonk/composer/standard_composer.cpp +++ b/cpp/src/aztec/plonk/composer/standard_composer.cpp @@ -256,246 +256,6 @@ void StandardComposer::create_poly_gate(const poly_triple& in) ++n; } -void StandardComposer::create_fixed_group_add_gate_with_init(const fixed_group_add_quad& in, - const fixed_group_init_quad& init) -{ - uint32_t x_0_idx = in.a; - uint32_t y_0_idx = in.b; - uint32_t x_alpha_idx = in.c; - uint32_t a_0_idx = in.d; - - fr x_alpha = get_variable(x_alpha_idx); - fr a_0 = get_variable(a_0_idx); - - // weird names here follow the Turbo notation - fr q_4 = init.q_x_1; - fr q_5 = init.q_x_2; - fr q_m = init.q_y_1; - fr q_c = init.q_y_2; - - // We will think of s = 1-a_0 as an auxiliary "switch" which is equal to either -x_alpha or 0 - // during the initialization step, but we will not add this variable to the composer for reasons of efficiency. - - // (ɑ^4 identity) impose 1-a_0 = 0 or -x_alpha - // // first check formula for sx_alpha - fr sx_alpha = (fr(1) - a_0) * x_alpha; - uint32_t sx_alpha_idx = add_variable(sx_alpha); - create_poly_gate( - { .a = a_0_idx, .b = x_alpha_idx, .c = sx_alpha_idx, .q_m = 1, .q_l = 0, .q_r = -1, .q_o = 1, .q_c = 0 }); - - // // now add the desired constraint on sx_alpha - // // s(s + x_alpha) = s*s + s*x_alpha = 0 - create_poly_gate( - { .a = a_0_idx, .b = a_0_idx, .c = sx_alpha_idx, .q_m = 1, .q_l = -2, .q_r = 0, .q_o = 1, .q_c = 1 }); - - // (ɑ^5 identity) - create_poly_gate( - { .a = x_0_idx, .b = x_alpha_idx, .c = a_0_idx, .q_m = -1, .q_l = 0, .q_r = q_4, .q_o = -q_5, .q_c = q_5 }); - - // (ɑ^6 identity) - create_poly_gate( - { .a = y_0_idx, .b = x_alpha_idx, .c = a_0_idx, .q_m = -1, .q_l = 0, .q_r = q_m, .q_o = -q_c, .q_c = q_c }); - - // There is no previous add quad. - previous_add_quad = in; -} - -void StandardComposer::create_fixed_group_add_gate(const fixed_group_add_quad& in) -{ - assert_valid_variables({ in.a, in.b, in.c, in.d }); - - auto row_1 = previous_add_quad; - auto row_2 = in; - previous_add_quad = in; - - fr a_1 = get_variable(row_1.d); - fr a_2 = get_variable(row_2.d); - fr x_1 = get_variable(row_1.a); - fr y_1 = get_variable(row_1.b); - fr x_2 = get_variable(row_2.a); - fr y_2 = get_variable(row_2.b); - fr x_alpha = get_variable(row_2.c); - - fr q_x_alpha_1 = row_1.q_x_1; - fr q_x_alpha_2 = row_1.q_x_2; - fr q_y_alpha_1 = row_1.q_y_1; - fr q_y_alpha_2 = row_1.q_y_2; - - uint32_t a_1_idx = row_1.d; - uint32_t a_2_idx = row_2.d; - uint32_t x_1_idx = row_1.a; - uint32_t y_1_idx = row_1.b; - uint32_t x_2_idx = row_2.a; - uint32_t y_2_idx = row_2.b; - uint32_t x_alpha_idx = row_2.c; - - // add variable δ = a_2 - 4a_1 - fr delta = a_2 - (a_1 + a_1 + a_1 + a_1); - uint32_t delta_idx = add_variable(delta); - create_add_gate({ .a = a_2_idx, - .b = a_1_idx, - .c = delta_idx, - .a_scaling = 1, - .b_scaling = -4, - .c_scaling = -1, - .const_scaling = 0 }); - - // constraint: (δ + 3)(δ + 1)(δ - 1)(δ - 3) - // (δ + 3)(δ + 1)(δ - 1)(δ - 3) = (δ^2 - 9)(δ^2 - 1)=0 - // // first: (δ^2 - δ_sqr = 0) - fr delta_sqr = delta * delta; - uint32_t delta_sqr_idx = add_variable(delta_sqr); - create_mul_gate( - { .a = delta_idx, .b = delta_idx, .c = delta_sqr_idx, .mul_scaling = 1, .c_scaling = -1, .const_scaling = 0 }); - // // next (δ^2 - 9)( δ^2 - 1) = δ^2*δ^2 - 10 * δ^2 + 9 = 0 - create_mul_gate({ .a = delta_sqr_idx, - .b = delta_sqr_idx, - .c = delta_sqr_idx, - .mul_scaling = 1, - .c_scaling = -10, - .const_scaling = 9 }); - - // validate correctness of x_ɑ - // constraint: (δ^2) * q_x_ɑ,1 + q_x_ɑ,2 - x,ɑ = 0 - create_add_gate({ .a = delta_sqr_idx, - .b = x_alpha_idx, - .c = zero_idx, - .a_scaling = q_x_alpha_1, - .b_scaling = -1, - .c_scaling = 0, - .const_scaling = q_x_alpha_2 }); - - // compute y_alpha using lookup formula, instantiate as witness and validate - fr y_alpha = (x_alpha * q_y_alpha_1 + q_y_alpha_2) * delta; - uint32_t y_alpha_idx = add_variable(y_alpha); - create_poly_gate({ .a = delta_idx, - .b = x_alpha_idx, - .c = y_alpha_idx, - .q_m = q_y_alpha_1, - .q_l = q_y_alpha_2, - .q_r = 0, - .q_o = -1, - .q_c = 0 }); - - // show that (x_1, y_1) + (x_ɑ, y_ɑ) = (x_2, y_2) in 11 gates - // // 4 gates to compute commonly used expressions - // // // 2 differences: - fr diff_x_alpha_x_1 = x_alpha - x_1; - uint32_t diff_x_alpha_x_1_idx = add_variable(diff_x_alpha_x_1); - create_add_gate({ .a = diff_x_alpha_x_1_idx, - .b = x_1_idx, - .c = x_alpha_idx, - .a_scaling = 1, - .b_scaling = 1, - .c_scaling = -1, - .const_scaling = 0 }); - - fr diff_y_alpha_y_1 = y_alpha - y_1; - uint32_t diff_y_alpha_y_1_idx = add_variable(diff_y_alpha_y_1); - create_add_gate({ .a = diff_y_alpha_y_1_idx, - .b = y_1_idx, - .c = y_alpha_idx, - .a_scaling = 1, - .b_scaling = 1, - .c_scaling = -1, - .const_scaling = 0 }); - - // // // now the squares of these 2 differences - fr diff_x_alpha_x_1_sqr = diff_x_alpha_x_1 * diff_x_alpha_x_1; - uint32_t diff_x_alpha_x_1_sqr_idx = add_variable(diff_x_alpha_x_1_sqr); - create_mul_gate({ .a = diff_x_alpha_x_1_idx, - .b = diff_x_alpha_x_1_idx, - .c = diff_x_alpha_x_1_sqr_idx, - .mul_scaling = 1, - .c_scaling = -1, - .const_scaling = 0 }); - - fr diff_y_alpha_y_1_sqr = diff_y_alpha_y_1 * diff_y_alpha_y_1; - uint32_t diff_y_alpha_y_1_sqr_idx = add_variable(diff_y_alpha_y_1_sqr); - create_mul_gate({ .a = diff_y_alpha_y_1_idx, - .b = diff_y_alpha_y_1_idx, - .c = diff_y_alpha_y_1_sqr_idx, - .mul_scaling = 1, - .c_scaling = -1, - .const_scaling = 0 }); - - // // 3 gates to build identity for x_2 - // // // compute x_2 + x_ɑ + x_1 using 2 poly_gates via create_big_add_gate - fr sum_x_1_2_alpha = x_2 + x_alpha + x_1; - uint32_t sum_x_1_2_alpha_idx = add_variable(sum_x_1_2_alpha); - create_big_add_gate({ .a = x_2_idx, - .b = x_alpha_idx, - .c = x_1_idx, - .d = sum_x_1_2_alpha_idx, - .a_scaling = 1, - .b_scaling = 1, - .c_scaling = 1, - .d_scaling = -1, - .const_scaling = 0 }); - - // // // constraint: identity for x_2 - create_poly_gate({ .a = sum_x_1_2_alpha_idx, - .b = diff_x_alpha_x_1_sqr_idx, - .c = diff_y_alpha_y_1_sqr_idx, - .q_m = 1, - .q_l = 0, - .q_r = 0, - .q_o = -1, - .q_c = 0 }); - - // // 4 gates to build identity for y_2: - // // // 3 auxiliary - fr sum_y_1_y_2 = y_1 + y_2; - uint32_t sum_y_1_y_2_idx = add_variable(sum_y_1_y_2); - create_add_gate({ .a = y_1_idx, - .b = y_2_idx, - .c = sum_y_1_y_2_idx, - .a_scaling = 1, - .b_scaling = 1, - .c_scaling = -1, - .const_scaling = 0 }); - - fr diff_x_1_x_2 = x_1 - x_2; - uint32_t diff_x_1_x_2_idx = add_variable(diff_x_1_x_2); - create_add_gate({ .a = diff_x_1_x_2_idx, - .b = x_2_idx, - .c = x_1_idx, - .a_scaling = 1, - .b_scaling = 1, - .c_scaling = -1, - .const_scaling = 0 }); - - fr prod_y_diff_x_diff = diff_y_alpha_y_1 * diff_x_1_x_2; - uint32_t prod_y_diff_x_diff_idx = add_variable(prod_y_diff_x_diff); - create_mul_gate({ .a = diff_y_alpha_y_1_idx, - .b = diff_x_1_x_2_idx, - .c = prod_y_diff_x_diff_idx, - .mul_scaling = 1, - .c_scaling = -1, - .const_scaling = 0 }); - - // // // identity for y_2 - create_mul_gate({ .a = sum_y_1_y_2_idx, - .b = diff_x_alpha_x_1_idx, - .c = prod_y_diff_x_diff_idx, - .mul_scaling = 1, - .c_scaling = -1, - .const_scaling = 0 }); -} - -void StandardComposer::create_fixed_group_add_gate_final(const add_quad& in) -{ - fixed_group_add_quad final_round_quad{ .a = in.a, - .b = in.b, - .c = in.c, - .d = in.d, - .q_x_1 = fr::zero(), - .q_x_2 = fr::zero(), - .q_y_1 = fr::zero(), - .q_y_2 = fr::zero() }; - create_fixed_group_add_gate(final_round_quad); -} - std::vector StandardComposer::decompose_into_base4_accumulators(const uint32_t witness_index, const size_t num_bits, std::string const& msg) diff --git a/cpp/src/aztec/plonk/composer/standard_composer.hpp b/cpp/src/aztec/plonk/composer/standard_composer.hpp index dbb3464bc9..09a5cdee71 100644 --- a/cpp/src/aztec/plonk/composer/standard_composer.hpp +++ b/cpp/src/aztec/plonk/composer/standard_composer.hpp @@ -105,11 +105,6 @@ class StandardComposer : public ComposerBase { void create_big_add_gate_with_bit_extraction(const add_quad& in); void create_big_mul_gate(const mul_quad& in); void create_balanced_add_gate(const add_quad& in); - void create_fixed_group_add_gate(const fixed_group_add_quad& in); - void create_fixed_group_add_gate_with_init(const fixed_group_add_quad& in, const fixed_group_init_quad& init); - void create_fixed_group_add_gate_final(const add_quad& in); - - fixed_group_add_quad previous_add_quad; void fix_witness(const uint32_t witness_index, const barretenberg::fr& witness_value); diff --git a/cpp/src/aztec/plonk/composer/ultra_composer.cpp b/cpp/src/aztec/plonk/composer/ultra_composer.cpp index 24874f24ae..afafa91e79 100644 --- a/cpp/src/aztec/plonk/composer/ultra_composer.cpp +++ b/cpp/src/aztec/plonk/composer/ultra_composer.cpp @@ -39,7 +39,6 @@ namespace waffle { auto& q_3 = selectors[UltraSelectors::Q3]; \ auto& q_4 = selectors[UltraSelectors::Q4]; \ auto& q_arith = selectors[UltraSelectors::QARITH]; \ - auto& q_fixed_base = selectors[UltraSelectors::QFIXED]; \ auto& q_sort = selectors[UltraSelectors::QSORT]; \ auto& q_elliptic = selectors[UltraSelectors::QELLIPTIC]; \ auto& q_aux = selectors[UltraSelectors::QAUX]; \ @@ -48,9 +47,9 @@ namespace waffle { std::vector ultra_selector_properties() { std::vector result{ - { "q_m", true }, { "q_c", true }, { "q_1", true }, { "q_2", true }, - { "q_3", true }, { "q_4", false }, { "q_arith", false }, { "q_fixed_base", false }, - { "q_sort", false }, { "q_elliptic", false }, { "q_aux", false }, { "table_type", true }, + { "q_m", true }, { "q_c", true }, { "q_1", true }, { "q_2", true }, + { "q_3", true }, { "q_4", false }, { "q_arith", false }, { "q_sort", false }, + { "q_elliptic", false }, { "q_aux", false }, { "table_type", true }, }; return result; } @@ -108,7 +107,6 @@ void UltraComposer::create_add_gate(const add_triple& in) q_c.emplace_back(in.const_scaling); q_arith.emplace_back(1); q_4.emplace_back(0); - q_fixed_base.emplace_back(0); q_sort.emplace_back(0); q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); @@ -140,7 +138,6 @@ void UltraComposer::create_big_add_gate(const add_quad& in, const bool include_n q_c.emplace_back(in.const_scaling); q_arith.emplace_back(include_next_gate_w_4 ? 2 : 1); q_4.emplace_back(in.d_scaling); - q_fixed_base.emplace_back(0); q_sort.emplace_back(0); q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); @@ -233,7 +230,6 @@ void UltraComposer::create_big_mul_gate(const mul_quad& in) q_c.emplace_back(in.const_scaling); q_arith.emplace_back(1); q_4.emplace_back(in.d_scaling); - q_fixed_base.emplace_back(0); q_sort.emplace_back(0); q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); @@ -259,7 +255,6 @@ void UltraComposer::create_balanced_add_gate(const add_quad& in) q_c.emplace_back(in.const_scaling); q_arith.emplace_back(1); q_4.emplace_back(in.d_scaling); - q_fixed_base.emplace_back(0); q_sort.emplace_back(0); q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); @@ -301,7 +296,6 @@ void UltraComposer::create_mul_gate(const mul_triple& in) q_c.emplace_back(in.const_scaling); q_arith.emplace_back(1); q_4.emplace_back(0); - q_fixed_base.emplace_back(0); q_sort.emplace_back(0); q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); @@ -331,7 +325,6 @@ void UltraComposer::create_bool_gate(const uint32_t variable_index) q_arith.emplace_back(1); q_4.emplace_back(0); - q_fixed_base.emplace_back(0); q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); q_aux.emplace_back(0); @@ -361,75 +354,12 @@ void UltraComposer::create_poly_gate(const poly_triple& in) q_arith.emplace_back(1); q_4.emplace_back(0); - q_fixed_base.emplace_back(0); q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); q_aux.emplace_back(0); ++n; } -// adds a grumpkin point, from a 2-bit lookup table, into an accumulator point -void UltraComposer::create_fixed_group_add_gate(const fixed_group_add_quad& in) -{ - ULTRA_SELECTOR_REFS - assert_valid_variables({ in.a, in.b, in.c, in.d }); - - w_l.emplace_back(in.a); - w_r.emplace_back(in.b); - w_o.emplace_back(in.c); - w_4.emplace_back(in.d); - - q_1.emplace_back(in.q_x_1); - q_2.emplace_back(in.q_x_2); - q_3.emplace_back(in.q_y_1); - q_fixed_base.emplace_back(in.q_y_2); - - q_arith.emplace_back(0); - q_4.emplace_back(0); - q_m.emplace_back(0); - q_c.emplace_back(0); - q_lookup_type.emplace_back(0); - q_sort.emplace_back(0); - q_elliptic.emplace_back(0); - q_aux.emplace_back(0); - ++n; -} - -// adds a grumpkin point into an accumulator, while also initializing the accumulator -void UltraComposer::create_fixed_group_add_gate_with_init(const fixed_group_add_quad& in, - const fixed_group_init_quad& init) -{ - ULTRA_SELECTOR_REFS - assert_valid_variables({ in.a, in.b, in.c, in.d }); - - w_l.emplace_back(in.a); - w_r.emplace_back(in.b); - w_o.emplace_back(in.c); - w_4.emplace_back(in.d); - - // Initialization differs slightly with that in TurboComposer. - q_m.emplace_back(init.q_y_1); - q_c.emplace_back(init.q_y_2); - - q_1.emplace_back(in.q_x_1); - q_2.emplace_back(in.q_x_2); - q_3.emplace_back(in.q_y_1); - q_fixed_base.emplace_back(in.q_y_2); - - q_4.emplace_back(0); - q_aux.emplace_back(0); - q_arith.emplace_back(0); - q_lookup_type.emplace_back(0); - q_sort.emplace_back(0); - q_elliptic.emplace_back(0); - - ++n; -} - -void UltraComposer::create_fixed_group_add_gate_final(const add_quad& in) -{ - create_big_add_gate(in); -} /** * @brief Create an elliptic curve addition gate * @@ -481,7 +411,6 @@ void UltraComposer::create_ecc_add_gate(const ecc_add_gate& in) q_2.emplace_back(0); q_m.emplace_back(0); q_c.emplace_back(0); - q_fixed_base.emplace_back(0); q_sort.emplace_back(0); q_lookup_type.emplace_back(0); q_elliptic.emplace_back(1); @@ -500,7 +429,6 @@ void UltraComposer::create_ecc_add_gate(const ecc_add_gate& in) q_c.emplace_back(0); q_arith.emplace_back(0); q_4.emplace_back(0); - q_fixed_base.emplace_back(0); q_sort.emplace_back(0); q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); @@ -530,7 +458,6 @@ void UltraComposer::fix_witness(const uint32_t witness_index, const barretenberg q_c.emplace_back(-witness_value); q_arith.emplace_back(1); q_4.emplace_back(0); - q_fixed_base.emplace_back(0); q_sort.emplace_back(0); q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); @@ -612,7 +539,6 @@ std::shared_ptr UltraComposer::compute_proving_key() ASSERT(n == q_3.size()); ASSERT(n == q_4.size()); ASSERT(n == q_arith.size()); - ASSERT(n == q_fixed_base.size()); ASSERT(n == q_elliptic.size()); ASSERT(n == q_sort.size()); ASSERT(n == q_lookup_type.size()); @@ -884,9 +810,6 @@ UltraProver UltraComposer::create_prover() std::unique_ptr> arithmetic_widget = std::make_unique>(circuit_proving_key.get()); - std::unique_ptr> fixed_base_widget = - std::make_unique>(circuit_proving_key.get()); - std::unique_ptr> sort_widget = std::make_unique>(circuit_proving_key.get()); @@ -900,7 +823,6 @@ UltraProver UltraComposer::create_prover() output_state.random_widgets.emplace_back(std::move(plookup_widget)); output_state.transition_widgets.emplace_back(std::move(arithmetic_widget)); - output_state.transition_widgets.emplace_back(std::move(fixed_base_widget)); output_state.transition_widgets.emplace_back(std::move(sort_widget)); output_state.transition_widgets.emplace_back(std::move(elliptic_widget)); output_state.transition_widgets.emplace_back(std::move(auxiliary_widget)); @@ -932,9 +854,6 @@ UnrolledUltraProver UltraComposer::create_unrolled_prover() std::unique_ptr> arithmetic_widget = std::make_unique>(circuit_proving_key.get()); - std::unique_ptr> fixed_base_widget = - std::make_unique>(circuit_proving_key.get()); - std::unique_ptr> sort_widget = std::make_unique>(circuit_proving_key.get()); @@ -948,7 +867,6 @@ UnrolledUltraProver UltraComposer::create_unrolled_prover() output_state.random_widgets.emplace_back(std::move(plookup_widget)); output_state.transition_widgets.emplace_back(std::move(arithmetic_widget)); - output_state.transition_widgets.emplace_back(std::move(fixed_base_widget)); output_state.transition_widgets.emplace_back(std::move(sort_widget)); output_state.transition_widgets.emplace_back(std::move(elliptic_widget)); output_state.transition_widgets.emplace_back(std::move(auxiliary_widget)); @@ -981,9 +899,6 @@ UnrolledUltraToStandardProver UltraComposer::create_unrolled_ultra_to_standard_p std::unique_ptr> arithmetic_widget = std::make_unique>(circuit_proving_key.get()); - std::unique_ptr> fixed_base_widget = - std::make_unique>(circuit_proving_key.get()); - std::unique_ptr> sort_widget = std::make_unique>(circuit_proving_key.get()); @@ -997,7 +912,6 @@ UnrolledUltraToStandardProver UltraComposer::create_unrolled_ultra_to_standard_p output_state.random_widgets.emplace_back(std::move(plookup_widget)); output_state.transition_widgets.emplace_back(std::move(arithmetic_widget)); - output_state.transition_widgets.emplace_back(std::move(fixed_base_widget)); output_state.transition_widgets.emplace_back(std::move(sort_widget)); output_state.transition_widgets.emplace_back(std::move(elliptic_widget)); output_state.transition_widgets.emplace_back(std::move(auxiliary_widget)); @@ -1016,8 +930,8 @@ UltraVerifier UltraComposer::create_verifier() UltraVerifier output_state(circuit_verification_key, create_manifest(public_inputs.size())); - std::unique_ptr> kate_commitment_scheme = - std::make_unique>(); + std::unique_ptr> kate_commitment_scheme = + std::make_unique>(); output_state.commitment_scheme = std::move(kate_commitment_scheme); @@ -1123,7 +1037,6 @@ plookup::ReadData UltraComposer::create_gates_from_plookup_accumulator q_c.emplace_back((i == (num_lookups - 1) ? 0 : -multi_table.column_3_step_sizes[i + 1])); q_arith.emplace_back(0); q_4.emplace_back(0); - q_fixed_base.emplace_back(0); q_sort.emplace_back(0); q_elliptic.emplace_back(0); q_aux.emplace_back(0); @@ -1364,7 +1277,6 @@ void UltraComposer::create_sort_constraint(const std::vector& variable q_c.emplace_back(0); q_arith.emplace_back(0); q_4.emplace_back(0); - q_fixed_base.emplace_back(0); q_sort.emplace_back(1); q_elliptic.emplace_back(0); q_lookup_type.emplace_back(0); @@ -1383,7 +1295,6 @@ void UltraComposer::create_sort_constraint(const std::vector& variable q_c.emplace_back(0); q_arith.emplace_back(0); q_4.emplace_back(0); - q_fixed_base.emplace_back(0); q_sort.emplace_back(0); q_elliptic.emplace_back(0); q_lookup_type.emplace_back(0); @@ -1417,7 +1328,6 @@ void UltraComposer::create_dummy_constraints(const std::vector& variab q_c.emplace_back(0); q_arith.emplace_back(0); q_4.emplace_back(0); - q_fixed_base.emplace_back(0); q_sort.emplace_back(0); q_elliptic.emplace_back(0); q_lookup_type.emplace_back(0); @@ -1449,7 +1359,6 @@ void UltraComposer::create_sort_constraint_with_edges(const std::vector UltraComposer::decompose_into_default_range_better_for_odd void UltraComposer::apply_aux_selectors(const AUX_SELECTORS type) { ULTRA_SELECTOR_REFS; - q_fixed_base.emplace_back(0); q_aux.emplace_back(type == AUX_SELECTORS::NONE ? 0 : 1); q_sort.emplace_back(0); q_lookup_type.emplace_back(0); @@ -2236,7 +2141,6 @@ std::array UltraComposer::evaluate_non_native_field_addition( q_arith.emplace_back(1); for (size_t i = 0; i < 4; ++i) { - q_fixed_base.emplace_back(0); q_sort.emplace_back(0); q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); @@ -2363,7 +2267,6 @@ std::array UltraComposer::evaluate_non_native_field_subtraction( q_arith.emplace_back(1); for (size_t i = 0; i < 4; ++i) { - q_fixed_base.emplace_back(0); q_sort.emplace_back(0); q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); diff --git a/cpp/src/aztec/plonk/composer/ultra_composer.hpp b/cpp/src/aztec/plonk/composer/ultra_composer.hpp index 364cec9f3c..c9821727dc 100644 --- a/cpp/src/aztec/plonk/composer/ultra_composer.hpp +++ b/cpp/src/aztec/plonk/composer/ultra_composer.hpp @@ -11,7 +11,7 @@ class UltraComposer : public ComposerBase { public: static constexpr ComposerType type = ComposerType::PLOOKUP; - static constexpr MerkleHashType merkle_hash_type = MerkleHashType::FIXED_BASE_PEDERSEN; + static constexpr MerkleHashType merkle_hash_type = MerkleHashType::LOOKUP_PEDERSEN; static constexpr size_t NUM_RESERVED_GATES = 4; // This must be >= num_roots_cut_out_of_vanishing_polynomial // See the comment in plonk/proof_system/prover/prover.cpp // ProverBase::compute_quotient_commitments() for why 4 exactly. @@ -135,7 +135,7 @@ class UltraComposer : public ComposerBase { std::vector records; }; - enum UltraSelectors { QM, QC, Q1, Q2, Q3, Q4, QARITH, QFIXED, QSORT, QELLIPTIC, QAUX, QLOOKUPTYPE, NUM }; + enum UltraSelectors { QM, QC, Q1, Q2, Q3, Q4, QARITH, QSORT, QELLIPTIC, QAUX, QLOOKUPTYPE, NUM }; UltraComposer(); UltraComposer(std::string const& crs_path, const size_t size_hint = 0); @@ -170,10 +170,6 @@ class UltraComposer : public ComposerBase { void create_mul_gate(const mul_triple& in) override; void create_bool_gate(const uint32_t a) override; void create_poly_gate(const poly_triple& in) override; - void create_fixed_group_add_gate(const fixed_group_add_quad& in); - void create_fixed_group_add_gate_with_init(const fixed_group_add_quad& in, const fixed_group_init_quad& init); - void create_fixed_group_add_gate_final(const add_quad& in); - void create_ecc_add_gate(const ecc_add_gate& in); void fix_witness(const uint32_t witness_index, const barretenberg::fr& witness_value); @@ -495,89 +491,14 @@ class UltraComposer : public ComposerBase { * Program Manifests **/ + /** + * @brief Create a manifest object + * + * @note UltraPlonk manifest does not use linearisation trick + * @param num_public_inputs + * @return transcript::Manifest + */ static transcript::Manifest create_manifest(const size_t num_public_inputs) - { - // add public inputs.... - constexpr size_t g1_size = 64; - constexpr size_t fr_size = 32; - const size_t public_input_size = fr_size * num_public_inputs; - const transcript::Manifest output = transcript::Manifest( - - { transcript::Manifest::RoundManifest( - { { "circuit_size", 4, true }, { "public_input_size", 4, true } }, "init", 1), - - transcript::Manifest::RoundManifest({ { "public_inputs", public_input_size, false }, - { "W_1", g1_size, false }, - { "W_2", g1_size, false }, - { "W_3", g1_size, false } }, - "eta", - 1), - - transcript::Manifest::RoundManifest({ { "W_4", g1_size, false }, { "S", g1_size, false } }, "beta", 2), - - transcript::Manifest::RoundManifest( - { { "Z_PERM", g1_size, false }, { "Z_LOOKUP", g1_size, false } }, "alpha", 1), - - transcript::Manifest::RoundManifest({ { "T_1", g1_size, false }, - { "T_2", g1_size, false }, - { "T_3", g1_size, false }, - { "T_4", g1_size, false } }, - "z", - 1), - - transcript::Manifest::RoundManifest( - { - { "w_1", fr_size, false, 0 }, - { "w_2", fr_size, false, 1 }, - { "w_3", fr_size, false, 2 }, - { "w_4", fr_size, false, 3 }, - { "sigma_1", fr_size, false, 4 }, - { "sigma_2", fr_size, false, 5 }, - { "sigma_3", fr_size, false, 6 }, - { "q_arith", fr_size, false, 7 }, - { "q_fixed_base", fr_size, false, 27 }, - { "q_aux", fr_size, false, 26 }, - { "q_1", fr_size, false, 25 }, - { "q_2", fr_size, false, 8 }, - { "q_3", fr_size, false, 9 }, - { "q_4", fr_size, false, 10 }, - { "q_m", fr_size, false, 11 }, - { "q_c", fr_size, false, 12 }, - { "table_value_1", fr_size, false, 13 }, - { "table_value_2", fr_size, false, 14 }, - { "table_value_3", fr_size, false, 15 }, - { "table_value_4", fr_size, false, 16 }, - { "table_type", fr_size, false, 17 }, - { "s", fr_size, false, 18 }, - { "z_lookup", fr_size, false, 19 }, - { "id_1", fr_size, false, 21 }, - { "id_2", fr_size, false, 22 }, - { "id_3", fr_size, false, 23 }, - { "id_4", fr_size, false, 24 }, - { "z_perm_omega", fr_size, false, -1 }, - { "w_1_omega", fr_size, false, 0 }, - { "w_2_omega", fr_size, false, 1 }, - { "w_3_omega", fr_size, false, 2 }, - { "w_4_omega", fr_size, false, 3 }, - { "table_value_1_omega", fr_size, false, 4 }, - { "table_value_2_omega", fr_size, false, 5 }, - { "table_value_3_omega", fr_size, false, 6 }, - { "table_value_4_omega", fr_size, false, 7 }, - { "s_omega", fr_size, false, 8 }, - { "z_lookup_omega", fr_size, false, 9 }, - }, - "nu", - ULTRA_UNROLLED_MANIFEST_SIZE - 3, - true), - - transcript::Manifest::RoundManifest( - { { "PI_Z", g1_size, false }, { "PI_Z_OMEGA", g1_size, false } }, "separator", 1) }); - - return output; - } - - // @note 'unrolled' means "don't use linearisation techniques from the plonk paper". - static transcript::Manifest create_unrolled_manifest(const size_t num_public_inputs) { // add public inputs.... constexpr size_t g1_size = 64; @@ -652,7 +573,6 @@ class UltraComposer : public ComposerBase { { "q_sort", fr_size, false, 14 }, // * { "q_elliptic", fr_size, false, 15 }, // * { "q_aux", fr_size, false, 16 }, - { "q_fixed_base", fr_size, false, 30 }, { "sigma_1", fr_size, false, 17 }, { "sigma_2", fr_size, false, 18 }, { "sigma_3", fr_size, false, 19 }, @@ -693,5 +613,22 @@ class UltraComposer : public ComposerBase { return output; } + + // @note 'unrolled' means "don't use linearisation techniques from the plonk paper". + /** + * @brief Create a unrolled manifest object + * + * @note UP rolled/unrolled manifests are the same. Difference between regulur && unrolled Prover/Verifier is that + * unrolled Prover/Verifier uses 16-byte challenges and a SNARK-friendly hash algorithm to generate challenges. + * (i.e. unrolled Prover/Verifier is used in recursive setting) + * + * TODO: remove linearisation trick entirely from barretenberg and relabel `unrolled` to `recursive`! + * @param num_public_inputs + * @return transcript::Manifest + */ + static transcript::Manifest create_unrolled_manifest(const size_t num_public_inputs) + { + return create_manifest(num_public_inputs); + } }; } // namespace waffle diff --git a/cpp/src/aztec/plonk/proof_system/types/program_settings.hpp b/cpp/src/aztec/plonk/proof_system/types/program_settings.hpp index 9bae0b38c1..bc7156f317 100644 --- a/cpp/src/aztec/plonk/proof_system/types/program_settings.hpp +++ b/cpp/src/aztec/plonk/proof_system/types/program_settings.hpp @@ -155,7 +155,6 @@ class ultra_verifier_settings : public ultra_settings { typedef barretenberg::g1 g1; typedef transcript::StandardTranscript Transcript; typedef VerifierPlookupArithmeticWidget PlookupArithmeticWidget; - typedef VerifierUltraFixedBaseWidget UltraFixedBaseWidget; typedef VerifierGenPermSortWidget GenPermSortWidget; typedef VerifierTurboLogicWidget TurboLogicWidget; typedef VerifierPermutationWidget PermutationWidget; @@ -165,7 +164,7 @@ class ultra_verifier_settings : public ultra_settings { static constexpr size_t num_challenge_bytes = 32; static constexpr transcript::HashType hash_type = transcript::HashType::Keccak256; - static constexpr bool use_linearisation = true; + static constexpr bool use_linearisation = false; static constexpr bool idpolys = true; static fr append_scalar_multiplication_inputs(verification_key* key, @@ -180,8 +179,6 @@ class ultra_verifier_settings : public ultra_settings { key, updated_alpha, transcript, scalars, use_linearisation); updated_alpha = PlookupArithmeticWidget::append_scalar_multiplication_inputs(key, updated_alpha, transcript, scalars); - updated_alpha = - UltraFixedBaseWidget::append_scalar_multiplication_inputs(key, updated_alpha, transcript, scalars); updated_alpha = GenPermSortWidget::append_scalar_multiplication_inputs(key, updated_alpha, transcript, scalars); updated_alpha = EllipticWidget::append_scalar_multiplication_inputs(key, updated_alpha, transcript, scalars); updated_alpha = @@ -201,8 +198,6 @@ class ultra_verifier_settings : public ultra_settings { key, updated_alpha_base, transcript, r_0, use_linearisation); updated_alpha_base = PlookupArithmeticWidget::compute_quotient_evaluation_contribution(key, updated_alpha_base, transcript, r_0); - updated_alpha_base = - UltraFixedBaseWidget::compute_quotient_evaluation_contribution(key, updated_alpha_base, transcript, r_0); updated_alpha_base = GenPermSortWidget::compute_quotient_evaluation_contribution(key, updated_alpha_base, transcript, r_0); updated_alpha_base = @@ -281,8 +276,6 @@ class unrolled_ultra_verifier_settings : public unrolled_ultra_settings { typedef transcript::StandardTranscript Transcript; typedef VerifierPlookupArithmeticWidget PlookupArithmeticWidget; - typedef VerifierUltraFixedBaseWidget - UltraFixedBaseWidget; typedef VerifierGenPermSortWidget GenPermSortWidget; typedef VerifierTurboLogicWidget TurboLogicWidget; typedef VerifierPermutationWidget PermutationWidget; @@ -307,8 +300,6 @@ class unrolled_ultra_verifier_settings : public unrolled_ultra_settings { key, updated_alpha, transcript, scalars, use_linearisation); updated_alpha = PlookupArithmeticWidget::append_scalar_multiplication_inputs(key, updated_alpha, transcript, scalars); - updated_alpha = - UltraFixedBaseWidget::append_scalar_multiplication_inputs(key, updated_alpha, transcript, scalars); updated_alpha = GenPermSortWidget::append_scalar_multiplication_inputs(key, updated_alpha, transcript, scalars); updated_alpha = EllipticWidget::append_scalar_multiplication_inputs(key, updated_alpha, transcript, scalars); updated_alpha = @@ -328,8 +319,6 @@ class unrolled_ultra_verifier_settings : public unrolled_ultra_settings { key, updated_alpha_base, transcript, r_0, use_linearisation); updated_alpha_base = PlookupArithmeticWidget::compute_quotient_evaluation_contribution(key, updated_alpha_base, transcript, r_0); - updated_alpha_base = - UltraFixedBaseWidget::compute_quotient_evaluation_contribution(key, updated_alpha_base, transcript, r_0); updated_alpha_base = GenPermSortWidget::compute_quotient_evaluation_contribution(key, updated_alpha_base, transcript, r_0); updated_alpha_base = diff --git a/cpp/src/aztec/plonk/proof_system/types/prover_settings.hpp b/cpp/src/aztec/plonk/proof_system/types/prover_settings.hpp index 7ed739a95d..bd620fd53e 100644 --- a/cpp/src/aztec/plonk/proof_system/types/prover_settings.hpp +++ b/cpp/src/aztec/plonk/proof_system/types/prover_settings.hpp @@ -60,7 +60,7 @@ class ultra_settings : public settings_base { static constexpr uint64_t wire_shift_settings = 0b1111; static constexpr uint32_t permutation_shift = 30; static constexpr uint32_t permutation_mask = 0xC0000000; - static constexpr bool use_linearisation = true; + static constexpr bool use_linearisation = false; static constexpr size_t num_roots_cut_out_of_vanishing_polynomial = 4; static constexpr bool is_plookup = true; }; diff --git a/cpp/src/aztec/plonk/proof_system/widgets/transition_widgets/plookup_arithmetic_widget.hpp b/cpp/src/aztec/plonk/proof_system/widgets/transition_widgets/plookup_arithmetic_widget.hpp index cd809c4f39..0ba06fb00f 100644 --- a/cpp/src/aztec/plonk/proof_system/widgets/transition_widgets/plookup_arithmetic_widget.hpp +++ b/cpp/src/aztec/plonk/proof_system/widgets/transition_widgets/plookup_arithmetic_widget.hpp @@ -126,7 +126,7 @@ template class PlookupArith Getters::template get_value(polynomials, i); const Field& alpha_base = challenges.alpha_powers[0]; - const Field& alpha = challenges.alpha_powers[1]; + const Field& alpha = challenges.elements[ChallengeIndex::ALPHA]; // basic arithmetic gate identity // (w_1 . w_2 . q_m) + (w_1 . q_1) + (w_2 . q_2) + (w_3 . q_3) + (w_4 . q_4) + q_c = 0 diff --git a/cpp/src/aztec/proof_system/types/polynomial_manifest.hpp b/cpp/src/aztec/proof_system/types/polynomial_manifest.hpp index 8cddc3d876..4ccb3479e9 100644 --- a/cpp/src/aztec/proof_system/types/polynomial_manifest.hpp +++ b/cpp/src/aztec/proof_system/types/polynomial_manifest.hpp @@ -137,39 +137,38 @@ static constexpr PolynomialDescriptor turbo_polynomial_manifest[TURBO_UNROLLED_M PolynomialDescriptor("SIGMA_4", "sigma_4", true, false, PERMUTATION, SIGMA_4), // }; -static constexpr size_t ULTRA_UNROLLED_MANIFEST_SIZE = 31; +static constexpr size_t ULTRA_UNROLLED_MANIFEST_SIZE = 30; static constexpr PolynomialDescriptor ultra_polynomial_manifest[ULTRA_UNROLLED_MANIFEST_SIZE]{ - PolynomialDescriptor("W_1", "w_1", false, true, WITNESS, W_1), // - PolynomialDescriptor("W_2", "w_2", false, true, WITNESS, W_2), // - PolynomialDescriptor("W_3", "w_3", false, true, WITNESS, W_3), // - PolynomialDescriptor("W_4", "w_4", false, true, WITNESS, W_4), // - PolynomialDescriptor("S", "s", false, true, WITNESS, S), // - PolynomialDescriptor("Z_PERM", "z_perm", true, true, WITNESS, Z), // - PolynomialDescriptor("Z_LOOKUP", "z_lookup", false, true, WITNESS, Z_LOOKUP), // - PolynomialDescriptor("Q_1", "q_1", false, false, SELECTOR, Q_1), // - PolynomialDescriptor("Q_2", "q_2", false, false, SELECTOR, Q_2), // - PolynomialDescriptor("Q_3", "q_3", false, false, SELECTOR, Q_3), // - PolynomialDescriptor("Q_4", "q_4", false, false, SELECTOR, Q_4), // - PolynomialDescriptor("Q_M", "q_m", false, false, SELECTOR, Q_M), // - PolynomialDescriptor("Q_C", "q_c", false, false, SELECTOR, Q_C), // - PolynomialDescriptor("Q_ARITHMETIC", "q_arith", false, false, SELECTOR, Q_ARITHMETIC), // - PolynomialDescriptor("Q_FIXED_BASE", "q_fixed_base", false, false, SELECTOR, Q_FIXED_BASE), // - PolynomialDescriptor("Q_SORT", "q_sort", true, false, SELECTOR, Q_SORT), // - PolynomialDescriptor("Q_ELLIPTIC", "q_elliptic", true, false, SELECTOR, Q_ELLIPTIC), // - PolynomialDescriptor("Q_AUX", "q_aux", false, false, SELECTOR, Q_AUX), // - PolynomialDescriptor("SIGMA_1", "sigma_1", false, false, PERMUTATION, SIGMA_1), // - PolynomialDescriptor("SIGMA_2", "sigma_2", false, false, PERMUTATION, SIGMA_2), // - PolynomialDescriptor("SIGMA_3", "sigma_3", false, false, PERMUTATION, SIGMA_3), // - PolynomialDescriptor("SIGMA_4", "sigma_4", true, false, PERMUTATION, SIGMA_4), // - PolynomialDescriptor("TABLE_1", "table_value_1", false, true, SELECTOR, TABLE_1), // - PolynomialDescriptor("TABLE_2", "table_value_2", false, true, SELECTOR, TABLE_2), // - PolynomialDescriptor("TABLE_3", "table_value_3", false, true, SELECTOR, TABLE_3), // - PolynomialDescriptor("TABLE_4", "table_value_4", false, true, SELECTOR, TABLE_4), // - PolynomialDescriptor("TABLE_TYPE", "table_type", false, false, SELECTOR, TABLE_TYPE), // - PolynomialDescriptor("ID_1", "id_1", false, false, PERMUTATION, ID_1), // - PolynomialDescriptor("ID_2", "id_2", false, false, PERMUTATION, ID_2), // - PolynomialDescriptor("ID_3", "id_3", false, false, PERMUTATION, ID_3), // - PolynomialDescriptor("ID_4", "id_4", false, false, PERMUTATION, ID_4), // + PolynomialDescriptor("W_1", "w_1", false, true, WITNESS, W_1), // + PolynomialDescriptor("W_2", "w_2", false, true, WITNESS, W_2), // + PolynomialDescriptor("W_3", "w_3", false, true, WITNESS, W_3), // + PolynomialDescriptor("W_4", "w_4", false, true, WITNESS, W_4), // + PolynomialDescriptor("S", "s", false, true, WITNESS, S), // + PolynomialDescriptor("Z_PERM", "z_perm", false, true, WITNESS, Z), // + PolynomialDescriptor("Z_LOOKUP", "z_lookup", false, true, WITNESS, Z_LOOKUP), // + PolynomialDescriptor("Q_1", "q_1", false, false, SELECTOR, Q_1), // + PolynomialDescriptor("Q_2", "q_2", false, false, SELECTOR, Q_2), // + PolynomialDescriptor("Q_3", "q_3", false, false, SELECTOR, Q_3), // + PolynomialDescriptor("Q_4", "q_4", false, false, SELECTOR, Q_4), // + PolynomialDescriptor("Q_M", "q_m", false, false, SELECTOR, Q_M), // + PolynomialDescriptor("Q_C", "q_c", false, false, SELECTOR, Q_C), // + PolynomialDescriptor("Q_ARITHMETIC", "q_arith", false, false, SELECTOR, Q_ARITHMETIC), // + PolynomialDescriptor("Q_SORT", "q_sort", false, false, SELECTOR, Q_SORT), // + PolynomialDescriptor("Q_ELLIPTIC", "q_elliptic", false, false, SELECTOR, Q_ELLIPTIC), // + PolynomialDescriptor("Q_AUX", "q_aux", false, false, SELECTOR, Q_AUX), // + PolynomialDescriptor("SIGMA_1", "sigma_1", false, false, PERMUTATION, SIGMA_1), // + PolynomialDescriptor("SIGMA_2", "sigma_2", false, false, PERMUTATION, SIGMA_2), // + PolynomialDescriptor("SIGMA_3", "sigma_3", false, false, PERMUTATION, SIGMA_3), // + PolynomialDescriptor("SIGMA_4", "sigma_4", false, false, PERMUTATION, SIGMA_4), // + PolynomialDescriptor("TABLE_1", "table_value_1", false, true, SELECTOR, TABLE_1), // + PolynomialDescriptor("TABLE_2", "table_value_2", false, true, SELECTOR, TABLE_2), // + PolynomialDescriptor("TABLE_3", "table_value_3", false, true, SELECTOR, TABLE_3), // + PolynomialDescriptor("TABLE_4", "table_value_4", false, true, SELECTOR, TABLE_4), // + PolynomialDescriptor("TABLE_TYPE", "table_type", false, false, SELECTOR, TABLE_TYPE), // + PolynomialDescriptor("ID_1", "id_1", false, false, PERMUTATION, ID_1), // + PolynomialDescriptor("ID_2", "id_2", false, false, PERMUTATION, ID_2), // + PolynomialDescriptor("ID_3", "id_3", false, false, PERMUTATION, ID_3), // + PolynomialDescriptor("ID_4", "id_4", false, false, PERMUTATION, ID_4), // }; // TODO(Cody): Get this right; just using for now to extract names. diff --git a/cpp/src/aztec/proof_system/verification_key/sol_gen.hpp b/cpp/src/aztec/proof_system/verification_key/sol_gen.hpp index 713a335933..93ebf37b05 100644 --- a/cpp/src/aztec/proof_system/verification_key/sol_gen.hpp +++ b/cpp/src/aztec/proof_system/verification_key/sol_gen.hpp @@ -4,7 +4,9 @@ namespace waffle { * Write a solidity file containing the vk params to the given stream. * Uses StandardPlonk **/ -inline void output_vk_sol(std::ostream& os, std::shared_ptr const& key, std::string const& class_name) +inline void output_vk_sol_standard(std::ostream& os, + std::shared_ptr const& key, + std::string const& class_name) { const auto print_u256 = [&](const std::string& offset, const barretenberg::fr& element, const std::string& name) { os << " mstore(add(_vk, " << offset << "), " << element << ") // " << name << std::endl; @@ -57,4 +59,108 @@ inline void output_vk_sol(std::ostream& os, std::shared_ptr co os << std::flush; } + + +/** + * Write a solidity file containing the vk params to the given stream. + * Uses UltraPlonk + **/ +inline void output_vk_sol_ultra(std::ostream& os, std::shared_ptr const& key, std::string const& class_name) +{ + const auto print_u256 = [&](const std::string& offset, const barretenberg::fr& element, const std::string& name) { + os << " mstore(add(_vk, " << offset << "), " << element << ") // " << name << std::endl; + }; + + const auto print_g1 = [&](const std::string& offsetX, + const std::string& offsetY, + const barretenberg::g1::affine_element& element, + const std::string& name) { + os << " mstore(add(_vk, " << offsetX << "), " << element.x << ") // " << name << ".x" << std::endl; + os << " mstore(add(_vk, " << offsetY << "), " << element.y << ") // " << name << ".y" << std::endl; + }; + + // clang-format off + os << + "// Verification Key Hash: " << key->sha256_hash() << "\n" + "// SPDX-License-Identifier: Apache-2.0\n" + "// Copyright 2022 Aztec\n" + "pragma solidity >=0.8.4;\n" + "\n" + "library " << class_name << " {\n" + " function verificationKeyHash() internal pure returns(bytes32) {\n" + " return 0x" << key->sha256_hash() << ";\n" + " }\n\n" + " function loadVerificationKey(uint256 _vk, uint256 _omegaInverseLoc) internal pure {\n" + " assembly {\n"; + print_u256("0x00", key->domain.size, "vk.circuit_size"); + print_u256("0x20", key->num_public_inputs, "vk.num_inputs"); + print_u256("0x40", key->domain.root, "vk.work_root"); + print_u256("0x60", key->domain.domain_inverse, "vk.domain_inverse"); + print_g1("0x80", "0xa0", key->constraint_selectors.at("Q_1"), "vk.Q1"); + print_g1("0xc0", "0xe0", key->constraint_selectors.at("Q_2"), "vk.Q2"); + print_g1("0x100", "0x120", key->constraint_selectors.at("Q_3"), "vk.Q3"); + print_g1("0x140", "0x160", key->constraint_selectors.at("Q_4"), "vk.Q4"); + print_g1("0x180", "0x1a0", key->constraint_selectors.at("Q_M"), "vk.Q_M"); + print_g1("0x1c0", "0x1e0", key->constraint_selectors.at("Q_C"), "vk.Q_C"); + print_g1("0x200", "0x220", key->constraint_selectors.at("Q_ARITHMETIC"), "vk.Q_ARITHMETIC"); + print_g1("0x240", "0x260", key->constraint_selectors.at("Q_SORT"), "vk.QSORT"); + print_g1("0x280", "0x2a0", key->constraint_selectors.at("Q_ELLIPTIC"), "vk.Q_ELLIPTIC"); + print_g1("0x2c0", "0x2e0", key->constraint_selectors.at("Q_AUX"), "vk.Q_AUX"); + print_g1("0x300", "0x320", key->permutation_selectors.at("SIGMA_1"), "vk.SIGMA1"); + print_g1("0x340", "0x360", key->permutation_selectors.at("SIGMA_2"), "vk.SIGMA2"); + print_g1("0x380", "0x3a0", key->permutation_selectors.at("SIGMA_3"), "vk.SIGMA3"); + print_g1("0x3c0", "0x3e0", key->permutation_selectors.at("SIGMA_4"), "vk.SIGMA4"); + print_g1("0x400", "0x420", key->constraint_selectors.at("TABLE_1"), "vk.TABLE1"); + print_g1("0x440", "0x460", key->constraint_selectors.at("TABLE_2"), "vk.TABLE2"); + print_g1("0x480", "0x4a0", key->constraint_selectors.at("TABLE_3"), "vk.TABLE3"); + print_g1("0x4c0", "0x4e0", key->constraint_selectors.at("TABLE_4"), "vk.TABLE4"); + print_g1("0x500", "0x520", key->constraint_selectors.at("TABLE_TYPE"), "vk.TABLE_TYPE"); + print_g1("0x540", "0x560", key->permutation_selectors.at("ID_1"), "vk.ID1"); + print_g1("0x580", "0x5a0", key->permutation_selectors.at("ID_2"), "vk.ID2"); + print_g1("0x5c0", "0x5e0", key->permutation_selectors.at("ID_3"), "vk.ID3"); + print_g1("0x600", "0x620", key->permutation_selectors.at("ID_4"), "vk.ID4"); + os << + " mstore(add(_vk, 0x640), " << (key->contains_recursive_proof ? "0x01" : "0x00") << ") // vk.contains_recursive_proof\n" + " mstore(add(_vk, 0x660), " << (key->contains_recursive_proof ? key->recursive_proof_public_input_indices[0] : 0) << ") // vk.recursive_proof_public_input_indices\n" + " mstore(add(_vk, 0x680), " << key->reference_string->get_g2x().x.c1 << ") // vk.g2_x.X.c1 \n" + " mstore(add(_vk, 0x6a0), " << key->reference_string->get_g2x().x.c0 << ") // vk.g2_x.X.c0 \n" + " mstore(add(_vk, 0x6c0), " << key->reference_string->get_g2x().y.c1 << ") // vk.g2_x.Y.c1 \n" + " mstore(add(_vk, 0x6e0), " << key->reference_string->get_g2x().y.c0 << ") // vk.g2_x.Y.c0 \n" + " mstore(_omegaInverseLoc, " << key->domain.root_inverse << ") // vk.work_root_inverse\n" + " }\n" + " }\n" + "}\n"; + + os << std::flush; +} + +/** + * @brief Wrapper method to output a solidity verification key. Composer type determined from key + * + * @param os + * @param key + * @param class_name + */ +inline void output_vk_sol(std::ostream& os, std::shared_ptr const& key, std::string const& class_name) +{ + waffle::ComposerType composer_type = static_cast(key->composer_type); + switch (composer_type) { + case waffle::ComposerType::STANDARD: { + return output_vk_sol_standard(os, key, class_name); + break; + } + // case waffle::ComposerType::TURBO: { + // return output_vk_sol_turbo(os, key, class_name); + // break; + // } + case waffle::ComposerType::PLOOKUP: { + return output_vk_sol_ultra(os, key, class_name); + break; + } + default: { + std::cerr << "waffle::output_vk_sol unsupported composer type. Defaulting to standard composer" << std::endl; + return output_vk_sol_standard(os, key, class_name); + } + } +} } // namespace waffle \ No newline at end of file diff --git a/cpp/src/aztec/stdlib/hash/pedersen/pedersen.cpp b/cpp/src/aztec/stdlib/hash/pedersen/pedersen.cpp index d345333aa5..c10a027f89 100644 --- a/cpp/src/aztec/stdlib/hash/pedersen/pedersen.cpp +++ b/cpp/src/aztec/stdlib/hash/pedersen/pedersen.cpp @@ -1,5 +1,6 @@ #include "pedersen.hpp" #include "pedersen_plookup.hpp" +#include "pedersen_gates.hpp" #include #include @@ -195,6 +196,7 @@ point pedersen::hash_single(const field_t& in, * * where x_{α,i} is decided based on the corresponding quad value. */ + pedersen_gates gates(ctx); fr x_alpha = accumulator_offset; std::vector accumulator_witnesses; for (size_t i = 0; i < num_quads; ++i) { @@ -221,7 +223,7 @@ point pedersen::hash_single(const field_t& in, round_quad.q_y_2 = ladder[i + 1].q_y_2; if (i > 0) { - ctx->create_fixed_group_add_gate(round_quad); + gates.create_fixed_group_add_gate(round_quad); } else { if constexpr (C::type == waffle::PLOOKUP && C::merkle_hash_type == waffle::MerkleHashType::FIXED_BASE_PEDERSEN) { @@ -255,7 +257,7 @@ point pedersen::hash_single(const field_t& in, .const_scaling = init_quad.q_x_2 }; ctx->create_big_mul_gate(x_init_quad); } - ctx->create_fixed_group_add_gate_with_init(round_quad, init_quad); + gates.create_fixed_group_add_gate_with_init(round_quad, init_quad); }; accumulator_witnesses.push_back(round_quad.d); @@ -272,7 +274,7 @@ point pedersen::hash_single(const field_t& in, fr::zero(), fr::zero(), fr::zero() }; - ctx->create_fixed_group_add_gate_final(add_quad); + gates.create_fixed_group_add_gate_final(add_quad); accumulator_witnesses.push_back(add_quad.d); point result; @@ -516,11 +518,6 @@ field_t pedersen::compress_unsafe(const field_t& in_left, const size_t hash_index, const bool validate_input_is_in_field) { - if constexpr (C::type == waffle::ComposerType::PLOOKUP && - C::merkle_hash_type == waffle::MerkleHashType::LOOKUP_PEDERSEN) { - return pedersen_plookup::compress({ in_left, in_right }); - } - std::vector accumulators; generator_index_t index_1 = { hash_index, 0 }; generator_index_t index_2 = { hash_index, 1 }; @@ -531,11 +528,6 @@ field_t pedersen::compress_unsafe(const field_t& in_left, template point pedersen::commit(const std::vector& inputs, const size_t hash_index) { - if constexpr (C::type == waffle::ComposerType::PLOOKUP && - C::merkle_hash_type == waffle::MerkleHashType::LOOKUP_PEDERSEN) { - return pedersen_plookup::commit(inputs, hash_index); - } - std::vector to_accumulate; for (size_t i = 0; i < inputs.size(); ++i) { generator_index_t index = { hash_index, i }; @@ -546,11 +538,6 @@ template point pedersen::commit(const std::vector& i template field_t pedersen::compress(const std::vector& inputs, const size_t hash_index) { - if constexpr (C::type == waffle::ComposerType::PLOOKUP && - C::merkle_hash_type == waffle::MerkleHashType::LOOKUP_PEDERSEN) { - return pedersen_plookup::compress(inputs, hash_index); - } - return commit(inputs, hash_index).x; } diff --git a/cpp/src/aztec/stdlib/hash/pedersen/pedersen_gates.hpp b/cpp/src/aztec/stdlib/hash/pedersen/pedersen_gates.hpp new file mode 100644 index 0000000000..d3b8c955ec --- /dev/null +++ b/cpp/src/aztec/stdlib/hash/pedersen/pedersen_gates.hpp @@ -0,0 +1,315 @@ +#pragma once +#include +#include "../../primitives/composers/composers_fwd.hpp" +#include "../../primitives/field/field.hpp" +#include "../../primitives/point/point.hpp" +#include "../../primitives/byte_array/byte_array.hpp" + +namespace plonk { +namespace stdlib { + +/** + * @brief Creates constraints required for TurboPlonk pedersen hash algorithm + * (see https://hackmd.io/@aztec-network/S1mRod9wF?type=view for details) + * + * StandardPlonk and UltraPlonk do not have support the custom TurboPlonk pedersen hash gate. + * This class reduces the TP gate to a sequence of regular arithmetic gates for compatability purposes. + * + * N.B. wherever possible, UltraPlonk should use pedersen_plookup as it is MUCH more efficient! + * pedersen_plookup produces different hash outputs to the TurboPlonk pedersen hash, use this if interoperability + * between proof systems is required + * @tparam Composer + */ +template class pedersen_gates { + public: + using fixed_group_add_quad = waffle::fixed_group_add_quad; + using fixed_group_init_quad = waffle::fixed_group_init_quad; + using add_quad = waffle::add_quad; + using ComposerType = waffle::ComposerType; + + Composer* context; + fixed_group_add_quad previous_add_quad; + + pedersen_gates(Composer* input_context = nullptr) + : context(input_context) + {} + + void create_fixed_group_add_gate(const fixed_group_add_quad& in) + { + if constexpr (Composer::type == ComposerType::TURBO) { + context->create_fixed_group_add_gate(in); + } else { + + context->assert_valid_variables({ in.a, in.b, in.c, in.d }); + + auto row_1 = previous_add_quad; + auto row_2 = in; + previous_add_quad = in; + + fr a_1 = context->get_variable(row_1.d); + fr a_2 = context->get_variable(row_2.d); + fr x_1 = context->get_variable(row_1.a); + fr y_1 = context->get_variable(row_1.b); + fr x_2 = context->get_variable(row_2.a); + fr y_2 = context->get_variable(row_2.b); + fr x_alpha = context->get_variable(row_2.c); + + fr q_x_alpha_1 = row_1.q_x_1; + fr q_x_alpha_2 = row_1.q_x_2; + fr q_y_alpha_1 = row_1.q_y_1; + fr q_y_alpha_2 = row_1.q_y_2; + + uint32_t a_1_idx = row_1.d; + uint32_t a_2_idx = row_2.d; + uint32_t x_1_idx = row_1.a; + uint32_t y_1_idx = row_1.b; + uint32_t x_2_idx = row_2.a; + uint32_t y_2_idx = row_2.b; + uint32_t x_alpha_idx = row_2.c; + + // add variable δ = a_2 - 4a_1 + fr delta = a_2 - (a_1 + a_1 + a_1 + a_1); + uint32_t delta_idx = context->add_variable(delta); + context->create_add_gate({ .a = a_2_idx, + .b = a_1_idx, + .c = delta_idx, + .a_scaling = 1, + .b_scaling = -4, + .c_scaling = -1, + .const_scaling = 0 }); + + // constraint: (δ + 3)(δ + 1)(δ - 1)(δ - 3) + // (δ + 3)(δ + 1)(δ - 1)(δ - 3) = (δ^2 - 9)(δ^2 - 1)=0 + // // first: (δ^2 - δ_sqr = 0) + fr delta_sqr = delta * delta; + uint32_t delta_sqr_idx = context->add_variable(delta_sqr); + context->create_mul_gate({ .a = delta_idx, + .b = delta_idx, + .c = delta_sqr_idx, + .mul_scaling = 1, + .c_scaling = -1, + .const_scaling = 0 }); + // // next (δ^2 - 9)( δ^2 - 1) = δ^2*δ^2 - 10 * δ^2 + 9 = 0 + context->create_mul_gate({ .a = delta_sqr_idx, + .b = delta_sqr_idx, + .c = delta_sqr_idx, + .mul_scaling = 1, + .c_scaling = -10, + .const_scaling = 9 }); + + // validate correctness of x_ɑ + // constraint: (δ^2) * q_x_ɑ,1 + q_x_ɑ,2 - x,ɑ = 0 + context->create_add_gate({ .a = delta_sqr_idx, + .b = x_alpha_idx, + .c = context->zero_idx, + .a_scaling = q_x_alpha_1, + .b_scaling = -1, + .c_scaling = 0, + .const_scaling = q_x_alpha_2 }); + + // compute y_alpha using lookup formula, instantiate as witness and validate + fr y_alpha = (x_alpha * q_y_alpha_1 + q_y_alpha_2) * delta; + uint32_t y_alpha_idx = context->add_variable(y_alpha); + context->create_poly_gate({ .a = delta_idx, + .b = x_alpha_idx, + .c = y_alpha_idx, + .q_m = q_y_alpha_1, + .q_l = q_y_alpha_2, + .q_r = 0, + .q_o = -1, + .q_c = 0 }); + + // show that (x_1, y_1) + (x_ɑ, y_ɑ) = (x_2, y_2) in 11 gates + // // 4 gates to compute commonly used expressions + // // // 2 differences: + fr diff_x_alpha_x_1 = x_alpha - x_1; + uint32_t diff_x_alpha_x_1_idx = context->add_variable(diff_x_alpha_x_1); + context->create_add_gate({ .a = diff_x_alpha_x_1_idx, + .b = x_1_idx, + .c = x_alpha_idx, + .a_scaling = 1, + .b_scaling = 1, + .c_scaling = -1, + .const_scaling = 0 }); + + fr diff_y_alpha_y_1 = y_alpha - y_1; + uint32_t diff_y_alpha_y_1_idx = context->add_variable(diff_y_alpha_y_1); + context->create_add_gate({ .a = diff_y_alpha_y_1_idx, + .b = y_1_idx, + .c = y_alpha_idx, + .a_scaling = 1, + .b_scaling = 1, + .c_scaling = -1, + .const_scaling = 0 }); + + // // // now the squares of these 2 differences + fr diff_x_alpha_x_1_sqr = diff_x_alpha_x_1 * diff_x_alpha_x_1; + uint32_t diff_x_alpha_x_1_sqr_idx = context->add_variable(diff_x_alpha_x_1_sqr); + context->create_mul_gate({ .a = diff_x_alpha_x_1_idx, + .b = diff_x_alpha_x_1_idx, + .c = diff_x_alpha_x_1_sqr_idx, + .mul_scaling = 1, + .c_scaling = -1, + .const_scaling = 0 }); + + fr diff_y_alpha_y_1_sqr = diff_y_alpha_y_1 * diff_y_alpha_y_1; + uint32_t diff_y_alpha_y_1_sqr_idx = context->add_variable(diff_y_alpha_y_1_sqr); + context->create_mul_gate({ .a = diff_y_alpha_y_1_idx, + .b = diff_y_alpha_y_1_idx, + .c = diff_y_alpha_y_1_sqr_idx, + .mul_scaling = 1, + .c_scaling = -1, + .const_scaling = 0 }); + + // // 3 gates to build identity for x_2 + // // // compute x_2 + x_ɑ + x_1 using 2 poly_gates via create_big_add_gate + fr sum_x_1_2_alpha = x_2 + x_alpha + x_1; + uint32_t sum_x_1_2_alpha_idx = context->add_variable(sum_x_1_2_alpha); + context->create_big_add_gate({ .a = x_2_idx, + .b = x_alpha_idx, + .c = x_1_idx, + .d = sum_x_1_2_alpha_idx, + .a_scaling = 1, + .b_scaling = 1, + .c_scaling = 1, + .d_scaling = -1, + .const_scaling = 0 }); + + // // // constraint: identity for x_2 + context->create_poly_gate({ .a = sum_x_1_2_alpha_idx, + .b = diff_x_alpha_x_1_sqr_idx, + .c = diff_y_alpha_y_1_sqr_idx, + .q_m = 1, + .q_l = 0, + .q_r = 0, + .q_o = -1, + .q_c = 0 }); + + // // 4 gates to build identity for y_2: + // // // 3 auxiliary + fr sum_y_1_y_2 = y_1 + y_2; + uint32_t sum_y_1_y_2_idx = context->add_variable(sum_y_1_y_2); + context->create_add_gate({ .a = y_1_idx, + .b = y_2_idx, + .c = sum_y_1_y_2_idx, + .a_scaling = 1, + .b_scaling = 1, + .c_scaling = -1, + .const_scaling = 0 }); + + fr diff_x_1_x_2 = x_1 - x_2; + uint32_t diff_x_1_x_2_idx = context->add_variable(diff_x_1_x_2); + context->create_add_gate({ .a = diff_x_1_x_2_idx, + .b = x_2_idx, + .c = x_1_idx, + .a_scaling = 1, + .b_scaling = 1, + .c_scaling = -1, + .const_scaling = 0 }); + + fr prod_y_diff_x_diff = diff_y_alpha_y_1 * diff_x_1_x_2; + uint32_t prod_y_diff_x_diff_idx = context->add_variable(prod_y_diff_x_diff); + context->create_mul_gate({ .a = diff_y_alpha_y_1_idx, + .b = diff_x_1_x_2_idx, + .c = prod_y_diff_x_diff_idx, + .mul_scaling = 1, + .c_scaling = -1, + .const_scaling = 0 }); + + // // // identity for y_2 + context->create_mul_gate({ .a = sum_y_1_y_2_idx, + .b = diff_x_alpha_x_1_idx, + .c = prod_y_diff_x_diff_idx, + .mul_scaling = 1, + .c_scaling = -1, + .const_scaling = 0 }); + } + } + + void create_fixed_group_add_gate_with_init(const fixed_group_add_quad& in, const fixed_group_init_quad& init) + { + if constexpr (Composer::type == ComposerType::TURBO) { + context->create_fixed_group_add_gate_with_init(in, init); + } else { + uint32_t x_0_idx = in.a; + uint32_t y_0_idx = in.b; + uint32_t x_alpha_idx = in.c; + uint32_t a_0_idx = in.d; + + fr x_alpha = context->get_variable(x_alpha_idx); + fr a_0 = context->get_variable(a_0_idx); + + // weird names here follow the Turbo notation + fr q_4 = init.q_x_1; + fr q_5 = init.q_x_2; + fr q_m = init.q_y_1; + fr q_c = init.q_y_2; + + // We will think of s = 1-a_0 as an auxiliary "switch" which is equal to either -x_alpha or 0 + // during the initialization step, but we will not add this variable to the composer for reasons of + // efficiency. + + // (ɑ^4 identity) impose 1-a_0 = 0 or -x_alpha + // // first check formula for sx_alpha + fr sx_alpha = (fr(1) - a_0) * x_alpha; + uint32_t sx_alpha_idx = context->add_variable(sx_alpha); + context->create_poly_gate({ .a = a_0_idx, + .b = x_alpha_idx, + .c = sx_alpha_idx, + .q_m = 1, + .q_l = 0, + .q_r = -1, + .q_o = 1, + .q_c = 0 }); + + // // now add the desired constraint on sx_alpha + // // s(s + x_alpha) = s*s + s*x_alpha = 0 + context->create_poly_gate( + { .a = a_0_idx, .b = a_0_idx, .c = sx_alpha_idx, .q_m = 1, .q_l = -2, .q_r = 0, .q_o = 1, .q_c = 1 }); + + // (ɑ^5 identity) + context->create_poly_gate({ .a = x_0_idx, + .b = x_alpha_idx, + .c = a_0_idx, + .q_m = -1, + .q_l = 0, + .q_r = q_4, + .q_o = -q_5, + .q_c = q_5 }); + + // (ɑ^6 identity) + context->create_poly_gate({ .a = y_0_idx, + .b = x_alpha_idx, + .c = a_0_idx, + .q_m = -1, + .q_l = 0, + .q_r = q_m, + .q_o = -q_c, + .q_c = q_c }); + + // There is no previous add quad. + previous_add_quad = in; + } + } + + void create_fixed_group_add_gate_final(const add_quad& in) + { + if constexpr (Composer::type == ComposerType::TURBO) { + context->create_fixed_group_add_gate_final(in); + } else { + + fixed_group_add_quad final_round_quad{ .a = in.a, + .b = in.b, + .c = in.c, + .d = in.d, + .q_x_1 = fr::zero(), + .q_x_2 = fr::zero(), + .q_y_1 = fr::zero(), + .q_y_2 = fr::zero() }; + create_fixed_group_add_gate(final_round_quad); + } + } +}; + +} // namespace stdlib +} // namespace plonk \ No newline at end of file diff --git a/cpp/src/aztec/stdlib/primitives/group/group.hpp b/cpp/src/aztec/stdlib/primitives/group/group.hpp index 186c43044c..a572612c72 100644 --- a/cpp/src/aztec/stdlib/primitives/group/group.hpp +++ b/cpp/src/aztec/stdlib/primitives/group/group.hpp @@ -6,6 +6,7 @@ #include #include "../../hash/pedersen/pedersen.hpp" +#include "../../hash/pedersen/pedersen_gates.hpp" using namespace bonk; @@ -162,6 +163,7 @@ auto group::fixed_base_scalar_mul_internal(const field_t accumulator_witnesses; + pedersen_gates pedersen_gates(ctx); for (size_t i = 0; i < num_quads; ++i) { fixed_group_add_quad round_quad; round_quad.d = ctx->add_variable(accumulator_transcript[i]); @@ -187,9 +189,9 @@ auto group::fixed_base_scalar_mul_internal(const field_t 0) { - ctx->create_fixed_group_add_gate(round_quad); + pedersen_gates.create_fixed_group_add_gate(round_quad); } else { - ctx->create_fixed_group_add_gate_with_init(round_quad, init_quad); + pedersen_gates.create_fixed_group_add_gate_with_init(round_quad, init_quad); } accumulator_witnesses.push_back(round_quad.d); } diff --git a/cpp/src/aztec/stdlib/primitives/memory/ram_table.cpp b/cpp/src/aztec/stdlib/primitives/memory/ram_table.cpp index f2dc5fb30f..4c8a8fcb9c 100644 --- a/cpp/src/aztec/stdlib/primitives/memory/ram_table.cpp +++ b/cpp/src/aztec/stdlib/primitives/memory/ram_table.cpp @@ -242,11 +242,10 @@ template void ram_table::write(const field_pt& ind value_wire = field_pt::from_witness_index(_context, _context->put_constant_variable(native_value)); } - const size_t array_index = static_cast(static_cast(native_index)); - if (index.is_constant() && _index_initialized[array_index] == false) { - _context->init_RAM_element(_ram_id, array_index, value_wire.get_witness_index()); + if (index.is_constant() && _index_initialized[static_cast(native_index)] == false) { + _context->init_RAM_element(_ram_id, static_cast(native_index), value_wire.get_witness_index()); - _index_initialized[array_index] = true; + _index_initialized[static_cast(native_index)] = true; } else { _context->write_RAM_array(_ram_id, index_wire.normalize().get_witness_index(), value_wire.get_witness_index()); } diff --git a/cpp/src/aztec/stdlib/types/types.hpp b/cpp/src/aztec/stdlib/types/types.hpp index 66f41b93ee..39c2ac8a17 100644 --- a/cpp/src/aztec/stdlib/types/types.hpp +++ b/cpp/src/aztec/stdlib/types/types.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -74,7 +75,11 @@ typedef stdlib::bit_array bit_array_ct; typedef stdlib::bigfield fq_ct; typedef stdlib::element biggroup_ct; typedef stdlib::point point_ct; -typedef stdlib::pedersen pedersen; + +typedef std:: + conditional_t, stdlib::pedersen> + pedersen; + typedef stdlib::group group_ct; typedef stdlib::bn254 bn254; typedef stdlib::secp256k1 secp256k1_ct; From 56f3685f28456cccc406b543335c7cfe1695d531 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Thu, 2 Feb 2023 12:53:41 +0000 Subject: [PATCH 2/5] bonk --- cpp/src/aztec/stdlib/hash/pedersen/pedersen_gates.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cpp/src/aztec/stdlib/hash/pedersen/pedersen_gates.hpp b/cpp/src/aztec/stdlib/hash/pedersen/pedersen_gates.hpp index d3b8c955ec..66afa61a92 100644 --- a/cpp/src/aztec/stdlib/hash/pedersen/pedersen_gates.hpp +++ b/cpp/src/aztec/stdlib/hash/pedersen/pedersen_gates.hpp @@ -1,5 +1,5 @@ #pragma once -#include +#include #include "../../primitives/composers/composers_fwd.hpp" #include "../../primitives/field/field.hpp" #include "../../primitives/point/point.hpp" @@ -22,9 +22,9 @@ namespace stdlib { */ template class pedersen_gates { public: - using fixed_group_add_quad = waffle::fixed_group_add_quad; - using fixed_group_init_quad = waffle::fixed_group_init_quad; - using add_quad = waffle::add_quad; + using fixed_group_add_quad = bonk::fixed_group_add_quad; + using fixed_group_init_quad = bonk::fixed_group_init_quad; + using add_quad = bonk::add_quad; using ComposerType = waffle::ComposerType; Composer* context; From aea07d1b52970b41535da08bd5a21c628da463d0 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Thu, 2 Feb 2023 12:57:06 +0000 Subject: [PATCH 3/5] removed composer tests that use now-deleted fixed_group gates for standard composer --- .../standard_circuit_constructor.test.cpp | 167 ---------------- .../plonk/composer/standard_composer.test.cpp | 179 ------------------ .../stdlib/hash/pedersen/pedersen_gates.hpp | 3 +- 3 files changed, 2 insertions(+), 347 deletions(-) diff --git a/cpp/src/aztec/honk/circuit_constructors/standard_circuit_constructor.test.cpp b/cpp/src/aztec/honk/circuit_constructors/standard_circuit_constructor.test.cpp index 3b12d0e882..79c2b9bfdc 100644 --- a/cpp/src/aztec/honk/circuit_constructors/standard_circuit_constructor.test.cpp +++ b/cpp/src/aztec/honk/circuit_constructors/standard_circuit_constructor.test.cpp @@ -417,172 +417,5 @@ TEST(standard_circuit_constructor, test_check_circuit_broken) EXPECT_EQ(result, false); } -TEST(standard_circuit_constructor, test_fixed_group_add_gate_with_init) -{ - StandardCircuitConstructor composer = StandardCircuitConstructor(); - auto gen_data = crypto::pedersen::get_generator_data({ 0, 0 }); - - // 1. generate two origin points P, Q - // 2. derive gate constant values from P, Q - // 3. instantiate P as accumulator - // 4. generate accumulator initial value 1 and instantiate as circuit variable - // 5. use the above to call `create_fixed_group_add_gate_with_init` - // 6. validate proof passes - constexpr size_t num_bits = 63; - constexpr size_t initial_exponent = ((num_bits & 1) == 1) ? num_bits - 1 : num_bits; - - const crypto::pedersen::fixed_base_ladder* ladder = gen_data.get_ladder(num_bits); - grumpkin::g1::affine_element generator = gen_data.aux_generator; - - grumpkin::g1::element origin_points[2]; - origin_points[0] = grumpkin::g1::element(ladder[0].one); // this is P - origin_points[1] = origin_points[0] + generator; - origin_points[1] = origin_points[1].normalize(); // this is Q - - fr accumulator_offset = (fr::one() + fr::one()).pow(static_cast(initial_exponent)).invert(); - fr origin_accumulators[2]{ fr::one(), accumulator_offset + fr::one() }; - - for (size_t i = 0; i < 2; ++i) { - fr starting_accumulator = origin_accumulators[i]; // skew = 0 - - fixed_group_init_quad init_quad{ origin_points[0].x, - (origin_points[0].x - origin_points[1].x), - origin_points[0].y, - (origin_points[0].y - origin_points[1].y) }; - - fixed_group_add_quad round_quad{ - .a = composer.add_variable(origin_points[i].x), - .b = composer.add_variable(origin_points[i].y), - .c = composer.add_variable(accumulator_offset), - .d = composer.add_variable(starting_accumulator), - .q_x_1 = 0, - .q_x_2 = 0, - .q_y_1 = 0, - .q_y_2 = 0, - }; - composer.create_fixed_group_add_gate_with_init(round_quad, init_quad); - } - - bool result = composer.check_circuit(); - - EXPECT_EQ(result, true); -} - -TEST(standard_circuit_constructor, test_fixed_group_add_gate) -{ - auto composer = StandardCircuitConstructor(); - auto gen_data = crypto::pedersen::get_generator_data({ 0, 0 }); - - constexpr size_t num_bits = 63; - constexpr size_t num_quads_base = (num_bits - 1) >> 1; - constexpr size_t num_quads = ((num_quads_base << 1) + 1 < num_bits) ? num_quads_base + 1 : num_quads_base; - constexpr size_t num_wnaf_bits = (num_quads << 1) + 1; - constexpr size_t initial_exponent = ((num_bits & 1) == 1) ? num_bits - 1 : num_bits; - constexpr uint64_t bit_mask = (1ULL << num_bits) - 1UL; - const crypto::pedersen::fixed_base_ladder* ladder = gen_data.get_hash_ladder(num_bits); - grumpkin::g1::affine_element generator = gen_data.aux_generator; // also passes with aux_generator? - - grumpkin::g1::element origin_points[2]; - origin_points[0] = grumpkin::g1::element(ladder[0].one); - origin_points[1] = origin_points[0] + generator; - origin_points[1] = origin_points[1].normalize(); - - grumpkin::fr scalar_multiplier_entropy = grumpkin::fr::random_element(); - grumpkin::fr scalar_multiplier_base{ scalar_multiplier_entropy.data[0] & bit_mask, 0, 0, 0 }; - scalar_multiplier_base.data[0] = scalar_multiplier_base.data[0] & (~1ULL); - - uint64_t wnaf_entries[num_quads + 1] = { 0 }; - if ((scalar_multiplier_base.data[0] & 1) == 0) { - scalar_multiplier_base.data[0] -= 2; - } - bool skew = false; - barretenberg::wnaf::fixed_wnaf(&scalar_multiplier_base.data[0], &wnaf_entries[0], skew, 0); - - fr accumulator_offset = (fr::one() + fr::one()).pow(static_cast(initial_exponent)).invert(); - fr origin_accumulators[2]{ fr::one(), accumulator_offset + fr::one() }; - - grumpkin::g1::element* multiplication_transcript = - static_cast(aligned_alloc(64, sizeof(grumpkin::g1::element) * (num_quads + 1))); - fr* accumulator_transcript = static_cast(aligned_alloc(64, sizeof(fr) * (num_quads + 1))); - - if (skew) { - multiplication_transcript[0] = origin_points[1]; - accumulator_transcript[0] = origin_accumulators[1]; - } else { - multiplication_transcript[0] = origin_points[0]; - accumulator_transcript[0] = origin_accumulators[0]; - } - - fr one = fr::one(); - fr three = ((one + one) + one); - for (size_t i = 0; i < num_quads; ++i) { - uint64_t entry = wnaf_entries[i + 1] & crypto::pedersen::WNAF_MASK; - fr prev_accumulator = accumulator_transcript[i] + accumulator_transcript[i]; - prev_accumulator = prev_accumulator + prev_accumulator; - - grumpkin::g1::affine_element point_to_add = (entry == 1) ? ladder[i + 1].three : ladder[i + 1].one; - fr scalar_to_add = (entry == 1) ? three : one; - uint64_t predicate = (wnaf_entries[i + 1] >> 31U) & 1U; - if (predicate) { - point_to_add = -point_to_add; - scalar_to_add.self_neg(); - } - accumulator_transcript[i + 1] = prev_accumulator + scalar_to_add; - multiplication_transcript[i + 1] = multiplication_transcript[i] + point_to_add; - } - grumpkin::g1::element::batch_normalize(&multiplication_transcript[0], num_quads + 1); - - fixed_group_init_quad init_quad{ origin_points[0].x, - (origin_points[0].x - origin_points[1].x), - origin_points[0].y, - (origin_points[0].y - origin_points[1].y) }; - - fr x_alpha = accumulator_offset; - for (size_t i = 0; i < 2; ++i) { - fixed_group_add_quad round_quad; - round_quad.d = composer.add_variable(accumulator_transcript[i]); - round_quad.a = composer.add_variable(multiplication_transcript[i].x); - round_quad.b = composer.add_variable(multiplication_transcript[i].y); - - if (i == 0) { - // we need to ensure that the first value of x_alpha is a defined constant. - // However, repeated applications of the pedersen hash will use the same constant value. - // `put_constant_variable` will create a gate that fixes the value of x_alpha, but only once - round_quad.c = composer.put_constant_variable(x_alpha); - } else { - round_quad.c = composer.add_variable(x_alpha); - } - - if ((wnaf_entries[i + 1] & 0xffffffU) == 0) { - x_alpha = ladder[i + 1].one.x; - } else { - x_alpha = ladder[i + 1].three.x; - } - round_quad.q_x_1 = ladder[i + 1].q_x_1; - round_quad.q_x_2 = ladder[i + 1].q_x_2; - round_quad.q_y_1 = ladder[i + 1].q_y_1; - round_quad.q_y_2 = ladder[i + 1].q_y_2; - - if (i > 0) { - composer.create_fixed_group_add_gate(round_quad); - } else { - composer.create_fixed_group_add_gate_with_init(round_quad, init_quad); - } - } - add_quad add_quad{ composer.add_variable(multiplication_transcript[2].x), - composer.add_variable(multiplication_transcript[2].y), - composer.add_variable(x_alpha), - composer.add_variable(accumulator_transcript[2]), - fr::zero(), - fr::zero(), - fr::zero(), - fr::zero(), - fr::zero() }; - composer.create_fixed_group_add_gate_final(add_quad); - - bool result = composer.check_circuit(); - - EXPECT_EQ(result, true); -} } // namespace standard_circuit_constructor_tests \ No newline at end of file diff --git a/cpp/src/aztec/plonk/composer/standard_composer.test.cpp b/cpp/src/aztec/plonk/composer/standard_composer.test.cpp index c789f2fce0..0609dd5db1 100644 --- a/cpp/src/aztec/plonk/composer/standard_composer.test.cpp +++ b/cpp/src/aztec/plonk/composer/standard_composer.test.cpp @@ -554,182 +554,3 @@ TEST(standard_composer, test_check_circuit_broken) bool result = composer.check_circuit(); EXPECT_EQ(result, false); } - -TEST(standard_composer, test_fixed_group_add_gate_with_init) -{ - waffle::StandardComposer composer = waffle::StandardComposer(); - auto gen_data = crypto::pedersen::get_generator_data({ 0, 0 }); - - // 1. generate two origin points P, Q - // 2. derive gate constant values from P, Q - // 3. instantiate P as accumulator - // 4. generate accumulator initial value 1 and instantiate as circuit variable - // 5. use the above to call `create_fixed_group_add_gate_with_init` - // 6. validate proof passes - constexpr size_t num_bits = 63; - constexpr size_t initial_exponent = ((num_bits & 1) == 1) ? num_bits - 1 : num_bits; - - const crypto::pedersen::fixed_base_ladder* ladder = gen_data.get_ladder(num_bits); - grumpkin::g1::affine_element generator = gen_data.aux_generator; - - grumpkin::g1::element origin_points[2]; - origin_points[0] = grumpkin::g1::element(ladder[0].one); // this is P - origin_points[1] = origin_points[0] + generator; - origin_points[1] = origin_points[1].normalize(); // this is Q - - fr accumulator_offset = (fr::one() + fr::one()).pow(static_cast(initial_exponent)).invert(); - fr origin_accumulators[2]{ fr::one(), accumulator_offset + fr::one() }; - - for (size_t i = 0; i < 2; ++i) { - fr starting_accumulator = origin_accumulators[i]; // skew = 0 - - fixed_group_init_quad init_quad{ origin_points[0].x, - (origin_points[0].x - origin_points[1].x), - origin_points[0].y, - (origin_points[0].y - origin_points[1].y) }; - - fixed_group_add_quad round_quad{ - .a = composer.add_variable(origin_points[i].x), - .b = composer.add_variable(origin_points[i].y), - .c = composer.add_variable(accumulator_offset), - .d = composer.add_variable(starting_accumulator), - .q_x_1 = 0, - .q_x_2 = 0, - .q_y_1 = 0, - .q_y_2 = 0, - }; - composer.create_fixed_group_add_gate_with_init(round_quad, init_quad); - } - waffle::Prover prover = composer.preprocess(); - - waffle::Verifier verifier = composer.create_verifier(); - - waffle::plonk_proof proof = prover.construct_proof(); - - bool result = verifier.verify_proof(proof); - - EXPECT_EQ(result, true); -} - -TEST(standard_composer, test_fixed_group_add_gate) -{ - auto composer = waffle::StandardComposer(); - auto gen_data = crypto::pedersen::get_generator_data({ 0, 0 }); - - constexpr size_t num_bits = 63; - constexpr size_t num_quads_base = (num_bits - 1) >> 1; - constexpr size_t num_quads = ((num_quads_base << 1) + 1 < num_bits) ? num_quads_base + 1 : num_quads_base; - constexpr size_t num_wnaf_bits = (num_quads << 1) + 1; - constexpr size_t initial_exponent = ((num_bits & 1) == 1) ? num_bits - 1 : num_bits; - constexpr uint64_t bit_mask = (1ULL << num_bits) - 1UL; - const crypto::pedersen::fixed_base_ladder* ladder = gen_data.get_hash_ladder(num_bits); - grumpkin::g1::affine_element generator = gen_data.aux_generator; // also passes with aux_generator? - - grumpkin::g1::element origin_points[2]; - origin_points[0] = grumpkin::g1::element(ladder[0].one); - origin_points[1] = origin_points[0] + generator; - origin_points[1] = origin_points[1].normalize(); - - grumpkin::fr scalar_multiplier_entropy = grumpkin::fr::random_element(); - grumpkin::fr scalar_multiplier_base{ scalar_multiplier_entropy.data[0] & bit_mask, 0, 0, 0 }; - scalar_multiplier_base.data[0] = scalar_multiplier_base.data[0] & (~1ULL); - - uint64_t wnaf_entries[num_quads + 1] = { 0 }; - if ((scalar_multiplier_base.data[0] & 1) == 0) { - scalar_multiplier_base.data[0] -= 2; - } - bool skew = false; - barretenberg::wnaf::fixed_wnaf(&scalar_multiplier_base.data[0], &wnaf_entries[0], skew, 0); - - fr accumulator_offset = (fr::one() + fr::one()).pow(static_cast(initial_exponent)).invert(); - fr origin_accumulators[2]{ fr::one(), accumulator_offset + fr::one() }; - - grumpkin::g1::element* multiplication_transcript = - static_cast(aligned_alloc(64, sizeof(grumpkin::g1::element) * (num_quads + 1))); - fr* accumulator_transcript = static_cast(aligned_alloc(64, sizeof(fr) * (num_quads + 1))); - - if (skew) { - multiplication_transcript[0] = origin_points[1]; - accumulator_transcript[0] = origin_accumulators[1]; - } else { - multiplication_transcript[0] = origin_points[0]; - accumulator_transcript[0] = origin_accumulators[0]; - } - - fr one = fr::one(); - fr three = ((one + one) + one); - for (size_t i = 0; i < num_quads; ++i) { - uint64_t entry = wnaf_entries[i + 1] & crypto::pedersen::WNAF_MASK; - fr prev_accumulator = accumulator_transcript[i] + accumulator_transcript[i]; - prev_accumulator = prev_accumulator + prev_accumulator; - - grumpkin::g1::affine_element point_to_add = (entry == 1) ? ladder[i + 1].three : ladder[i + 1].one; - fr scalar_to_add = (entry == 1) ? three : one; - uint64_t predicate = (wnaf_entries[i + 1] >> 31U) & 1U; - if (predicate) { - point_to_add = -point_to_add; - scalar_to_add.self_neg(); - } - accumulator_transcript[i + 1] = prev_accumulator + scalar_to_add; - multiplication_transcript[i + 1] = multiplication_transcript[i] + point_to_add; - } - grumpkin::g1::element::batch_normalize(&multiplication_transcript[0], num_quads + 1); - - fixed_group_init_quad init_quad{ origin_points[0].x, - (origin_points[0].x - origin_points[1].x), - origin_points[0].y, - (origin_points[0].y - origin_points[1].y) }; - - fr x_alpha = accumulator_offset; - for (size_t i = 0; i < 2; ++i) { - fixed_group_add_quad round_quad; - round_quad.d = composer.add_variable(accumulator_transcript[i]); - round_quad.a = composer.add_variable(multiplication_transcript[i].x); - round_quad.b = composer.add_variable(multiplication_transcript[i].y); - - if (i == 0) { - // we need to ensure that the first value of x_alpha is a defined constant. - // However, repeated applications of the pedersen hash will use the same constant value. - // `put_constant_variable` will create a gate that fixes the value of x_alpha, but only once - round_quad.c = composer.put_constant_variable(x_alpha); - } else { - round_quad.c = composer.add_variable(x_alpha); - } - - if ((wnaf_entries[i + 1] & 0xffffffU) == 0) { - x_alpha = ladder[i + 1].one.x; - } else { - x_alpha = ladder[i + 1].three.x; - } - round_quad.q_x_1 = ladder[i + 1].q_x_1; - round_quad.q_x_2 = ladder[i + 1].q_x_2; - round_quad.q_y_1 = ladder[i + 1].q_y_1; - round_quad.q_y_2 = ladder[i + 1].q_y_2; - - if (i > 0) { - composer.create_fixed_group_add_gate(round_quad); - } else { - composer.create_fixed_group_add_gate_with_init(round_quad, init_quad); - } - } - - add_quad add_quad{ composer.add_variable(multiplication_transcript[2].x), - composer.add_variable(multiplication_transcript[2].y), - composer.add_variable(x_alpha), - composer.add_variable(accumulator_transcript[2]), - fr::zero(), - fr::zero(), - fr::zero(), - fr::zero(), - fr::zero() }; - composer.create_fixed_group_add_gate_final(add_quad); - waffle::Prover prover = composer.create_prover(); - - waffle::Verifier verifier = composer.create_verifier(); - - waffle::plonk_proof proof = prover.construct_proof(); - - bool result = verifier.verify_proof(proof); - - EXPECT_EQ(result, true); -} \ No newline at end of file diff --git a/cpp/src/aztec/stdlib/hash/pedersen/pedersen_gates.hpp b/cpp/src/aztec/stdlib/hash/pedersen/pedersen_gates.hpp index 66afa61a92..a2679172b8 100644 --- a/cpp/src/aztec/stdlib/hash/pedersen/pedersen_gates.hpp +++ b/cpp/src/aztec/stdlib/hash/pedersen/pedersen_gates.hpp @@ -40,7 +40,8 @@ template class pedersen_gates { context->create_fixed_group_add_gate(in); } else { - context->assert_valid_variables({ in.a, in.b, in.c, in.d }); + // TODO: not supported by honk composer? + // context->assert_valid_variables({ in.a, in.b, in.c, in.d }); auto row_1 = previous_add_quad; auto row_2 = in; From f9ec1f27314ead8643080856211814566f90955d Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Thu, 2 Feb 2023 13:04:00 +0000 Subject: [PATCH 4/5] fixed wasm build error --- cpp/src/aztec/stdlib/primitives/memory/ram_table.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cpp/src/aztec/stdlib/primitives/memory/ram_table.cpp b/cpp/src/aztec/stdlib/primitives/memory/ram_table.cpp index 4c8a8fcb9c..042003f4d7 100644 --- a/cpp/src/aztec/stdlib/primitives/memory/ram_table.cpp +++ b/cpp/src/aztec/stdlib/primitives/memory/ram_table.cpp @@ -242,10 +242,11 @@ template void ram_table::write(const field_pt& ind value_wire = field_pt::from_witness_index(_context, _context->put_constant_variable(native_value)); } - if (index.is_constant() && _index_initialized[static_cast(native_index)] == false) { - _context->init_RAM_element(_ram_id, static_cast(native_index), value_wire.get_witness_index()); + const size_t cast_index = static_cast(static_cast(native_index)); + if (index.is_constant() && _index_initialized[cast_index] == false) { + _context->init_RAM_element(_ram_id, cast_index, value_wire.get_witness_index()); - _index_initialized[static_cast(native_index)] = true; + _index_initialized[cast_index] = true; } else { _context->write_RAM_array(_ram_id, index_wire.normalize().get_witness_index(), value_wire.get_witness_index()); } From ea8309264694a6f87939a36a48ee1e09fad91782 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Thu, 2 Feb 2023 17:05:30 +0000 Subject: [PATCH 5/5] fixed ultra recursive verifier to not use fixed base widget. removed unused `generalized_permutation_verifier_settings` --- .../proof_system/types/program_settings.hpp | 61 ------------------- .../plonk/proof_system/verifier/verifier.cpp | 1 - .../plonk/proof_system/verifier/verifier.hpp | 2 - .../recursion/verifier/program_settings.hpp | 8 --- 4 files changed, 72 deletions(-) diff --git a/cpp/src/aztec/plonk/proof_system/types/program_settings.hpp b/cpp/src/aztec/plonk/proof_system/types/program_settings.hpp index bc7156f317..875c36fddc 100644 --- a/cpp/src/aztec/plonk/proof_system/types/program_settings.hpp +++ b/cpp/src/aztec/plonk/proof_system/types/program_settings.hpp @@ -336,8 +336,6 @@ class unrolled_ultra_to_standard_verifier_settings : public unrolled_ultra_verif public: typedef VerifierPlookupArithmeticWidget PlookupArithmeticWidget; - typedef VerifierUltraFixedBaseWidget - UltraFixedBaseWidget; typedef VerifierGenPermSortWidget GenPermSortWidget; typedef VerifierTurboLogicWidget @@ -352,63 +350,4 @@ class unrolled_ultra_to_standard_verifier_settings : public unrolled_ultra_verif static constexpr transcript::HashType hash_type = transcript::HashType::PedersenBlake3s; }; -class generalized_permutation_verifier_settings : public turbo_settings { - public: - typedef barretenberg::fr fr; - typedef barretenberg::g1 g1; - typedef transcript::StandardTranscript Transcript; - typedef VerifierTurboArithmeticWidget TurboArithmeticWidget; - typedef VerifierTurboFixedBaseWidget TurboFixedBaseWidget; - // typedef VerifierTurboRangeWidget TurboRangeWidget; - typedef VerifierTurboLogicWidget TurboLogicWidget; - typedef VerifierGenPermSortWidget GenPermSortWidget; - - typedef VerifierPermutationWidget PermutationWidget; - - static constexpr size_t num_challenge_bytes = 32; - static constexpr transcript::HashType hash_type = transcript::HashType::Keccak256; - static constexpr bool use_linearisation = true; - static constexpr bool idpolys = true; - - static fr append_scalar_multiplication_inputs(verification_key* key, - const fr& alpha_base, - const transcript::StandardTranscript& transcript, - std::map& scalars) - { - auto updated_alpha = PermutationWidget::append_scalar_multiplication_inputs( - key, alpha_base, transcript, scalars, use_linearisation, idpolys); - - updated_alpha = - TurboArithmeticWidget::append_scalar_multiplication_inputs(key, updated_alpha, transcript, scalars); - updated_alpha = - TurboFixedBaseWidget::append_scalar_multiplication_inputs(key, updated_alpha, transcript, scalars); - // updated_alpha = TurboRangeWidget::append_scalar_multiplication_inputs( - // key, updated_alpha, transcript, scalars); - updated_alpha = TurboLogicWidget::append_scalar_multiplication_inputs(key, updated_alpha, transcript, scalars); - updated_alpha = GenPermSortWidget::append_scalar_multiplication_inputs(key, updated_alpha, transcript, scalars); - - return updated_alpha; - } - - static barretenberg::fr compute_quotient_evaluation_contribution(verification_key* key, - const fr& alpha_base, - const Transcript& transcript, - fr& r_0) - { - auto updated_alpha_base = PermutationWidget::compute_quotient_evaluation_contribution( - key, alpha_base, transcript, r_0, use_linearisation, idpolys); - - updated_alpha_base = - TurboArithmeticWidget::compute_quotient_evaluation_contribution(key, updated_alpha_base, transcript, r_0); - updated_alpha_base = - TurboFixedBaseWidget::compute_quotient_evaluation_contribution(key, updated_alpha_base, transcript, r_0); - updated_alpha_base = - TurboLogicWidget::compute_quotient_evaluation_contribution(key, updated_alpha_base, transcript, r_0); - updated_alpha_base = - GenPermSortWidget::compute_quotient_evaluation_contribution(key, updated_alpha_base, transcript, r_0); - - return updated_alpha_base; - } -}; - } // namespace waffle \ No newline at end of file diff --git a/cpp/src/aztec/plonk/proof_system/verifier/verifier.cpp b/cpp/src/aztec/plonk/proof_system/verifier/verifier.cpp index f4513ea313..7428f0f585 100644 --- a/cpp/src/aztec/plonk/proof_system/verifier/verifier.cpp +++ b/cpp/src/aztec/plonk/proof_system/verifier/verifier.cpp @@ -252,6 +252,5 @@ template class VerifierBase; template class VerifierBase; template class VerifierBase; template class VerifierBase; -template class VerifierBase; } // namespace waffle \ No newline at end of file diff --git a/cpp/src/aztec/plonk/proof_system/verifier/verifier.hpp b/cpp/src/aztec/plonk/proof_system/verifier/verifier.hpp index bf054c096b..58ada2bc36 100644 --- a/cpp/src/aztec/plonk/proof_system/verifier/verifier.hpp +++ b/cpp/src/aztec/plonk/proof_system/verifier/verifier.hpp @@ -36,7 +36,6 @@ extern template class VerifierBase extern template class VerifierBase; extern template class VerifierBase; extern template class VerifierBase; -extern template class VerifierBase; typedef VerifierBase UnrolledVerifier; typedef VerifierBase UnrolledTurboVerifier; @@ -46,6 +45,5 @@ typedef VerifierBase UnrolledUltra typedef VerifierBase Verifier; typedef VerifierBase TurboVerifier; typedef VerifierBase UltraVerifier; -typedef VerifierBase GenPermVerifier; } // namespace waffle \ No newline at end of file diff --git a/cpp/src/aztec/stdlib/recursion/verifier/program_settings.hpp b/cpp/src/aztec/stdlib/recursion/verifier/program_settings.hpp index c547f81d06..8e2dbb60ca 100644 --- a/cpp/src/aztec/stdlib/recursion/verifier/program_settings.hpp +++ b/cpp/src/aztec/stdlib/recursion/verifier/program_settings.hpp @@ -19,7 +19,6 @@ template class recursive_ultra_verifier_settings : public waffl typedef waffle::unrolled_ultra_settings base_settings; - typedef waffle::VerifierUltraFixedBaseWidget UltraFixedBaseWidget; typedef waffle::VerifierPlookupArithmeticWidget PlookupArithmeticWidget; typedef waffle::VerifierTurboLogicWidget TurboLogicWidget; typedef waffle::VerifierGenPermSortWidget GenPermSortWidget; @@ -49,9 +48,6 @@ template class recursive_ultra_verifier_settings : public waffl updated_alpha = PlookupArithmeticWidget::append_scalar_multiplication_inputs(key, updated_alpha, transcript, scalars); - updated_alpha = - UltraFixedBaseWidget::append_scalar_multiplication_inputs(key, updated_alpha, transcript, scalars); - updated_alpha = GenPermSortWidget::append_scalar_multiplication_inputs(key, updated_alpha, transcript, scalars); updated_alpha = EllipticWidget::append_scalar_multiplication_inputs(key, updated_alpha, transcript, scalars); @@ -76,9 +72,6 @@ template class recursive_ultra_verifier_settings : public waffl updated_alpha_base = PlookupArithmeticWidget::compute_quotient_evaluation_contribution(key, updated_alpha_base, transcript, r_0); - updated_alpha_base = - UltraFixedBaseWidget::compute_quotient_evaluation_contribution(key, updated_alpha_base, transcript, r_0); - updated_alpha_base = GenPermSortWidget::compute_quotient_evaluation_contribution(key, updated_alpha_base, transcript, r_0); @@ -106,7 +99,6 @@ class recursive_ultra_to_standard_verifier_settings : public recursive_ultra_ver typedef waffle::unrolled_ultra_to_standard_settings base_settings; - typedef waffle::VerifierUltraFixedBaseWidget UltraFixedBaseWidget; typedef waffle::VerifierPlookupArithmeticWidget PlookupArithmeticWidget; typedef waffle::VerifierTurboLogicWidget TurboLogicWidget; typedef waffle::VerifierGenPermSortWidget GenPermSortWidget;