hash_value.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2018-2020 Mikhail Komarov <nemo@nil.foundation>
3 //
4 // MIT License
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to deal
8 // in the Software without restriction, including without limitation the rights
9 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 // copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
13 // The above copyright notice and this permission notice shall be included in all
14 // copies or substantial portions of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 // SOFTWARE.
23 //---------------------------------------------------------------------------//
24 
25 #ifndef CRYPTO3_HASH_STREAM_POSTPROCESSOR_HPP
26 #define CRYPTO3_HASH_STREAM_POSTPROCESSOR_HPP
27 
28 #include <array>
29 
30 #include <boost/assert.hpp>
31 #include <boost/concept_check.hpp>
32 
33 #include <boost/range/concepts.hpp>
34 #include <boost/array.hpp>
35 
36 #include <nil/crypto3/detail/pack.hpp>
37 
39 
40 namespace nil {
41  namespace crypto3 {
42  namespace hashes {
43  namespace detail {
44  template<typename HashAccumulatorSet>
45  struct ref_hash_impl {
46  typedef HashAccumulatorSet accumulator_set_type;
47  typedef
48  typename boost::mpl::front<typename accumulator_set_type::features_type>::type accumulator_type;
49 
50  typedef typename accumulator_type::hash_type hash_type;
51 
52  ref_hash_impl(accumulator_set_type &&stream_hash) : accumulator_set(stream_hash) {
53  }
54 
56  };
57 
58  template<typename HashAccumulatorSet>
59  struct value_hash_impl {
60  typedef HashAccumulatorSet accumulator_set_type;
61  typedef
62  typename boost::mpl::front<typename accumulator_set_type::features_type>::type accumulator_type;
63 
64  typedef typename accumulator_type::hash_type hash_type;
65 
67  accumulator_set(std::forward<accumulator_set_type>(stream_hash)) {
68  }
69 
71  };
72 
73  template<typename HashStateImpl>
74  struct range_hash_impl : public HashStateImpl {
75  typedef HashStateImpl hash_state_impl_type;
76 
77  typedef typename hash_state_impl_type::accumulator_type accumulator_type;
78  typedef typename hash_state_impl_type::accumulator_set_type accumulator_set_type;
79 
80  typedef typename hash_state_impl_type::hash_type hash_type;
81 
82  typedef typename boost::mpl::apply<accumulator_set_type, accumulator_type>::type::result_type
84 
85  template<typename SinglePassRange>
86  range_hash_impl(const SinglePassRange &range, accumulator_set_type &&ise) :
87  HashStateImpl(std::forward<accumulator_set_type>(ise)) {
88  BOOST_RANGE_CONCEPT_ASSERT((boost::SinglePassRangeConcept<const SinglePassRange>));
89 
90  typedef
91  typename std::iterator_traits<typename SinglePassRange::iterator>::value_type value_type;
92  BOOST_STATIC_ASSERT(std::numeric_limits<value_type>::is_specialized);
93  typedef typename hash_type::template stream_processor<
95  std::numeric_limits<value_type>::digits + std::numeric_limits<value_type>::is_signed>::type
96  stream_processor;
97 
98  stream_processor(this->accumulator_set)(range.begin(), range.end());
99  }
100 
101  template<typename InputIterator>
102  range_hash_impl(InputIterator first, InputIterator last, accumulator_set_type &&ise) :
103  HashStateImpl(std::forward<accumulator_set_type>(ise)) {
104  BOOST_CONCEPT_ASSERT((boost::InputIteratorConcept<InputIterator>));
105 
106  typedef typename std::iterator_traits<InputIterator>::value_type value_type;
107  BOOST_STATIC_ASSERT(std::numeric_limits<value_type>::is_specialized);
108  typedef typename hash_type::template stream_processor<
110  std::numeric_limits<value_type>::digits + std::numeric_limits<value_type>::is_signed>::type
111  stream_processor;
112 
113  stream_processor(this->accumulator_set)(first, last);
114  }
115 
116  template<typename T, std::size_t Size>
117  inline operator std::array<T, Size>() const {
118  result_type result =
119  boost::accumulators::extract_result<accumulator_type>(this->accumulator_set);
120  std::array<T, Size> out;
121  std::copy(result.begin(), result.end(), out.end());
122  return out;
123  }
124 
125  template<typename T, std::size_t Size>
126  inline operator boost::array<T, Size>() const {
127  result_type result =
128  boost::accumulators::extract_result<accumulator_type>(this->accumulator_set);
129  boost::array<T, Size> out;
130  std::copy(result.begin(), result.end(), out.end());
131  return out;
132  }
133 
134  template<typename OutputRange>
135  inline operator OutputRange() const {
136  result_type result =
137  boost::accumulators::extract_result<accumulator_type>(this->accumulator_set);
138  return OutputRange(result.begin(), result.end());
139  }
140 
141  inline operator result_type() const {
142  return boost::accumulators::extract_result<accumulator_type>(this->accumulator_set);
143  }
144 
145  inline operator accumulator_set_type &() const {
146  return this->accumulator_set;
147  }
148 
149  template<typename Integral,
150  typename = typename std::enable_if<std::is_integral<Integral>::value &&
151  hash_type::digest_bits <=
152  std::numeric_limits<Integral>::digits>::type>
153  inline operator Integral() const {
154  std::array<Integral, 1> out;
155  result_type res = boost::accumulators::extract_result<accumulator_type>(this->accumulator_set);
156  ::nil::crypto3::detail::pack_to<stream_endian::little_octet_big_bit>(res, out);
157  return out[0];
158  }
159 
160 #ifndef CRYPTO3_RAW_HASH_STRING_OUTPUT
161 
162  template<typename Char, typename CharTraits, typename Alloc>
163  inline operator std::basic_string<Char, CharTraits, Alloc>() const {
164  return std::to_string(
165  boost::accumulators::extract_result<accumulator_type>(this->accumulator_set));
166  }
167 
168 #endif
169  };
170 
171  template<typename HashStateImpl, typename OutputIterator>
172  struct itr_hash_impl : public HashStateImpl {
173  private:
174  mutable OutputIterator out;
175 
176  public:
177  typedef HashStateImpl hash_state_impl_type;
178 
179  typedef typename hash_state_impl_type::accumulator_type accumulator_type;
180  typedef typename hash_state_impl_type::accumulator_set_type accumulator_set_type;
181 
182  typedef typename hash_state_impl_type::hash_type hash_type;
183 
184  typedef typename boost::mpl::apply<accumulator_set_type, accumulator_type>::type::result_type
186 
187  template<typename SinglePassRange>
188  itr_hash_impl(const SinglePassRange &range, OutputIterator out, accumulator_set_type &&ise) :
189  HashStateImpl(std::forward<accumulator_set_type>(ise)), out(std::move(out)) {
190  BOOST_CONCEPT_ASSERT((boost::SinglePassRangeConcept<const SinglePassRange>));
191 
192  typedef
193  typename std::iterator_traits<typename SinglePassRange::iterator>::value_type value_type;
194  BOOST_STATIC_ASSERT(std::numeric_limits<value_type>::is_specialized);
195  typedef typename hash_type::template stream_processor<
197  std::numeric_limits<value_type>::digits + std::numeric_limits<value_type>::is_signed>::type
198  stream_processor;
199 
200  stream_processor(this->accumulator_set)(range.begin(), range.end());
201  }
202 
203  template<typename InputIterator>
204  itr_hash_impl(InputIterator first, InputIterator last, OutputIterator out,
205  accumulator_set_type &&ise) :
206  HashStateImpl(std::forward<accumulator_set_type>(ise)),
207  out(std::move(out)) {
208  BOOST_CONCEPT_ASSERT((boost::InputIteratorConcept<InputIterator>));
209 
210  typedef typename std::iterator_traits<InputIterator>::value_type value_type;
211  BOOST_STATIC_ASSERT(std::numeric_limits<value_type>::is_specialized);
212  typedef typename hash_type::template stream_processor<
214  std::numeric_limits<value_type>::digits + std::numeric_limits<value_type>::is_signed>::type
215  stream_processor;
216 
217  stream_processor(this->accumulator_set)(first, last);
218  }
219 
220  inline operator accumulator_set_type &() const {
221  return this->accumulator_set;
222  }
223 
224  inline operator OutputIterator() const {
225  result_type result =
226  boost::accumulators::extract_result<accumulator_type>(this->accumulator_set);
227  return std::move(result.cbegin(), result.cend(), out);
228  }
229  };
230  } // namespace detail
231  } // namespace hashes
232  } // namespace crypto3
233 } // namespace nil
234 
235 #endif
boost::accumulators::accumulator_set< digest< ProcessingMode::block_bits >, boost::accumulators::features< accumulators::tag::block< ProcessingMode > >, std::size_t > accumulator_set
Accumulator set with pre-defined block cipher accumulator params.
Definition: block/include/nil/crypto3/block/cipher_state.hpp:51
OutputIterator move(const SinglePassRange &rng, OutputIterator result)
Definition: move.hpp:45
Definition: pair.hpp:31
Definition: hash_state.hpp:43
Definition: hash_value.hpp:172
hash_state_impl_type::accumulator_set_type accumulator_set_type
Definition: hash_value.hpp:180
boost::mpl::apply< accumulator_set_type, accumulator_type >::type::result_type result_type
Definition: hash_value.hpp:185
HashStateImpl hash_state_impl_type
Definition: hash_value.hpp:177
itr_hash_impl(const SinglePassRange &range, OutputIterator out, accumulator_set_type &&ise)
Definition: hash_value.hpp:188
hash_state_impl_type::accumulator_type accumulator_type
Definition: hash_value.hpp:179
itr_hash_impl(InputIterator first, InputIterator last, OutputIterator out, accumulator_set_type &&ise)
Definition: hash_value.hpp:204
hash_state_impl_type::hash_type hash_type
Definition: hash_value.hpp:182
hash_state_impl_type::accumulator_set_type accumulator_set_type
Definition: hash_value.hpp:78
range_hash_impl(const SinglePassRange &range, accumulator_set_type &&ise)
Definition: hash_value.hpp:86
boost::mpl::apply< accumulator_set_type, accumulator_type >::type::result_type result_type
Definition: hash_value.hpp:83
range_hash_impl(InputIterator first, InputIterator last, accumulator_set_type &&ise)
Definition: hash_value.hpp:102
hash_state_impl_type::hash_type hash_type
Definition: hash_value.hpp:80
hash_state_impl_type::accumulator_type accumulator_type
Definition: hash_value.hpp:77
HashStateImpl hash_state_impl_type
Definition: hash_value.hpp:75
Definition: hash_value.hpp:45
boost::mpl::front< typename accumulator_set_type::features_type >::type accumulator_type
Definition: hash_value.hpp:48
accumulator_set_type & accumulator_set
Definition: hash_value.hpp:55
ref_hash_impl(accumulator_set_type &&stream_hash)
Definition: hash_value.hpp:52
accumulator_type::hash_type hash_type
Definition: hash_value.hpp:50
HashAccumulatorSet accumulator_set_type
Definition: hash_value.hpp:46
accumulator_set_type accumulator_set
Definition: hash_value.hpp:70
accumulator_type::hash_type hash_type
Definition: hash_value.hpp:64
value_hash_impl(accumulator_set_type &&stream_hash)
Definition: hash_value.hpp:66
boost::mpl::front< typename accumulator_set_type::features_type >::type accumulator_type
Definition: hash_value.hpp:62
HashAccumulatorSet accumulator_set_type
Definition: hash_value.hpp:60