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

Commit f1b1bae

Browse files
committed
work in progress on implementing the marshalling #318
Fixing the compilation. Finished with marshalling of all supported curves #318
1 parent 246955a commit f1b1bae

File tree

17 files changed

+2771
-1216
lines changed

17 files changed

+2771
-1216
lines changed

libs/algebra/include/nil/crypto3/algebra/curves/curve25519.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ namespace nil {
4646
typedef typename policy_type::scalar_field_type scalar_field_type;
4747

4848
template<typename Coordinates = coordinates::extended_with_a_minus_1,
49-
typename Form = forms::montgomery>
49+
typename Form = forms::twisted_edwards>
5050
using g1_type = typename detail::curve25519_g1<Form, Coordinates>;
5151
};
5252
} // namespace curves

libs/algebra/include/nil/crypto3/algebra/curves/detail/babyjubjub/g1.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131

3232
#include <nil/crypto3/algebra/curves/forms.hpp>
3333
#include <nil/crypto3/algebra/curves/detail/forms/twisted_edwards/element_g1_affine.hpp>
34-
#include <nil/crypto3/algebra/curves/detail/forms/montgomery/element_g1_affine.hpp>
3534

3635
namespace nil {
3736
namespace crypto3 {

libs/algebra/include/nil/crypto3/algebra/curves/detail/curve25519/g1.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
#include <nil/crypto3/algebra/curves/detail/forms/twisted_edwards/coordinates.hpp>
3232
#ifdef __ZKLLVM__
3333
#else
34-
// #include <nil/crypto3/algebra/curves/detail/forms/montgomery/xz/element_g1.hpp>
3534
#include <nil/crypto3/algebra/curves/detail/forms/twisted_edwards/extended_with_a_minus_1/element_g1.hpp>
3635
#endif
3736

Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
//---------------------------------------------------------------------------//
2+
// Copyright (c) 2017-2021 Mikhail Komarov <[email protected]>
3+
// Copyright (c) 2020-2021 Nikita Kaskov <[email protected]>
4+
// Copyright (c) 2024 Vasiliy Olekhov <[email protected]>
5+
//
6+
// MIT License
7+
//
8+
// Permission is hereby granted, free of charge, to any person obtaining a copy
9+
// of this software and associated documentation files (the "Software"), to deal
10+
// in the Software without restriction, including without limitation the rights
11+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
// copies of the Software, and to permit persons to whom the Software is
13+
// furnished to do so, subject to the following conditions:
14+
//
15+
// The above copyright notice and this permission notice shall be included in all
16+
// copies or substantial portions of the Software.
17+
//
18+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24+
// SOFTWARE.
25+
//---------------------------------------------------------------------------//
26+
27+
#ifndef CRYPTO3_MARSHALLING_PROCESSING_ALT_BN128_CURVE_ELEMENT_HPP
28+
#define CRYPTO3_MARSHALLING_PROCESSING_ALT_BN128_CURVE_ELEMENT_HPP
29+
30+
#include <cstddef>
31+
#include <cstdint>
32+
#include <type_traits>
33+
#include <limits>
34+
#include <iterator>
35+
36+
#include <nil/marshalling/endianness.hpp>
37+
#include <nil/marshalling/status_type.hpp>
38+
39+
#include <nil/crypto3/algebra/type_traits.hpp>
40+
41+
#include <nil/crypto3/algebra/curves/alt_bn128.hpp>
42+
43+
#include <nil/crypto3/marshalling/multiprecision/processing/integral.hpp>
44+
45+
#include <nil/crypto3/marshalling/algebra/processing/detail/curve_element.hpp>
46+
#include <nil/crypto3/marshalling/algebra/processing/curve_element.hpp>
47+
48+
namespace nil {
49+
namespace crypto3 {
50+
namespace marshalling {
51+
namespace processing {
52+
53+
54+
template<typename Coordinates>
55+
struct curve_element_writer<
56+
nil::marshalling::endian::big_endian,
57+
typename algebra::curves::alt_bn128_254::template g1_type<
58+
Coordinates,
59+
algebra::curves::forms::short_weierstrass>> {
60+
using group_type = typename algebra::curves::alt_bn128_254::
61+
template g1_type<Coordinates, algebra::curves::forms::short_weierstrass>;
62+
using group_value_type = typename group_type::value_type;
63+
using g1_value_type = group_value_type;
64+
using g1_field_type = typename group_value_type::field_type;
65+
using coordinates = typename group_value_type::coordinates;
66+
using form = typename group_value_type::form;
67+
using endianness = nil::marshalling::endian::big_endian;
68+
using params_type = curve_element_marshalling_params<group_type>;
69+
70+
template<typename TIter>
71+
static nil::marshalling::status_type process(const group_value_type &point, TIter &iter) {
72+
73+
/* Point is always encoded in compressed form, only X coordinate.
74+
* Highest bit is Infinity flag
75+
* Second highest bit is sign of Y coordinate */
76+
77+
using chunk_type = typename TIter::value_type;
78+
constexpr static const chunk_type I_bit = 0x80;
79+
constexpr static const chunk_type S_bit = 0x40;
80+
81+
auto point_affine = point.to_affine();
82+
83+
write_data<params_type::bit_length(), endianness>(
84+
static_cast<typename group_value_type::field_type::integral_type>(point_affine.X.data),
85+
iter);
86+
87+
if (point_affine.is_zero()) {
88+
*iter |= I_bit;
89+
}
90+
91+
if (detail::sign_gf_p<g1_field_type>(point_affine.Y)) {
92+
*iter |= S_bit;
93+
}
94+
95+
return nil::marshalling::status_type::success;
96+
}
97+
};
98+
99+
template<typename Coordinates>
100+
struct curve_element_writer<
101+
nil::marshalling::endian::big_endian,
102+
typename algebra::curves::alt_bn128_254::template g2_type<
103+
Coordinates,
104+
algebra::curves::forms::short_weierstrass>> {
105+
using group_type = typename algebra::curves::alt_bn128_254::
106+
template g2_type<Coordinates, algebra::curves::forms::short_weierstrass>;
107+
using group_value_type = typename group_type::value_type;
108+
using g2_value_type = group_value_type;
109+
using g2_field_type = typename group_value_type::field_type;
110+
using coordinates = typename group_value_type::coordinates;
111+
using form = typename group_value_type::form;
112+
using endianness = nil::marshalling::endian::big_endian;
113+
using params_type = curve_element_marshalling_params<group_type>;
114+
115+
template<typename TIter>
116+
static nil::marshalling::status_type process(const group_value_type &point, TIter &iter) {
117+
118+
/* Point is always encoded in compressed form, only X coordinate.
119+
* Highest bit is Infinity flag
120+
* Second highest bit is sign of Y coordinate */
121+
122+
using chunk_type = typename TIter::value_type;
123+
124+
constexpr static const std::size_t sizeof_field_element =
125+
params_type::bit_length() / (group_value_type::field_type::arity);
126+
constexpr static const std::size_t units_bits = 8;
127+
constexpr static const std::size_t chunk_bits = sizeof(typename TIter::value_type) * units_bits;
128+
constexpr static const std::size_t sizeof_field_element_chunks_count =
129+
(sizeof_field_element / chunk_bits) + ((sizeof_field_element % chunk_bits) ? 1 : 0);
130+
131+
constexpr static const chunk_type I_bit = 0x80;
132+
constexpr static const chunk_type S_bit = 0x40;
133+
typename group_type::curve_type::template g2_type<
134+
typename algebra::curves::coordinates::affine,
135+
form>::value_type point_affine = point.to_affine();
136+
137+
TIter write_iter = iter;
138+
// We assume here, that write_data doesn't change the iter
139+
write_data<sizeof_field_element, endianness>(
140+
static_cast<typename group_value_type::field_type::integral_type>(
141+
point_affine.X.data[1].data),
142+
write_iter);
143+
write_iter += sizeof_field_element_chunks_count;
144+
// We assume here, that write_data doesn't change the iter
145+
write_data<sizeof_field_element, endianness>(
146+
static_cast<typename group_value_type::field_type::integral_type>(
147+
point_affine.X.data[0].data),
148+
write_iter);
149+
150+
if(point.is_zero()) {
151+
*iter |= I_bit;
152+
}
153+
154+
if (detail::sign_gf_p<g2_field_type>(point_affine.Y)) {
155+
*iter |= S_bit;
156+
}
157+
158+
return nil::marshalling::status_type::success;
159+
}
160+
};
161+
162+
163+
template<typename Coordinates>
164+
struct curve_element_reader<
165+
nil::marshalling::endian::big_endian,
166+
typename algebra::curves::alt_bn128_254::template g1_type<
167+
Coordinates,
168+
algebra::curves::forms::short_weierstrass>> {
169+
using group_type = typename algebra::curves::alt_bn128_254::
170+
template g1_type<Coordinates, algebra::curves::forms::short_weierstrass>;
171+
using group_value_type = typename group_type::value_type;
172+
using coordinates = typename group_value_type::coordinates;
173+
using form = typename group_value_type::form;
174+
using endianness = nil::marshalling::endian::big_endian;
175+
using params_type = curve_element_marshalling_params<group_type>;
176+
177+
template<typename TIter>
178+
static nil::marshalling::status_type process(group_value_type &point, TIter &iter) {
179+
using chunk_type = typename TIter::value_type;
180+
181+
constexpr static const std::size_t sizeof_field_element =
182+
params_type::bit_length() / (group_value_type::field_type::arity);
183+
using g1_value_type = group_value_type;
184+
using g1_field_type = typename group_value_type::field_type;
185+
using g1_field_value_type = typename g1_field_type::value_type;
186+
using integral_type = typename g1_value_type::field_type::integral_type;
187+
188+
chunk_type I_bit = *iter & 0x80;
189+
chunk_type S_bit = *iter & 0x40;
190+
191+
integral_type x = read_data<sizeof_field_element, integral_type, endianness>(iter);
192+
193+
if (I_bit) {
194+
// point at infinity
195+
point = g1_value_type();
196+
return nil::marshalling::status_type::success;
197+
}
198+
199+
g1_field_value_type x_mod(x);
200+
g1_field_value_type y2_mod = x_mod.pow(3) + group_type::params_type::b;
201+
BOOST_ASSERT(y2_mod.is_square());
202+
g1_field_value_type y_mod = y2_mod.sqrt();
203+
bool Y_bit = detail::sign_gf_p<g1_field_type>(y_mod);
204+
if (Y_bit == bool(S_bit)) {
205+
g1_value_type result(x_mod, y_mod, g1_field_value_type::one());
206+
BOOST_ASSERT(result.is_well_formed());
207+
point = result;
208+
} else {
209+
g1_value_type result(x_mod, -y_mod, g1_field_value_type::one());
210+
BOOST_ASSERT(result.is_well_formed());
211+
point = result;
212+
}
213+
214+
return nil::marshalling::status_type::success;
215+
}
216+
};
217+
218+
template<typename Coordinates>
219+
struct curve_element_reader<
220+
nil::marshalling::endian::big_endian,
221+
typename algebra::curves::alt_bn128_254::template g2_type<
222+
Coordinates,
223+
algebra::curves::forms::short_weierstrass>> {
224+
using group_type = typename algebra::curves::alt_bn128_254::
225+
template g2_type<Coordinates, algebra::curves::forms::short_weierstrass>;
226+
using group_value_type = typename group_type::value_type;
227+
using coordinates = typename group_value_type::coordinates;
228+
using form = typename group_value_type::form;
229+
using endianness = nil::marshalling::endian::big_endian;
230+
using params_type = curve_element_marshalling_params<group_type>;
231+
232+
template<typename TIter>
233+
static nil::marshalling::status_type process(group_value_type &point, TIter &iter) {
234+
using chunk_type = typename TIter::value_type;
235+
236+
constexpr static const std::size_t sizeof_field_element =
237+
params_type::bit_length() / (group_value_type::field_type::arity);
238+
constexpr static const std::size_t units_bits = 8;
239+
constexpr static const std::size_t chunk_bits = sizeof(chunk_type) * units_bits;
240+
constexpr static const std::size_t sizeof_field_element_chunks_count =
241+
(sizeof_field_element / chunk_bits) + ((sizeof_field_element % chunk_bits) ? 1 : 0);
242+
using g2_value_type = group_value_type;
243+
using g2_field_type = typename g2_value_type::field_type;
244+
using g2_field_value_type = typename g2_field_type::value_type;
245+
using integral_type = typename g2_value_type::field_type::integral_type;
246+
247+
chunk_type I_bit = *iter & 0x80;
248+
chunk_type S_bit = *iter & 0x40;
249+
250+
TIter read_iter = iter;
251+
integral_type x_1 = read_data<sizeof_field_element, integral_type, endianness>(read_iter);
252+
read_iter += sizeof_field_element_chunks_count;
253+
integral_type x_0 = read_data<sizeof_field_element, integral_type, endianness>(read_iter);
254+
255+
if (I_bit) {
256+
// point at infinity
257+
point = group_value_type();
258+
return nil::marshalling::status_type::success;
259+
}
260+
261+
g2_field_value_type x_mod(x_0, x_1);
262+
g2_field_value_type y2_mod = x_mod.pow(3) + group_type::params_type::b;
263+
BOOST_ASSERT(y2_mod.is_square());
264+
g2_field_value_type y_mod = y2_mod.sqrt();
265+
bool Y_bit = detail::sign_gf_p<g2_field_type>(y_mod);
266+
if (Y_bit == bool(S_bit)) {
267+
g2_value_type result(x_mod, y_mod, g2_field_value_type::one());
268+
BOOST_ASSERT(result.is_well_formed());
269+
point = result;
270+
} else {
271+
g2_value_type result(x_mod, -y_mod, g2_field_value_type::one());
272+
BOOST_ASSERT(result.is_well_formed());
273+
point = result;
274+
}
275+
276+
return nil::marshalling::status_type::success;
277+
}
278+
};
279+
280+
} // namespace processing
281+
} // namespace marshalling
282+
} // namespace crypto3
283+
} // namespace nil
284+
#endif // CRYPTO3_MARSHALLING_PROCESSING_CURVE_ELEMENT_HPP

0 commit comments

Comments
 (0)