Clearmatics Libff  0.1
C++ library for Finite Fields and Elliptic Curves
profile_algebra_groups.cpp
Go to the documentation of this file.
1 
8 #include <exception>
12 
13 using namespace libff;
14 
16 static const size_t ADD_NUM_DIFFERENT_ELEMENTS = 1024;
17 
19 static const size_t ADD_NUM_ELEMENTS = 1024 * 1024;
20 
21 template<typename GroupT> bool profile_group_add()
22 {
23  std::vector<GroupT> elements;
24  {
25  elements.reserve(ADD_NUM_ELEMENTS);
26  size_t i = 0;
27  for (; i < ADD_NUM_DIFFERENT_ELEMENTS; ++i) {
28  elements.push_back(GroupT::random_element());
29  }
30  for (; i < ADD_NUM_ELEMENTS; ++i) {
31  elements.push_back(elements[i % ADD_NUM_DIFFERENT_ELEMENTS]);
32  }
33  }
34 
35  std::cout << " num elements: " << std::to_string(ADD_NUM_ELEMENTS)
36  << "\n";
37 
38  size_t num_elements = 0;
39  GroupT accum = GroupT::zero();
40  enter_block("group add operation profiling");
41  for (const GroupT &el : elements) {
42  accum = accum.add(el);
43  num_elements++;
44  }
45  leave_block("group add operation profiling");
46 
47  if (num_elements != ADD_NUM_ELEMENTS) {
48  throw std::runtime_error("invalid number of elements seen");
49  }
50 
51  return true;
52 }
53 
54 template<typename GroupT> bool profile_group_mixed_add()
55 {
56  std::vector<GroupT> elements;
57  {
58  elements.reserve(ADD_NUM_ELEMENTS);
59  size_t i = 0;
60  for (; i < ADD_NUM_DIFFERENT_ELEMENTS; ++i) {
61  GroupT e = GroupT::random_element();
62  e.to_affine_coordinates();
63  elements.push_back(e);
64  }
65  for (; i < ADD_NUM_ELEMENTS; ++i) {
66  elements.push_back(elements[i % ADD_NUM_DIFFERENT_ELEMENTS]);
67  }
68  }
69 
70  std::cout << " num elements: " << std::to_string(ADD_NUM_ELEMENTS)
71  << "\n";
72 
73  size_t num_elements = 0;
74  GroupT accum = GroupT::one();
75  enter_block("group mixed add operation profiling");
76  for (const GroupT &el : elements) {
77  accum = accum.mixed_add(el);
78  num_elements++;
79  }
80  leave_block("group mixed add operation profiling");
81 
82  if (num_elements != ADD_NUM_ELEMENTS) {
83  throw std::runtime_error("invalid number of elements seen");
84  }
85 
86  return true;
87 }
88 
89 template<typename GroupT> bool profile_group_membership()
90 {
91  static const size_t NUM_ELEMENTS = 1000;
92 
93  // Measure the time taken to check membership of 1000 elements. (Note all
94  // elements are in fact members of the group - we are not testing
95  // correctness here).
96 
97  std::vector<GroupT> elements;
98  elements.reserve(NUM_ELEMENTS);
99  for (size_t i = 0; i < NUM_ELEMENTS; ++i) {
100  elements.push_back(GroupT::random_element());
101  }
102 
103  enter_block("group membership profiling");
104  for (const GroupT &el : elements) {
105  if (!el.is_in_safe_subgroup()) {
106  return false;
107  }
108  }
109  leave_block("group membership profiling");
110 
111  return true;
112 }
113 
114 template<typename ppT> bool profile_pairing_e_over_e()
115 {
116  constexpr size_t NUM_ITERATIONS = ADD_NUM_DIFFERENT_ELEMENTS;
117 
118  // Mock BLS signature verification
119 
120  const Fr<ppT> sk = Fr<ppT>::random_element();
121  G2<ppT> pk = sk * G2<ppT>::one();
122  pk.to_affine_coordinates();
123 
124  // Messages to sign
125  std::vector<Fr<ppT>> messages;
126  messages.reserve(NUM_ITERATIONS);
127  for (size_t i = 0; i < NUM_ITERATIONS; ++i) {
128  messages.push_back(Fr<ppT>::random_element());
129  }
130 
131  // Signatures. Every other one is invalid.
132  std::vector<G1<ppT>> signatures;
133  signatures.reserve(NUM_ITERATIONS);
134  for (size_t i = 0; i < NUM_ITERATIONS; ++i) {
135  if (i & 1) {
136  signatures.push_back(sk * messages[i] * G1<ppT>::one());
137  } else {
138  signatures.push_back(messages[i] * G1<ppT>::one());
139  }
140  signatures.back().to_affine_coordinates();
141  }
142 
143  // Precompute the parts we expect to be known up-front.
144  const G2_precomp<ppT> id_precomp = ppT::precompute_G2(-G2<ppT>::one());
145  const G2_precomp<ppT> pk_precomp = ppT::precompute_G2(pk);
146 
147  enter_block("pairing_e_over_e");
148 
149  // NOTE: the pairing implementations call enter_block and leave_block in
150  // several places, generating a lot of output, which slows down the
151  // performance a lot. Hence we suppress the profiling here, and re-enable
152  // it before the end of the block.
153 
156 
157  for (size_t i = 0; i < NUM_ITERATIONS; ++i) {
158  const G1_precomp<ppT> sig_prec = ppT::precompute_G1(signatures[i]);
159  const G1_precomp<ppT> H_precomp =
160  ppT::precompute_G1(messages[i] * G1<ppT>::one());
161 
162  const Fqk<ppT> result =
163  ppT::final_exponentiation(ppT::double_miller_loop(
164  sig_prec, id_precomp, H_precomp, pk_precomp));
165 
166  if (i & 1) {
167  if (result != Fqk<ppT>::one()) {
168  throw std::runtime_error(
169  "signature verification failed " + std::to_string(i));
170  }
171  } else {
172  if (result == Fqk<ppT>::one()) {
173  throw std::runtime_error(
174  "signature verification passed (should fail)");
175  }
176  }
177  }
178 
181 
182  leave_block("pairing_e_over_e");
183 
184  return true;
185 }
186 
187 int main(void)
188 {
189  std::cout << "alt_bn128_pp\n";
191 
192  std::cout << " profile_group_add<alt_bn128_G1>:\n";
193  if (!profile_group_add<alt_bn128_G1>()) {
194  throw std::runtime_error("failed");
195  }
196 
197  std::cout << " profile_group_mixed_add<alt_bn128_G1>:\n";
198  if (!profile_group_mixed_add<alt_bn128_G1>()) {
199  throw std::runtime_error("failed");
200  }
201 
202  std::cout << " profile_group_add<alt_bn128_G2>:\n";
203  if (!profile_group_add<alt_bn128_G2>()) {
204  throw std::runtime_error("failed");
205  }
206 
207  std::cout << " profile_group_mixed_add<alt_bn128_G2>:\n";
208  if (!profile_group_mixed_add<alt_bn128_G2>()) {
209  throw std::runtime_error("failed");
210  }
211 
212  std::cout << " profile_affine_e_over_e<alt_bn128>:\n";
213  profile_pairing_e_over_e<alt_bn128_pp>();
214 
215  std::cout << "bls12_377_pp\n";
217 
218  std::cout << " profile_group_add<bls12_377_G1>:\n";
219  if (!profile_group_add<bls12_377_G1>()) {
220  throw std::runtime_error("failed");
221  }
222 
223  std::cout << " profile_group_mixed_add<bls12_377_G1>:\n";
224  if (!profile_group_mixed_add<bls12_377_G1>()) {
225  throw std::runtime_error("failed");
226  }
227 
228  std::cout << " profile_group_add<bls12_377_G2>:\n";
229  if (!profile_group_add<bls12_377_G2>()) {
230  throw std::runtime_error("failed");
231  }
232 
233  std::cout << " profile_group_membership<bls12_377_G1>:\n";
234  if (!profile_group_membership<bls12_377_G1>()) {
235  throw std::runtime_error("failed");
236  }
237 
238  std::cout << " profile_group_membership<bls12_377_G2>:\n";
239  if (!profile_group_membership<bls12_377_G2>()) {
240  throw std::runtime_error("failed");
241  }
242 
243  std::cout << " profile_affine_e_over_e<bls12_377>:\n";
244  profile_pairing_e_over_e<bls12_377_pp>();
245 
246  return 0;
247 }
main
int main(void)
Definition: profile_algebra_groups.cpp:187
libff::enter_block
void enter_block(const std::string &msg, const bool indent)
Definition: profiling.cpp:271
libff
Definition: ffi.cpp:8
profile_group_membership
bool profile_group_membership()
Definition: profile_algebra_groups.cpp:89
profile_group_mixed_add
bool profile_group_mixed_add()
Definition: profile_algebra_groups.cpp:54
libff::G1
typename EC_ppT::G1_type G1
Definition: public_params.hpp:76
libff::bls12_377_pp::init_public_params
static void init_public_params()
Definition: bls12_377_pp.cpp:15
libff::G2
typename EC_ppT::G2_type G2
Definition: public_params.hpp:77
libff::alt_bn128_pp::init_public_params
static void init_public_params()
Definition: alt_bn128_pp.cpp:15
libff::G1_precomp
typename EC_ppT::G1_precomp_type G1_precomp
Definition: public_params.hpp:78
alt_bn128_pp.hpp
libff::Fqk
typename EC_ppT::Fqk_type Fqk
Definition: public_params.hpp:86
libff::Fr
typename EC_ppT::Fp_type Fr
Definition: public_params.hpp:75
bls12_377_pp.hpp
libff::G2_precomp
typename EC_ppT::G2_precomp_type G2_precomp
Definition: public_params.hpp:79
NUM_ITERATIONS
constexpr size_t NUM_ITERATIONS
Definition: profile_multiexp.cpp:14
profiling.hpp
libff::leave_block
void leave_block(const std::string &msg, const bool indent)
Definition: profiling.cpp:305
profile_pairing_e_over_e
bool profile_pairing_e_over_e()
Definition: profile_algebra_groups.cpp:114
libff::inhibit_profiling_counters
bool inhibit_profiling_counters
Definition: profiling.cpp:108
libff::inhibit_profiling_info
bool inhibit_profiling_info
Definition: profiling.cpp:107
profile_group_add
bool profile_group_add()
Definition: profile_algebra_groups.cpp:21