emsa1.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2020 Mikhail Komarov <nemo@nil.foundation>
3 // Copyright (c) 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_PK_PAD_EMSA1_HPP
27 #define CRYPTO3_PK_PAD_EMSA1_HPP
28 
29 #include <iterator>
30 #include <type_traits>
31 
33 
35 
36 #include <nil/marshalling/field_type.hpp>
37 #include <nil/crypto3/marshalling/algebra/types/field_element.hpp>
38 
39 namespace nil {
40  namespace crypto3 {
41  namespace pubkey {
42  namespace padding {
43  namespace detail {
44  template<typename MsgReprType, typename Hash, typename = void>
46 
47  template<typename MsgReprType, typename Hash>
49  MsgReprType, Hash,
50  typename std::enable_if<
51  algebra::is_field<typename MsgReprType::field_type>::value &&
52  !algebra::is_extended_field<typename MsgReprType::field_type>::value>::type> {
53  typedef Hash hash_type;
54 
55  protected:
56  typedef typename MsgReprType::field_type field_type;
57  typedef ::nil::marshalling::option::big_endian endianness;
58  typedef ::nil::crypto3::marshalling::types::field_element<
59  ::nil::marshalling::field_type<::nil::marshalling::option::big_endian>, field_type>
61 
62  constexpr static std::size_t digest_bits = hash_type::digest_bits;
63 
64  constexpr static std::size_t modulus_bits = field_type::modulus_bits;
65  constexpr static std::size_t modulus_octets =
66  modulus_bits / 8 + static_cast<std::size_t>(modulus_bits % 8 != 0);
67 
68  typedef std::array<std::uint8_t, modulus_octets> modulus_octets_container_type;
69 
70  public:
71  typedef MsgReprType msg_repr_type;
74 
75  static inline void init_accumulator(internal_accumulator_type &acc) {
76  }
77 
78  template<typename InputRange>
79  static inline void update(internal_accumulator_type &acc, const InputRange &range) {
80  hash<hash_type>(range, acc);
81  }
82 
83  template<typename InputIterator>
84  static inline void update(internal_accumulator_type &acc, InputIterator first,
85  InputIterator last) {
86  hash<hash_type>(first, last, acc);
87  }
88 
89  template<std::size_t DigistBits = digest_bits, std::size_t ModulusBits = modulus_bits,
90  typename std::enable_if<(DigistBits >= ModulusBits), bool>::type = true>
92  typename hash_type::digest_type digest =
93  ::nil::crypto3::accumulators::extract::hash<hash_type>(acc);
94  marshalling_field_element_type marshalling_field_element;
95  auto it = digest.cbegin();
96  marshalling_field_element.read(it, digest.size());
97  return marshalling::types::make_field_element<field_type, endianness>(
98  marshalling_field_element);
99  }
100 
101  template<std::size_t DigistBits = digest_bits, std::size_t ModulusBits = modulus_bits,
102  typename std::enable_if<(DigistBits < ModulusBits), bool>::type = true>
104  typename hash_type::digest_type digest =
105  ::nil::crypto3::accumulators::extract::hash<hash_type>(acc);
106  // TODO: creating copy of digest range of modulus_octets size is a bottleneck:
107  // extend marshaling interface by function supporting initialization from container which
108  // length is less than modulus_octets
109  modulus_octets_container_type modulus_octets_container;
110  modulus_octets_container.fill(0);
111  std::copy(std::crbegin(digest), std::crend(digest), std::rbegin(modulus_octets_container));
112  marshalling_field_element_type marshalling_field_element;
113  auto it = modulus_octets_container.cbegin();
114  marshalling_field_element.read(it, modulus_octets_container.size());
115  return marshalling::types::make_field_element<field_type, endianness>(
116  marshalling_field_element);
117  }
118  };
119 
120  template<typename MsgReprType, typename Hash>
122  MsgReprType, Hash,
123  typename std::enable_if<
127 
128  template<typename MsgReprType, typename Hash, typename = void>
130 
131  template<typename MsgReprType, typename Hash>
133  MsgReprType, Hash,
134  typename std::enable_if<
135  algebra::is_field<typename MsgReprType::field_type>::value &&
136  !algebra::is_extended_field<typename MsgReprType::field_type>::value>::type> {
137  protected:
138  typedef typename MsgReprType::field_type field_type;
139  typedef ::nil::crypto3::marshalling::types::field_element<
140  ::nil::marshalling::field_type<::nil::marshalling::option::big_endian>, field_type>
143 
144  public:
145  typedef Hash hash_type;
146  typedef MsgReprType msg_repr_type;
147  typedef typename encoding_policy::internal_accumulator_type internal_accumulator_type;
148  typedef bool result_type;
149 
150  static inline void init_accumulator(internal_accumulator_type &acc) {
151  encoding_policy::init_accumulator(acc);
152  }
153 
154  template<typename InputRange>
155  static inline void update(internal_accumulator_type &acc, const InputRange &range) {
156  encoding_policy::update(range, acc);
157  }
158 
159  template<typename InputIterator>
160  static inline void update(internal_accumulator_type &acc, InputIterator first,
161  InputIterator last) {
162  encoding_policy::update(first, last, acc);
163  }
164 
166  const msg_repr_type &msg_repr) {
167  return encoding_policy::process(acc) == msg_repr;
168  }
169  };
170 
171  template<typename MsgReprType, typename Hash>
173  MsgReprType, Hash,
174  typename std::enable_if<
175  algebra::is_field<MsgReprType>::value &&
176  !algebra::is_extended_field<typename MsgReprType::field_type>::value>::type>
177  : public emsa1_verification_policy<typename MsgReprType::value_type, Hash> { };
178 
179  template<typename MsgReprType, typename Hash>
181  MsgReprType, Hash,
182  typename std::enable_if<std::is_same<typename Hash::digest_type, MsgReprType>::value>::type> {
183  typedef Hash hash_type;
184  typedef MsgReprType msg_repr_type;
187 
188  static inline void init_accumulator(internal_accumulator_type &acc) {
189  }
190 
191  template<typename InputRange>
192  static inline void update(internal_accumulator_type &acc, const InputRange &range) {
193  hash<hash_type>(range, acc);
194  }
195 
196  template<typename InputIterator>
197  static inline void update(internal_accumulator_type &acc, InputIterator first,
198  InputIterator last) {
199  hash<hash_type>(first, last, acc);
200  }
201 
203  return ::nil::crypto3::accumulators::extract::hash<hash_type>(acc);
204  }
205  };
206 
207  template<typename MsgReprType, typename Hash>
209  MsgReprType, Hash,
210  typename std::enable_if<std::is_same<typename Hash::digest_type, MsgReprType>::value>::type> {
211  protected:
213 
214  public:
215  typedef Hash hash_type;
216  typedef MsgReprType msg_repr_type;
217  typedef typename encoding_policy::internal_accumulator_type internal_accumulator_type;
218  typedef bool result_type;
219 
220  static inline void init_accumulator(internal_accumulator_type &acc) {
221  encoding_policy::init_accumulator(acc);
222  }
223 
224  template<typename InputRange>
225  static inline void update(internal_accumulator_type &acc, const InputRange &range) {
226  encoding_policy::update(range, acc);
227  }
228 
229  template<typename InputIterator>
230  static inline void update(internal_accumulator_type &acc, InputIterator first,
231  InputIterator last) {
232  encoding_policy::update(first, last, acc);
233  }
234 
236  const msg_repr_type &msg_repr) {
237  return encoding_policy::process(acc) == msg_repr;
238  }
239  };
240  } // namespace detail
241 
250  template<typename MsgReprType, typename Hash, typename Params = void>
251  struct emsa1 {
252  typedef MsgReprType msg_repr_type;
253  typedef Hash hash_type;
254 
257  };
258  } // namespace padding
259  } // namespace pubkey
260  } // namespace crypto3
261 } // namespace nil
262 
263 #endif // CRYPTO3_PK_PAD_EMSA1_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: hash_state.hpp:43
Definition: algebra/include/nil/crypto3/algebra/type_traits.hpp:105
Definition: algebra/include/nil/crypto3/algebra/type_traits.hpp:95
Definition: block/include/nil/crypto3/detail/digest.hpp:72
::nil::crypto3::marshalling::types::field_element< ::nil::marshalling::field_type<::nil::marshalling::option::big_endian >, field_type > marshalling_field_element_type
Definition: emsa1.hpp:60
::nil::crypto3::marshalling::types::field_element< ::nil::marshalling::field_type<::nil::marshalling::option::big_endian >, field_type > marshalling_field_element_type
Definition: emsa1.hpp:141
EMSA1 from IEEE 1363. Essentially, sign the hash directly.
Definition: emsa1.hpp:251
detail::emsa1_encoding_policy< MsgReprType, Hash > encoding_policy
Definition: emsa1.hpp:255
Hash hash_type
Definition: emsa1.hpp:253
MsgReprType msg_repr_type
Definition: emsa1.hpp:252
detail::emsa1_verification_policy< MsgReprType, Hash > verification_policy
Definition: emsa1.hpp:256