Skip to content

Commit

Permalink
fix: handle properly invalid witness assignment in ec add (#7690)
Browse files Browse the repository at this point in the history
Apply the strategy added used for MSM in PR #7653 in regard to invalid
witness assignment for grumpking points with constant or witness input,
also for ec add.
  • Loading branch information
guipublic authored Jul 31, 2024
1 parent cfb4aa8 commit 6c19c7e
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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<Builder>;
using bool_ct = bb::stdlib::bool_t<Builder>;

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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,50 +18,18 @@ void create_multi_scalar_mul_constraint(Builder& builder,
using cycle_group_ct = stdlib::cycle_group<Builder>;
using cycle_scalar_ct = typename stdlib::cycle_group<Builder>::cycle_scalar;
using field_ct = stdlib::field_t<Builder>;
using bool_ct = stdlib::bool_t<Builder>;

std::vector<cycle_group_ct> points;
std::vector<cycle_scalar_ct> 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
Expand All @@ -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());
Expand Down
Original file line number Diff line number Diff line change
@@ -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 <typename Builder, typename FF>
bb::stdlib::cycle_group<Builder> to_grumpkin_point(const WitnessOrConstant<FF>& input_x,
const WitnessOrConstant<FF>& input_y,
const WitnessOrConstant<FF>& input_infinite,
bool has_valid_witness_assignments,
Builder& builder)
{
using bool_ct = bb::stdlib::bool_t<Builder>;
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<Builder> input_point(point_x, point_y, infinite);
return input_point;
}

template bb::stdlib::cycle_group<UltraCircuitBuilder> to_grumpkin_point(const WitnessOrConstant<fr>& input_x,
const WitnessOrConstant<fr>& input_y,
const WitnessOrConstant<fr>& input_infinite,
bool has_valid_witness_assignments,
UltraCircuitBuilder& builder);
template bb::stdlib::cycle_group<MegaCircuitBuilder> to_grumpkin_point(const WitnessOrConstant<fr>& input_x,
const WitnessOrConstant<fr>& input_y,
const WitnessOrConstant<fr>& input_infinite,
bool has_valid_witness_assignments,
MegaCircuitBuilder& builder);

} // namespace acir_format
Original file line number Diff line number Diff line change
@@ -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 <typename FF> struct WitnessOrConstant {
Expand Down Expand Up @@ -30,4 +32,11 @@ bb::stdlib::field_t<Builder> to_field_ct(const WitnessOrConstant<FF>& input, Bui
return field_ct::from_witness_index(&builder, input.index);
}

template <typename Builder, typename FF>
bb::stdlib::cycle_group<Builder> to_grumpkin_point(const WitnessOrConstant<FF>& input_x,
const WitnessOrConstant<FF>& input_y,
const WitnessOrConstant<FF>& input_infinite,
bool has_valid_witness_assignments,
Builder& builder);

} // namespace acir_format

0 comments on commit 6c19c7e

Please sign in to comment.