Kagome
Polkadot Runtime Engine in C++17
entropy_accumulator.cpp
Go to the documentation of this file.
1 
7 
8 #include "crypto/sha/sha256.hpp"
9 
10 namespace kagome::crypto::bip39 {
11  outcome::result<EntropyAccumulator> EntropyAccumulator::create(
12  size_t words_count) {
13  switch (words_count) {
14  case 12:
15  return EntropyAccumulator(132, 4);
16  case 15:
17  return EntropyAccumulator(165, 5);
18  case 18:
19  return EntropyAccumulator(198, 6);
20  case 21:
21  return EntropyAccumulator(231, 7);
22  case 24:
23  return EntropyAccumulator(264, 8);
24  default:
25  break;
26  }
28  }
29 
30  outcome::result<std::vector<uint8_t>> EntropyAccumulator::getEntropy() const {
31  if (bits_.size() != total_bits_count_) {
33  }
34 
35  // convert data
36  size_t bytes_count = (total_bits_count_ - checksum_bits_count_) / 8;
37  std::vector<uint8_t> res;
38  res.reserve(bytes_count);
39  auto it = bits_.begin();
40  for (size_t i = 0; i < bytes_count; ++i) {
41  uint8_t byte = 0;
42  for (size_t j = 0; j < 8u; ++j) {
43  byte <<= 1u;
44  byte += *it++;
45  }
46 
47  res.push_back(byte);
48  }
49 
50  return res;
51  }
52 
53  outcome::result<uint8_t> EntropyAccumulator::getChecksum() const {
54  if (bits_.size() != total_bits_count_) {
56  }
57 
58  uint8_t checksum = 0u;
59  auto it = bits_.rbegin();
60  for (auto i = 0u; i < checksum_bits_count_; ++i) {
61  checksum += (*it++ << i);
62  }
63 
64  return checksum;
65  }
66 
67  outcome::result<void> EntropyAccumulator::append(const EntropyToken &value) {
68  if (bits_.size() + value.size() > total_bits_count_) {
70  }
71 
72  for (size_t i = 0; i < value.size(); ++i) {
73  // bits order is little-endian, but we need big endian, reverse it
74  auto position = value.size() - i - 1;
75  uint8_t v = value.test(position) ? 1 : 0;
76  bits_.push_back(v);
77  }
78 
79  return outcome::success();
80  }
81 
82  outcome::result<uint8_t> EntropyAccumulator::calculateChecksum() const {
83  OUTCOME_TRY(entropy, getEntropy());
84  auto hash = sha256(entropy);
85  return hash[0] >> static_cast<uint8_t>(8 - checksum_bits_count_);
86  }
87 
89  size_t checksum_bits_count)
90  : total_bits_count_{bits_count},
91  checksum_bits_count_{checksum_bits_count} {
92  BOOST_ASSERT_MSG((bits_count - checksum_bits_count) % 32 == 0,
93  "invalid bits count");
94  BOOST_ASSERT_MSG(bits_count <= 264 && bits_count >= 132,
95  "unsupported bits count");
96 
97  bits_.reserve(bits_count);
98  }
99 
100 } // namespace kagome::crypto::bip39
101 
104  switch (error) {
106  return "invalid or unsupported words count";
108  return "cannot get info from storage while it is still not complete";
109  case E::STORAGE_IS_FULL:
110  return "cannot put more data into storage, it is full";
111  }
112 
113  return "unknown Bip39EntropyError error";
114 }
outcome::result< uint8_t > getChecksum() const
checksum is a part of last byte
OUTCOME_CPP_DEFINE_CATEGORY(kagome::crypto::bip39, Bip39EntropyError, error)
static outcome::result< EntropyAccumulator > create(size_t words_count)
create class instance
outcome::result< std::vector< uint8_t > > getEntropy() const
outcome::result< uint8_t > calculateChecksum() const
calculates checksum of significant bits
common::Hash256 sha256(std::string_view input)
Definition: sha256.cpp:11
outcome::result< void > append(const EntropyToken &value)
append a new entropy token
EntropyAccumulator(size_t bits_count, size_t checksum_bits_count)