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); } }
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)); }
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); } }
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); }
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); }