poseidon_constants_operator.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2020 Ilias Khairullin <ilias@nil.foundation>
3 // Copyright (c) 2020 Mikhail Komarov <nemo@nil.foundation>
4 //
5 // Distributed under the Boost Software License, Version 1.0
6 // See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt
8 //---------------------------------------------------------------------------//
9 
10 #ifndef CRYPTO3_HASH_POSEIDON_CONSTANTS_HPP
11 #define CRYPTO3_HASH_POSEIDON_CONSTANTS_HPP
12 
16 
17 #include <boost/assert.hpp>
18 
19 namespace nil {
20  namespace crypto3 {
21  namespace hashes {
22  namespace detail {
23  template<typename FieldType, std::size_t Arity, std::size_t PartRounds>
25  typedef FieldType field_type;
29 
30  typedef typename field_type::value_type element_type;
32 
33  constexpr static const std::size_t state_words = policy_type::state_words;
34  typedef typename policy_type::state_type state_type;
35 
36  constexpr static const std::size_t full_rounds = policy_type::full_rounds;
37  constexpr static const std::size_t half_full_rounds = policy_type::half_full_rounds;
38  constexpr static const std::size_t part_rounds = policy_type::part_rounds;
39 
40  constexpr static const std::size_t round_constants_size = (full_rounds + part_rounds) * state_words;
41  constexpr static const std::size_t equivalent_round_constants_size =
42  (full_rounds + 1) * state_words + part_rounds - 1;
45 
46  /*
47  * =========================================================
48  * Optimized
49  * =========================================================
50  */
51 
53  std::size_t round_number) const {
54  BOOST_ASSERT_MSG(round_number < half_full_rounds,
55  "wrong using: arc_sbox_mds_full_round_optimized_first");
56  std::size_t constant_number_base = round_number * state_words;
57  for (std::size_t i = 0; i < state_words; i++) {
58  A[i] += get_equivalent_round_constant(constant_number_base + i);
59  A[i] = A[i] * A[i] * A[i] * A[i] * A[i];
60  }
62  }
63 
65  std::size_t round_number) const {
66  BOOST_ASSERT_MSG(round_number >= half_full_rounds + part_rounds,
67  "wrong using: arc_sbox_mds_full_round_optimized_last");
68  std::size_t constant_number_base =
69  (half_full_rounds + 1) * state_words + (part_rounds - 1) +
70  (round_number - half_full_rounds - part_rounds) * state_words;
71  for (std::size_t i = 0; i < state_words; i++) {
72  A[i] += get_equivalent_round_constant(constant_number_base + i);
73  A[i] = A[i] * A[i] * A[i] * A[i] * A[i];
74  }
76  }
77 
79  std::size_t round_number) const {
80  BOOST_ASSERT_MSG(round_number == half_full_rounds,
81  "wrong using: arc_mds_part_round_optimized_init");
82  std::size_t constant_number_base = half_full_rounds * state_words;
83  for (std::size_t i = 0; i < state_words; i++) {
84  A[i] += get_equivalent_round_constant(constant_number_base + i);
85  }
87  }
88 
90  std::size_t round_number) const {
91  BOOST_ASSERT_MSG(round_number >= half_full_rounds &&
92  round_number < half_full_rounds + part_rounds - 1,
93  "wrong using: sbox_arc_mds_part_round_optimized");
94  std::size_t constant_number_base =
95  (half_full_rounds + 1) * state_words + (round_number - half_full_rounds - 1) + 1;
96  A[0] = A[0] * A[0] * A[0] * A[0] * A[0];
97  A[0] += get_equivalent_round_constant(constant_number_base);
99  }
100 
102  std::size_t round_number) const {
103  BOOST_ASSERT_MSG(round_number == half_full_rounds + part_rounds - 1,
104  "wrong using: sbox_mds_part_round_optimized_last");
105  A[0] = A[0] * A[0] * A[0] * A[0] * A[0];
107  }
108 
109  /*
110  * =========================================================
111  * Default
112  * =========================================================
113  */
114 
115  inline void arc_sbox_mds_full_round(state_vector_type &A, std::size_t round_number) const {
116  BOOST_ASSERT_MSG(round_number < half_full_rounds ||
117  round_number >= half_full_rounds + part_rounds,
118  "wrong using: arc_sbox_mds_full_round");
119  for (std::size_t i = 0; i < state_words; i++) {
120  A[i] += get_round_constant(round_number * state_words + i);
121  A[i] = A[i] * A[i] * A[i] * A[i] * A[i];
122  }
124  }
125 
126  inline void arc_sbox_mds_part_round(state_vector_type &A, std::size_t round_number) const {
127  BOOST_ASSERT_MSG(round_number >= half_full_rounds &&
128  round_number < half_full_rounds + part_rounds,
129  "wrong using: arc_sbox_mds_part_round");
130  for (std::size_t i = 0; i < state_words; i++) {
131  A[i] += get_round_constant(round_number * state_words + i);
132  }
133  A[0] = A[0] * A[0] * A[0] * A[0] * A[0];
135  }
136 
137  // private:
138  constexpr inline const element_type &get_round_constant(std::size_t constant_number) const {
139  return round_constants_generator.round_constants[constant_number];
140  }
141 
142  constexpr inline state_vector_type
143  get_round_constants_slice(std::size_t constants_number_base) const {
144  return algebra::slice<state_words>(round_constants_generator.round_constants,
145  constants_number_base);
146  }
147 
148 #ifdef CRYPTO3_HASH_POSEIDON_COMPILE_TIME
149  constexpr
150 #endif
152  state_vector_type inv_cip1;
153  state_vector_type agregated_round_constants;
154  std::size_t equivalent_constant_number_base =
156 
157  for (std::size_t i = 0; i < half_full_rounds * state_words; i++) {
161  }
162 
163  for (std::size_t i = half_full_rounds * state_words;
165  i++) {
167  }
168 
169  for (std::size_t r = half_full_rounds + part_rounds - 2; r >= half_full_rounds; r--) {
170  agregated_round_constants = get_round_constants_slice((r + 1) * state_words) + inv_cip1;
171  policy_matrix.product_with_inverse_mds_matrix_noalias(agregated_round_constants, inv_cip1);
172  equivalent_round_constants[equivalent_constant_number_base + r] = inv_cip1[0];
173  inv_cip1[0] = 0;
174  }
175 
176  policy_matrix.product_with_inverse_mds_matrix_noalias(agregated_round_constants, inv_cip1);
177  inv_cip1[0] = 0;
178  for (std::size_t i = 0; i < state_words; i++) {
180  }
181  }
182 
183  inline const element_type &get_equivalent_round_constant(std::size_t constant_number) const {
184  return equivalent_round_constants[constant_number];
185  }
186 
187 #ifdef CRYPTO3_HASH_POSEIDON_COMPILE_TIME
188  constexpr
189 #endif
193  }
194 
198  };
199  } // namespace detail
200  } // namespace hashes
201  } // namespace crypto3
202 } // namespace nil
203 
204 #endif // CRYPTO3_HASH_POSEIDON_CONSTANTS_HPP
Definition: pair.hpp:31
A container representing a vector.
Definition: vector.hpp:50
Definition: poseidon_constants_operator.hpp:24
constants_generator_policy_type round_constants_generator
Definition: poseidon_constants_operator.hpp:196
constexpr static const std::size_t state_words
Definition: poseidon_constants_operator.hpp:33
void arc_mds_part_round_optimized_init(state_vector_type &A, std::size_t round_number) const
Definition: poseidon_constants_operator.hpp:78
void arc_sbox_mds_full_round_optimized_first(state_vector_type &A, std::size_t round_number) const
Definition: poseidon_constants_operator.hpp:52
matrix_policy_type policy_matrix
Definition: poseidon_constants_operator.hpp:195
void generate_equivalent_round_constants()
Definition: poseidon_constants_operator.hpp:151
FieldType field_type
Definition: poseidon_constants_operator.hpp:25
constexpr static const std::size_t round_constants_size
Definition: poseidon_constants_operator.hpp:40
poseidon_policy< field_type, Arity, PartRounds > policy_type
Definition: poseidon_constants_operator.hpp:26
constexpr static const std::size_t full_rounds
Definition: poseidon_constants_operator.hpp:36
poseidon_constants_operator()
Definition: poseidon_constants_operator.hpp:190
equivalent_round_constants_type equivalent_round_constants
Definition: poseidon_constants_operator.hpp:197
poseidon_mds_matrix< field_type, Arity, PartRounds > matrix_policy_type
Definition: poseidon_constants_operator.hpp:27
constexpr static const std::size_t half_full_rounds
Definition: poseidon_constants_operator.hpp:37
constexpr const element_type & get_round_constant(std::size_t constant_number) const
Definition: poseidon_constants_operator.hpp:138
void arc_sbox_mds_full_round_optimized_last(state_vector_type &A, std::size_t round_number) const
Definition: poseidon_constants_operator.hpp:64
const element_type & get_equivalent_round_constant(std::size_t constant_number) const
Definition: poseidon_constants_operator.hpp:183
void sbox_arc_mds_part_round_optimized(state_vector_type &A, std::size_t round_number) const
Definition: poseidon_constants_operator.hpp:89
constexpr static const std::size_t equivalent_round_constants_size
Definition: poseidon_constants_operator.hpp:41
poseidon_lfsr< field_type, Arity, PartRounds > constants_generator_policy_type
Definition: poseidon_constants_operator.hpp:28
constexpr state_vector_type get_round_constants_slice(std::size_t constants_number_base) const
Definition: poseidon_constants_operator.hpp:143
matrix_policy_type::state_vector_type state_vector_type
Definition: poseidon_constants_operator.hpp:31
void sbox_mds_part_round_optimized_last(state_vector_type &A, std::size_t round_number) const
Definition: poseidon_constants_operator.hpp:101
constexpr static const std::size_t part_rounds
Definition: poseidon_constants_operator.hpp:38
void arc_sbox_mds_full_round(state_vector_type &A, std::size_t round_number) const
Definition: poseidon_constants_operator.hpp:115
field_type::value_type element_type
Definition: poseidon_constants_operator.hpp:30
void arc_sbox_mds_part_round(state_vector_type &A, std::size_t round_number) const
Definition: poseidon_constants_operator.hpp:126
algebra::vector< element_type, equivalent_round_constants_size > equivalent_round_constants_type
Definition: poseidon_constants_operator.hpp:44
policy_type::state_type state_type
Definition: poseidon_constants_operator.hpp:34
round_constants_type round_constants
Definition: poseidon_lfsr.hpp:116
void product_with_mds_matrix(state_vector_type &A_vector) const
Definition: poseidon_mds_matrix.hpp:42
void product_with_equivalent_mds_matrix_init(state_vector_type &A_vector, std::size_t round_number) const
Definition: poseidon_mds_matrix.hpp:51
constexpr void product_with_inverse_mds_matrix_noalias(const state_vector_type &A_vector_in, state_vector_type &A_vector_out) const
Definition: poseidon_mds_matrix.hpp:46
void product_with_equivalent_mds_matrix(state_vector_type &A_vector, std::size_t round_number) const
Definition: poseidon_mds_matrix.hpp:58
Definition: poseidon_policy.hpp:65