示例#1
0
        public static bool MillerRabinAlgorithm(BigNum n, BigNum t, BigNum u)
        {
            bool   isPrimeNumber   = true;
            BigNum randomNumber    = GenerateNumberFromOneToGivenTop(n);
            BigNum x0              = Power(randomNumber, u, n);
            BigNum x1              = new BigNum();
            BigNum iterationNumber = new BigNum(GlobalVariables.one);

            while (iterationNumber <= t)    // Iterates t times.
            {
                x1 = Power(x0, GlobalVariables.two, n);
                x0.Set(x1);
                if ((x1.CompNumWithoutPrint(GlobalVariables.one)) &&
                    (!x0.CompNumWithoutPrint(GlobalVariables.one)) &&
                    (!x0.CompNumWithoutPrint(GlobalVariables.minusOne)))
                {
                    isPrimeNumber = false;
                    break;
                }

                iterationNumber.AddNum(GlobalVariables.one);
            }

            if (isPrimeNumber)
            {
                if (!x1.CompNumWithoutPrint(GlobalVariables.one))
                {
                    isPrimeNumber = false;
                }
            }

            return(isPrimeNumber);
        }
示例#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>
        /// 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);
        }
示例#4
0
        /// <summary>
        /// Gets BigNum number.
        /// Finds the index of the MSB 1 digit, run from it to the LSB.
        /// It has boolean variable <isSmaller> that set to true when the first 1's digits is cleared
        /// (set to 0).
        /// Unless <isSmaller> = true, this method cannot set any bit.
        /// Use random (IsGeneratedToSet() method) to set or clear that bit.
        /// </summary>
        /// <param name="top"></param>
        /// <returns></returns>
        private static BigNum GenerateNumberFromOneToGivenTop(BigNum top)
        {
            BigNum generatedNumber = new BigNum();

            if (top.MSB1Location.HasValue)
            {
                do
                {
                    bool       isSmaller         = false;
                    List <int> PositionsOf1sList = new List <int>();
                    for (int i = top.MSB1Location.Value; i < GlobalVariables.MAX_NUM; ++i)
                    {
                        if (top[i] == 1)
                        {
                            if (GenerateOneOrZero() == 0)
                            {
                                isSmaller = true;
                            }
                            else
                            {
                                PositionsOf1sList.Add(i);
                            }
                        }
                        else
                        {
                            if ((GenerateOneOrZero() == 1) && (isSmaller))
                            {
                                PositionsOf1sList.Add(i);
                            }
                        }
                    }

                    generatedNumber.ReadNum(PositionsOf1sList);
                } while ((generatedNumber.CompNumWithoutPrint(GlobalVariables.zero)) ||
                         (generatedNumber.CompNumWithoutPrint(top)));
            }

            return(generatedNumber);
        }
示例#5
0
        /// <summary>
        /// L.
        /// Gets two BigNums, calculates the opposite number of a in mod m. ([a^-1][mod m]).
        /// Returns null if the a does not have an inverse mode m. (i.e: gcd(a, m) != 1).
        /// </summary>
        /// <param name="a"></param>
        /// <param name="m"></param>
        public static BigNum Inverse(BigNum a, BigNum m)
        {
            BigNum inverse = null;
            BigNum x       = new BigNum();
            BigNum y       = new BigNum();
            BigNum d       = new BigNum(); // d will be gcd(a, m).

            ExtendedGCD(a, m, x, y, d);
            if (d.CompNumWithoutPrint(GlobalVariables.one))
            {
                inverse = y;
            }

            return(inverse);
        }
示例#6
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);
        }