示例#1
0
        /// <summary>
        /// M.
        /// Computes x to the power of y at mod z.
        /// </summary>
        /// <returns></returns>
        public static BigNum Power(BigNum x, BigNum y, BigNum z)
        {
            BigNum result = new BigNum();

            if (y.CompNumWithoutPrint(GlobalVariables.zero))
            {
                result = new BigNum(GlobalVariables.one);
            }
            else
            {
                if (y.IsEven())
                {
                    // x^y = [x^(y/2)]^2 mod z.
                    BigNum yDividedBy2 = new BigNum();
                    DivNum(y, GlobalVariables.two, yDividedBy2, result);      // y = y/2.
                    result = Power(x, yDividedBy2, z);
                    result.MultNum(new BigNum(result));
                    DivNum(result, z, new BigNum(), result);
                }
                else
                {
                    BigNum yMinus1DividedBy2 = new BigNum(y);
                    yMinus1DividedBy2.SubNum(GlobalVariables.one);             // y = y-1.

                    DivNum(y, GlobalVariables.two, yMinus1DividedBy2, result); // y = y-1/2.
                    result = Power(x, yMinus1DividedBy2, z);
                    result.MultNum(new BigNum(result));
                    DivNum(result, z, new BigNum(), result);
                    result.MultNum(x);
                    DivNum(result, z, new BigNum(), result);
                }
            }

            return(result);
        }
示例#2
0
        /// <summary>
        /// Gets BigNum <paramref name="b"/>.
        /// Generates p and q, prime numbers.
        /// While b is not inverse number to p-1 and q-1, p and q re-generates.
        /// After finding good p and q, calculate a that is inverse of b mod ((p-1)(q-1)).
        /// n is calculated as p * q.
        /// Returns by reference the BigNum a, p, q, and n.
        /// </summary>
        /// <param name="b"></param>
        /// <param name="a"></param>
        /// <param name="q"></param>
        /// <param name="p"></param>
        /// <param name="nByRef"></param>
        public static void GenRSA(BigNum b, BigNum a, BigNum q, BigNum p, BigNum nByRef)
        {
            bool   isBInverseOfPMinus1AndQMinus1 = false;
            BigNum n = new BigNum();

            while (!isBInverseOfPMinus1AndQMinus1)
            {
                p.Set(GenPrime());
                q.Set(GenPrime());

                BigNum pMinus1 = new BigNum(p);
                pMinus1.SubNum(GlobalVariables.one);
                BigNum qMinus1 = new BigNum(q);
                qMinus1.SubNum(GlobalVariables.one);

                BigNum fiOfN = new BigNum(pMinus1);
                fiOfN.MultNum(qMinus1);
                BigNum gcd = new BigNum();
                ExtendedGCD(b, fiOfN, new BigNum(), new BigNum(), gcd);
                if (gcd.CompNumWithoutPrint(GlobalVariables.one))
                {
                    isBInverseOfPMinus1AndQMinus1 = true;
                    a.Set(Inverse(b, fiOfN));
                    if (a.IsNegative)
                    {
                        a.AddNum(fiOfN);
                    }
                    n = new BigNum(p);
                    n.MultNum(q);
                }
            }

            nByRef.Set(n);
        }
示例#3
0
        /// <summary>
        /// Overloading the ">=" operator.
        /// If num1 >= num2, num1-num2 should be positive => subResult.IsNegative = false.
        /// It should return true, therefore !subResult.IsNegative.
        /// </summary>
        /// <param name="num1"></param>
        /// <param name="num2"></param>
        /// <returns></returns>
        public static bool operator >=(BigNum num1, BigNum num2)
        {
            BigNum subResult = new BigNum(num1);

            subResult.SubNum(num2);
            return(!subResult.IsNegative);
        }
