示例#1
0
        public override void Run(object?arg)
        {
            string prefix1 = string.Concat(AddressPrefix, "3", keyword);
            string prefix2 = string.Concat(AddressPrefix, "1", keyword);
            string suffix1 = keyword;

            byte[] seedBytes      = new byte[32];
            byte[] secretBytes    = new byte[32];
            byte[] indexBytes     = new byte[4];
            byte[] publicKeyBytes = new byte[32];
            byte[] checksumBytes  = new byte[5];

            byte[] tmp = new byte[64];

            AddressBuffer addressBuffer = new(AddressPrefix.Length + 60);

            bool canMatchPrefix = this.canMatchPrefix;
            bool canMatchSuffix = this.canMatchSuffix;
            CancellationToken cancellationToken = this.cancellationToken;

            System.Action <string, string> resultCallback = this.resultCallback;

            addressBuffer.Append(AddressPrefix);
            while (!cancellationToken.IsCancellationRequested)
            {
                random.GetBytes(seedBytes);

                var hasher = Blake2b.CreateIncrementalHasher(32);
                hasher.Update(seedBytes);
                hasher.Update(indexBytes);
                hasher.Finish(secretBytes);

                Chaos.NaCl.Internal.Ed25519Ref10.Ed25519Operations.crypto_public_key(
                    secretBytes, 0, publicKeyBytes, 0, tmp);

                Blake2b.ComputeAndWriteHash(5, publicKeyBytes, checksumBytes);
                Reverse(checksumBytes);

                NanoBase32(publicKeyBytes, ref addressBuffer);
                NanoBase32(checksumBytes, ref addressBuffer);

                bool isMatched = false;
                if (canMatchPrefix)
                {
                    isMatched = addressBuffer.StartsWith(prefix1) || addressBuffer.StartsWith(prefix2);
                }
                if (!isMatched && canMatchSuffix)
                {
                    isMatched = addressBuffer.EndsWith(suffix1);
                }

                if (isMatched)
                {
                    var address = addressBuffer.ToString();
                    if (resultCallback != null)
                    {
                        resultCallback.Invoke(HexUtils.HexFromByteArray(seedBytes), address);
                    }
                    else
                    {
                        FoundSeed    = HexUtils.HexFromByteArray(seedBytes);
                        FoundAddress = address;
                        break;
                    }
                }

                ++attempts;
                addressBuffer.Length = AddressPrefix.Length;
            }
        }
示例#2
0
        public override void Run(object?arg)
        {
            string prefix1 = string.Concat(AddressPrefix, "3", keyword);
            string prefix2 = string.Concat(AddressPrefix, "1", keyword);
            string suffix1 = keyword;

            int workSize = this.workSize;

            byte[] bigPublicKeyBytes = new byte[32 * workSize];
            byte[] bigChecksumBytes  = new byte[5 * workSize];
            byte[] bigSeedBytes      = new byte[31 + workSize];

            AddressBuffer addressBuffer = new(AddressPrefix.Length + 60);

            bool canMatchPrefix = this.canMatchPrefix;
            bool canMatchSuffix = this.canMatchSuffix;
            CancellationToken cancellationToken = this.cancellationToken;

            GCHandle hPublicKey = GCHandle.Alloc(bigPublicKeyBytes, GCHandleType.Pinned);
            GCHandle hChecksum  = GCHandle.Alloc(bigChecksumBytes, GCHandleType.Pinned);
            GCHandle hSeed      = GCHandle.Alloc(bigSeedBytes, GCHandleType.Pinned);

            ComputePlatform platform = ComputePlatform.Platforms[platformIndex];
            ComputeContext  context  = new(
                ComputeDeviceTypes.Gpu,
                new ComputeContextPropertyList(platform),
                null, IntPtr.Zero);
            ComputeProgram program = new(context, new string[]
            {
                OpenCl.Blake2b,
                OpenCl.Curve25519Constants,
                OpenCl.Curve25519Constants2,
                OpenCl.Curve25519,
                OpenCl.Entry,
            });

            program.Build(null, null, null, IntPtr.Zero);
            ComputeKernel       kernel = program.CreateKernel("generate_pubkey");
            ComputeCommandQueue queue  = new(context, context.Devices[0], ComputeCommandQueueFlags.None);

            ComputeBuffer <byte> argPublicKey = new(context, ComputeMemoryFlags.ReadWrite | ComputeMemoryFlags.UseHostPointer, bigPublicKeyBytes);
            ComputeBuffer <byte> argChecksum  = new(context, ComputeMemoryFlags.ReadWrite | ComputeMemoryFlags.UseHostPointer, bigChecksumBytes);
            ComputeBuffer <byte> argSeed      = new(context, ComputeMemoryFlags.ReadWrite | ComputeMemoryFlags.UseHostPointer, bigSeedBytes);

            addressBuffer.Append(AddressPrefix);
            while (!cancellationToken.IsCancellationRequested)
            {
                random.GetBytes(bigSeedBytes);
                queue.Write(argSeed, true, 0, bigSeedBytes.Length, hSeed.AddrOfPinnedObject(), null);
                kernel.SetMemoryArgument(0, argPublicKey);
                kernel.SetMemoryArgument(1, argChecksum);
                kernel.SetMemoryArgument(2, argSeed);
                queue.Execute(kernel, null, new long[] { workSize }, null, null);
                queue.Read(argPublicKey, true, 0, bigPublicKeyBytes.Length, hPublicKey.AddrOfPinnedObject(), null);
                queue.Read(argChecksum, true, 0, bigChecksumBytes.Length, hChecksum.AddrOfPinnedObject(), null);
                queue.Finish();

                string foundSeed = null;
                for (int i = 0; i < workSize; ++i)
                {
                    ArraySegment <byte> seed      = new(bigSeedBytes, i, 32);
                    ArraySegment <byte> publicKey = new(bigPublicKeyBytes, i * 32, 32);
                    ArraySegment <byte> checksum  = new(bigChecksumBytes, i * 5, 5);
                    Reverse(checksum);

                    NanoBase32(publicKey, ref addressBuffer);
                    NanoBase32(checksum, ref addressBuffer);

                    bool isMatched = false;
                    if (canMatchPrefix)
                    {
                        isMatched = addressBuffer.StartsWith(prefix1) || addressBuffer.StartsWith(prefix2);
                    }
                    if (!isMatched && canMatchSuffix)
                    {
                        isMatched = addressBuffer.EndsWith(suffix1);
                    }

                    if (isMatched)
                    {
                        var address = addressBuffer.ToString();
                        if (resultCallback != null)
                        {
                            resultCallback.Invoke(HexUtils.HexFromByteArray(seed), address);
                        }
                        else
                        {
                            foundSeed    = HexUtils.HexFromByteArray(seed);
                            FoundSeed    = foundSeed;
                            FoundAddress = address;

                            attempts += i;
                            break;
                        }
                    }

                    addressBuffer.Length = AddressPrefix.Length;
                }

                if (foundSeed != null)
                {
                    break;
                }

                attempts += workSize;
            }

            argPublicKey.Dispose();
            argChecksum.Dispose();
            argSeed.Dispose();

            hPublicKey.Free();
            hChecksum.Free();
            hSeed.Free();
        }