Skip to content

Commit

Permalink
Fix circuit to create group from coordinates.
Browse files Browse the repository at this point in the history
This issue was discovered in the circuit to cast a field to a group, but it
really affects the sub-circuit of that circuit that turns two field coordinates
into a group element. The issue is not in the witness computation, but in the
circuit, which generates constraints about the point being in the group (i.e.
being on the curve, and being in the subgroup) that apply not to the given
point, but to a freshly created point, i.e. two different R1CS variables than
the ones given as input. This can be seen by generating sample circuits: there
is no connection between the input variables and the point being constrained.

This commit fixes the issue by adding equality constraints that tie the input
coordinates with the point that is constrained to be in the (sub)group. This is
not the most efficient circuit, because it uses more variables and constraints
than needed, but it is a simple fix for now.
  • Loading branch information
acoglio authored and d0cd committed Oct 13, 2023
1 parent eadefa4 commit 42f3d77
Showing 1 changed file with 13 additions and 1 deletion.
14 changes: 13 additions & 1 deletion circuit/types/group/src/helpers/from_xy_coordinates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,19 @@ impl<E: Environment> Group<E> {
// Note: We use the **unchecked** ('console::Group::from_xy_coordinates_unchecked') variant
// here so that the recovery does not halt in witness mode, and subsequently, the point is
// enforced to be on the curve by injecting with `circuit::Group::new`.
witness!(|x, y| console::Group::from_xy_coordinates_unchecked(x, y))
let point = witness!(|x, y| console::Group::from_xy_coordinates_unchecked(x, y));

// Note that `point` above, returned by `witness!`,
// consists of new R1CS variables for the x and y components,
// unrelated to the `x` and `y` inputs of this `from_xy_coordinates` function.
// So we add R1CS constraints to enforce that
// the coordinates of `point` are equal to `x` and `y`.
// This is not the most efficient circuit,
// because it has more variables and constraints than necessary,
// but we will look into optimizing this later.
E::assert_eq(&x, point.x);
E::assert_eq(&y, point.y);
point
}

/// Initializes an affine group element from a given x- and y-coordinate field element.
Expand Down

0 comments on commit 42f3d77

Please sign in to comment.