Пример #1
0
        private static void SMix(uint[] B, int BOff, int N, int d, int r)
        {
            int powN = Integers.NumberOfTrailingZeros(N);
            int blocksPerChunk = N >> d;
            int chunkCount = 1 << d, chunkMask = blocksPerChunk - 1, chunkPow = powN - d;

            int BCount = r * 32;

            uint[] blockX1 = new uint[16];
            uint[] blockX2 = new uint[16];
            uint[] blockY  = new uint[BCount];

            uint[]   X  = new uint[BCount];
            uint[][] VV = new uint[chunkCount][];

            try
            {
                Array.Copy(B, BOff, X, 0, BCount);

                for (int c = 0; c < chunkCount; ++c)
                {
                    uint[] V = new uint[blocksPerChunk * BCount];
                    VV[c] = V;

                    int off = 0;
                    for (int i = 0; i < blocksPerChunk; i += 2)
                    {
                        Array.Copy(X, 0, V, off, BCount);
                        off += BCount;
                        BlockMix(X, blockX1, blockX2, blockY, r);
                        Array.Copy(blockY, 0, V, off, BCount);
                        off += BCount;
                        BlockMix(blockY, blockX1, blockX2, X, r);
                    }
                }

                uint mask = (uint)N - 1;
                for (int i = 0; i < N; ++i)
                {
                    int    j    = (int)(X[BCount - 16] & mask);
                    uint[] V    = VV[j >> chunkPow];
                    int    VOff = (j & chunkMask) * BCount;
                    Array.Copy(V, VOff, blockY, 0, BCount);
                    Xor(blockY, X, 0, blockY);
                    BlockMix(blockY, blockX1, blockX2, X, r);
                }

                Array.Copy(X, 0, B, BOff, BCount);
            }
            finally
            {
                ClearAll(VV);
                ClearAll(X, blockX1, blockX2, blockY);
            }
        }
Пример #2
0
        public void TestNumberOfTrailingZeros()
        {
            for (int i = 0; i < 31; ++i)
            {
                Assert.AreEqual(i, Integers.NumberOfTrailingZeros(1 << i));
                Assert.AreEqual(i, Integers.NumberOfTrailingZeros(-1 << i));
            }

            Assert.AreEqual(31, Integers.NumberOfTrailingZeros(int.MinValue));
            Assert.AreEqual(32, Integers.NumberOfTrailingZeros(0));
        }
Пример #3
0
        private static void InversionStep(uint[] p, uint[] u, int uLen, uint[] x, ref int xc)
        {
            int len   = p.Length;
            int count = 0;

            while (u[0] == 0)
            {
                Nat.ShiftDownWord(uLen, u, 0);
                count += 32;
            }

            {
                int zeroes = Integers.NumberOfTrailingZeros((int)u[0]);
                if (zeroes > 0)
                {
                    Nat.ShiftDownBits(uLen, u, zeroes, 0);
                    count += zeroes;
                }
            }

            for (int i = 0; i < count; ++i)
            {
                if ((x[0] & 1) != 0)
                {
                    if (xc < 0)
                    {
                        xc += (int)Nat.AddTo(len, p, x);
                    }
                    else
                    {
                        xc += Nat.SubFrom(len, p, x);
                    }
                }

                Debug.Assert(xc == 0 || xc == -1);
                Nat.ShiftDownBit(len, x, (uint)xc);
            }
        }
Пример #4
0
        private static int Legendre(BigInteger a, BigInteger b)
        {
            //int r = 0, bits = b.IntValue;

            //for (;;)
            //{
            //    int lowestSetBit = a.GetLowestSetBit();
            //    a = a.ShiftRight(lowestSetBit);
            //    r ^= (bits ^ (bits >> 1)) & (lowestSetBit << 1);

            //    int cmp = a.CompareTo(b);
            //    if (cmp == 0)
            //        break;

            //    if (cmp < 0)
            //    {
            //        BigInteger t = a; a = b; b = t;

            //        int oldBits = bits;
            //        bits = b.IntValue;
            //        r ^= oldBits & bits;
            //    }

            //    a = a.Subtract(b);
            //}

            //return BigInteger.One.Equals(b) ? (1 - (r & 2)) : 0;

            int bitLength = b.BitLength;

            uint[] A = Nat.FromBigInteger(bitLength, a);
            uint[] B = Nat.FromBigInteger(bitLength, b);

            int r = 0;

            int len = B.Length;

            for (;;)
            {
                while (A[0] == 0)
                {
                    Nat.ShiftDownWord(len, A, 0);
                }

                int shift = Integers.NumberOfTrailingZeros((int)A[0]);
                if (shift > 0)
                {
                    Nat.ShiftDownBits(len, A, shift, 0);
                    int bits = (int)B[0];
                    r ^= (bits ^ (bits >> 1)) & (shift << 1);
                }

                int cmp = Nat.Compare(len, A, B);
                if (cmp == 0)
                {
                    break;
                }

                if (cmp < 0)
                {
                    r ^= (int)(A[0] & B[0]);
                    uint[] t = A; A = B; B = t;
                }

                while (A[len - 1] == 0)
                {
                    len = len - 1;
                }

                Nat.Sub(len, A, B, A);
            }

            return(Nat.IsOne(len, B) ? (1 - (r & 2)) : 0);
        }
Пример #5
0
        private static int Divsteps30Var(int eta, int f0, int g0, int[] t)
        {
            int u = 1, v = 0, q = 0, r = 1;
            int f = f0, g = g0, m, w, x, y, z;
            int i = 30, limit, zeros;

            for (;;)
            {
                // Use a sentinel bit to count zeros only up to i.
                zeros = Integers.NumberOfTrailingZeros(g | (-1 << i));

                g  >>= zeros;
                u  <<= zeros;
                v  <<= zeros;
                eta -= zeros;
                i   -= zeros;

                if (i <= 0)
                {
                    break;
                }

                Debug.Assert((f & 1) == 1);
                Debug.Assert((g & 1) == 1);
                Debug.Assert((u * f0 + v * g0) == f << (30 - i));
                Debug.Assert((q * f0 + r * g0) == g << (30 - i));

                if (eta < 0)
                {
                    eta = -eta;
                    x   = f; f = g; g = -x;
                    y   = u; u = q; q = -y;
                    z   = v; v = r; r = -z;

                    // Handle up to 6 divsteps at once, subject to eta and i.
                    limit = (eta + 1) > i ? i : (eta + 1);
                    m     = (int)((uint.MaxValue >> (32 - limit)) & 63U);

                    w = (f * g * (f * f - 2)) & m;
                }
                else
                {
                    // Handle up to 4 divsteps at once, subject to eta and i.
                    limit = (eta + 1) > i ? i : (eta + 1);
                    m     = (int)((uint.MaxValue >> (32 - limit)) & 15U);

                    w = f + (((f + 1) & 4) << 1);
                    w = (-w * g) & m;
                }

                g += f * w;
                q += u * w;
                r += v * w;

                Debug.Assert((g & m) == 0);
            }

            t[0] = u;
            t[1] = v;
            t[2] = q;
            t[3] = r;

            return(eta);
        }