Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
elliptic_relation.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: Complete, auditors: [Luke, Raju], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
7#pragma once
11
12namespace bb {
13
53template <typename FF_> class EllipticRelationImpl {
54 public:
55 using FF = FF_;
56
57 static constexpr std::array<size_t, 2> SUBRELATION_PARTIAL_LENGTHS{
58 6, // x-coordinate sub-relation
59 6, // y-coordinate sub-relation
60 };
61
66 template <typename AllEntities> inline static bool skip(const AllEntities& in)
67 {
68 return in[AllEntities::EntityId::q_elliptic].is_zero();
69 }
70
71 static constexpr FF get_curve_b()
72 {
73 if constexpr (FF::modulus == bb::fq::modulus) {
74 return bb::g1::curve_b;
75 } else if constexpr (FF::modulus == grumpkin::fq::modulus) {
77 } else {
78 static_assert(!std::is_same_v<FF, FF>, "Unsupported field type for elliptic relation");
79 }
80 }
81
88 template <typename ContainerOverSubrelations, typename AllEntities, typename Parameters>
89 inline static void accumulate(ContainerOverSubrelations& accumulators,
90 const AllEntities& in,
91 const Parameters&,
92 const FF& scaling_factor)
93 {
95 using CoefficientAccumulator = typename Accumulator::CoefficientAccumulator;
96 auto x_3_m = CoefficientAccumulator(in[AllEntities::EntityId::w_r_shift]);
97 auto y_1_m = CoefficientAccumulator(in[AllEntities::EntityId::w_o]);
98 auto y_2_m = CoefficientAccumulator(in[AllEntities::EntityId::w_4_shift]);
99
100 auto x_1_m = CoefficientAccumulator(in[AllEntities::EntityId::w_r]);
101 auto x_2_m = CoefficientAccumulator(in[AllEntities::EntityId::w_l_shift]);
102 auto y_3_m = CoefficientAccumulator(in[AllEntities::EntityId::w_o_shift]);
103 auto q_elliptic_m = CoefficientAccumulator(in[AllEntities::EntityId::q_elliptic]);
104 auto q_is_double_m = CoefficientAccumulator(in[AllEntities::EntityId::q_m]);
105 auto q_sign_m = CoefficientAccumulator(in[AllEntities::EntityId::q_l]);
106
107 // We efficiently construct the following:
108 auto x2_sub_x1_m = (x_2_m - x_1_m); // (x2 - x1)
109 auto x1_mul_3_m = (x_1_m + x_1_m + x_1_m); // (3*x1)
110 auto x3_sub_x1_m = x_3_m - x_1_m; // (x3 - x1)
111 auto x3_plus_two_x1_m = x3_sub_x1_m + x1_mul_3_m; // (x3 - x1 + 3*x1) = (x3 + 2*x1)
112 auto x3_plus_x2_plus_x1_m = x3_plus_two_x1_m + x2_sub_x1_m; // (x3 + 2*x1 + x2 - x1) = (x3 + x2 + x1)
113 Accumulator x3_plus_x2_plus_x1(x3_plus_x2_plus_x1_m);
114 Accumulator x3_sub_x1(x3_sub_x1_m);
115 Accumulator x1_mul_3(x1_mul_3_m);
116 Accumulator x3_plus_two_x1(x3_plus_two_x1_m);
117
118 // Contribution (1) point addition, x-coordinate check:
119 // q_elliptic * (q_is_double - 1) * (x3 + x2 + x1)(x2 - x1)(x2 - x1) - y2^2 - y1^2 + 2(y2y1)*q_sign = 0
120 auto y2_sqr_m = y_2_m.sqr();
121 auto y1_sqr_m = y_1_m.sqr();
122 auto y2_mul_q_sign_m = y_2_m * q_sign_m;
123 auto x_add_identity = x3_plus_x2_plus_x1 * Accumulator(x2_sub_x1_m.sqr()) - Accumulator(y2_sqr_m + y1_sqr_m) +
124 Accumulator(y2_mul_q_sign_m + y2_mul_q_sign_m) * Accumulator(y_1_m);
125
126 auto q_elliptic_by_scaling_m = q_elliptic_m * scaling_factor; // a * q_elliptic
127 auto q_elliptic_q_double_scaling_m = (q_elliptic_by_scaling_m * q_is_double_m); // a * q_elliptic * q_is_double
128 Accumulator q_elliptic_q_double_scaling(q_elliptic_q_double_scaling_m);
129 // (a * q_elliptic * q_is_double - a * q_elliptic) = a * q_elliptic * (q_is_double - 1)
130 auto neg_q_elliptic_not_double_scaling = Accumulator(q_elliptic_q_double_scaling_m - q_elliptic_by_scaling_m);
131 std::get<0>(accumulators) -= x_add_identity * neg_q_elliptic_not_double_scaling;
132
133 // Contribution (2) point addition, x-coordinate check:
134 // q_elliptic * (q_is_double - 1) * (y1 + y3)(x2 - x1) + (x3 - x1)(q_sign * y2 - y1) = 0
135 auto y1_plus_y3_m = y_1_m + y_3_m; // (y1 + y3)
136 auto y_diff_m = y2_mul_q_sign_m - y_1_m; // (q_sign * y2 - y1)
137 auto y_diff = Accumulator(y_diff_m);
138 auto y_add_identity = Accumulator(y1_plus_y3_m * x2_sub_x1_m) + (x3_sub_x1)*y_diff;
139 std::get<1>(accumulators) -= y_add_identity * neg_q_elliptic_not_double_scaling;
140
141 // Contribution (3) point doubling, x-coordinate check
142 // (x3 + x1 + x1) (4*y1*y1) - 9 * x1 * x1 * x1 * x1 = 0
143 // N.B. we're using the equivalence x1^3 === y1^2 - curve_b to reduce degree by 1
144 const auto curve_b = get_curve_b();
145 auto x_pow_4_mul_3 = (Accumulator(y1_sqr_m - curve_b)) * x1_mul_3;
146 auto y1_sqr_mul_4_m = y1_sqr_m + y1_sqr_m;
147 y1_sqr_mul_4_m += y1_sqr_mul_4_m;
148 auto x1_pow_4_mul_9 = x_pow_4_mul_3 + x_pow_4_mul_3 + x_pow_4_mul_3;
149 auto x_double_identity = x3_plus_two_x1 * Accumulator(y1_sqr_mul_4_m) - x1_pow_4_mul_9;
150 std::get<0>(accumulators) += x_double_identity * q_elliptic_q_double_scaling;
151
152 // Contribution (4) point doubling, y-coordinate check
153 // (y1 + y3) (2*y1) - (3 * x1 * x1)(x1 - x3) = 0
154 auto x1_sqr_mul_3 = Accumulator(x1_mul_3_m * x_1_m);
155 auto neg_y_double_identity = x1_sqr_mul_3 * (x3_sub_x1) + Accumulator((y_1_m + y_1_m) * (y1_plus_y3_m));
156 std::get<1>(accumulators) -= neg_y_double_identity * q_elliptic_q_double_scaling;
157 };
158};
159
161} // namespace bb
Expression for elliptic curve point addition and doubling.
static constexpr std::array< size_t, 2 > SUBRELATION_PARTIAL_LENGTHS
static bool skip(const AllEntities &in)
Returns true if the contribution from all subrelations for the provided inputs is identically zero.
static constexpr FF get_curve_b()
static void accumulate(ContainerOverSubrelations &accumulators, const AllEntities &in, const Parameters &, const FF &scaling_factor)
A wrapper for Relations to expose methods used by the Sumcheck prover or verifier to add the contribu...
static constexpr Fq curve_b
Definition group.hpp:53
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
static constexpr uint256_t modulus