示例#4
0
        /// <summary>
        /// K.
        /// Gets two BigNum type numbers a and m and returns by reference (d, x, y), also BigNum type numbers.
        /// d represents GCD(m,a). (Greatest common divider).
        /// Note: If d = 1, it means that x is the opposite number of m(mod a) and
        ///                               y is the opposite number of a(mod m).
        /// Proofe for Note: 1 = [m*x + a*y](mod m) ==> 1 = a*y.
        /// </summary>
        /// <param name="a"></param>
        /// <param name="m"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="d"></param>
        public static void ExtendedGCD(BigNum a, BigNum m, BigNum x, BigNum y, BigNum d)
        {
            BigNum r0 = new BigNum(m);
            BigNum x0 = new BigNum(GlobalVariables.one);
            BigNum y0 = new BigNum(GlobalVariables.zero);

            BigNum r1 = new BigNum(a);
            BigNum x1 = new BigNum(GlobalVariables.zero);
            BigNum y1 = new BigNum(GlobalVariables.one);

            BigNum r = new BigNum(GlobalVariables.one);    // Just to be able to enter the while loop.
            BigNum q = new BigNum();

            DivNum(r0, r1, q, r);

            while (!r.CompNumWithoutPrint(GlobalVariables.zero))
            {
                // x = x0 - qx1.
                BigNum qx1 = new BigNum(q);
                qx1.MultNum(x1);
                x.Set(x0);
                x.SubNum(qx1);

                // y = y0 - qy1.
                BigNum qy1 = new BigNum(q);
                qy1.MultNum(y1);
                y.Set(y0);
                y.SubNum(qy1);

                r0.Set(r1);
                x0.Set(x1);
                y0.Set(y1);

                r1.Set(r);
                x1.Set(x);
                y1.Set(y);

                DivNum(r0, r1, q, r);
            }

            d.Set(r1);
            x.Set(x1);
            y.Set(y1);
        }
示例#5
0
        public static void I()
        {
            Console.WriteLine("(I) Using SubNum method.");
            Console.WriteLine("18 - 5 = 13");
            BigNum bigNumI1 = new BigNum(18L);
            BigNum bigNumI2 = new BigNum(5L);

            bigNumI1.SubNum(bigNumI2);
            Console.WriteLine(bigNumI1.WriteNum());

            Console.WriteLine("375683 - 12345 = 363338 (1011000101101001010 in binary.)");
            BigNum bigNumI3 = new BigNum(375683L);
            BigNum bigNumI4 = new BigNum(12345L);

            bigNumI3.SubNum(bigNumI4);
            Console.WriteLine(bigNumI3.WriteNum());

            Console.WriteLine();
        }
示例#6
0
        /// <summary>
        /// N.
        /// Runs Miller-Rabin algorithm k times.
        /// </summary>
        /// <param name="n"></param>
        /// <param name="k"></param>
        /// <returns></returns>
        public static bool IsPrime(BigNum n, int k)
        {
            bool   isPrimeNumber = true;
            BigNum t             = new BigNum();
            BigNum u             = new BigNum();
            BigNum nMinusOne     = new BigNum(n);

            nMinusOne.SubNum(GlobalVariables.one);
            FindExpressionOfGivenNumberByPowerOfTwoTimesOddNumber(nMinusOne, t, u);

            for (int i = 0; i < k; ++i)
            {
                if (!MillerRabinAlgorithm(n, new BigNum(t), u))
                {
                    isPrimeNumber = false;
                    break;
                }
            }

            return(isPrimeNumber);
        }
示例#7
0
        /// <summary>
        /// J.
        /// Gets two BigNum type numbers, divided and divider.
        /// Returns by reference the result - quotient and reminder.
        /// </summary>
        /// <param name="divider"></param>
        public static void DivNum(BigNum divided, BigNum divider, BigNum quotientRetrunByRef, BigNum reminderReturnByRef)
        {
            List <int> positionsOf1s = new List <int>();

            if (divided.MSB1Location.HasValue)
            {
                int indexPos = divided.MSB1Location.Value + divider.Length - 1;

                BigNum subResult = new BigNum(divided);
                while (indexPos < GlobalVariables.MAX_NUM)
                {
                    BigNum numberFromLeftToIndex = GetSubBigNumFromLeftToIndex(subResult, indexPos);

                    if (numberFromLeftToIndex >= divider)
                    {
                        // Saving quotient's info.
                        positionsOf1s.Add(indexPos);

                        // Subtract.
                        int    numberOfShifts   = GlobalVariables.MAX_NUM - indexPos - 1;
                        BigNum numberToSubtract = new BigNum(divider);
                        numberToSubtract.ShiftLeft(numberOfShifts);
                        subResult.SubNum(numberToSubtract);
                    }

                    indexPos++;
                }

                quotientRetrunByRef.ReadNum(positionsOf1s);
                reminderReturnByRef.Set(subResult);
            }
            else
            {
                Console.WriteLine("Cannot divide by zero");
            }
        }