bls_basic_functions.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2018-2020 Mikhail Komarov <nemo@nil.foundation>
3 // Copyright (c) 2020-2021 Ilias Khairullin <ilias@nil.foundation>
4 //
5 // MIT License
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a copy
8 // of this software and associated documentation files (the "Software"), to deal
9 // in the Software without restriction, including without limitation the rights
10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 // copies of the Software, and to permit persons to whom the Software is
12 // furnished to do so, subject to the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be included in all
15 // copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 // SOFTWARE.
24 //---------------------------------------------------------------------------//
25 
26 #ifndef CRYPTO3_PUBKEY_BLS_CORE_FUNCTIONS_HPP
27 #define CRYPTO3_PUBKEY_BLS_CORE_FUNCTIONS_HPP
28 
29 #include <utility>
30 #include <vector>
31 #include <array>
32 #include <type_traits>
33 #include <iterator>
34 #include <algorithm>
35 
36 #include <boost/assert.hpp>
37 #include <boost/concept_check.hpp>
38 
39 #include <boost/range/concepts.hpp>
40 
42 
44 
45 #include <nil/crypto3/detail/type_traits.hpp>
46 
47 namespace nil {
48  namespace crypto3 {
49  namespace pubkey {
50  namespace detail {
51  template<typename policy_type>
53  typedef typename policy_type::curve_type curve_type;
54  typedef typename policy_type::gt_value_type gt_value_type;
55  typedef typename policy_type::private_key_type private_key_type;
56  typedef typename policy_type::public_key_type public_key_type;
57  typedef typename policy_type::signature_type signature_type;
58  typedef typename policy_type::h2c_policy h2c_policy;
59 
60  typedef typename policy_type::bls_serializer bls_serializer;
61  typedef typename policy_type::public_key_serialized_type public_key_serialized_type;
62  typedef typename policy_type::signature_serialized_type signature_serialized_type;
63 
64  typedef typename policy_type::internal_accumulator_type internal_accumulator_type;
65  typedef std::pair<std::vector<public_key_type>, std::vector<internal_accumulator_type>>
67  typedef std::pair<std::vector<public_key_type>, internal_accumulator_type>
69 
70  constexpr static const std::size_t private_key_bits = policy_type::private_key_bits;
71  constexpr static const std::size_t L = static_cast<std::size_t>((3 * private_key_bits) / 16) +
72  static_cast<std::size_t>((3 * private_key_bits) % 16 != 0);
73  static_assert(L < 0x10000, "L is required to fit in 2 octets");
74  constexpr static const std::array<std::uint8_t, 2> L_os = {static_cast<std::uint8_t>(L >> 8u),
75  static_cast<std::uint8_t>(L % 0x100)};
76 
77  // TODO: implement key_gen
78  // template<typename IkmType, typename KeyInfoType>
79  // static inline private_key_type key_gen(const IkmType &ikm, const KeyInfoType &key_info) {}
80 
81  static inline bool validate_private_key(const private_key_type &sk) {
82  return !sk.is_zero();
83  }
84 
86  BOOST_ASSERT(validate_private_key(sk));
87 
88  return sk * public_key_type::one();
89  }
90 
91  static inline bool validate_public_key(const public_key_type &pk) {
92  return !(pk.is_zero() || !pk.is_well_formed());
93  }
94 
95  template<typename InputRange>
96  static inline void update(internal_accumulator_type &acc, const InputRange &range) {
97  BOOST_CONCEPT_ASSERT((boost::SinglePassRangeConcept<InputRange>));
98 
99  to_curve<h2c_policy>(range, acc);
100  }
101 
102  template<typename InputIterator>
103  static inline void update(internal_accumulator_type &acc, InputIterator first, InputIterator last) {
104  BOOST_CONCEPT_ASSERT((boost::InputIteratorConcept<InputIterator>));
105 
106  to_curve<h2c_policy>(first, last, acc);
107  }
108 
110  const private_key_type &sk) {
111  BOOST_ASSERT(validate_private_key(sk));
112 
113  signature_type Q = hashes::accumulators::extract::to_curve<h2c_policy>(acc);
114  return sk * Q;
115  }
116 
117  static inline bool verify(const internal_accumulator_type &acc, const public_key_type &pk,
118  const signature_type &sig) {
120  if (!sig.is_well_formed()) {
121  return false;
122  }
123  if (!validate_public_key(pk)) {
124  return false;
125  }
126  signature_type Q = hashes::accumulators::extract::to_curve<h2c_policy>(acc);
127  auto C1 = policy_type::pairing(Q, pk);
128  auto C2 = policy_type::pairing(sig, public_key_type::one());
129  return C1 == C2;
130  }
131 
132  template<
133  typename SignatureIterator,
134  typename = typename std::enable_if<std::is_same<
135  signature_type, typename std::iterator_traits<SignatureIterator>::value_type>::value>::type>
136  static inline void aggregate(signature_type &acc, SignatureIterator sig_first,
137  SignatureIterator sig_last) {
138  BOOST_CONCEPT_ASSERT((boost::InputIteratorConcept<SignatureIterator>));
139  assert(std::distance(sig_first, sig_last) > 0);
140 
141  while (sig_first != sig_last) {
142  signature_type next_p = *sig_first++;
143  acc = acc + next_p;
144  }
145  }
146 
147  template<typename SignatureRange,
148  typename = typename std::enable_if<std::is_same<
149  signature_type, typename std::iterator_traits<
150  typename SignatureRange::iterator>::value_type>::value>::type>
151  static inline void aggregate(signature_type &acc, const SignatureRange &sig_n) {
152  BOOST_CONCEPT_ASSERT((boost::SinglePassRangeConcept<SignatureRange>));
153 
154  aggregate(acc, std::cbegin(sig_n), std::cend(sig_n));
155  }
156 
158  const signature_type &sig) {
159  const typename internal_aggregation_accumulator_type::first_type &pk_n = acc.first;
160  const typename internal_aggregation_accumulator_type::second_type &acc_n = acc.second;
161  assert(std::distance(pk_n.begin(), pk_n.end()) > 0 &&
162  std::distance(pk_n.begin(), pk_n.end()) == std::distance(acc_n.begin(), acc_n.end()));
163 
164  if (!sig.is_well_formed()) {
165  return false;
166  }
167  auto pk_n_iter = std::cbegin(pk_n);
168  auto acc_n_iter = std::cbegin(acc_n);
169  gt_value_type C1 = gt_value_type::one();
170  while (pk_n_iter != std::cend(pk_n) && acc_n_iter != std::cend(acc_n)) {
171  if (!validate_public_key(*pk_n_iter)) {
172  return false;
173  }
174  signature_type Q = hashes::accumulators::extract::to_curve<h2c_policy>(*acc_n_iter++);
175  C1 = C1 * policy_type::pairing(Q, *pk_n_iter++);
176  }
177  return C1 == policy_type::pairing(sig, public_key_type::one());
178  }
179 
181  const signature_type &sig) {
182  const typename internal_fast_aggregation_accumulator_type::first_type &pk_n = acc.first;
183  const typename internal_fast_aggregation_accumulator_type::second_type &msg_acc = acc.second;
184  assert(std::distance(pk_n.begin(), pk_n.end()) > 0);
185 
186  auto pk_n_iter = pk_n.begin();
187  public_key_type aggregate_p = *pk_n_iter++;
188  while (pk_n_iter != pk_n.end()) {
189  public_key_type next_p = *pk_n_iter++;
190  aggregate_p = aggregate_p + next_p;
191  }
192  return verify(msg_acc, aggregate_p, sig);
193  }
194 
195  static inline signature_type pop_prove(const private_key_type &sk) {
196  assert(validate_private_key(sk));
197 
199  signature_type Q = to_curve<h2c_policy>(point_to_pubkey(pk));
200  return sk * Q;
201  }
202 
203  static inline bool pop_verify(const public_key_type &pk, const signature_type &pop) {
204  if (!pop.is_well_formed()) {
205  return false;
206  }
207  if (!validate_public_key(pk)) {
208  return false;
209  }
210  signature_type Q = to_curve<h2c_policy>(point_to_pubkey(pk));
211  auto C1 = policy_type::pairing(Q, pk);
212  auto C2 = policy_type::pairing(pop, public_key_type::one());
213  return C1 == C2;
214  }
215 
217  return bls_serializer::point_to_octets_compress(pk);
218  }
219 
221  return bls_serializer::point_to_octets_compress(sig);
222  }
223  };
224  } // namespace detail
225  } // namespace pubkey
226  } // namespace crypto3
227 } // namespace nil
228 
229 #endif // CRYPTO3_PUBKEY_BLS_CORE_FUNCTIONS_HPP
boost::mpl::apply< AccumulatorSet, tag::pubkey< ProcessingMode > >::type::result_type pubkey(const AccumulatorSet &acc)
Definition: accumulators/pubkey.hpp:106
Definition: pair.hpp:31
Definition: bls_basic_functions.hpp:52
policy_type::bls_serializer bls_serializer
Definition: bls_basic_functions.hpp:60
static void aggregate(signature_type &acc, SignatureIterator sig_first, SignatureIterator sig_last)
Definition: bls_basic_functions.hpp:136
policy_type::h2c_policy h2c_policy
Definition: bls_basic_functions.hpp:58
constexpr static const std::size_t private_key_bits
Definition: bls_basic_functions.hpp:70
static signature_type pop_prove(const private_key_type &sk)
Definition: bls_basic_functions.hpp:195
policy_type::public_key_serialized_type public_key_serialized_type
Definition: bls_basic_functions.hpp:61
static bool pop_verify(const public_key_type &pk, const signature_type &pop)
Definition: bls_basic_functions.hpp:203
static bool aggregate_verify(const internal_aggregation_accumulator_type &acc, const signature_type &sig)
Definition: bls_basic_functions.hpp:157
policy_type::signature_serialized_type signature_serialized_type
Definition: bls_basic_functions.hpp:62
policy_type::internal_accumulator_type internal_accumulator_type
Definition: bls_basic_functions.hpp:64
static bool verify(const internal_accumulator_type &acc, const public_key_type &pk, const signature_type &sig)
Definition: bls_basic_functions.hpp:117
std::pair< std::vector< public_key_type >, std::vector< internal_accumulator_type > > internal_aggregation_accumulator_type
Definition: bls_basic_functions.hpp:66
policy_type::private_key_type private_key_type
Definition: bls_basic_functions.hpp:55
constexpr static const std::size_t L
Definition: bls_basic_functions.hpp:71
policy_type::gt_value_type gt_value_type
Definition: bls_basic_functions.hpp:54
static void update(internal_accumulator_type &acc, const InputRange &range)
Definition: bls_basic_functions.hpp:96
policy_type::curve_type curve_type
Definition: bls_basic_functions.hpp:53
std::pair< std::vector< public_key_type >, internal_accumulator_type > internal_fast_aggregation_accumulator_type
Definition: bls_basic_functions.hpp:68
policy_type::signature_type signature_type
Definition: bls_basic_functions.hpp:57
static public_key_serialized_type point_to_pubkey(const public_key_type &pk)
Definition: bls_basic_functions.hpp:216
static bool validate_private_key(const private_key_type &sk)
Definition: bls_basic_functions.hpp:81
policy_type::public_key_type public_key_type
Definition: bls_basic_functions.hpp:56
static signature_serialized_type point_to_signature(const signature_type &sig)
Definition: bls_basic_functions.hpp:220
static void aggregate(signature_type &acc, const SignatureRange &sig_n)
Definition: bls_basic_functions.hpp:151
static public_key_type privkey_to_pubkey(const private_key_type &sk)
Definition: bls_basic_functions.hpp:85
static signature_type sign(const internal_accumulator_type &acc, const private_key_type &sk)
Definition: bls_basic_functions.hpp:109
static bool validate_public_key(const public_key_type &pk)
Definition: bls_basic_functions.hpp:91
static void update(internal_accumulator_type &acc, InputIterator first, InputIterator last)
Definition: bls_basic_functions.hpp:103
static bool aggregate_verify(const internal_fast_aggregation_accumulator_type &acc, const signature_type &sig)
Definition: bls_basic_functions.hpp:180
constexpr static const std::array< std::uint8_t, 2 > L_os
Definition: bls_basic_functions.hpp:74