public bool Verify(Solution sol) { for (int i = 0; i < 4; ++i) { _blockTemplate[_nonceOffset + i] = (byte)(sol.Nonce >> (8 * i)); } byte[] key = _blake.ComputeHash(_blockTemplate); _blakeKeyed = new Blake2B256(key); var pow = _blakeKeyed.ComputeHash(sol.Result); if (!BinaryUtils.ArraysEqual(pow, sol.ProofOfWork)) { Console.WriteLine("Invalid PoW"); return(false); } var program = _factory.GenProgram(key); _runner.WriteProgram(program); var auxiliary = _blakeKeyed.ComputeHash(_runner.Buffer, 0, _runner.ProgramLength); if ((auxiliary[0] ^ sol.Result[0]) >= _bound) { Console.WriteLine("Invalid Auxiliary"); return(false); } auxiliary[0] &= _clearMask; var ri = _runner.ExecuteProgram(); if (!ri.Success) { throw new Exception(string.Format($"Program execution failed. Nonce value: {(sol.Nonce)}. Seed: {BinaryUtils.ByteArrayToString(key)}, {ri.Output}")); } var result = _blakeKeyed.ComputeHash(Encoding.ASCII.GetBytes(ri.Output)); for (int i = 0; i < result.Length; ++i) { result[i] ^= auxiliary[i]; } if (!BinaryUtils.ArraysEqual(sol.Result, result)) { Console.WriteLine("Invalid Result"); return(false); } return(true); }