Clearmatics Libff  0.1
C++ library for Finite Fields and Elliptic Curves
curve_utils.tcc
Go to the documentation of this file.
1 /** @file
2  *****************************************************************************
3  * @author This file is part of libff, developed by SCIPR Lab
4  * and contributors (see AUTHORS).
5  * @copyright MIT license (see LICENSE file)
6  *****************************************************************************/
7 
8 #ifndef CURVE_UTILS_TCC_
9 #define CURVE_UTILS_TCC_
10 
11 namespace libff
12 {
13 
14 template<typename GroupT, mp_size_t m>
15 GroupT scalar_mul(const GroupT &base, const bigint<m> &scalar)
16 {
17  GroupT result = GroupT::zero();
18 
19  bool found_one = false;
20  for (long i = static_cast<long>(scalar.max_bits() - 1); i >= 0; --i) {
21  if (found_one) {
22  result = result.dbl();
23  }
24 
25  if (scalar.test_bit(i)) {
26  found_one = true;
27  result = result + base;
28  }
29  }
30 
31  return result;
32 }
33 
34 template<typename GroupT>
35 decltype(((GroupT *)nullptr)->X) curve_point_y_at_x(
36  const decltype(((GroupT *)nullptr)->X) &x)
37 {
38  using base_field = decltype(((GroupT *)nullptr)->X);
39  const base_field x_squared = x * x;
40  const base_field x_cubed = x_squared * x;
41  const base_field y_squared =
42  x_cubed + (GroupT::coeff_a * x) + GroupT::coeff_b;
43  // TODO Check that y_squared is a quadratic residue (ensuring that sqrt()
44  // terminates).
45  return y_squared.sqrt();
46 }
47 
48 template<typename GroupT>
49 GroupT g1_curve_point_at_x(const typename GroupT::base_field &x)
50 {
51  const typename GroupT::base_field x_squared = x * x;
52  const typename GroupT::base_field x_cubed = x_squared * x;
53  const typename GroupT::base_field y_squared =
54  x_cubed + (GroupT::coeff_a * x) + GroupT::coeff_b;
55  // Check that y_squared is a quadratic residue (ensuring that sqrt()
56  // terminates).
57  if ((y_squared ^ GroupT::base_field::euler) != GroupT::base_field::one()) {
58  throw std::runtime_error("curve eqn has no solution at x");
59  }
60 
61  const typename GroupT::base_field y = y_squared.sqrt();
62  return GroupT(x, y, GroupT::base_field::one());
63 }
64 
65 template<typename GroupT>
66 GroupT g2_curve_point_at_x(const typename GroupT::twist_field &x)
67 {
68  // TODO: Generic check (over all fields) that y_squared.sqrt() terminates.
69  return GroupT(x, curve_point_y_at_x<GroupT>(x), GroupT::twist_field::one());
70 }
71 
72 } // namespace libff
73 #endif // CURVE_UTILS_TCC_