Ejemplo n.º 1
0
        public static ULongIntB BinaryOr(ULongIntB a, ULongIntB b)
        {
            ULongIntB c = new ULongIntB(a.CoefLength);

            for (int i = 0; i < a.Size; ++i)
                c[i] = (ushort)(a[i] | b[i]);

            c.Size = System.Math.Max(a.Size, b.Size);
            return c;
        }
Ejemplo n.º 2
0
        public static ULongIntB BinaryXor(ULongIntB a, ULongIntB b)
        {
            ULongIntB c = new ULongIntB(a.CoefLength);

            for (int i = 0; i < a.Size; ++i)
                c[i] = (ushort)(a[i] ^ b[i]);

            c.Size = System.Math.Max(a.Size, b.Size);

            int s = c.Size - 1;
            if (s > 0)
                while (c[s] == 0)
                {
                    --s;
                    if (s == 0)
                        break;
                }

            c.Size = s + 1;

            return c;
        }
Ejemplo n.º 3
0
        internal static int TestSmallPrimes(ULongIntB n, uint ladgestSmallPrime)
        {
            if (ladgestSmallPrime > LIntConstant.smallPrimes[LIntConstant.smallPrimes.Length - 1])
                ladgestSmallPrime = LIntConstant.smallPrimes[LIntConstant.smallPrimes.Length - 1];

            // by testing small numbers
            // we can avoid testing on 85% other natural numbers
            for (int i = 0; LIntConstant.smallPrimes[i] < ladgestSmallPrime; ++i)
            {
                ushort r = n % LIntConstant.smallPrimes[i];
                if (r == 0)
                    return r;
            }

            return 0;
        }
