public void Digest(ReadOnlySpan <byte> data, Span <byte> result, params object[] extra) { Contract.RequiresNonNull(extra, nameof(extra)); Contract.Requires <ArgumentException>(extra.Length > 0, $"{nameof(extra)} must not be empty"); Contract.Requires <ArgumentException>(result.Length >= 32, $"{nameof(result)} must be greater or equal 32 bytes"); // concat nTime as hex string to data var nTime = (ulong)extra[0]; var nTimeHex = nTime.ToString("X").HexToByteArray(); Span <byte> dataEx = stackalloc byte[data.Length + nTimeHex.Length]; data.CopyTo(dataEx); if (nTimeHex.Length > 0) { var dest = dataEx.Slice(data.Length); nTimeHex.CopyTo(dest); } fixed(byte *input = dataEx) { fixed(byte *output = result) { LibMultihash.keccak(input, output, (uint)data.Length); } } }
public override bool Verify(byte[] header, byte[] solution) { Contract.RequiresNonNull(header, nameof(header)); Contract.Requires <ArgumentException>(header.Length == 140, $"{nameof(header)} must be exactly 140 bytes"); Contract.RequiresNonNull(solution, nameof(solution)); Contract.Requires <ArgumentException>(solution.Length == 100, $"{nameof(solution)} must be exactly 100 bytes"); logger.LogInvoke(); try { sem.Value.WaitOne(); fixed(byte *h = header) { fixed(byte *s = solution) { return(LibMultihash.equihash_verify_btg(h, header.Length, s, solution.Length)); } } } finally { sem.Value.Release(); } }
public override bool Verify(ReadOnlySpan <byte> header, ReadOnlySpan <byte> solution) { var sw = Stopwatch.StartNew(); try { sem.Value.WaitOne(); fixed(byte *h = header) { fixed(byte *s = solution) { var result = LibMultihash.equihash_verify_144_5(h, header.Length, s, solution.Length, personalization); messageBus?.SendTelemetry(personalization ?? "Equihash 144-5", TelemetryCategory.Hash, sw.Elapsed, result); return(result); } } } finally { sem.Value.Release(); } }
public async ValueTask GenerateAsync(string dagDir, ILogger logger, CancellationToken ct) { Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(dagDir), $"{nameof(dagDir)} must not be empty"); if (handle == IntPtr.Zero) { await Task.Run(() => { try { sem.WaitOne(); // re-check after obtaining lock if (handle != IntPtr.Zero) { return; } logger.Info(() => $"Generating DAG for epoch {Epoch}"); var started = DateTime.Now; var block = Epoch * EthereumConstants.EpochLength; // Generate a temporary cache var light = LibMultihash.ethash_light_new(block); try { // Generate the actual DAG handle = LibMultihash.ethash_full_new(dagDir, light, progress => { logger.Info(() => $"Generating DAG for epoch {Epoch}: {progress}%"); return(!ct.IsCancellationRequested ? 0 : 1); }); if (handle == IntPtr.Zero) { throw new OutOfMemoryException("ethash_full_new IO or memory error"); } logger.Info(() => $"Done generating DAG for epoch {Epoch} after {DateTime.Now - started}"); } finally { if (light != IntPtr.Zero) { LibMultihash.ethash_light_delete(light); } } } finally { sem.Release(); } }, ct); } }
/// <summary> /// Verify an Equihash solution /// </summary> /// <param name="header">header including nonce (140 bytes)</param> /// <param name="solution">equihash solution (excluding 3 bytes with size, so 1344 bytes length) - Do not include byte size preamble "fd4005"</param> /// <returns></returns> public bool Verify(byte[] header, byte[] solution) { Contract.RequiresNonNull(header, nameof(header)); Contract.Requires <ArgumentException>(header.Length == 140, $"{nameof(header)} must be exactly 140 bytes"); Contract.RequiresNonNull(solution, nameof(solution)); Contract.Requires <ArgumentException>(solution.Length == 1344, $"{nameof(solution)} must be exactly 1344 bytes"); try { sem.WaitOne(); fixed(byte *_header = header) { fixed(byte *_solution = solution) { return(LibMultihash.equihash_verify(_header, _solution)); } } } finally { sem.Release(); } }
public void Dispose() { if (handle != IntPtr.Zero) { LibMultihash.ethash_full_delete(handle); handle = IntPtr.Zero; } }
public async Task GenerateAsync(string dagDir, ILogger logger) { Assertion.Requires <ArgumentException>(!string.IsNullOrEmpty(dagDir), $"{nameof(dagDir)} must not be empty"); if (handle == IntPtr.Zero) { await Task.Run(() => { try { sem.WaitOne(); if (handle != IntPtr.Zero) { return; } logger.Info(() => $"Generating DAG for epoch {Epoch}"); var started = DateTime.Now; var block = Epoch * EthereumConstants.EpochLength; var light = LibMultihash.ethash_light_new(block); try { handle = LibMultihash.ethash_full_new(dagDir, light, progress => { logger.Info(() => $"Generating DAG for epoch {Epoch}: {progress}%"); return(0); }); if (handle == IntPtr.Zero) { throw new OutOfMemoryException("ethash_full_new IO or memory error"); } logger.Info(() => $"Done generating DAG for epoch {Epoch} after {DateTime.Now - started}"); } finally { if (light != IntPtr.Zero) { LibMultihash.ethash_light_delete(light); } } } finally { sem.Release(); } }); } }
public void Digest(ReadOnlySpan <byte> data, Span <byte> result, params object[] extra) { fixed(byte *input = data) { fixed(byte *output = result) { LibMultihash.blake2b(input, output, (uint)data.Length); } } }
public void Digest(ReadOnlySpan <byte> data, Span <byte> result, params object[] extra) { Contract.Requires <ArgumentException>(result.Length >= 32, $"{nameof(result)} must be greater or equal 32 bytes"); fixed(byte *input = data) { fixed(byte *output = result) { LibMultihash.yespower_sugar(input, output, (uint)data.Length); } } }
public void Digest(ReadOnlySpan <byte> data, Span <byte> result, params object[] extra) { Contract.Requires <ArgumentException>(data.Length == 80, $"{nameof(data)} must be exactly 80 bytes long"); Contract.Requires <ArgumentException>(result.Length >= 32, $"{nameof(result)} must be greater or equal 32 bytes"); fixed(byte *input = data) { fixed(byte *output = result) { LibMultihash.lyra2rev2(input, output); } } }
public bool DigestInit(PoolConfig poolConfig) { var vertHashDataFile = "verthash.dat"; if (poolConfig.Extra.TryGetValue("vertHashDataFile", out var result)) { vertHashDataFile = ((string)result).Trim(); } logger.Info(() => $"Loading verthash data file {vertHashDataFile}"); return(LibMultihash.verthash_init(vertHashDataFile, false) == 0); }
public byte[] Digest(byte[] data, params object[] extra) { Assertion.RequiresNonNull(data, nameof(data)); var result = new byte[32]; fixed(byte *input = data) { fixed(byte *output = result) { LibMultihash.x11(input, output, (uint)data.Length); } } return(result); }
public byte[] Digest(byte[] data, params object[] extra) { Contract.RequiresNonNull(data, nameof(data)); var result = new byte[64]; fixed(byte *input = data) { fixed(byte *output = result) { LibMultihash.sha3_512(input, output, (uint)data.Length); } } return(result); }
public async Task GenerateAsync(string dagDir) { Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(dagDir), $"{nameof(dagDir)} must not be empty"); await Task.Run(() => { lock (genLock) { if (!isGenerated) { logger.Info(() => $"Generating DAG for epoch {Epoch}"); var started = DateTime.Now; var block = Epoch * EthereumConstants.EpochLength; // Generate a temporary cache var light = LibMultihash.ethash_light_new(block); try { // Generate the actual DAG handle = LibMultihash.ethash_full_new(dagDir, light, progress => { logger.Info(() => $"Generating DAG: {progress}%"); return(0); }); if (handle == IntPtr.Zero) { throw new OutOfMemoryException("ethash_full_new IO or memory error"); } logger.Info(() => $"Done generating DAG for epoch {Epoch} after {DateTime.Now - started}"); isGenerated = true; } finally { if (light != IntPtr.Zero) { LibMultihash.ethash_light_delete(light); } } } } }); }
public void Digest(ReadOnlySpan <byte> data, Span <byte> result, params object[] extra) { Contract.Requires <ArgumentException>(result.Length >= 32, $"{nameof(result)} must be greater or equal 32 bytes"); // get nFactor var ts = ((DateTimeOffset)clock.Now).ToUnixTimeSeconds(); var n = timetable.First(x => ts >= x.Item2).Item1; var nFactor = Math.Log(n) / Math.Log(2); fixed(byte *input = data) { fixed(byte *output = result) { LibMultihash.scryptn(input, output, (uint)nFactor, (uint)data.Length); } } }
public byte[] Digest(byte[] data, params object[] extra) { Assertion.RequiresNonNull(data, nameof(data)); Assertion.Requires <ArgumentException>(data.Length == 80, $"{nameof(data)} length must be exactly 80 bytes"); var result = new byte[32]; fixed(byte *input = data) { fixed(byte *output = result) { LibMultihash.neoscrypt(input, output, (uint)data.Length, profile); } } return(result); }
public byte[] Digest(byte[] data, params object[] extra) { Contract.RequiresNonNull(data, nameof(data)); Contract.Requires <ArgumentException>(data.Length == 80, $"{nameof(data)} must be exactly 80 bytes long"); var result = new byte[32]; fixed(byte *input = data) { fixed(byte *output = result) { LibMultihash.lyra2rev2(input, output); } } return(result); }
public void Digest(ReadOnlySpan <byte> data, Span <byte> result, params object[] extra) { Contract.Requires <ArgumentException>(data.Length == 80, $"{nameof(data)} must be exactly 80 bytes long"); Contract.Requires <ArgumentException>(result.Length >= 32, $"{nameof(result)} must be greater or equal 32 bytes"); var sw = Stopwatch.StartNew(); fixed(byte *input = data) { fixed(byte *output = result) { LibMultihash.verthash(input, output, data.Length); } } messageBus?.SendTelemetry("Verthash", TelemetryCategory.Hash, sw.Elapsed); }
public async Task GenerateAsync() { await Task.Run(() => { lock (genLock) { if (!isGenerated) { logger.Debug(() => $"Generating DAG for epoch {Epoch}"); var started = DateTime.Now; var block = Epoch * EthereumConstants.EpochLength; // Generate a temporary cache var light = LibMultihash.ethash_light_new(block); try { // Generate the actual DAG handle = LibMultihash.ethash_full_new(light, progress => { logger.Debug(() => $"Generating DAG: {progress}%"); return(0); }); if (handle == IntPtr.Zero) { throw new OutOfMemoryException("ethash_full_new IO or memory error"); } logger.Debug(() => $"Done generating DAG for epoch {Epoch} after {DateTime.Now - started}"); isGenerated = true; } finally { if (light != IntPtr.Zero) { LibMultihash.ethash_light_delete(light); } } } } }); }
public bool Compute(byte[] hash, ulong nonce, out byte[] mixDigest, out byte[] result) { Contract.RequiresNonNull(hash, nameof(hash)); mixDigest = null; result = null; LibMultihash.ethash_return_value value; LibMultihash.ethash_light_compute(handle, hash, nonce, out value); if (value.success) { mixDigest = value.mix_hash.value; result = value.result.value; } return(value.success); }
public void Digest(ReadOnlySpan <byte> data, Span <byte> result, params object[] extra) { Contract.Requires <ArgumentException>(extra.Length >= 4, $"{nameof(extra)} four extra parameters expected"); Contract.Requires <ArgumentException>(data.Length <= 80, $"{nameof(data)} must be less or equal 80 bytes"); Contract.Requires <ArgumentException>(result.Length >= 32, $"{nameof(result)} must be greater or equal 32 bytes"); var nTime = (uint)(ulong)extra[0]; var networkParams = (BitcoinNetworkParams)extra[3]; var config = configs.GetValue(networkParams, (bnp) => bnp.Extra.SafeExtensionDataAs <OdoCryptConfig>()); var key = nTime - nTime % config.OdoCryptShapeChangeInterval; fixed(byte *input = data) { fixed(byte *output = result) { LibMultihash.odocrypt(input, output, (uint)data.Length, key); } } }
public override bool Verify(ReadOnlySpan <byte> header, ReadOnlySpan <byte> solution) { try { sem.Value.WaitOne(); fixed(byte *h = header) { fixed(byte *s = solution) { return(LibMultihash.equihash_verify_96_5(h, header.Length, s, solution.Length, personalization)); } } } finally { sem.Value.Release(); } }
public byte[] Digest(byte[] data, params object[] extra) { Assertion.RequiresNonNull(data, nameof(data)); var ts = ((DateTimeOffset)clock.Now).ToUnixTimeSeconds(); var n = timetable.First(x => ts >= x.Item2).Item1; var nFactor = Math.Log(n) / Math.Log(2); var result = new byte[32]; fixed(byte *input = data) { fixed(byte *output = result) { LibMultihash.scryptn(input, output, (uint)nFactor, (uint)data.Length); } } return(result); }
public async Task GenerateAsync() { await Task.Run(() => { lock (genLock) { if (!isGenerated) { var started = DateTime.Now; logger.Debug(() => $"Generating cache for epoch {Epoch}"); var block = Epoch * EthereumConstants.EpochLength; handle = LibMultihash.ethash_light_new(block); logger.Debug(() => $"Done generating cache for epoch {Epoch} after {DateTime.Now - started}"); isGenerated = true; } } }); }
public byte[] Digest(byte[] data, params object[] extra) { Assertion.RequiresNonNull(data, nameof(data)); Assertion.RequiresNonNull(extra, nameof(extra)); Assertion.Requires <ArgumentException>(extra.Length > 0, $"{nameof(extra)} must not be empty"); var nTime = (ulong)extra[0]; var dataEx = data.Concat(nTime.ToString("X").HexToByteArray()).ToArray(); var result = new byte[32]; fixed(byte *input = dataEx) { fixed(byte *output = result) { LibMultihash.kezzak(input, output, (uint)data.Length); } } return(result); }
public unsafe bool Compute(byte[] hash, ulong nonce, out byte[] mixDigest, out byte[] result) { Contract.RequiresNonNull(hash, nameof(hash)); mixDigest = null; result = null; var value = new LibMultihash.ethash_return_value(); fixed(byte *input = hash) { LibMultihash.ethash_full_compute(handle, input, nonce, ref value); } if (value.success) { mixDigest = value.mix_hash.value; result = value.result.value; } return(value.success); }
public static unsafe string GetDefaultDagDirectory() { var chars = new byte[512]; fixed(byte *data = chars) { if (LibMultihash.ethash_get_default_dirname(data, chars.Length)) { int length; for (length = 0; length < chars.Length; length++) { if (data[length] == 0) { break; } } return(Encoding.UTF8.GetString(data, length)); } } return(null); }
public unsafe bool Compute(ILogger logger, byte[] hash, ulong nonce, out byte[] mixDigest, out byte[] result) { Assertion.RequiresNonNull(hash, nameof(hash)); logger.LogInvoke(); mixDigest = null; result = null; var value = new LibMultihash.ethash_return_value(); fixed(byte *input = hash) { LibMultihash.ethash_light_compute(handle, input, nonce, ref value); } if (value.success) { mixDigest = value.mix_hash.value; result = value.result.value; } return(value.success); }