zcashd/src/gtest/test_equihash.cpp

293 lines
9.8 KiB
C++
Raw Normal View History

#if defined(HAVE_CONFIG_H)
#include "config/bitcoin-config.h"
#endif
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "crypto/equihash.h"
#include "uint256.h"
scripted-diff: Move util files to separate directory. -BEGIN VERIFY SCRIPT- mkdir -p src/util git mv src/util.h src/util/system.h git mv src/util.cpp src/util/system.cpp git mv src/utilmoneystr.h src/util/moneystr.h git mv src/utilmoneystr.cpp src/util/moneystr.cpp git mv src/utilstrencodings.h src/util/strencodings.h git mv src/utilstrencodings.cpp src/util/strencodings.cpp git mv src/utiltime.h src/util/time.h git mv src/utiltime.cpp src/util/time.cpp sed -i -e 's/"util\.h"/"util\/system\.h"/g' $(git ls-files 'src/*.h' 'src/*.cpp') git checkout HEAD -- src/secp256k1 # exclude secp256k1, which has its own "util.h" sed -i -e 's/"utilmoneystr\.h"/"util\/moneystr\.h"/g' $(git ls-files 'src/*.h' 'src/*.cpp') sed -i -e 's/"utilstrencodings\.h"/"util\/strencodings\.h"/g' $(git ls-files 'src/*.h' 'src/*.cpp') sed -i -e 's/<utilstrencodings\.h>/<util\/strencodings\.h>/g' $(git ls-files 'src/*.h' 'src/*.cpp') sed -i -e 's/"utiltime\.h"/"util\/time\.h"/g' $(git ls-files 'src/*.h' 'src/*.cpp') sed -i -e 's/BITCOIN_UTIL_H/BITCOIN_UTIL_SYSTEM_H/g' src/util/system.h sed -i -e 's/BITCOIN_UTILMONEYSTR_H/BITCOIN_UTIL_MONEYSTR_H/g' src/util/moneystr.h sed -i -e 's/BITCOIN_UTILSTRENCODINGS_H/BITCOIN_UTIL_STRENCODINGS_H/g' src/util/strencodings.h sed -i -e 's/BITCOIN_UTILTIME_H/BITCOIN_UTIL_TIME_H/g' src/util/time.h sed -i -e 's/ util\.\(h\|cpp\)/ util\/system\.\1/g' src/Makefile.am sed -i -e 's/utilmoneystr\.\(h\|cpp\)/util\/moneystr\.\1/g' src/Makefile.am sed -i -e 's/utilstrencodings\.\(h\|cpp\)/util\/strencodings\.\1/g' src/Makefile.am sed -i -e 's/utiltime\.\(h\|cpp\)/util\/time\.\1/g' src/Makefile.am sed -i -e 's/src\/util\.cpp/src\/util\/system\.cpp/g' test/lint/lint-locale-dependence.sh sed -i -e 's/src\/utilmoneystr\.cpp/src\/util\/moneystr\.cpp/g' test/lint/lint-locale-dependence.sh sed -i -e 's/src\/utilstrencodings\.\(h\|cpp\)/src\/util\/strencodings\.\1/g' test/lint/lint-locale-dependence.sh -END VERIFY SCRIPT-
2018-10-22 15:51:11 -07:00
#include "util/strencodings.h"
void TestExpandAndCompress(const std::string &scope, size_t bit_len, size_t byte_pad,
std::vector<unsigned char> compact,
std::vector<unsigned char> expanded)
{
SCOPED_TRACE(scope);
std::vector<unsigned char> out(expanded.size());
ExpandArray(compact.data(), compact.size(),
out.data(), out.size(), bit_len, byte_pad);
EXPECT_EQ(expanded, out);
out.resize(compact.size());
CompressArray(expanded.data(), expanded.size(),
out.data(), out.size(), bit_len, byte_pad);
EXPECT_EQ(compact, out);
}
TEST(EquihashTests, ExpandAndContractArrays) {
TestExpandAndCompress("8 11-bit chunks, all-ones", 11, 0,
ParseHex("ffffffffffffffffffffff"),
ParseHex("07ff07ff07ff07ff07ff07ff07ff07ff"));
TestExpandAndCompress("8 21-bit chunks, alternating 1s and 0s", 21, 0,
ParseHex("aaaaad55556aaaab55555aaaaad55556aaaab55555"),
ParseHex("155555155555155555155555155555155555155555155555"));
TestExpandAndCompress("8 21-bit chunks, based on example in the spec", 21, 0,
ParseHex("000220000a7ffffe00123022b38226ac19bdf23456"),
ParseHex("0000440000291fffff0001230045670089ab00cdef123456"));
TestExpandAndCompress("16 14-bit chunks, alternating 11s and 00s", 14, 0,
ParseHex("cccf333cccf333cccf333cccf333cccf333cccf333cccf333cccf333"),
ParseHex("3333333333333333333333333333333333333333333333333333333333333333"));
TestExpandAndCompress("8 11-bit chunks, all-ones, 2-byte padding", 11, 2,
ParseHex("ffffffffffffffffffffff"),
ParseHex("000007ff000007ff000007ff000007ff000007ff000007ff000007ff000007ff"));
}
void TestMinimalSolnRepr(const std::string &scope, size_t cBitLen,
std::vector<eh_index> indices,
std::vector<unsigned char> minimal)
{
SCOPED_TRACE(scope);
#if ENABLE_MINING
EXPECT_EQ(indices, GetIndicesFromMinimal(minimal, cBitLen));
#endif
EXPECT_EQ(minimal, GetMinimalFromIndices(indices, cBitLen));
}
TEST(EquihashTests, MinimalSolutionRepresentation) {
TestMinimalSolnRepr("Test 1", 20,
{1, 1, 1, 1, 1, 1, 1, 1},
ParseHex("000008000040000200001000008000040000200001"));
TestMinimalSolnRepr("Test 2", 20,
{2097151, 2097151, 2097151, 2097151,
2097151, 2097151, 2097151, 2097151},
ParseHex("ffffffffffffffffffffffffffffffffffffffffff"));
TestMinimalSolnRepr("Test 3", 20,
{131071, 128, 131071, 128, 131071, 128, 131071, 128},
ParseHex("0ffff8002003fffe000800ffff8002003fffe00080"));
TestMinimalSolnRepr("Test 4", 20,
{68, 41, 2097151, 1233, 665, 1023, 1, 1048575},
ParseHex("000220000a7ffffe004d10014c800ffc00002fffff"));
}
#if ENABLE_MINING
TEST(EquihashTests, IsProbablyDuplicate) {
2016-08-10 19:02:00 -07:00
std::shared_ptr<eh_trunc> p1 (new eh_trunc[4] {0, 1, 2, 3}, std::default_delete<eh_trunc[]>());
std::shared_ptr<eh_trunc> p2 (new eh_trunc[4] {0, 1, 1, 3}, std::default_delete<eh_trunc[]>());
std::shared_ptr<eh_trunc> p3 (new eh_trunc[4] {3, 1, 1, 3}, std::default_delete<eh_trunc[]>());
ASSERT_FALSE(IsProbablyDuplicate<4>(p1, 4));
ASSERT_FALSE(IsProbablyDuplicate<4>(p2, 4));
ASSERT_TRUE(IsProbablyDuplicate<4>(p3, 4));
}
TEST(EquihashTests, CheckBasicSolverCancelled) {
Equihash<48,5> Eh48_5;
2022-05-26 09:09:30 -07:00
eh_HashState state = Eh48_5.InitialiseState();
uint256 V = uint256S("0x00");
state.Update(V.begin(), V.size());
{
ASSERT_NO_THROW(Eh48_5.BasicSolve(state, [](std::vector<unsigned char> soln) {
return false;
}, [](EhSolverCancelCheck pos) {
return false;
}));
}
{
ASSERT_THROW(Eh48_5.BasicSolve(state, [](std::vector<unsigned char> soln) {
return false;
}, [](EhSolverCancelCheck pos) {
return pos == ListGeneration;
}), EhSolverCancelledException);
}
{
ASSERT_THROW(Eh48_5.BasicSolve(state, [](std::vector<unsigned char> soln) {
return false;
}, [](EhSolverCancelCheck pos) {
return pos == ListSorting;
}), EhSolverCancelledException);
}
{
ASSERT_THROW(Eh48_5.BasicSolve(state, [](std::vector<unsigned char> soln) {
return false;
}, [](EhSolverCancelCheck pos) {
return pos == ListColliding;
}), EhSolverCancelledException);
}
{
ASSERT_THROW(Eh48_5.BasicSolve(state, [](std::vector<unsigned char> soln) {
return false;
}, [](EhSolverCancelCheck pos) {
return pos == RoundEnd;
}), EhSolverCancelledException);
}
{
ASSERT_THROW(Eh48_5.BasicSolve(state, [](std::vector<unsigned char> soln) {
return false;
}, [](EhSolverCancelCheck pos) {
return pos == FinalSorting;
}), EhSolverCancelledException);
}
{
ASSERT_THROW(Eh48_5.BasicSolve(state, [](std::vector<unsigned char> soln) {
return false;
}, [](EhSolverCancelCheck pos) {
return pos == FinalColliding;
}), EhSolverCancelledException);
}
{
ASSERT_NO_THROW(Eh48_5.BasicSolve(state, [](std::vector<unsigned char> soln) {
return false;
}, [](EhSolverCancelCheck pos) {
return pos == PartialGeneration;
}));
}
{
ASSERT_NO_THROW(Eh48_5.BasicSolve(state, [](std::vector<unsigned char> soln) {
return false;
}, [](EhSolverCancelCheck pos) {
return pos == PartialSorting;
}));
}
{
ASSERT_NO_THROW(Eh48_5.BasicSolve(state, [](std::vector<unsigned char> soln) {
return false;
}, [](EhSolverCancelCheck pos) {
return pos == PartialSubtreeEnd;
}));
}
{
ASSERT_NO_THROW(Eh48_5.BasicSolve(state, [](std::vector<unsigned char> soln) {
return false;
}, [](EhSolverCancelCheck pos) {
return pos == PartialIndexEnd;
}));
}
{
ASSERT_NO_THROW(Eh48_5.BasicSolve(state, [](std::vector<unsigned char> soln) {
return false;
}, [](EhSolverCancelCheck pos) {
return pos == PartialEnd;
}));
}
}
TEST(EquihashTests, CheckOptimisedSolverCancelled) {
Equihash<48,5> Eh48_5;
2022-05-26 09:09:30 -07:00
eh_HashState state = Eh48_5.InitialiseState();
uint256 V = uint256S("0x00");
state.Update(V.begin(), V.size());
{
ASSERT_NO_THROW(Eh48_5.OptimisedSolve(state, [](std::vector<unsigned char> soln) {
return false;
}, [](EhSolverCancelCheck pos) {
return false;
}));
}
{
ASSERT_THROW(Eh48_5.OptimisedSolve(state, [](std::vector<unsigned char> soln) {
return false;
}, [](EhSolverCancelCheck pos) {
return pos == ListGeneration;
}), EhSolverCancelledException);
}
{
ASSERT_THROW(Eh48_5.OptimisedSolve(state, [](std::vector<unsigned char> soln) {
return false;
}, [](EhSolverCancelCheck pos) {
return pos == ListSorting;
}), EhSolverCancelledException);
}
{
ASSERT_THROW(Eh48_5.OptimisedSolve(state, [](std::vector<unsigned char> soln) {
return false;
}, [](EhSolverCancelCheck pos) {
return pos == ListColliding;
}), EhSolverCancelledException);
}
{
ASSERT_THROW(Eh48_5.OptimisedSolve(state, [](std::vector<unsigned char> soln) {
return false;
}, [](EhSolverCancelCheck pos) {
return pos == RoundEnd;
}), EhSolverCancelledException);
}
{
ASSERT_THROW(Eh48_5.OptimisedSolve(state, [](std::vector<unsigned char> soln) {
return false;
}, [](EhSolverCancelCheck pos) {
return pos == FinalSorting;
}), EhSolverCancelledException);
}
{
ASSERT_THROW(Eh48_5.OptimisedSolve(state, [](std::vector<unsigned char> soln) {
return false;
}, [](EhSolverCancelCheck pos) {
return pos == FinalColliding;
}), EhSolverCancelledException);
}
{
ASSERT_THROW(Eh48_5.OptimisedSolve(state, [](std::vector<unsigned char> soln) {
return false;
}, [](EhSolverCancelCheck pos) {
return pos == PartialGeneration;
}), EhSolverCancelledException);
}
{
ASSERT_THROW(Eh48_5.OptimisedSolve(state, [](std::vector<unsigned char> soln) {
return false;
}, [](EhSolverCancelCheck pos) {
return pos == PartialSorting;
}), EhSolverCancelledException);
}
{
ASSERT_THROW(Eh48_5.OptimisedSolve(state, [](std::vector<unsigned char> soln) {
return false;
}, [](EhSolverCancelCheck pos) {
return pos == PartialSubtreeEnd;
}), EhSolverCancelledException);
}
{
ASSERT_THROW(Eh48_5.OptimisedSolve(state, [](std::vector<unsigned char> soln) {
return false;
}, [](EhSolverCancelCheck pos) {
return pos == PartialIndexEnd;
}), EhSolverCancelledException);
}
{
ASSERT_THROW(Eh48_5.OptimisedSolve(state, [](std::vector<unsigned char> soln) {
return false;
}, [](EhSolverCancelCheck pos) {
return pos == PartialEnd;
}), EhSolverCancelledException);
}
}
#endif // ENABLE_MINING