26 #ifndef CRYPTO3_MARSHALLING_ALGEBRA_CURVES_HPP
27 #define CRYPTO3_MARSHALLING_ALGEBRA_CURVES_HPP
31 #include <nil/crypto3/multiprecision/cpp_int.hpp>
33 #include <boost/concept/assert.hpp>
38 namespace marshalling {
42 template<
typename CurveType>
51 typedef typename curve_type::template g1_type<>::value_type
g1_value_type;
52 typedef typename curve_type::template g2_type<>::value_type
g2_value_type;
54 typedef typename curve_type::template g1_type<algebra::curves::coordinates::affine>::value_type
56 typedef typename curve_type::template g2_type<algebra::curves::coordinates::affine>::value_type
64 constexpr
static const unsigned sizeof_field_element = 48;
75 auto m_byte = evaluate_m_byte(point, point_affine,
true);
77 if (!(I_bit & m_byte)) {
78 multiprecision::export_bits(
79 point_affine.X.data.template convert_to<integral_type>(), result.rbegin(), 8,
false);
88 auto m_byte = evaluate_m_byte(point, point_affine,
false);
90 if (!(I_bit & m_byte)) {
91 multiprecision::export_bits(
92 point_affine.Y.data.template convert_to<integral_type>(), result.rbegin(), 8,
false);
93 multiprecision::export_bits(point_affine.X.data.template convert_to<integral_type>(),
94 result.rbegin() + sizeof_field_element,
105 auto m_byte = evaluate_m_byte(point, point_affine,
true);
107 if (!(I_bit & m_byte)) {
108 multiprecision::export_bits(
109 point_affine.X.data[0].data.template convert_to<integral_type>(), result.rbegin(), 8,
false);
110 multiprecision::export_bits(point_affine.X.data[1].data.template convert_to<integral_type>(),
111 result.rbegin() + sizeof_field_element,
122 auto m_byte = evaluate_m_byte(point, point_affine,
false);
124 if (!(I_bit & m_byte)) {
125 multiprecision::export_bits(
126 point_affine.Y.data[0].data.template convert_to<integral_type>(), result.rbegin(), 8,
false);
127 multiprecision::export_bits(point_affine.Y.data[1].data.template convert_to<integral_type>(),
128 result.rbegin() + sizeof_field_element,
131 multiprecision::export_bits(point_affine.X.data[0].data.template convert_to<integral_type>(),
132 result.rbegin() + 2 * sizeof_field_element,
135 multiprecision::export_bits(point_affine.X.data[1].data.template convert_to<integral_type>(),
136 result.rbegin() + 3 * sizeof_field_element,
147 template<
typename PointOctetsRange,
148 typename =
typename std::enable_if<
149 std::is_same<std::uint8_t, typename PointOctetsRange::value_type>::value>::type>
151 BOOST_CONCEPT_ASSERT((boost::SinglePassRangeConcept<PointOctetsRange>));
153 const std::uint8_t m_byte = *octets.begin() & 0xE0;
154 BOOST_ASSERT(m_byte != 0x20 && m_byte != 0x60 && m_byte != 0xE0);
156 PointOctetsRange point_octets;
157 std::copy(octets.begin(), octets.end(), point_octets.begin());
158 *point_octets.begin() &= 0x1F;
160 if (m_byte & C_bit) {
161 return compressed_to_g1_point(point_octets, m_byte);
163 return uncompressed_to_g1_point(point_octets, m_byte);
167 template<
typename PointOctetsRange,
168 typename =
typename std::enable_if<
169 std::is_same<std::uint8_t, typename PointOctetsRange::value_type>::value>::type>
171 BOOST_CONCEPT_ASSERT((boost::SinglePassRangeConcept<PointOctetsRange>));
173 const std::uint8_t m_byte = *octets.begin() & 0xE0;
174 BOOST_ASSERT(m_byte != 0x20 && m_byte != 0x60 && m_byte != 0xE0);
176 PointOctetsRange point_octets;
177 std::copy(octets.begin(), octets.end(), point_octets.begin());
178 *point_octets.begin() &= 0x1F;
180 if (m_byte & C_bit) {
181 return compressed_to_g2_point(point_octets, m_byte);
183 return uncompressed_to_g2_point(point_octets, m_byte);
187 constexpr
static const std::uint8_t C_bit = 0x80;
188 constexpr
static const std::uint8_t I_bit = 0x40;
189 constexpr
static const std::uint8_t S_bit = 0x20;
193 template<
typename PointOctetsRange,
194 typename =
typename std::enable_if<
195 std::is_same<std::uint8_t, typename PointOctetsRange::value_type>::value>::type>
197 BOOST_ASSERT(std::distance(point_octets.begin(), point_octets.end()) == sizeof_field_element);
199 if (m_byte & I_bit) {
200 BOOST_ASSERT(point_octets.end() == std::find(point_octets.begin(), point_octets.end(),
true));
205 multiprecision::import_bits(x, point_octets.rbegin(), point_octets.rend(), 8,
false);
208 BOOST_ASSERT(y2_mod.is_square());
210 bool Y_bit = sign_gf_p(y_mod);
211 if (Y_bit ==
bool(m_byte & S_bit)) {
212 g1_value_type result(x_mod, y_mod, g1_field_value_type::one());
213 BOOST_ASSERT(result.is_well_formed());
216 g1_value_type result(x_mod, -y_mod, g1_field_value_type::one());
217 BOOST_ASSERT(result.is_well_formed());
221 template<
typename PointOctetsRange,
222 typename =
typename std::enable_if<
223 std::is_same<std::uint8_t, typename PointOctetsRange::value_type>::value>::type>
225 BOOST_ASSERT(std::distance(point_octets.begin(), point_octets.end()) == 2 * sizeof_field_element);
227 if (m_byte & I_bit) {
228 BOOST_ASSERT(point_octets.end() == std::find(point_octets.begin(), point_octets.end(),
true));
233 multiprecision::import_bits(
234 y, point_octets.rbegin(), point_octets.rbegin() + sizeof_field_element, 8,
false);
235 multiprecision::import_bits(
236 x, point_octets.rbegin() + sizeof_field_element, point_octets.rend(), 8,
false);
238 BOOST_ASSERT(result.is_well_formed());
242 template<
typename PointOctetsRange,
243 typename =
typename std::enable_if<
244 std::is_same<std::uint8_t, typename PointOctetsRange::value_type>::value>::type>
246 BOOST_ASSERT(std::distance(point_octets.begin(), point_octets.end()) == 2 * sizeof_field_element);
248 if (m_byte & I_bit) {
249 BOOST_ASSERT(point_octets.end() == std::find(point_octets.begin(), point_octets.end(),
true));
254 multiprecision::import_bits(
255 x_0, point_octets.rbegin(), point_octets.rbegin() + sizeof_field_element, 8,
false);
256 multiprecision::import_bits(
257 x_1, point_octets.rbegin() + sizeof_field_element, point_octets.rend(), 8,
false);
260 BOOST_ASSERT(y2_mod.is_square());
262 bool Y_bit = sign_gf_p(y_mod);
263 if (Y_bit ==
bool(m_byte & S_bit)) {
264 g2_value_type result(x_mod, y_mod, g2_field_value_type::one());
265 BOOST_ASSERT(result.is_well_formed());
268 g2_value_type result(x_mod, -y_mod, g2_field_value_type::one());
269 BOOST_ASSERT(result.is_well_formed());
273 template<
typename PointOctetsRange,
274 typename =
typename std::enable_if<
275 std::is_same<std::uint8_t, typename PointOctetsRange::value_type>::value>::type>
277 BOOST_ASSERT(std::distance(point_octets.begin(), point_octets.end()) == 4 * sizeof_field_element);
279 if (m_byte & I_bit) {
280 BOOST_ASSERT(point_octets.end() == std::find(point_octets.begin(), point_octets.end(),
true));
285 multiprecision::import_bits(
286 y_0, point_octets.rbegin(), point_octets.rbegin() + sizeof_field_element, 8,
false);
287 multiprecision::import_bits(y_1,
288 point_octets.rbegin() + sizeof_field_element,
289 point_octets.rbegin() + 2 * sizeof_field_element,
292 multiprecision::import_bits(x_0,
293 point_octets.rbegin() + 2 * sizeof_field_element,
294 point_octets.rbegin() + 3 * sizeof_field_element,
297 multiprecision::import_bits(
298 x_1, point_octets.rbegin() + 3 * sizeof_field_element, point_octets.rend(), 8,
false);
301 g2_field_value_type::one());
302 BOOST_ASSERT(result.is_well_formed());
307 static const typename g1_field_value_type::integral_type half_p =
317 if (v.data[1] == 0) {
318 return sign_gf_p(v.data[0]);
320 return sign_gf_p(v.data[1]);
323 template<
typename GroupValueType,
typename GroupAffineValueType>
325 const GroupAffineValueType &point_affine,
327 std::uint8_t result = 0;
332 if (point.is_zero()) {
334 }
else if (compression && sign_gf_p(point_affine.Y)) {
A struct representing a BLS12-381 and BLS12-377 curve.
Definition: curves/bls12.hpp:49
g1_value_type::field_type::value_type g1_field_value_type
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:59
static g1_value_type compressed_to_g1_point(PointOctetsRange &point_octets, std::uint8_t m_byte)
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:196
static g1_value_type uncompressed_to_g1_point(PointOctetsRange &point_octets, std::uint8_t m_byte)
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:224
static bool sign_gf_p(const g1_field_value_type &v)
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:306
static g2_value_type compressed_to_g2_point(PointOctetsRange &point_octets, std::uint8_t m_byte)
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:245
std::array< std::uint8_t, 2 *sizeof_field_element > compressed_g2_octets
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:67
curve_type::template g1_type ::value_type g1_value_type
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:51
static g1_value_type octets_to_g1_point(const PointOctetsRange &octets)
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:150
g1_field_value_type::integral_type integral_type
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:62
algebra::curves::bls12_381 curve_type
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:49
curve_type::template g2_type< algebra::curves::coordinates::affine >::value_type g2_affine_value_type
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:57
curve_type::template g1_type< algebra::curves::coordinates::affine >::value_type g1_affine_value_type
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:55
std::array< std::uint8_t, 4 *sizeof_field_element > uncompressed_g2_octets
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:68
static g2_value_type octets_to_g2_point(const PointOctetsRange &octets)
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:170
std::array< std::uint8_t, sizeof_field_element > compressed_g1_octets
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:65
curve_type::template g2_type ::value_type g2_value_type
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:52
g2_value_type::field_type::value_type g2_field_value_type
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:60
static uncompressed_g2_octets point_to_octets(const g2_value_type &point)
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:119
static compressed_g2_octets point_to_octets_compress(const g2_value_type &point)
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:102
static std::uint8_t evaluate_m_byte(const GroupValueType &point, const GroupAffineValueType &point_affine, bool compression)
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:324
static uncompressed_g1_octets point_to_octets(const g1_value_type &point)
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:85
static bool sign_gf_p(const g2_field_value_type &v)
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:316
static compressed_g1_octets point_to_octets_compress(const g1_value_type &point)
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:72
static g2_value_type uncompressed_to_g2_point(PointOctetsRange &point_octets, std::uint8_t m_byte)
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:276
std::array< std::uint8_t, 2 *sizeof_field_element > uncompressed_g1_octets
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:66
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:43