1 #ifndef CRYPTO3_DETAIL_POLY_DBL_HPP
2 #define CRYPTO3_DETAIL_POLY_DBL_HPP
24 template<std::
size_t LIMBS, min_weight_polynomial P>
25 void poly_double(uint8_t out[],
const uint8_t in[]) {
27 load_be(W, in, LIMBS);
29 const uint64_t POLY =
static_cast<uint64_t
>(P);
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);
35 W[LIMBS - 1] = (W[LIMBS - 1] << 1) ^ carry;
37 copy_out_be(out, LIMBS * 8, W);
40 template<std::
size_t LIMBS, min_weight_polynomial P,
typename InputIterator>
41 void poly_double_le(uint8_t out[], InputIterator first, InputIterator last) {
43 load_le(W, &*first, LIMBS);
45 const uint64_t POLY =
static_cast<uint64_t
>(P);
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);
51 W[0] = (W[0] << 1) ^ carry;
53 copy_out_le(out, LIMBS * 8, W);
60 template<
typename InputIterator>
61 void poly_double_n(uint8_t out[], InputIterator first, InputIterator last) {
62 switch (std::distance(first, last)) {
64 return detail::poly_double<1, detail::min_weight_polynomial::P64>(out, first, last);
66 return detail::poly_double<2, detail::min_weight_polynomial::P128>(out, first, last);
68 return detail::poly_double<3, detail::min_weight_polynomial::P192>(out, first, last);
70 return detail::poly_double<4, detail::min_weight_polynomial::P256>(out, first, last);
72 return detail::poly_double<8, detail::min_weight_polynomial::P512>(out, first, last);
74 return detail::poly_double<8, detail::min_weight_polynomial::P1024>(out, first, last);
76 throw std::invalid_argument(
"Unsupported size for poly_double_n");
84 return (n == 8 || n == 16 || n == 24 || n == 32 || n == 64 || n == 128);
87 template<
typename Container>
95 template<
typename InputIterator>
96 void poly_double_n_le(uint8_t out[], InputIterator first, InputIterator last) {
97 switch (std::distance(first, last)) {
99 return detail::poly_double_le<1, detail::min_weight_polynomial::P64>(out, first, last);
101 return detail::poly_double_le<2, detail::min_weight_polynomial::P128>(out, first, last);
103 return detail::poly_double_le<3, detail::min_weight_polynomial::P192>(out, first, last);
105 return detail::poly_double_le<4, detail::min_weight_polynomial::P256>(out, first, last);
107 return detail::poly_double_le<8, detail::min_weight_polynomial::P512>(out, first, last);
109 return detail::poly_double_le<8, detail::min_weight_polynomial::P1024>(out, first, last);
111 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