33
33
#include < nil/crypto3/algebra/fields/arithmetic_params/pallas.hpp>
34
34
#include < nil/crypto3/algebra/curves/vesta.hpp>
35
35
#include < nil/crypto3/algebra/fields/arithmetic_params/vesta.hpp>
36
- #include < nil/crypto3/algebra/random_element .hpp>
36
+ #include < nil/crypto3/random/algebraic_engine .hpp>
37
37
38
38
#include < nil/crypto3/hash/algorithm/hash.hpp>
39
39
#include < nil/crypto3/hash/sha2.hpp>
47
47
48
48
#include " test_plonk_component.hpp"
49
49
50
+ template <typename CurveType>
51
+ struct endo_scalar_params ;
52
+
53
+ template <>
54
+ struct endo_scalar_params <nil::crypto3::algebra::curves::vesta> {
55
+ using curve_type = nil::crypto3::algebra::curves::vesta;
56
+ using scalar_field_type = typename curve_type::scalar_field_type;
57
+ using base_field_type = typename curve_type::base_field_type;
58
+ constexpr static const typename scalar_field_type::value_type endo_r =
59
+ 0x12CCCA834ACDBA712CAAD5DC57AAB1B01D1F8BD237AD31491DAD5EBDFDFE4AB9_cppui255;
60
+ constexpr static const typename base_field_type::value_type endo_q =
61
+ 0x2D33357CB532458ED3552A23A8554E5005270D29D19FC7D27B7FD22F0201B547_cppui255;
62
+ };
63
+
64
+ template <>
65
+ struct endo_scalar_params <nil::crypto3::algebra::curves::pallas> {
66
+ using curve_type = nil::crypto3::algebra::curves::pallas;
67
+ using scalar_field_type = typename curve_type::scalar_field_type;
68
+ using base_field_type = typename curve_type::base_field_type;
69
+ constexpr static const typename scalar_field_type::value_type endo_r =
70
+ 0x397E65A7D7C1AD71AEE24B27E308F0A61259527EC1D4752E619D1840AF55F1B1_cppui255;
71
+ constexpr static const typename base_field_type::value_type endo_q =
72
+ 0x2D33357CB532458ED3552A23A8554E5005270D29D19FC7D27B7FD22F0201B547_cppui255;
73
+ };
74
+
75
+ template <typename CurveType, std::size_t ScalarSize>
76
+ typename CurveType::scalar_field_type::value_type calculate_endo_scalar (typename CurveType::scalar_field_type::value_type scalar) {
77
+
78
+ using endo_params = endo_scalar_params<CurveType>;
79
+ using BlueprintFieldType = typename CurveType::scalar_field_type;
80
+
81
+ typename BlueprintFieldType::value_type endo_r = endo_params::endo_r;
82
+
83
+ const std::size_t crumbs_per_row = 8 ;
84
+ const std::size_t bits_per_crumb = 2 ;
85
+ const std::size_t bits_per_row =
86
+ bits_per_crumb * crumbs_per_row; // we suppose that ScalarSize % bits_per_row = 0
87
+
88
+ typename BlueprintFieldType::integral_type integral_scalar =
89
+ typename BlueprintFieldType::integral_type (scalar.data );
90
+ std::array<bool , ScalarSize> bits_msb;
91
+ {
92
+ nil::marshalling::status_type status;
93
+ assert (ScalarSize <= 255 );
94
+ std::array<bool , 255 > bits_msb_all =
95
+ nil::marshalling::pack<nil::marshalling::option::big_endian>(integral_scalar, status);
96
+ assert (status == nil::marshalling::status_type::success);
97
+ std::copy (bits_msb_all.end () - ScalarSize, bits_msb_all.end (), bits_msb.begin ());
98
+
99
+ for (std::size_t i = 0 ; i < 255 - ScalarSize; ++i) {
100
+ assert (bits_msb_all[i] == false );
101
+ }
102
+ }
103
+ typename BlueprintFieldType::value_type a = 2 ;
104
+ typename BlueprintFieldType::value_type b = 2 ;
105
+ typename BlueprintFieldType::value_type n = 0 ;
106
+
107
+ assert (ScalarSize % bits_per_row == 0 );
108
+ for (std::size_t chunk_start = 0 ; chunk_start < bits_msb.size (); chunk_start += bits_per_row) {
109
+ for (std::size_t j = 0 ; j < crumbs_per_row; j++) {
110
+ std::size_t crumb = chunk_start + j * bits_per_crumb;
111
+ typename BlueprintFieldType::value_type b0 = static_cast <int >(bits_msb[crumb + 1 ]);
112
+ typename BlueprintFieldType::value_type b1 = static_cast <int >(bits_msb[crumb + 0 ]);
113
+
114
+ typename BlueprintFieldType::value_type crumb_value = b0 + b1.doubled ();
115
+
116
+ a = a.doubled ();
117
+ b = b.doubled ();
118
+
119
+ typename BlueprintFieldType::value_type s =
120
+ (b0 == BlueprintFieldType::value_type::one ()) ? 1 : -1 ;
121
+ if (b1 == BlueprintFieldType::value_type::zero ()) {
122
+ b += s;
123
+ } else {
124
+ a += s;
125
+ }
126
+
127
+ n = (n.doubled ()).doubled ();
128
+ n += crumb_value;
129
+ }
130
+ }
131
+ auto res = a * endo_r + b;
132
+ return res;
133
+ }
134
+
50
135
template <typename CurveType>
51
136
void test_endo_scalar (std::vector<typename CurveType::scalar_field_type::value_type> public_input,
52
- typename CurveType::scalar_field_type::value_type expected_res){
137
+ typename CurveType::scalar_field_type::value_type expected_res){
53
138
using BlueprintFieldType = typename CurveType::scalar_field_type;
54
139
constexpr std::size_t WitnessColumns = 15 ;
55
140
constexpr std::size_t PublicInputColumns = 1 ;
@@ -70,8 +155,14 @@ void test_endo_scalar(std::vector<typename CurveType::scalar_field_type::value_t
70
155
var challenge_var (0 , 0 , false , var::column_type::public_input);
71
156
typename component_type::input_type instance_input = {challenge_var};
72
157
73
- auto result_check = [&expected_res](AssignmentType &assignment,
158
+ auto result_check = [&expected_res, public_input ](AssignmentType &assignment,
74
159
typename component_type::result_type &real_res) {
160
+ #ifdef BLUEPRINT_PLONK_PROFILING_ENABLED
161
+ std::cout << " endo_scalar input: " << std::hex << public_input[0 ].data << " \n " ;
162
+ std::cout << " expected result : " << std::hex << expected_res.data << " \n " ;
163
+ std::cout << " real result : " << std::hex << var_value (assignment, real_res.output ).data << " \n\n " ;
164
+ #endif
165
+
75
166
assert (expected_res == var_value (assignment, real_res.output ));
76
167
};
77
168
@@ -80,18 +171,59 @@ void test_endo_scalar(std::vector<typename CurveType::scalar_field_type::value_t
80
171
nil::crypto3::test_component<component_type, BlueprintFieldType, ArithmetizationParams, hash_type, Lambda> (component_instance, public_input, result_check, instance_input);
81
172
}
82
173
174
+ constexpr static const std::size_t random_tests_amount = 10 ;
175
+
83
176
BOOST_AUTO_TEST_SUITE (blueprint_plonk_endo_scalar_test_suite)
84
177
85
- BOOST_AUTO_TEST_CASE(blueprint_plonk_unified_addition_addition ) {
178
+ BOOST_AUTO_TEST_CASE(blueprint_plonk_endo_scalar_vesta ) {
86
179
using curve_type = nil::crypto3::algebra::curves::vesta;
87
180
using BlueprintFieldType = typename curve_type::scalar_field_type;
88
-
181
+
89
182
typename BlueprintFieldType::value_type challenge = 0x00000000000000000000000000000000FC93536CAE0C612C18FBE5F6D8E8EEF2_cppui255;
90
183
typename BlueprintFieldType::value_type result = 0x004638173549A4C55A118327904B54E5F6F6314225C8C862F5AFA2506C77AC65_cppui255;
91
184
92
- std::vector<typename BlueprintFieldType::value_type> public_input = {challenge};
93
-
94
- test_endo_scalar<curve_type>(public_input, result);
185
+ test_endo_scalar<curve_type>({challenge}, result);
186
+ test_endo_scalar<curve_type>({1 }, calculate_endo_scalar<curve_type, 128 >(1 ));
187
+ test_endo_scalar<curve_type>({0 }, calculate_endo_scalar<curve_type, 128 >(0 ));
188
+ test_endo_scalar<curve_type>({0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_cppui255},
189
+ calculate_endo_scalar<curve_type, 128 >(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_cppui255));
190
+
191
+ nil::crypto3::random::algebraic_engine<curve_type::scalar_field_type> generate_random;
192
+ boost::random::mt19937 seed_seq;
193
+ generate_random.seed (seed_seq);
194
+
195
+ for (std::size_t i = 0 ; i < random_tests_amount; i++){
196
+ typename curve_type::scalar_field_type::value_type input = generate_random ();
197
+ typename curve_type::scalar_field_type::integral_type input_integral = typename curve_type::scalar_field_type::integral_type (input.data );
198
+ input_integral = input_integral & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_cppui255;
199
+ typename curve_type::scalar_field_type::value_type input_scalar = input_integral;
200
+ test_endo_scalar<curve_type>({input_scalar}, calculate_endo_scalar<curve_type, 128 >(input_scalar));
201
+ }
202
+ }
203
+
204
+ BOOST_AUTO_TEST_CASE (blueprint_plonk_endo_scalar_pallas) {
205
+ using curve_type = nil::crypto3::algebra::curves::pallas;
206
+ using BlueprintFieldType = typename curve_type::scalar_field_type;
207
+
208
+ typename BlueprintFieldType::value_type challenge = 0x00000000000000000000000000000000FC93536CAE0C612C18FBE5F6D8E8EEF2_cppui255;
209
+
210
+ test_endo_scalar<curve_type>({challenge}, calculate_endo_scalar<curve_type, 128 >(challenge));
211
+ test_endo_scalar<curve_type>({1 }, calculate_endo_scalar<curve_type, 128 >(1 ));
212
+ test_endo_scalar<curve_type>({0 }, calculate_endo_scalar<curve_type, 128 >(0 ));
213
+ test_endo_scalar<curve_type>({0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_cppui255},
214
+ calculate_endo_scalar<curve_type, 128 >(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_cppui255));
215
+
216
+ nil::crypto3::random::algebraic_engine<curve_type::scalar_field_type> generate_random;
217
+ boost::random::mt19937 seed_seq;
218
+ generate_random.seed (seed_seq);
219
+
220
+ for (std::size_t i = 0 ; i < random_tests_amount; i++){
221
+ typename curve_type::scalar_field_type::value_type input = generate_random ();
222
+ typename curve_type::scalar_field_type::integral_type input_integral = typename curve_type::scalar_field_type::integral_type (input.data );
223
+ input_integral = input_integral & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_cppui255;
224
+ typename curve_type::scalar_field_type::value_type input_scalar = input_integral;
225
+ test_endo_scalar<curve_type>({input_scalar}, calculate_endo_scalar<curve_type, 128 >(input_scalar));
226
+ }
95
227
}
96
228
97
229
BOOST_AUTO_TEST_SUITE_END ()
0 commit comments