12 using namespace libff;
20 template<
typename GroupT>
using run_result_t = std::pair<long long, GroupT>;
24 template<
typename GroupT>
28 result.reserve(num_elements);
29 assert(result.size() == 0);
37 GroupT x = GroupT::random_element();
43 for (; i < num_elements; ++i) {
44 assert(result.size() == i);
48 assert(result.size() == num_elements);
52 template<
typename FieldT>
57 result.reserve(num_elements);
58 for (
size_t i = 0; i < num_elements; i++) {
59 result.push_back(SHA512_rng<FieldT>(i));
62 assert(result.size() == num_elements);
86 template<form_t Form, compression_t Comp>
88 const std::string &tag,
89 const size_t num_elements,
90 const size_t precompute_c = 0)
92 return std::string(
"multiexp_base_elements_") + tag +
93 ((Form ==
form_plain) ?
"_plain_" :
"_montgomery_") +
95 std::to_string(num_elements) +
96 ((precompute_c) ? (
"_" + std::to_string(precompute_c)) :
"") +
100 template<form_t Form, compression_t Comp,
typename GroupT>
104 const std::string filename =
105 base_elements_filename<Form, Comp>(tag, base_elements.size());
107 std::cout <<
"Writing file '" << filename <<
"' ...";
108 std::flush(std::cout);
111 filename.c_str(), std::ios_base::out | std::ios_base::binary);
112 for (
const GroupT &el : base_elements) {
113 group_write<encoding_binary, Form, Comp>(el, out_s);
117 std::cout <<
" DONE\n";
120 template<form_t Form, compression_t Comp,
typename GroupT>
124 using Field =
typename GroupT::scalar_field;
125 const size_t c = bdlo12_signed_optimal_c(base_elements.size());
126 const size_t entries_per_base_element = (Field::num_bits + c - 1) / c;
128 const std::string filename =
129 base_elements_filename<Form, Comp>(tag, base_elements.size(), c);
131 std::cout <<
"Writing file '" << filename <<
"' ...";
132 std::flush(std::cout);
135 filename.c_str(), std::ios_base::out | std::ios_base::binary);
136 for (GroupT el : base_elements) {
138 group_write<encoding_binary, Form, Comp>(el, out_s);
139 for (
size_t i = 0; i < entries_per_base_element - 1; ++i) {
141 for (
size_t j = 0; j < c; ++j) {
144 group_write<encoding_binary, Form, Comp>(el, out_s);
149 std::cout <<
" DONE\n";
152 template<
typename GroupT>
154 const std::string &tag,
const size_t num_elements)
157 generate_group_elements<GroupT>(num_elements);
158 create_base_element_file_for_config<FORM, COMP>(tag, base_elements);
159 create_precompute_file_for_config<FORM, COMP>(tag, base_elements);
162 template<
typename GroupT>
164 const std::string &tag,
const size_t num_elements)
166 const std::string filename =
167 base_elements_filename<FORM, COMP>(tag, num_elements);
170 elements.reserve(num_elements);
173 in_s.exceptions(std::ifstream::badbit | std::ifstream::failbit);
174 in_s.open(filename, std::ios_base::in | std::ios_base::binary);
175 for (
size_t i = 0; i < num_elements; ++i) {
177 group_read<encoding_binary, FORM, COMP>(v, in_s);
178 elements.push_back(v);
196 answer = multi_exp<GroupT, FieldT, Method, BaseForm>(
197 group_elements.cbegin(),
198 group_elements.cend(),
209 template<form_t Form, compression_t Comp,
typename GroupT,
typename FieldT>
211 const std::string &tag,
const std::vector<FieldT> &scalars)
213 const size_t num_elements = scalars.size();
214 const std::string filename =
215 base_elements_filename<Form, Comp>(tag, num_elements);
218 if (stat(filename.c_str(), &s)) {
219 throw std::ifstream::failure(
"no file: " + filename);
223 filename.c_str(), std::ios_base::in | std::ios_base::binary);
225 std::ios_base::eofbit | std::ios_base::badbit | std::ios_base::failbit);
233 answer = multi_exp_stream<Form, Comp, GroupT, FieldT>(in_s, scalars);
241 template<form_t Form, compression_t Comp,
typename GroupT,
typename FieldT>
243 const std::string &tag,
const std::vector<FieldT> &scalars)
245 const size_t num_elements = scalars.size();
246 const size_t c = bdlo12_signed_optimal_c(num_elements);
247 const std::string filename =
248 base_elements_filename<Form, Comp>(tag, num_elements, c);
251 if (stat(filename.c_str(), &s)) {
252 throw std::ifstream::failure(
"no file: " + filename);
256 filename.c_str(), std::ios_base::in | std::ios_base::binary);
258 std::ios_base::eofbit | std::ios_base::badbit | std::ios_base::failbit);
266 answer = multi_exp_stream_with_precompute<Form, Comp, GroupT, FieldT>(
275 template<
typename GroupT,
typename FieldT>
277 const std::string &tag,
279 size_t expn_end_fast,
280 size_t expn_end_naive,
281 bool compare_answers)
283 std::cout <<
"Profiling " << tag <<
"\n";
285 "\t%16s\t%16s\t%16s\t%16s\t%16s\t%16s\t%16s\n",
291 "from_stream_precompute",
293 for (
size_t expn = expn_start; expn <= expn_end_fast; expn++) {
299 read_group_elements<GroupT>(tag, 1 << expn);
302 generate_scalars<FieldT>(1 << expn);
305 profile_multiexp<GroupT, FieldT, multi_exp_method_bos_coster>(
306 group_elements, scalars);
307 printf(
"\t%16lld", result_bos_coster.first);
311 profile_multiexp<GroupT, FieldT, multi_exp_method_BDLO12>(
312 group_elements, scalars);
313 printf(
"\t%16lld", result_djb.first);
316 if (compare_answers &&
317 (result_bos_coster.second != result_djb.second)) {
318 fprintf(stderr,
"Answers NOT MATCHING (bos coster != djb)\n");
325 printf(
"\t%16lld", result_djb_signed.first);
328 if (compare_answers &&
329 (result_djb.second != result_djb_signed.second)) {
330 fprintf(stderr,
"Answers NOT MATCHING (djb != djb_signed)\n");
338 printf(
"\t%16lld", result_djb_signed_mixed.first);
341 if (compare_answers &&
342 (result_djb_signed.second != result_djb_signed_mixed.second)) {
345 "Answers NOT MATCHING (djb_signed != djb_signed_mixed)\n");
349 profile_multiexp_stream<FORM, COMP, GroupT, FieldT>(
351 printf(
"\t%16lld", result_stream.first);
354 if (compare_answers &&
355 (result_djb_signed_mixed.second != result_stream.second)) {
358 "Answers NOT MATCHING (djb_signed_mixed != stream)\n");
366 FieldT>(tag, scalars);
367 printf(
"\t%16lld", result_stream_precomp.first);
370 if (compare_answers &&
371 (result_stream.second != result_stream_precomp.second)) {
374 "Answers NOT MATCHING (stream != stream_precomp)\n");
377 if (expn <= expn_end_naive) {
379 profile_multiexp<GroupT, FieldT, multi_exp_method_naive>(
380 group_elements, scalars);
381 printf(
"\t%16lld", result_naive.first);
384 if (compare_answers &&
385 (result_bos_coster.second != result_naive.second)) {
387 stderr,
"Answers NOT MATCHING (bos coster != naive)\n");
393 }
catch (
const std::ifstream::failure &e) {
394 std::cout <<
"(Generating files for 1<<" << expn <<
")\n";
395 create_base_element_files<GroupT>(tag, 1 << expn);
408 "alt_bn128_g1", 8, 20, 14,
true);
411 "alt_bn128_g2", 8, 20, 14,
true);