@@ -14,10 +14,11 @@ using namespace bb::stdlib;
1414
1515/* *
1616 * @brief Convert inputs representing a Grumpkin point into a cycle_group element.
17- * @details Inputs x, y, and is_infinite are used to construct the point. If no valid witness is provided or if the
18- * predicate is constant false, the point is set to the generator point. If the predicate is a non-constant witness, the
19- * point is conditionally assigned to the generator point based on the predicate value. This ensures that the point is
20- * always valid and will not trigger any on_curve assertions.
17+ * @details Inputs x, y, and is_infinite are used to construct the point. We handle two cases:
18+ * 1. has_valid_witness_assignments is false: we are in a write_vk scenario. In this case, we set the point to be the
19+ * generator of Grumpkin.
20+ * 2. predicate is a witness: we conditionally assign the point depending on the predicate; if it is witness true, we
21+ * use the witnesses provided, otherwise, we set the point to be the generator of Grumpkin.
2122 *
2223 * @tparam Builder
2324 * @tparam FF
@@ -29,69 +30,59 @@ using namespace bb::stdlib;
2930 * @param builder
3031 * @return bb::stdlib::cycle_group<Builder>
3132 */
32- template <typename Builder, typename FF >
33- bb::stdlib::cycle_group<Builder> to_grumpkin_point (const WitnessOrConstant<FF>& input_x,
34- const WitnessOrConstant<FF>& input_y,
35- const WitnessOrConstant<FF>& input_infinite,
33+ template <typename Builder>
34+ bb::stdlib::cycle_group<Builder> to_grumpkin_point (const WitnessOrConstant<typename Builder:: FF>& input_x,
35+ const WitnessOrConstant<typename Builder:: FF>& input_y,
36+ const WitnessOrConstant<typename Builder:: FF>& input_infinite,
3637 bool has_valid_witness_assignments,
37- const WitnessOrConstant<FF >& predicate,
38+ const bb::stdlib:: bool_t <Builder >& predicate,
3839 Builder& builder)
3940{
4041 using bool_ct = bb::stdlib::bool_t <Builder>;
4142 using field_ct = bb::stdlib::field_t <Builder>;
43+
44+ bool constant_coordinates = input_x.is_constant && input_y.is_constant ;
45+
4246 auto point_x = to_field_ct (input_x, builder);
4347 auto point_y = to_field_ct (input_y, builder);
4448 auto infinite = bool_ct (to_field_ct (input_infinite, builder));
4549
46- // Coordinates should not have mixed constancy. In the case they do, convert constant coordinate to fixed witness.
47- BB_ASSERT_EQ (input_x.is_constant , input_y.is_constant , " to_grumpkin_point: Inconsistent constancy of coordinates" );
48- // TODO(https://github.com/AztecProtocol/aztec-packages/issues/17514): Avoid mixing constant/witness coordinates
49- if (point_x.is_constant () != point_y.is_constant ()) {
50- if (point_x.is_constant ()) {
51- point_x.convert_constant_to_fixed_witness (&builder);
52- } else if (point_y.is_constant ()) {
53- point_y.convert_constant_to_fixed_witness (&builder);
54- }
55- }
56-
57- bool constant_coordinates = input_x.is_constant && input_y.is_constant ;
58-
59- // In a witness is not provided, or the relevant predicate is constant false, we ensure the coordinates correspond
60- // to a valid point to avoid erroneous failures during circuit construction. We only do this if the coordinates are
61- // non-constant since otherwise no variable indices exist.
62- bool constant_false_predicate = predicate.is_constant && predicate.value == FF (0 );
63- if ((!has_valid_witness_assignments || constant_false_predicate) && !constant_coordinates) {
64- auto one = bb::grumpkin::g1::affine_one;
65- builder.set_variable (input_x.index , one.x );
66- builder.set_variable (input_y.index , one.y );
50+ // If a witness is not provided (we are in a write_vk scenario) we ensure the coordinates correspond to a valid
51+ // point to avoid erroneous failures during circuit construction. We only do this if the coordinates are
52+ // non-constant since otherwise no variable indices exist. Note that there is no need to assign the infinite flag
53+ // because native on-curve checks will always pass as long x and y coordinates correspond to a valid point on
54+ // Grumpkin.
55+ if (!has_valid_witness_assignments && !constant_coordinates) {
56+ builder.set_variable (input_x.index , bb::grumpkin::g1::affine_one.x );
57+ builder.set_variable (input_y.index , bb::grumpkin::g1::affine_one.y );
6758 }
6859
6960 // If the predicate is a non-constant witness, conditionally replace coordinates with a valid point.
70- // Note: this must be done before constructing the cycle_group to avoid triggering on_curve assertions
71- if (!predicate.is_constant ) {
72- bool_ct predicate_witness = bool_ct::from_witness_index_unsafe (&builder, predicate.index );
73- auto generator = bb::grumpkin::g1::affine_one;
74- point_x = field_ct::conditional_assign (predicate_witness, point_x, generator.x );
75- point_y = field_ct::conditional_assign (predicate_witness, point_y, generator.y );
76- bool_ct generator_is_infinity = bool_ct (&builder, generator.is_point_at_infinity ());
77- infinite = bool_ct::conditional_assign (predicate_witness, infinite, generator_is_infinity);
61+ if (!predicate.is_constant ()) {
62+ point_x = field_ct::conditional_assign (predicate, point_x, field_ct (bb::grumpkin::g1::affine_one.x ));
63+ point_y = field_ct::conditional_assign (predicate, point_y, field_ct (bb::grumpkin::g1::affine_one.y ));
64+ infinite = bool_ct::conditional_assign (predicate, infinite, bool_ct (false ));
65+ } else {
66+ BB_ASSERT (predicate.get_value (), " Creating Grumpkin point with a constant predicate equal to false." );
7867 }
7968
8069 cycle_group<Builder> input_point (point_x, point_y, infinite, /* assert_on_curve=*/ true );
8170 return input_point;
8271}
8372
84- template bb::stdlib::cycle_group<UltraCircuitBuilder> to_grumpkin_point (const WitnessOrConstant<fr>& input_x,
85- const WitnessOrConstant<fr>& input_y,
86- const WitnessOrConstant<fr>& input_infinite,
87- bool has_valid_witness_assignments,
88- const WitnessOrConstant<fr>& predicate,
89- UltraCircuitBuilder& builder);
90- template bb::stdlib::cycle_group<MegaCircuitBuilder> to_grumpkin_point (const WitnessOrConstant<fr>& input_x,
91- const WitnessOrConstant<fr>& input_y,
92- const WitnessOrConstant<fr>& input_infinite,
93- bool has_valid_witness_assignments,
94- const WitnessOrConstant<fr>& predicate,
95- MegaCircuitBuilder& builder);
73+ template bb::stdlib::cycle_group<UltraCircuitBuilder> to_grumpkin_point (
74+ const WitnessOrConstant<UltraCircuitBuilder::FF>& input_x,
75+ const WitnessOrConstant<UltraCircuitBuilder::FF>& input_y,
76+ const WitnessOrConstant<UltraCircuitBuilder::FF>& input_infinite,
77+ bool has_valid_witness_assignments,
78+ const bb::stdlib::bool_t <UltraCircuitBuilder>& predicate,
79+ UltraCircuitBuilder& builder);
9680
81+ template bb::stdlib::cycle_group<MegaCircuitBuilder> to_grumpkin_point (
82+ const WitnessOrConstant<MegaCircuitBuilder::FF>& input_x,
83+ const WitnessOrConstant<MegaCircuitBuilder::FF>& input_y,
84+ const WitnessOrConstant<MegaCircuitBuilder::FF>& input_infinite,
85+ bool has_valid_witness_assignments,
86+ const bb::stdlib::bool_t <MegaCircuitBuilder>& predicate,
87+ MegaCircuitBuilder& builder);
9788} // namespace acir_format
0 commit comments