block/include/nil/crypto3/detail/exploder.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2018-2020 Mikhail Komarov <nemo@nil.foundation>
3 // Copyright (c) 2020 Alexander Sokolov <asokolov@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_DETAIL_EXPLODER_HPP
27 #define CRYPTO3_DETAIL_EXPLODER_HPP
28 
29 #include <nil/crypto3/detail/stream_endian.hpp>
30 #include <nil/crypto3/detail/unbounded_shift.hpp>
31 #include <nil/crypto3/detail/reverser.hpp>
32 
33 #include <boost/integer.hpp>
34 #include <boost/static_assert.hpp>
35 
36 #include <iterator>
37 
38 namespace nil {
39  namespace crypto3 {
40  namespace detail {
41 
42  // By definition, for all exploders, InputValueBits > OutputValueBits,
43  // so we're taking one value and splitting it into many smaller values
44 
62  template<typename OutIter, int OutBits, typename T = typename std::iterator_traits<OutIter>::value_type>
63  struct outvalue_helper {
64  typedef T type;
65  };
66  template<typename OutIter, int OutBits>
67  struct outvalue_helper<OutIter, OutBits, void> {
68  typedef typename boost::uint_t<OutBits>::least type;
69  };
70 
86  template<typename InputEndianness, int UnitBits, int InputBits, int OutputBits, int k,
89 
90  template<typename InputEndianness, int UnitBits, int InputBits, int OutputBits, int k>
91  struct exploder_shift<InputEndianness, UnitBits, InputBits, OutputBits, k, false> {
92  constexpr static int const value = InputBits - (OutputBits + k);
93  };
94 
95  template<typename InputEndianness, int UnitBits, int InputBits, int OutputBits, int k>
96  struct exploder_shift<InputEndianness, UnitBits, InputBits, OutputBits, k, true> {
97  constexpr static int const value = k;
98  };
99 
116  template<typename InputEndianness, typename OutputEndianness, int UnitBits, int InputBits, int OutputBits,
117  int k>
118  struct exploder_step {
119  constexpr static int const shift =
121 
122  template<typename InputValue, typename OutputIterator>
123  inline static void step(InputValue const &in, OutputIterator &out) {
124  typedef typename outvalue_helper<OutputIterator, OutputBits>::type OutValue;
125  OutValue tmp = OutValue(low_bits<OutputBits>(unbounded_shr<shift>(in)));
128  *out++ = tmp;
129  }
130  };
131 
147  template<typename InputEndianness, typename OutputEndianness, int InputBits, int OutputBits, int k = 0>
148  struct exploder;
149 
150  template<template<int> class InputEndian, template<int> class OutputEndian, int UnitBits, int InputBits,
151  int OutputBits, int k>
152  struct exploder<InputEndian<UnitBits>, OutputEndian<UnitBits>, InputBits, OutputBits, k> {
153 
154  // To keep the implementation managable, input and output sizes must
155  // be multiples or factors of the unit size.
156  // If one of these is firing, you may want a bit-only stream_endian
157  // rather than one that mentions bytes or octets.
158  BOOST_STATIC_ASSERT(!(InputBits % UnitBits && UnitBits % InputBits));
159  BOOST_STATIC_ASSERT(!(OutputBits % UnitBits && UnitBits % OutputBits));
160 
161  typedef InputEndian<UnitBits> InputEndianness;
162  typedef OutputEndian<UnitBits> OutputEndianness;
165 
166  template<typename InputValue, typename OutIter>
167  inline static void explode(InputValue const &x, OutIter &out) {
168  step_type::step(x, out);
169  next_type::explode(x, out);
170  }
171  };
172 
173  template<template<int> class InputEndian, template<int> class OutputEndian, int UnitBits, int InputBits,
174  int OutputBits>
175  struct exploder<InputEndian<UnitBits>, OutputEndian<UnitBits>, InputBits, OutputBits, InputBits> {
176  template<typename InputValue, typename OutIter>
177  inline static void explode(InputValue const &, OutIter &) {
178  }
179  };
180 
181  } // namespace detail
182  } // namespace crypto3
183 } // namespace nil
184 
185 #endif // CRYPTO3_DETAIL_EXPLODER_HPP
void reverse(Range &a, std::size_t n)
Definition: basic_operations.hpp:54
Definition: pair.hpp:31
exploder_step< InputEndianness, OutputEndianness, UnitBits, InputBits, OutputBits, k > step_type
Definition: block/include/nil/crypto3/detail/exploder.hpp:163
static void explode(InputValue const &x, OutIter &out)
Definition: block/include/nil/crypto3/detail/exploder.hpp:167
exploder< InputEndianness, OutputEndianness, InputBits, OutputBits, k+OutputBits > next_type
Definition: block/include/nil/crypto3/detail/exploder.hpp:164
OutputEndian< UnitBits > OutputEndianness
Definition: block/include/nil/crypto3/detail/exploder.hpp:162
InputEndian< UnitBits > InputEndianness
Definition: block/include/nil/crypto3/detail/exploder.hpp:161
static void explode(InputValue const &, OutIter &)
Definition: block/include/nil/crypto3/detail/exploder.hpp:177
exploder_shift trait is used to determine whether the output elements are splitted from an input elem...
Definition: block/include/nil/crypto3/detail/exploder.hpp:88
exploder_step obtains an output value represented in OutputEndianness endianness from an input value ...
Definition: block/include/nil/crypto3/detail/exploder.hpp:118
static void step(InputValue const &in, OutputIterator &out)
Definition: block/include/nil/crypto3/detail/exploder.hpp:123
constexpr static int const shift
Definition: block/include/nil/crypto3/detail/exploder.hpp:119
exploder forms a sequence of output values represented in OutputEndianness endianness from an input v...
Definition: block/include/nil/crypto3/detail/exploder.hpp:148
Trait to determine whether the order of units defined by Endianness endianness is little.
Definition: block/include/nil/crypto3/detail/reverser.hpp:388
boost::uint_t< OutBits >::least type
Definition: block/include/nil/crypto3/detail/exploder.hpp:68
outvalue_helper trait is used to determine the output value type. If OutBits is not an exact power of...
Definition: block/include/nil/crypto3/detail/exploder.hpp:63
T type
Definition: block/include/nil/crypto3/detail/exploder.hpp:64