| 738 | |
| 739 | template<unsigned int N, unsigned int K> |
| 740 | bool Equihash<N,K>::IsValidSolution(const eh_HashState& base_state, std::vector<unsigned char> soln) |
| 741 | { |
| 742 | if (soln.size() != SolutionWidth) { |
| 743 | LogPrint(BCLog::POW, "Invalid solution length: %d (expected %d)\n", |
| 744 | soln.size(), SolutionWidth); |
| 745 | return false; |
| 746 | } |
| 747 | |
| 748 | std::vector<FullStepRow<FinalFullWidth>> X; |
| 749 | X.reserve(1 << K); |
| 750 | unsigned char tmpHash[HashOutput]; |
| 751 | for (eh_index i : GetIndicesFromMinimal(soln, CollisionBitLength)) { |
| 752 | GenerateHash(base_state, i/IndicesPerHashOutput, tmpHash, HashOutput); |
| 753 | X.emplace_back(tmpHash+((i % IndicesPerHashOutput) * N/8), |
| 754 | N/8, HashLength, CollisionBitLength, i); |
| 755 | } |
| 756 | |
| 757 | size_t hashLen = HashLength; |
| 758 | size_t lenIndices = sizeof(eh_index); |
| 759 | while (X.size() > 1) { |
| 760 | std::vector<FullStepRow<FinalFullWidth>> Xc; |
| 761 | for (size_t i = 0; i < X.size(); i += 2) { |
| 762 | if (!HasCollision(X[i], X[i+1], CollisionByteLength)) { |
| 763 | LogPrint(BCLog::POW, "Invalid solution: invalid collision length between StepRows\n"); |
| 764 | LogPrint(BCLog::POW, "X[i] = %s\n", X[i].GetHex(hashLen)); |
| 765 | LogPrint(BCLog::POW, "X[i+1] = %s\n", X[i+1].GetHex(hashLen)); |
| 766 | return false; |
| 767 | } |
| 768 | if (X[i+1].IndicesBefore(X[i], hashLen, lenIndices)) { |
| 769 | LogPrint(BCLog::POW, "Invalid solution: Index tree incorrectly ordered\n"); |
| 770 | return false; |
| 771 | } |
| 772 | if (!DistinctIndices(X[i], X[i+1], hashLen, lenIndices)) { |
| 773 | LogPrint(BCLog::POW, "Invalid solution: duplicate indices\n"); |
| 774 | return false; |
| 775 | } |
| 776 | Xc.emplace_back(X[i], X[i+1], hashLen, lenIndices, CollisionByteLength); |
| 777 | } |
| 778 | X = Xc; |
| 779 | hashLen -= CollisionByteLength; |
| 780 | lenIndices *= 2; |
| 781 | } |
| 782 | |
| 783 | assert(X.size() == 1); |
| 784 | return X[0].IsZero(hashLen); |
| 785 | } |
| 786 | |
| 787 | // Explicit instantiations for Equihash<96,3> |
| 788 | template int Equihash<96,3>::InitialiseState(eh_HashState& base_state, bool btg_salt); |
nothing calls this directly
no test coverage detected