Skip to content
This repository was archived by the owner on Feb 17, 2025. It is now read-only.

Commit 3a785a6

Browse files
ayashunskyIluvmagick
authored andcommitted
g2 point doubling and tests
1 parent 39cf40e commit 3a785a6

File tree

4 files changed

+442
-9
lines changed

4 files changed

+442
-9
lines changed
Lines changed: 311 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
//---------------------------------------------------------------------------//
2+
// Copyright (c) 2023 Alexey Yashunsky <[email protected]>
3+
//
4+
// MIT License
5+
//
6+
// Permission is hereby granted, free of charge, to any person obtaining a copy
7+
// of this software and associated documentation files (the "Software"), to deal
8+
// in the Software without restriction, including without limitation the rights
9+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
// copies of the Software, and to permit persons to whom the Software is
11+
// furnished to do so, subject to the following conditions:
12+
//
13+
// The above copyright notice and this permission notice shall be included in all
14+
// copies or substantial portions of the Software.
15+
//
16+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
// SOFTWARE.
23+
//---------------------------------------------------------------------------//
24+
// @file Declaration of interfaces for point doubling in the elliptic
25+
// curve group G2 = E'(F_p^2) : y^2 = x^3 + 4(1+u) with
26+
// F_p^2 = F_p[u]/(u^2 - (-1)).
27+
//---------------------------------------------------------------------------//
28+
29+
#ifndef CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_BLS12_G2_POINT_DOUBLE_HPP
30+
#define CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_BLS12_G2_POINT_DOUBLE_HPP
31+
32+
#include <nil/crypto3/zk/snark/arithmetization/plonk/constraint_system.hpp>
33+
34+
#include <nil/blueprint/blueprint/plonk/assignment.hpp>
35+
#include <nil/blueprint/blueprint/plonk/circuit.hpp>
36+
#include <nil/blueprint/component.hpp>
37+
#include <nil/blueprint/manifest.hpp>
38+
39+
#include <nil/crypto3/algebra/fields/detail/element/fp2.hpp>
40+
#include <nil/crypto3/algebra/fields/fp2.hpp>
41+
42+
namespace nil {
43+
namespace blueprint {
44+
namespace components {
45+
namespace detail {
46+
// actually compute bilinear forms that represent multiplication in F_p^2
47+
template<typename T>
48+
std::array<T,2> perform_fp2_mult(std::array<T,2> a, std::array<T,2> b) {
49+
std::array<T,2> c = {a[0]*b[0] - a[1]*b[1], a[0]*b[1] + a[1]*b[0]};
50+
return c;
51+
}
52+
53+
template<typename T>
54+
std::array<T,2> perform_fp2_add(std::array<T,2> a, std::array<T,2> b) {
55+
std::array<T,2> c = {a[0] + b[0], a[1] + b[1]};
56+
return c;
57+
}
58+
59+
template<typename T>
60+
std::array<T,2> perform_fp2_sub(std::array<T,2> a, std::array<T,2> b) {
61+
std::array<T,2> c = {a[0] - b[0], a[1] - b[1]};
62+
return c;
63+
}
64+
65+
template<typename T>
66+
std::array<T,2> perform_fp2_scale(std::array<T,2> a, int x) {
67+
std::array<T,2> c = {a[0]*x, a[1]*x};
68+
return c;
69+
}
70+
} // namespace detail
71+
// E'(F_p^2) : y^2 = x^3 + 4(1+u) point doubling gate
72+
// Input: (xP, yP) = P[4]
73+
// Output: (xR, yR) = R[4], R = [2]P as element of E'(F_p^2)
74+
75+
// constraint-generating functions
76+
using detail::perform_fp2_mult;
77+
using detail::perform_fp2_add;
78+
using detail::perform_fp2_sub;
79+
using detail::perform_fp2_scale;
80+
81+
template<typename ArithmetizationType, typename BlueprintFieldType>
82+
class bls12_g2_point_double;
83+
84+
template<typename BlueprintFieldType, typename ArithmetizationParams>
85+
class bls12_g2_point_double<crypto3::zk::snark::plonk_constraint_system<BlueprintFieldType, ArithmetizationParams>,
86+
BlueprintFieldType>
87+
: public plonk_component<BlueprintFieldType, ArithmetizationParams, 0, 0> {
88+
89+
public:
90+
using component_type = plonk_component<BlueprintFieldType, ArithmetizationParams, 0, 0>;
91+
92+
using var = typename component_type::var;
93+
using manifest_type = plonk_component_manifest;
94+
95+
class gate_manifest_type : public component_gate_manifest {
96+
public:
97+
std::uint32_t gates_amount() const override {
98+
return bls12_g2_point_double::gates_amount;
99+
}
100+
};
101+
102+
static gate_manifest get_gate_manifest(std::size_t witness_amount,
103+
std::size_t lookup_column_amount) {
104+
static gate_manifest manifest = gate_manifest(gate_manifest_type());
105+
return manifest;
106+
}
107+
108+
static manifest_type get_manifest() {
109+
static manifest_type manifest = manifest_type(
110+
std::shared_ptr<manifest_param>(new manifest_single_value_param(8)),
111+
false
112+
);
113+
return manifest;
114+
}
115+
116+
constexpr static std::size_t get_rows_amount(std::size_t witness_amount,
117+
std::size_t lookup_column_amount) {
118+
return 1;
119+
}
120+
121+
constexpr static const std::size_t gates_amount = 1;
122+
const std::size_t rows_amount = get_rows_amount(this->witness_amount(), 0);
123+
124+
struct input_type {
125+
std::array<var,4> P;
126+
127+
std::vector<var> all_vars() const {
128+
std::vector<var> res = {};
129+
for(auto & e : P) { res.push_back(e); }
130+
return res;
131+
}
132+
};
133+
134+
struct result_type {
135+
std::array<var,4> R;
136+
137+
result_type(const bls12_g2_point_double &component, std::uint32_t start_row_index) {
138+
for(std::size_t i = 0; i < 4; i++) {
139+
R[i] = var(component.W(i+4), start_row_index, false, var::column_type::witness);
140+
}
141+
}
142+
143+
std::vector<var> all_vars() const {
144+
std::vector<var> res = {};
145+
146+
for(auto & e : R) { res.push_back(e); }
147+
return res;
148+
}
149+
};
150+
151+
template<typename ContainerType>
152+
explicit bls12_g2_point_double(ContainerType witness) : component_type(witness, {}, {}, get_manifest()) {};
153+
154+
template<typename WitnessContainerType, typename ConstantContainerType,
155+
typename PublicInputContainerType>
156+
bls12_g2_point_double(WitnessContainerType witness, ConstantContainerType constant,
157+
PublicInputContainerType public_input) :
158+
component_type(witness, constant, public_input, get_manifest()) {};
159+
160+
bls12_g2_point_double(
161+
std::initializer_list<typename component_type::witness_container_type::value_type>
162+
witnesses,
163+
std::initializer_list<typename component_type::constant_container_type::value_type>
164+
constants,
165+
std::initializer_list<typename component_type::public_input_container_type::value_type>
166+
public_inputs) :
167+
component_type(witnesses, constants, public_inputs, get_manifest()) {};
168+
};
169+
170+
template<typename BlueprintFieldType, typename ArithmetizationParams>
171+
using plonk_bls12_g2_point_double =
172+
bls12_g2_point_double<
173+
crypto3::zk::snark::plonk_constraint_system<BlueprintFieldType, ArithmetizationParams>,
174+
BlueprintFieldType>;
175+
176+
template<typename BlueprintFieldType, typename ArithmetizationParams>
177+
typename plonk_bls12_g2_point_double<BlueprintFieldType, ArithmetizationParams>::result_type generate_assignments(
178+
const plonk_bls12_g2_point_double<BlueprintFieldType, ArithmetizationParams> &component,
179+
assignment<crypto3::zk::snark::plonk_constraint_system<BlueprintFieldType, ArithmetizationParams>>
180+
&assignment,
181+
const typename plonk_bls12_g2_point_double<BlueprintFieldType, ArithmetizationParams>::input_type
182+
&instance_input,
183+
const std::uint32_t start_row_index) {
184+
185+
using value_type = typename BlueprintFieldType::value_type;
186+
187+
using policy_type_fp2 = crypto3::algebra::fields::fp2<BlueprintFieldType>;
188+
using fp2_element = typename policy_type_fp2::value_type;
189+
190+
fp2_element xP = fp2_element(var_value(assignment, instance_input.P[0]),
191+
var_value(assignment, instance_input.P[1])),
192+
yP = fp2_element(var_value(assignment, instance_input.P[2]),
193+
var_value(assignment, instance_input.P[3]));
194+
fp2_element xR, yR, lambda, nu;
195+
196+
for(std::size_t i = 0; i < 4; i++) {
197+
assignment.witness(component.W(i),start_row_index) = var_value(assignment, instance_input.P[i]);
198+
}
199+
200+
lambda = 3*xP.pow(2) / (2*yP);
201+
nu = yP - lambda*xP;
202+
xR = lambda.pow(2) - 2*xP;
203+
yR = -(lambda*xR + nu);
204+
205+
for(std::size_t i = 0; i < 2; i++) {
206+
assignment.witness(component.W(4 + i),start_row_index) = xR.data[i];
207+
assignment.witness(component.W(6 + i),start_row_index) = yR.data[i];
208+
}
209+
210+
return typename plonk_bls12_g2_point_double<BlueprintFieldType, ArithmetizationParams>::result_type(
211+
component, start_row_index);
212+
}
213+
214+
template<typename BlueprintFieldType, typename ArithmetizationParams>
215+
std::size_t generate_gates(
216+
const plonk_bls12_g2_point_double<BlueprintFieldType, ArithmetizationParams> &component,
217+
circuit<crypto3::zk::snark::plonk_constraint_system<BlueprintFieldType, ArithmetizationParams>> &bp,
218+
assignment<crypto3::zk::snark::plonk_constraint_system<BlueprintFieldType, ArithmetizationParams>>
219+
&assignment,
220+
const typename plonk_bls12_g2_point_double<BlueprintFieldType, ArithmetizationParams>::input_type
221+
&instance_input) {
222+
223+
using var = typename plonk_bls12_g2_point_double<BlueprintFieldType, ArithmetizationParams>::var;
224+
using constraint_type = crypto3::zk::snark::plonk_constraint<BlueprintFieldType>;
225+
226+
std::array<constraint_type,2> xP, yP, xR, yR, C1, C2;
227+
228+
for(std::size_t i = 0; i < 2; i++) {
229+
xP[i] = var(component.W(i), 0, true);
230+
yP[i] = var(component.W(i+2), 0, true);
231+
xR[i] = var(component.W(i+4), 0, true);
232+
yR[i] = var(component.W(i+6), 0, true);
233+
}
234+
// the defining equations are
235+
// xR = (3xP^2 / 2yP)^2 - 2xP
236+
// yR = - (3xP^2 / 2yP) xR - yP + (3xP^2 / 2yP)xP
237+
// We transform them into constraints:
238+
// (2yP)^2 (xR + 2xP) - (3xP^2)^2 = 0
239+
// (2yP) (yR + yP) + (3xP^2)(xR - xP) = 0
240+
241+
C1 = perform_fp2_sub(
242+
perform_fp2_mult(
243+
perform_fp2_mult(perform_fp2_scale(yP,2),perform_fp2_scale(yP,2)),
244+
perform_fp2_add(xR, perform_fp2_scale(xP,2))
245+
),
246+
perform_fp2_mult(
247+
perform_fp2_scale(perform_fp2_mult(xP,xP),3),
248+
perform_fp2_scale(perform_fp2_mult(xP,xP),3)
249+
)
250+
);
251+
C2 = perform_fp2_add(
252+
perform_fp2_mult(
253+
perform_fp2_scale(yP,2),
254+
perform_fp2_add(yR,yP)
255+
),
256+
perform_fp2_mult(
257+
perform_fp2_scale(perform_fp2_mult(xP,xP),3),
258+
perform_fp2_sub(xR,xP)
259+
)
260+
);
261+
262+
std::vector<constraint_type> Cs = {};
263+
for(std::size_t i = 0; i < 2; i++) {
264+
Cs.push_back(C1[i]);
265+
Cs.push_back(C2[i]);
266+
}
267+
return bp.add_gate(Cs);
268+
}
269+
270+
template<typename BlueprintFieldType, typename ArithmetizationParams>
271+
void generate_copy_constraints(
272+
const plonk_bls12_g2_point_double<BlueprintFieldType, ArithmetizationParams> &component,
273+
circuit<crypto3::zk::snark::plonk_constraint_system<BlueprintFieldType, ArithmetizationParams>> &bp,
274+
assignment<crypto3::zk::snark::plonk_constraint_system<BlueprintFieldType, ArithmetizationParams>>
275+
&assignment,
276+
const typename plonk_bls12_g2_point_double<BlueprintFieldType, ArithmetizationParams>::input_type &instance_input,
277+
const std::size_t start_row_index) {
278+
279+
using var = typename plonk_bls12_g2_point_double<BlueprintFieldType, ArithmetizationParams>::var;
280+
281+
const std::size_t WA = component.witness_amount();
282+
283+
for(std::size_t i = 0; i < 4; i++) {
284+
bp.add_copy_constraint({var(component.W(i), start_row_index, false), instance_input.P[i]});
285+
}
286+
}
287+
288+
template<typename BlueprintFieldType, typename ArithmetizationParams>
289+
typename plonk_bls12_g2_point_double<BlueprintFieldType, ArithmetizationParams>::result_type generate_circuit(
290+
const plonk_bls12_g2_point_double<BlueprintFieldType, ArithmetizationParams> &component,
291+
circuit<crypto3::zk::snark::plonk_constraint_system<BlueprintFieldType, ArithmetizationParams>> &bp,
292+
assignment<crypto3::zk::snark::plonk_constraint_system<BlueprintFieldType, ArithmetizationParams>>
293+
&assignment,
294+
const typename plonk_bls12_g2_point_double<BlueprintFieldType, ArithmetizationParams>::input_type &instance_input,
295+
const std::size_t start_row_index) {
296+
297+
std::size_t selector_index = generate_gates(component, bp, assignment, instance_input);
298+
299+
assignment.enable_selector(selector_index, start_row_index);
300+
301+
generate_copy_constraints(component, bp, assignment, instance_input, start_row_index);
302+
303+
return typename plonk_bls12_g2_point_double<BlueprintFieldType, ArithmetizationParams>::result_type(
304+
component, start_row_index);
305+
}
306+
307+
} // namespace components
308+
} // namespace blueprint
309+
} // namespace nil
310+
311+
#endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_BLS12_G2_POINT_DOUBLE_HPP

include/nil/blueprint/components/algebra/fields/plonk/non_native/detail/perform_fp12_mult.hpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,6 @@
3131
#ifndef CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_PERFORM_FP12_MULT_HPP
3232
#define CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_PERFORM_FP12_MULT_HPP
3333

34-
/*
35-
#include <nil/crypto3/zk/snark/arithmetization/plonk/constraint_system.hpp>
36-
37-
#include <nil/blueprint/blueprint/plonk/assignment.hpp>
38-
#include <nil/blueprint/blueprint/plonk/circuit.hpp>
39-
#include <nil/blueprint/component.hpp>
40-
#include <nil/blueprint/manifest.hpp>
41-
*/
42-
4334
namespace nil {
4435
namespace blueprint {
4536
namespace components {

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ set(PLONK_TESTS_FILES
8686
"algebra/curves/plonk/unified_addition"
8787
"algebra/curves/plonk/variable_base_endo_scalar_mul"
8888
"algebra/curves/plonk/endo_scalar"
89+
"algebra/curves/plonk/bls12_g2"
8990
"hashes/plonk/poseidon"
9091
"hashes/plonk/sha256"
9192
"hashes/plonk/sha512"

0 commit comments

Comments
 (0)