Ejemplo n.º 4
0
        public static void TwoFact(ULongIntB A, out ULongIntB u, out int k)
        {
            k = 0;
            u = new ULongIntB(A);

            if (A == 0)
                return;

            while (LongMath.IsEven(u))
            {
                ++k;
                u.Shr();
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Test if input number is prime
        /// </summary>
        /// <param name="n">Input number</param>
        /// <param name="rounds">Number of times to provide test</param>
        /// <returns>Exact answer if input number is composite, and 
        /// a probable answer if input number can be prime. Probability of mistake
        /// answer is (0.25)^(Rounds number)</returns>
        public static PrimeTestResult TestPrimeMillerRabin(ULongIntB n, RoundsNumber rounds)
        {
            int r = TestSmallPrimes(n, 2000);
            if (r != 0)
                return PrimeTestResult.Composite;

            ULongIntB Nm1 = new ULongIntB(n);
            --Nm1;

            int t = 0;
            ULongIntB q = null;
            TwoFact(Nm1, out q, out t);

            RandomLong rand = new RandomLong((ulong)DateTime.Now.Millisecond);

            for (int i = 0; i < (int)rounds; ++i)
            {
                ULongIntB a = new ULongIntB(rand.NextNotOne(Nm1), ConstructorMode.Assign);
                ULongIntB b = ExpMod5(a, q, n);

                if ((b == 1) || b == Nm1)
                    continue;

                bool next = false;

                for (int j = 0; j < t - 1; ++j)
                {
                    b = SquareMod(b, n);
                    if (b == 1)
                        return PrimeTestResult.Composite;

                    if (b == Nm1)
                    {
                        next = true;
                        break;
                    }
                }

                if (!next)
                    return PrimeTestResult.Composite;
            }

            return PrimeTestResult.DontKnow;
        }
Ejemplo n.º 6
0
 //// <summary>
 /// Calculates square of input unsigned number by modulo
 /// </summary>
 /// <param name="a">Input number</param>
 /// <param name="m">Modulo</param>
 /// <returns>(a*a) % m</returns>
 public static ULongIntB SquareMod(ULongIntB a, ULongIntB m)
 {
     return LongMath.Sqr(a) % m;
 }
Ejemplo n.º 7
0
 /// <summary>
 /// Calculates square of input unsigned number N times by modulo
 /// </summary>
 /// <param name="a">Input number</param>
 /// <param name="n">Number of times to calculate square</param>
 /// <param name="m">Modulo</param>
 /// <returns>[ a ^ (2*n) ] % m</returns>
 public static ULongIntB NSquareMod(ULongIntB a, uint n, ULongIntB m)
 {
     ULongIntB res = a % m;
     for (int i = 0; i < n; ++i)
         res = LongMath.Sqr(res) % m;
     return res;
 }
Ejemplo n.º 8
0
        /// <summary>
        /// Calculates binary logarithm of input number
        /// </summary>
        /// <param name="a">Input number</param>
        /// <returns>Binary logarithm</returns>
        public static uint Log2(ULongIntB a)
        {
            if (a.Size <= 0)
                return 0;

            int temp = a[a.Size - 1];
            int bitsCount = 0;
            while (temp != 0)
            {
                ++bitsCount;
                temp >>= 1;
            }

            return (uint)(bitsCount + (a.Size - 1)*LIntConstant.BitsPerDigit - 1);
        }
Ejemplo n.º 9
0
        public static ULongIntB ExpMod5(ULongIntB a, ULongIntB n, ULongIntB m)
        {
            if (a == 0)
                return (ULongIntB)0;

            if (a == 1)
                return (ULongIntB)1;

            if (n == 0)
                return (ULongIntB)1;

            if (m == 1)
                return (ULongIntB)0;

            int k = 5;
            int M = (1 << k);

            ULongIntB[] mods = new ULongIntB[(M >> 1) + 1];
            ULongIntB tempSquare = SquareMod(a, m);
            mods[0] = a % m;

            // generate table of numbers  [  (a ^ k) mod m, where k == (2*j + 1) ]
            int index = 1;
            int i = 3;
            while (i <= M - 1)
            {
                mods[index] = (mods[index - 1] * tempSquare) % m;

                ++index;
                i += 2;
            }

            int bitsCount = LIntConstant.BitsPerDigit;

            int log = (int)Log2((ULongIntB)n) + 1;

            // length of power in 2^k number system
            int N = log / k;
            if ((log % k) != 0)
                ++N;

            i = N - 1;

            int s = (k*i) / bitsCount;
            int d = (k*i) % bitsCount;

            int eN = (((int)n[s] | ((int)n[s + 1] << bitsCount)) >> d) & (M - 1);

            int t, u;

            ULongIntB p = null;

            if (eN == 0)
                p = (ULongIntB)1;
            else
            {
                LongIntHelper.TwoFact(eN, out t, out u);

                index = ((u - 1) / 2);
                p = new ULongIntB(mods[index]);
                p = NSquareMod(p, (uint)t, m);
            }

            i = N - 2;

            while (i >= 0)
            {
                s = (k*i) / bitsCount;
                d = (k*i) % bitsCount;

                int e = (((int)n[s] | ((int)n[s + 1] << bitsCount)) >> d) & (M - 1);

                if (e == 0)
                    p = NSquareMod(p, (uint)k, m);
                else
                {
                    LongIntHelper.TwoFact(e, out t, out u);
                    p = NSquareMod(p, (uint)(k - t), m);

                    index = ((u - 1) / 2);
                    p = (p * mods[index]) % m;
                    p = NSquareMod(p, (uint)t, m);
                }

                --i;
            }

            return p;
        }
Ejemplo n.º 10
0
 /// <summary>
 /// Calculates A*A
 /// </summary>
 /// <param name="A">Long Number</param>
 /// <returns>Long number that is result of self-product of A</returns>
 public static ULongIntB Sqr(ULongIntB A)
 {
     return new ULongIntB(LongMath.InnerSqr(A), ConstructorMode.Assign);
 }
Ejemplo n.º 11
0
 public static ULongIntB Exp(ULongIntB A, ulong n)
 {
     return new ULongIntB(InnerPower(A, n), ConstructorMode.Assign);
 }
Ejemplo n.º 12
0
        public static void Divide(ULongIntB A, ULongIntB B, out ULongIntB Q, out ULongIntB R)
        {
            LongIntBase QNumber = new LongIntBase(A.Base);
            LongIntBase RNumber = new LongIntBase(B.Base);

            LongMath.Divide(A, B, out QNumber, out RNumber, true, true);
            Q = new ULongIntB(QNumber, ConstructorMode.Assign);
            R = new ULongIntB(RNumber, ConstructorMode.Assign);
        }