modes/include/nil/crypto3/detail/poly_dbl.hpp
Go to the documentation of this file.
1 #ifndef CRYPTO3_DETAIL_POLY_DBL_HPP
2 #define CRYPTO3_DETAIL_POLY_DBL_HPP
3 
4 #include <algorithm>
5 
6 namespace nil {
7  namespace crypto3 {
8  namespace detail {
9 
10  /*
11  * The minimum weight irreducible binary polynomial of size n
12  *
13  * See http://www.hpl.hp.com/techreports/98/HPL-98-135.pdf
14  */
15  enum class min_weight_polynomial : uint64_t {
16  P64 = 0x1B,
17  P128 = 0x87,
18  P192 = 0x87,
19  P256 = 0x425,
20  P512 = 0x125,
21  P1024 = 0x80043,
22  };
23 
24  template<std::size_t LIMBS, min_weight_polynomial P>
25  void poly_double(uint8_t out[], const uint8_t in[]) {
26  uint64_t W[LIMBS];
27  load_be(W, in, LIMBS);
28 
29  const uint64_t POLY = static_cast<uint64_t>(P);
30 
31  const uint64_t carry = POLY * (W[0] >> 63);
32  for (std::size_t i = 0; i != LIMBS - 1; ++i) {
33  W[i] = (W[i] << 1) ^ (W[i + 1] >> 63);
34  }
35  W[LIMBS - 1] = (W[LIMBS - 1] << 1) ^ carry;
36 
37  copy_out_be(out, LIMBS * 8, W);
38  }
39 
40  template<std::size_t LIMBS, min_weight_polynomial P, typename InputIterator>
41  void poly_double_le(uint8_t out[], InputIterator first, InputIterator last) {
42  uint64_t W[LIMBS];
43  load_le(W, &*first, LIMBS);
44 
45  const uint64_t POLY = static_cast<uint64_t>(P);
46 
47  const uint64_t carry = POLY * (W[LIMBS - 1] >> 63);
48  for (std::size_t i = 0; i != LIMBS - 1; ++i) {
49  W[LIMBS - 1 - i] = (W[LIMBS - 1 - i] << 1) ^ (W[LIMBS - 2 - i] >> 63);
50  }
51  W[0] = (W[0] << 1) ^ carry;
52 
53  copy_out_le(out, LIMBS * 8, W);
54  }
55  } // namespace detail
56 
60  template<typename InputIterator>
61  void poly_double_n(uint8_t out[], InputIterator first, InputIterator last) {
62  switch (std::distance(first, last)) {
63  case 8:
64  return detail::poly_double<1, detail::min_weight_polynomial::P64>(out, first, last);
65  case 16:
66  return detail::poly_double<2, detail::min_weight_polynomial::P128>(out, first, last);
67  case 24:
68  return detail::poly_double<3, detail::min_weight_polynomial::P192>(out, first, last);
69  case 32:
70  return detail::poly_double<4, detail::min_weight_polynomial::P256>(out, first, last);
71  case 64:
72  return detail::poly_double<8, detail::min_weight_polynomial::P512>(out, first, last);
73  case 128:
74  return detail::poly_double<8, detail::min_weight_polynomial::P1024>(out, first, last);
75  default:
76  throw std::invalid_argument("Unsupported size for poly_double_n");
77  }
78  }
79 
83  inline constexpr bool poly_double_supported_size(size_t n) {
84  return (n == 8 || n == 16 || n == 24 || n == 32 || n == 64 || n == 128);
85  }
86 
87  template<typename Container>
88  inline void poly_double_n(const Container &c) {
89  return poly_double_n(c, c, c.size());
90  }
91 
92  /*
93  * Little endian convention - used for XTS
94  */
95  template<typename InputIterator>
96  void poly_double_n_le(uint8_t out[], InputIterator first, InputIterator last) {
97  switch (std::distance(first, last)) {
98  case 8:
99  return detail::poly_double_le<1, detail::min_weight_polynomial::P64>(out, first, last);
100  case 16:
101  return detail::poly_double_le<2, detail::min_weight_polynomial::P128>(out, first, last);
102  case 24:
103  return detail::poly_double_le<3, detail::min_weight_polynomial::P192>(out, first, last);
104  case 32:
105  return detail::poly_double_le<4, detail::min_weight_polynomial::P256>(out, first, last);
106  case 64:
107  return detail::poly_double_le<8, detail::min_weight_polynomial::P512>(out, first, last);
108  case 128:
109  return detail::poly_double_le<8, detail::min_weight_polynomial::P1024>(out, first, last);
110  default:
111  throw std::invalid_argument("Unsupported size for poly_double_n_le");
112  }
113  }
114  } // namespace crypto3
115 } // namespace nil
116 
117 #endif
void poly_double(uint8_t out[], const uint8_t in[])
Definition: mac/include/nil/crypto3/detail/poly_dbl.hpp:47
void poly_double_le(uint8_t out[], InputIterator first, InputIterator last)
Definition: mac/include/nil/crypto3/detail/poly_dbl.hpp:63
min_weight_polynomial
Definition: mac/include/nil/crypto3/detail/poly_dbl.hpp:37
void poly_double_n_le(uint8_t out[], InputIterator first, InputIterator last)
Definition: mac/include/nil/crypto3/detail/poly_dbl.hpp:118
void poly_double_n(uint8_t out[], InputIterator first, InputIterator last)
Definition: mac/include/nil/crypto3/detail/poly_dbl.hpp:83
constexpr bool poly_double_supported_size(size_t n)
Definition: mac/include/nil/crypto3/detail/poly_dbl.hpp:105
Definition: pair.hpp:31