25 #ifndef CRYPTO3_DETAIL_POLY_DBL_HPP
26 #define CRYPTO3_DETAIL_POLY_DBL_HPP
46 template<
size_t LIMBS, min_weight_polynomial P>
49 load_be(W, in, LIMBS);
51 const uint64_t POLY =
static_cast<uint64_t
>(P);
53 const uint64_t carry = POLY * (W[0] >> 63);
54 for (
size_t i = 0; i != LIMBS - 1; ++i) {
55 W[i] = (W[i] << 1) ^ (W[i + 1] >> 63);
57 W[LIMBS - 1] = (W[LIMBS - 1] << 1) ^ carry;
59 copy_out_be(out, LIMBS * 8, W);
62 template<
size_t LIMBS, min_weight_polynomial P,
typename InputIterator>
63 void poly_double_le(uint8_t out[], InputIterator first, InputIterator last) {
65 load_le(W, &*first, LIMBS);
67 const uint64_t POLY =
static_cast<uint64_t
>(P);
69 const uint64_t carry = POLY * (W[LIMBS - 1] >> 63);
70 for (
size_t i = 0; i != LIMBS - 1; ++i) {
71 W[LIMBS - 1 - i] = (W[LIMBS - 1 - i] << 1) ^ (W[LIMBS - 2 - i] >> 63);
73 W[0] = (W[0] << 1) ^ carry;
75 copy_out_le(out, LIMBS * 8, W);
82 template<
typename InputIterator>
83 void poly_double_n(uint8_t out[], InputIterator first, InputIterator last) {
84 switch (std::distance(first, last)) {
86 return detail::poly_double<1, detail::min_weight_polynomial::P64>(out, first, last);
88 return detail::poly_double<2, detail::min_weight_polynomial::P128>(out, first, last);
90 return detail::poly_double<3, detail::min_weight_polynomial::P192>(out, first, last);
92 return detail::poly_double<4, detail::min_weight_polynomial::P256>(out, first, last);
94 return detail::poly_double<8, detail::min_weight_polynomial::P512>(out, first, last);
96 return detail::poly_double<8, detail::min_weight_polynomial::P1024>(out, first, last);
98 throw std::invalid_argument(
"Unsupported size for poly_double_n");
106 return (n == 8 || n == 16 || n == 24 || n == 32 || n == 64 || n == 128);
109 template<
typename Container>
117 template<
typename InputIterator>
119 switch (std::distance(first, last)) {
121 return detail::poly_double_le<1, detail::min_weight_polynomial::P64>(out, first, last);
123 return detail::poly_double_le<2, detail::min_weight_polynomial::P128>(out, first, last);
125 return detail::poly_double_le<3, detail::min_weight_polynomial::P192>(out, first, last);
127 return detail::poly_double_le<4, detail::min_weight_polynomial::P256>(out, first, last);
129 return detail::poly_double_le<8, detail::min_weight_polynomial::P512>(out, first, last);
131 return detail::poly_double_le<8, detail::min_weight_polynomial::P1024>(out, first, last);
133 throw std::invalid_argument(
"Unsupported size for poly_double_n_le");
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