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/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.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/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/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..875c36fddc 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 = @@ -347,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 @@ -363,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/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/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/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..a2679172b8 --- /dev/null +++ b/cpp/src/aztec/stdlib/hash/pedersen/pedersen_gates.hpp @@ -0,0 +1,316 @@ +#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 = 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; + 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 { + + // 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; + 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..042003f4d7 100644 --- a/cpp/src/aztec/stdlib/primitives/memory/ram_table.cpp +++ b/cpp/src/aztec/stdlib/primitives/memory/ram_table.cpp @@ -242,11 +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)); } - 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()); + 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[array_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()); } 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; 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;