示例#1
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);
        }
示例#2
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);
        }
示例#3
0
        /// <summary>
        /// Gets a number m.
        /// Finds p >= 0 and k (k is odd), where m = 2^p * k.
        /// Return p and k by ref.
        ///
        /// p = 0;
        /// if (!IsEven(m))
        /// {
        ///     k = m;
        /// }
        /// else // m is even.
        /// {
        ///     while(IsEven(m))
        ///     {
        ///          m /= 2;
        ///          p++;
        ///     }
        ///     k = m;
        /// }
        /// </summary>
        /// <param name=""></param>
        /// <param name=""></param>
        public static void FindExpressionOfGivenNumberByPowerOfTwoTimesOddNumber(BigNum m, BigNum p, BigNum k)
        {
            if (!m.IsEven())
            {
                k.Set(m);
            }
            else
            {
                while (m.IsEven())
                {
                    DivNum(m, GlobalVariables.two, m, new BigNum());
                    p.AddNum(GlobalVariables.one);
                }

                k.Set(m);
            }
        }
示例#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
        /// <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");
            }
        }