6 #ifndef BITCOIN_EQUIHASH_H 7 #define BITCOIN_EQUIHASH_H 22 #include <boost/static_assert.hpp> 28 void ExpandArray(
const unsigned char* in,
size_t in_len,
29 unsigned char* out,
size_t out_len,
30 size_t bit_len,
size_t byte_pad=0);
32 unsigned char* out,
size_t out_len,
33 size_t bit_len,
size_t byte_pad=0);
43 template<
size_t WIDTH>
54 StepRow(
const unsigned char* hashIn,
size_t hInLen,
55 size_t hLen,
size_t cBitLen);
80 template<
size_t WIDTH>
83 template<
size_t WIDTH>
92 FullStepRow(
const unsigned char* hashIn,
size_t hInLen,
93 size_t hLen,
size_t cBitLen,
eh_index i);
102 std::vector<unsigned char>
GetIndices(
size_t len,
size_t lenIndices,
103 size_t cBitLen)
const;
107 size_t len,
size_t lenIndices);
112 template<
size_t WIDTH>
122 size_t hLen,
size_t cBitLen,
152 virtual const char*
what()
const throw() {
153 return "Equihash solver was cancelled";
157 inline constexpr
size_t max(
const size_t A,
const size_t B) {
return A > B ? A : B; }
160 return (1 << K)*(N/(K+1)+1)/8;
163 template<
unsigned int N,
unsigned int K>
167 BOOST_STATIC_ASSERT(K < N);
169 BOOST_STATIC_ASSERT((N/(K+1)) + 1 < 8*
sizeof(
eh_index));
172 enum :
size_t { IndicesPerHashOutput=512/N };
173 enum :
size_t { HashLen=(N+7)/8 };
174 enum :
size_t { HashOutput=IndicesPerHashOutput*HashLen };
175 enum :
size_t { CollisionBitLength=N/(K+1) };
176 enum :
size_t { CollisionByteLength=(CollisionBitLength+7)/8 };
177 enum :
size_t { HashLength=(K+1)*CollisionByteLength };
178 enum :
size_t { FullWidth=2*CollisionByteLength+
sizeof(
eh_index)*(1 << (K-1)) };
179 enum :
size_t { FinalFullWidth=2*CollisionByteLength+
sizeof(
eh_index)*(1 << (K)) };
180 enum :
size_t { TruncatedWidth=
max(HashLength+
sizeof(
eh_trunc), 2*CollisionByteLength+
sizeof(
eh_trunc)*(1 << (K-1))) };
181 enum :
size_t { FinalTruncatedWidth=
max(HashLength+
sizeof(
eh_trunc), 2*CollisionByteLength+
sizeof(
eh_trunc)*(1 << (K))) };
182 enum :
size_t { SolutionWidth=(1 << K)*(CollisionBitLength+1)/8 };
188 const std::function<
bool(std::vector<unsigned char>)> validBlock,
191 const std::function<
bool(std::vector<unsigned char>)> validBlock,
193 bool IsValidSolution(
const eh_HashState& base_state, std::vector<unsigned char> soln);
196 #include "equihash.tcc" 204 #define EhInitialiseState(n, k, base_state) \ 205 if (n == 96 && k == 3) { \ 206 Eh96_3.InitialiseState(base_state); \ 207 } else if (n == 200 && k == 9) { \ 208 Eh200_9.InitialiseState(base_state); \ 209 } else if (n == 96 && k == 5) { \ 210 Eh96_5.InitialiseState(base_state); \ 211 } else if (n == 48 && k == 5) { \ 212 Eh48_5.InitialiseState(base_state); \ 213 } else if (n == 184 && k == 7) { \ 214 Eh184_7.InitialiseState(base_state); \ 216 throw std::invalid_argument("Unsupported Equihash parameters"); \ 220 const std::function<
bool(std::vector<unsigned char>)> validBlock,
223 if (n == 96 && k == 3) {
224 return Eh96_3.
BasicSolve(base_state, validBlock, cancelled);
225 }
else if (n == 200 && k == 9) {
226 return Eh200_9.
BasicSolve(base_state, validBlock, cancelled);
227 }
else if (n == 96 && k == 5) {
228 return Eh96_5.
BasicSolve(base_state, validBlock, cancelled);
229 }
else if (n == 48 && k == 5) {
230 return Eh48_5.
BasicSolve(base_state, validBlock, cancelled);
231 }
else if (n == 184 && k == 7) {
232 return Eh184_7.
BasicSolve(base_state, validBlock, cancelled);
234 throw std::invalid_argument(
"Unsupported Equihash parameters");
239 const std::function<
bool(std::vector<unsigned char>)> validBlock)
246 const std::function<
bool(std::vector<unsigned char>)> validBlock,
249 if (n == 96 && k == 3) {
251 }
else if (n == 200 && k == 9) {
253 }
else if (n == 96 && k == 5) {
255 }
else if (n == 48 && k == 5) {
257 }
else if (n == 184 && k == 7) {
260 throw std::invalid_argument(
"Unsupported Equihash parameters");
265 const std::function<
bool(std::vector<unsigned char>)> validBlock)
271 #define EhIsValidSolution(n, k, base_state, soln, ret) \ 272 if (n == 96 && k == 3) { \ 273 ret = Eh96_3.IsValidSolution(base_state, soln); \ 274 } else if (n == 200 && k == 9) { \ 275 ret = Eh200_9.IsValidSolution(base_state, soln); \ 276 } else if (n == 96 && k == 5) { \ 277 ret = Eh96_5.IsValidSolution(base_state, soln); \ 278 } else if (n == 48 && k == 5) { \ 279 ret = Eh48_5.IsValidSolution(base_state, soln); \ 280 } else if (n == 184 && k == 7) { \ 281 ret = Eh184_7.IsValidSolution(base_state, soln); \ 283 throw std::invalid_argument("Unsupported Equihash parameters"); \ 286 #endif // BITCOIN_EQUIHASH_H
#define function(a, b, c, d, k, s)
std::vector< unsigned char > GetIndices(size_t len, size_t lenIndices, size_t cBitLen) const
void ExpandArray(const unsigned char *in, size_t in_len, unsigned char *out, size_t out_len, size_t bit_len, size_t byte_pad=0)
constexpr size_t equihash_solution_size(unsigned int N, unsigned int K)
eh_trunc TruncateIndex(const eh_index i, const unsigned int ilen)
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
bool EhOptimisedSolveUncancellable(unsigned int n, unsigned int k, const eh_HashState &base_state, const std::function< bool(std::vector< unsigned char >)> validBlock)
eh_index ArrayToEhIndex(const unsigned char *array)
TruncatedStepRow & operator=(const TruncatedStepRow< WIDTH > &a)
friend class TruncatedStepRow
friend bool DistinctIndices(const FullStepRow< W > &a, const FullStepRow< W > &b, size_t len, size_t lenIndices)
FullStepRow(const FullStepRow< WIDTH > &a)
bool operator()(const StepRow< W > &a, const StepRow< W > &b)
friend bool IsValidBranch(const FullStepRow< W > &a, const size_t len, const unsigned int ilen, const eh_trunc t)
bool EhOptimisedSolve(unsigned int n, unsigned int k, const eh_HashState &base_state, const std::function< bool(std::vector< unsigned char >)> validBlock, const std::function< bool(EhSolverCancelCheck)> cancelled)
std::vector< unsigned char > GetMinimalFromIndices(std::vector< eh_index > indices, size_t cBitLen)
FullStepRow & operator=(const FullStepRow< WIDTH > &a)
bool IndicesBefore(const TruncatedStepRow< WIDTH > &a, size_t len, size_t lenIndices) const
std::string GetHex(size_t len)
std::vector< eh_index > GetIndicesFromMinimal(std::vector< unsigned char > minimal, size_t cBitLen)
std::shared_ptr< eh_trunc > GetTruncatedIndices(size_t len, size_t lenIndices) const
bool EhBasicSolveUncancellable(unsigned int n, unsigned int k, const eh_HashState &base_state, const std::function< bool(std::vector< unsigned char >)> validBlock)
void CompressArray(const unsigned char *in, size_t in_len, unsigned char *out, size_t out_len, size_t bit_len, size_t byte_pad=0)
bool BasicSolve(const eh_HashState &base_state, const std::function< bool(std::vector< unsigned char >)> validBlock, const std::function< bool(EhSolverCancelCheck)> cancelled)
constexpr size_t max(const size_t A, const size_t B)
virtual const char * what() const
crypto_generichash_blake2b_state eh_HashState
unsigned char hash[WIDTH]
friend bool HasCollision(StepRow< W > &a, StepRow< W > &b, size_t l)
bool OptimisedSolve(const eh_HashState &base_state, const std::function< bool(std::vector< unsigned char >)> validBlock, const std::function< bool(EhSolverCancelCheck)> cancelled)
TruncatedStepRow(const TruncatedStepRow< WIDTH > &a)
bool EhBasicSolve(unsigned int n, unsigned int k, const eh_HashState &base_state, const std::function< bool(std::vector< unsigned char >)> validBlock, const std::function< bool(EhSolverCancelCheck)> cancelled)
bool IndicesBefore(const FullStepRow< WIDTH > &a, size_t len, size_t lenIndices) const