poseidon_lfsr.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2020 Ilias Khairullin <ilias@nil.foundation>
3 //
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
7 //---------------------------------------------------------------------------//
8 
9 #ifndef CRYPTO3_HASH_POSEIDON_LFSR_HPP
10 #define CRYPTO3_HASH_POSEIDON_LFSR_HPP
11 
12 #include <nil/crypto3/multiprecision/cpp_int.hpp>
14 
15 namespace nil {
16  namespace crypto3 {
17  namespace hashes {
18  namespace detail {
19  using namespace nil::crypto3::multiprecision;
20 
21  template<typename FieldType, std::size_t Arity, std::size_t PartRounds>
22  struct poseidon_lfsr {
24  constexpr static const std::size_t state_words = policy_type::state_words;
25  constexpr static const std::size_t word_bits = policy_type::word_bits;
26  constexpr static const std::size_t full_rounds = policy_type::full_rounds;
27  constexpr static const std::size_t part_rounds = policy_type::part_rounds;
28 
29  typedef typename FieldType::value_type element_type;
30  typedef typename FieldType::integral_type integral_type;
31  constexpr static const integral_type modulus = FieldType::modulus;
32 
33  constexpr static const std::size_t lfsr_state_bits = 80;
34  typedef number<backends::cpp_int_backend<
35  lfsr_state_bits, lfsr_state_bits, cpp_integer_type::unsigned_magnitude,
36  cpp_int_check_type::unchecked, void>>
38 
39  constexpr static const std::size_t constants_number = (full_rounds + part_rounds) * state_words;
41 
42  constexpr void generate_round_constants() {
44  lfsr_state_type lfsr_state = get_lfsr_init_state();
45 
46  for (std::size_t i = 0; i < (full_rounds + part_rounds) * state_words; i++) {
47  while (true) {
48  constant = 0;
49  for (std::size_t j = 0; j < word_bits; j++) {
50  lfsr_state = update_lfsr_state(lfsr_state);
51  constant = set_new_bit<integral_type>(
52  constant, get_lfsr_state_bit(lfsr_state, lfsr_state_bits - 1));
53  }
54  if (constant < modulus) {
55  round_constants[i] = element_type(constant);
56  break;
57  }
58  }
59  }
60  }
61 
63  lfsr_state_type state = 0;
64  int i = 0;
65  for (i = 1; i >= 0; i--)
66  state = set_new_bit(state, (1U >> i) & 1U); // field - as in filecoin
67  for (i = 3; i >= 0; i--)
68  state = set_new_bit(state, (1U >> i) & 1U); // s-box - as in filecoin
69  for (i = 11; i >= 0; i--)
70  state = set_new_bit(state, (word_bits >> i) & 1U);
71  for (i = 11; i >= 0; i--)
72  state = set_new_bit(state, (state_words >> i) & 1U);
73  for (i = 9; i >= 0; i--)
74  state = set_new_bit(state, (full_rounds >> i) & 1U);
75  for (i = 9; i >= 0; i--)
76  state = set_new_bit(state, (part_rounds >> i) & 1U);
77  for (i = 29; i >= 0; i--)
78  state = set_new_bit(state, 1);
79  // idling
80  for (i = 0; i < 160; i++)
81  state = update_lfsr_state_raw(state);
82  return state;
83  }
84 
86  while (true) {
87  state = update_lfsr_state_raw(state);
88  if (get_lfsr_state_bit(state, lfsr_state_bits - 1))
89  break;
90  else
91  state = update_lfsr_state_raw(state);
92  }
93  return update_lfsr_state_raw(state);
94  }
95 
97  bool new_bit = get_lfsr_state_bit(state, 0) != get_lfsr_state_bit(state, 13) !=
98  get_lfsr_state_bit(state, 23) != get_lfsr_state_bit(state, 38) !=
99  get_lfsr_state_bit(state, 51) != get_lfsr_state_bit(state, 62);
100  return set_new_bit(state, new_bit);
101  }
102 
103  constexpr inline bool get_lfsr_state_bit(lfsr_state_type state, std::size_t pos) {
104  return bit_test(state, lfsr_state_bits - 1 - pos);
105  }
106 
107  template<typename T>
108  constexpr inline T set_new_bit(T var, bool new_bit) {
109  return (var << 1) | (new_bit ? 1 : 0);
110  }
111 
112  constexpr poseidon_lfsr() : round_constants() {
113  generate_round_constants();
114  }
115 
117  };
118  } // namespace detail
119  } // namespace hashes
120  } // namespace crypto3
121 } // namespace nil
122 
123 #endif // CRYPTO3_HASH_POSEIDON_LFSR_HPP
nil::crypto3::math::expressions::detail::parser::constant_ constant
Definition: pair.hpp:31
Definition: poseidon_lfsr.hpp:22
number< backends::cpp_int_backend< lfsr_state_bits, lfsr_state_bits, cpp_integer_type::unsigned_magnitude, cpp_int_check_type::unchecked, void > > lfsr_state_type
Definition: poseidon_lfsr.hpp:37
constexpr T set_new_bit(T var, bool new_bit)
Definition: poseidon_lfsr.hpp:108
constexpr lfsr_state_type get_lfsr_init_state()
Definition: poseidon_lfsr.hpp:62
algebra::vector< element_type, constants_number > round_constants_type
Definition: poseidon_lfsr.hpp:40
constexpr poseidon_lfsr()
Definition: poseidon_lfsr.hpp:112
constexpr void generate_round_constants()
Definition: poseidon_lfsr.hpp:42
constexpr bool get_lfsr_state_bit(lfsr_state_type state, std::size_t pos)
Definition: poseidon_lfsr.hpp:103
poseidon_policy< FieldType, Arity, PartRounds > policy_type
Definition: poseidon_lfsr.hpp:23
constexpr lfsr_state_type update_lfsr_state(lfsr_state_type state)
Definition: poseidon_lfsr.hpp:85
FieldType::value_type element_type
Definition: poseidon_lfsr.hpp:29
constexpr lfsr_state_type update_lfsr_state_raw(lfsr_state_type state)
Definition: poseidon_lfsr.hpp:96
FieldType::integral_type integral_type
Definition: poseidon_lfsr.hpp:30
round_constants_type round_constants
Definition: poseidon_lfsr.hpp:116
Definition: poseidon_policy.hpp:65