block/include/nil/crypto3/detail/imploder.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_IMPLODER_HPP
27 #define CRYPTO3_DETAIL_IMPLODER_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/static_assert.hpp>
34 
35 namespace nil {
36  namespace crypto3 {
37  namespace detail {
38 
39  // By definition, for all imploders, InputValueBits < OutputValueBits,
40  // so we're taking many smaller values and combining them into one value
41 
61  template<typename OutputEndianness, int UnitBits, int InputBits, int OutputBits, int k,
64 
65  template<typename OutputEndianness, int UnitBits, int InputBits, int OutputBits, int k>
66  struct imploder_shift<OutputEndianness, UnitBits, InputBits, OutputBits, k, false> {
67  constexpr static int const value = OutputBits - (InputBits + k);
68  };
69 
70  template<typename OutputEndianness, int UnitBits, int InputBits, int OutputBits, int k>
71  struct imploder_shift<OutputEndianness, UnitBits, InputBits, OutputBits, k, true> {
72  constexpr static int const value = k;
73  };
74 
91  template<typename InputEndianness, typename OutputEndianness, int UnitBits, int InputBits, int OutputBits,
92  int k>
93  struct imploder_step {
94  constexpr static int const shift =
96 
97  template<typename InputValue, typename OutputValue>
98  inline static void step(InputValue &in, OutputValue &out) {
99  InputValue tmp = in;
102  out |= unbounded_shl<shift>(low_bits<InputBits>(OutputValue(tmp)));
103  }
104  };
105 
121  template<typename InputEndianness, typename OutputEndianness, int InputBits, int OutputBits, int k = 0>
122  struct imploder;
123 
124  template<template<int> class InputEndian, template<int> class OutputEndian, int UnitBits, int InputBits,
125  int OutputBits, int k>
126  struct imploder<InputEndian<UnitBits>, OutputEndian<UnitBits>, InputBits, OutputBits, k> {
127 
128  // To keep the implementation managable, input and output sizes must
129  // be multiples or factors of the unit size.
130  // If one of these is firing, you may want a bit-only stream_endian
131  // rather than one that mentions bytes or octets.
132  BOOST_STATIC_ASSERT(!(InputBits % UnitBits && UnitBits % InputBits));
133  BOOST_STATIC_ASSERT(!(OutputBits % UnitBits && UnitBits % OutputBits));
134 
135  typedef InputEndian<UnitBits> InputEndianness;
136  typedef OutputEndian<UnitBits> OutputEndianness;
139 
140  template<typename InIter, typename OutputValue>
141  inline static void implode(InIter &in, OutputValue &x) {
142  step_type::step(*in++, x);
143  next_type::implode(in, x);
144  }
145  };
146 
147  template<template<int> class InputEndian, template<int> class OutputEndian, int UnitBits, int InputBits,
148  int OutputBits>
149  struct imploder<InputEndian<UnitBits>, OutputEndian<UnitBits>, InputBits, OutputBits, OutputBits> {
150  template<typename InIter, typename OutputValue>
151  inline static void implode(InIter &, OutputValue &) {
152  }
153  };
154 
155  } // namespace detail
156  } // namespace crypto3
157 } // namespace nil
158 
159 #endif // CRYPTO3_DETAIL_IMPLODER_HPP
void reverse(Range &a, std::size_t n)
Definition: basic_operations.hpp:54
Definition: pair.hpp:31
static void implode(InIter &, OutputValue &)
Definition: block/include/nil/crypto3/detail/imploder.hpp:151
static void implode(InIter &in, OutputValue &x)
Definition: block/include/nil/crypto3/detail/imploder.hpp:141
InputEndian< UnitBits > InputEndianness
Definition: block/include/nil/crypto3/detail/imploder.hpp:135
imploder_step< InputEndianness, OutputEndianness, UnitBits, InputBits, OutputBits, k > step_type
Definition: block/include/nil/crypto3/detail/imploder.hpp:137
imploder< InputEndianness, OutputEndianness, InputBits, OutputBits, k+InputBits > next_type
Definition: block/include/nil/crypto3/detail/imploder.hpp:138
OutputEndian< UnitBits > OutputEndianness
Definition: block/include/nil/crypto3/detail/imploder.hpp:136
imploder_shift trait is used to determine whether the input elements are packed into an output elemen...
Definition: block/include/nil/crypto3/detail/imploder.hpp:63
imploder_step packs an input value represented in InputEndianness endianness into an output value rep...
Definition: block/include/nil/crypto3/detail/imploder.hpp:93
constexpr static int const shift
Definition: block/include/nil/crypto3/detail/imploder.hpp:94
static void step(InputValue &in, OutputValue &out)
Definition: block/include/nil/crypto3/detail/imploder.hpp:98
imploder processes a sequence of input values represented in InputEndianness endianness into an outpu...
Definition: block/include/nil/crypto3/detail/imploder.hpp:122
constexpr static const bool value
Definition: block/include/nil/crypto3/detail/reverser.hpp:389