Exemple #1
0
        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);
                }
            }
        }
Exemple #2
0
        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();
            }
        }
Exemple #4
0
        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();
            }
        }
Exemple #6
0
 public void Dispose()
 {
     if (handle != IntPtr.Zero)
     {
         LibMultihash.ethash_full_delete(handle);
         handle = IntPtr.Zero;
     }
 }
Exemple #7
0
        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();
                    }
                });
            }
        }
Exemple #8
0
 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);
         }
     }
 }
Exemple #9
0
        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);
                }
            }
        }
Exemple #11
0
        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);
        }
Exemple #12
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);
        }
Exemple #13
0
        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);
        }
Exemple #14
0
        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);
                            }
                        }
                    }
                }
            });
        }
Exemple #15
0
        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);
        }
Exemple #17
0
        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);
        }
Exemple #18
0
        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);
        }
Exemple #19
0
        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);
                            }
                        }
                    }
                }
            });
        }
Exemple #20
0
        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);
        }
Exemple #21
0
        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);
                }
            }
        }
Exemple #22
0
        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();
            }
        }
Exemple #23
0
        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);
        }
Exemple #24
0
        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);
        }
Exemple #26
0
        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);
        }
Exemple #27
0
        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);
        }