/// <summary>
        /// The check.
        /// </summary>
        /// <param name="security">
        /// The security.
        /// </param>
        /// <param name="low">
        /// The low.
        /// </param>
        /// <param name="high">
        /// The high.
        /// </param>
        /// <returns>
        /// The <see cref="int"/>.
        /// </returns>
        private static int Check(int security, ulong[] low, ulong[] high)
        {
            var demux = new TrinaryDemultiplexer(new UlongTritTouple(low, high));

            for (var i = 0; i < demux.Length; i++)
            {
                var sum = 0;
                for (var j = 0; j < security; j++)
                {
                    sum += demux.Get(i).Skip(j * AbstractCurl.HashLength / 3).Take(AbstractCurl.HashLength / 3).Sum();

                    if (sum == 0 && j < security - 1)
                    {
                        sum = 1;
                        break;
                    }
                }

                if (sum == 0)
                {
                    return(i);
                }
            }

            return(0);
        }
        public void TestDemuxMapsCorrectly()
        {
            var trits      = Converter.TrytesToTrits("ADHMOICIPKGYHYL9VMLSSXHGKTUTEQUTIWUQWSVYHZWTAHNIYQICEJWFTCYBGRGRM9DWBCGDELIGEIIIH");
            var ulongTrits = UlongTritConverter.TritsToUlong(trits, Curl.StateLength);

            ulongTrits.Low[0] = 15811494920322472813;
            ulongTrits.Low[1] = 17941353825114769379;
            ulongTrits.Low[2] = 576458557575118879;
            ulongTrits.Low[3] = 18446741876833779711;

            ulongTrits.High[0] = 13176245766935394011;
            ulongTrits.High[1] = 14403622084951293727;
            ulongTrits.High[2] = 18445620372817592319;
            ulongTrits.High[3] = 2199023255551;

            var mux = new TrinaryDemultiplexer(ulongTrits);

            for (var i = 0; i < AbstractCurl.HashLength; i++)
            {
                var tritSum = mux.Get(0).Take(i).ToArray().Sum();
                Assert.AreEqual(ExpectedDemux[i], tritSum);
            }
        }
        public int[] Search(int[] trits, int security, int length, int offset)
        {
            var ulongTrits = this.PrepareTrits(trits, offset);
            var curl       = new NonceCurl(ulongTrits.Low, ulongTrits.High, this.Rounds);
            var size       = Math.Min(length, AbstractCurl.HashLength) - offset;

            var index = 0;

            while (index == 0)
            {
                var incrementResult = curl.Increment(offset + size * 2 / 3, offset + size);
                size = Math.Min(Pascal.RoundThird(offset + size * 2 / 3 + incrementResult), AbstractCurl.HashLength) - offset;

                var curlCopy = curl.Clone();
                curlCopy.Transform();

                index = Check(security, curlCopy.Low.Take(AbstractCurl.HashLength).ToArray(), curlCopy.High.Take(AbstractCurl.HashLength).ToArray());
            }

            var result = new TrinaryDemultiplexer(new UlongTritTouple(curl.Low.Take(size).ToArray(), curl.High.Take(size).ToArray()));

            return(result.Get(index));
        }