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); }
public unsafe Solution Solve() { byte[] result = null; byte[] auxiliary = null; uint nonce; fixed(byte *block = _blockTemplate) { uint *noncePtr = (uint *)(block + _nonceOffset); do { (*noncePtr)++; byte[] key = _blake.ComputeHash(_blockTemplate); var program = _factory.GenProgram(key); _runner.WriteProgram(program); _blakeKeyed = new Blake2B256(key); auxiliary = _blakeKeyed.ComputeHash(_runner.Buffer, 0, _runner.ProgramLength); var ri = _runner.ExecuteProgram(); if (!ri.Success) { throw new Exception(string.Format($"Program execution failed. Nonce value: {(*noncePtr)}. Seed: {BinaryUtils.ByteArrayToString(key)}, {ri.Output}")); } result = _blakeKeyed.ComputeHash(Encoding.ASCII.GetBytes(ri.Output)); }while ((result[0] ^ auxiliary[0]) >= _bound); nonce = *noncePtr; } result[0] &= _clearMask; for (int i = 0; i < result.Length; ++i) { result[i] ^= auxiliary[i]; } return(new Solution() { Nonce = nonce, Result = result, ProofOfWork = _blakeKeyed.ComputeHash(result) }); }