diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.cpp index cd05eb150ac..9083e8eb044 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.cpp @@ -12,42 +12,12 @@ void create_ec_add_constraint(Builder& builder, const EcAdd& input, bool has_val { // Input to cycle_group points using cycle_group_ct = bb::stdlib::cycle_group; - using bool_ct = bb::stdlib::bool_t; - auto x1 = to_field_ct(input.input1_x, builder); - auto y1 = to_field_ct(input.input1_y, builder); - auto x2 = to_field_ct(input.input2_x, builder); + auto input1_point = to_grumpkin_point( + input.input1_x, input.input1_y, input.input1_infinite, has_valid_witness_assignments, builder); + auto input2_point = to_grumpkin_point( + input.input2_x, input.input2_y, input.input2_infinite, has_valid_witness_assignments, builder); - auto y2 = to_field_ct(input.input2_y, builder); - - auto infinite1 = bool_ct(to_field_ct(input.input1_infinite, builder)); - - auto infinite2 = bool_ct(to_field_ct(input.input2_infinite, builder)); - - if (!has_valid_witness_assignments) { - auto g1 = bb::grumpkin::g1::affine_one; - // We need to have correct values representing points on the curve - if (!x1.is_constant()) { - builder.variables[x1.witness_index] = g1.x; - } - if (!y1.is_constant()) { - builder.variables[y1.witness_index] = g1.y; - } - if (!infinite1.is_constant()) { - builder.variables[infinite1.witness_index] = bb::fr(0); - } - if (!x2.is_constant()) { - builder.variables[x2.witness_index] = g1.x; - } - if (!y2.is_constant()) { - builder.variables[y2.witness_index] = g1.y; - } - if (!infinite2.is_constant()) { - builder.variables[infinite2.witness_index] = bb::fr(0); - } - } - cycle_group_ct input1_point(x1, y1, infinite1); - cycle_group_ct input2_point(x2, y2, infinite2); // Addition cycle_group_ct result = input1_point + input2_point; cycle_group_ct standard_result = result.get_standard_form(); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.cpp index 776baf67227..ef7e5c6b606 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.cpp @@ -18,50 +18,18 @@ void create_multi_scalar_mul_constraint(Builder& builder, using cycle_group_ct = stdlib::cycle_group; using cycle_scalar_ct = typename stdlib::cycle_group::cycle_scalar; using field_ct = stdlib::field_t; - using bool_ct = stdlib::bool_t; std::vector points; std::vector scalars; for (size_t i = 0; i < input.points.size(); i += 3) { // Instantiate the input point/variable base as `cycle_group_ct` - field_ct point_x; - field_ct point_y; - bool_ct infinite; + cycle_group_ct input_point = to_grumpkin_point( + input.points[i], input.points[i + 1], input.points[i + 2], has_valid_witness_assignments, builder); - point_x = to_field_ct(input.points[i], builder); - point_y = to_field_ct(input.points[i + 1], builder); - infinite = bool_ct(to_field_ct(input.points[i + 2], builder)); - - // When we do not have the witness assignments, we set is_infinite value to true if it is not constant - // else default values would give a point which is not on the curve and this will fail verification - if (!has_valid_witness_assignments) { - if (!input.points[i + 2].is_constant) { - builder.variables[input.points[i + 2].index] = fr(1); - } else if (input.points[i + 2].value == fr::zero() && - !(input.points[i].is_constant || input.points[i + 1].is_constant)) { - // else, if is_infinite is false, but the coordinates (x, y) are witness - // then we set their value so to a curve point. - auto g1 = bb::grumpkin::g1::affine_one; - builder.variables[input.points[i].index] = g1.x; - builder.variables[input.points[i + 1].index] = g1.y; - } - } - - cycle_group_ct input_point(point_x, point_y, infinite); - // Reconstruct the scalar from the low and high limbs - field_ct scalar_low_as_field; - field_ct scalar_high_as_field; - if (input.scalars[2 * (i / 3)].is_constant) { - scalar_low_as_field = field_ct(input.scalars[2 * (i / 3)].value); - } else { - scalar_low_as_field = field_ct::from_witness_index(&builder, input.scalars[2 * (i / 3)].index); - } - if (input.scalars[2 * (i / 3) + 1].is_constant) { - scalar_high_as_field = field_ct(input.scalars[2 * (i / 3) + 1].value); - } else { - scalar_high_as_field = field_ct::from_witness_index(&builder, input.scalars[2 * (i / 3) + 1].index); - } + // Reconstruct the scalar from the low and high limbs + field_ct scalar_low_as_field = to_field_ct(input.scalars[2 * (i / 3)], builder); + field_ct scalar_high_as_field = to_field_ct(input.scalars[2 * (i / 3) + 1], builder); cycle_scalar_ct scalar(scalar_low_as_field, scalar_high_as_field); // Add the point and scalar to the vectors @@ -70,6 +38,7 @@ void create_multi_scalar_mul_constraint(Builder& builder, } // Call batch_mul to multiply the points and scalars and sum the results auto output_point = cycle_group_ct::batch_mul(points, scalars).get_standard_form(); + // Add the constraints and handle constant values if (output_point.is_point_at_infinity().is_constant()) { builder.fix_witness(input.out_point_is_infinite, output_point.is_point_at_infinity().get_value()); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/witness_constant.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/witness_constant.cpp new file mode 100644 index 00000000000..d199eeb62f8 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/witness_constant.cpp @@ -0,0 +1,48 @@ +#include "witness_constant.hpp" +#include "barretenberg/ecc/curves/bn254/fr.hpp" + +namespace acir_format { + +using namespace bb; +using namespace bb::stdlib; +template +bb::stdlib::cycle_group to_grumpkin_point(const WitnessOrConstant& input_x, + const WitnessOrConstant& input_y, + const WitnessOrConstant& input_infinite, + bool has_valid_witness_assignments, + Builder& builder) +{ + using bool_ct = bb::stdlib::bool_t; + auto point_x = to_field_ct(input_x, builder); + auto point_y = to_field_ct(input_y, builder); + auto infinite = bool_ct(to_field_ct(input_infinite, builder)); + + // When we do not have the witness assignments, we set is_infinite value to true if it is not constant + // else default values would give a point which is not on the curve and this will fail verification + if (!has_valid_witness_assignments) { + if (!input_infinite.is_constant) { + builder.variables[input_infinite.index] = fr(1); + } else if (input_infinite.value == fr::zero() && !(input_x.is_constant || input_y.is_constant)) { + // else, if is_infinite is false, but the coordinates (x, y) are witness (and not constant) + // then we set their value to an arbitrary valid curve point (in our case G1). + auto g1 = bb::grumpkin::g1::affine_one; + builder.variables[input_x.index] = g1.x; + builder.variables[input_y.index] = g1.y; + } + } + cycle_group input_point(point_x, point_y, infinite); + return input_point; +} + +template bb::stdlib::cycle_group to_grumpkin_point(const WitnessOrConstant& input_x, + const WitnessOrConstant& input_y, + const WitnessOrConstant& input_infinite, + bool has_valid_witness_assignments, + UltraCircuitBuilder& builder); +template bb::stdlib::cycle_group to_grumpkin_point(const WitnessOrConstant& input_x, + const WitnessOrConstant& input_y, + const WitnessOrConstant& input_infinite, + bool has_valid_witness_assignments, + MegaCircuitBuilder& builder); + +} // namespace acir_format \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/witness_constant.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/witness_constant.hpp index 554c8ddf657..bb60a754d59 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/witness_constant.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/witness_constant.hpp @@ -1,6 +1,8 @@ #pragma once +#include "barretenberg/dsl/acir_format/ecdsa_secp256k1.hpp" #include "barretenberg/serialize/msgpack.hpp" #include "barretenberg/stdlib/primitives/field/field.hpp" +#include "barretenberg/stdlib/primitives/group/cycle_group.hpp" namespace acir_format { template struct WitnessOrConstant { @@ -30,4 +32,11 @@ bb::stdlib::field_t to_field_ct(const WitnessOrConstant& input, Bui return field_ct::from_witness_index(&builder, input.index); } +template +bb::stdlib::cycle_group to_grumpkin_point(const WitnessOrConstant& input_x, + const WitnessOrConstant& input_y, + const WitnessOrConstant& input_infinite, + bool has_valid_witness_assignments, + Builder& builder); + } // namespace acir_format \ No newline at end of file