Ejemplo n.º 1
0
        internal void SetupGeneralBaseArray(Integer GeneralBase)
        {
            // The word 'Base' comes from the base of a number
            // system.  Like normal decimal numbers have base
            // 10, binary numbers have base 2, etc.

            CurrentModReductionBase.Copy(GeneralBase);

            // The input to the accumulator can be twice the
            // bit length of GeneralBase.
            int HowManyDigits = ((GeneralBase.GetIndex() + 1) * 2) + 10; // Plus some extra for carries...

            GeneralBaseArray = new Integer[HowManyDigits];

            // int HowManyPrimes = 100;
            //                         Row, Column
            // SmallBasesArray = new uint[HowManyDigits, HowManyPrimes];

            Integer Base = new Integer();

            Base.SetFromULong(256);          // 0x100
            IntMath.MultiplyUInt(Base, 256); // 0x10000
            IntMath.MultiplyUInt(Base, 256); // 0x1000000
            IntMath.MultiplyUInt(Base, 256); // 0x100000000 is the base of this number system.
            // 0x1 0000 0000

            Integer BaseValue = new Integer();

            BaseValue.SetFromULong(1);

            for (int Column = 0; Column < HowManyDigits; Column++)
            {
                if (GeneralBaseArray[Column] == null)
                {
                    GeneralBaseArray[Column] = new Integer();
                }

                IntMath.Divider.Divide(BaseValue, GeneralBase, Quotient, Remainder);
                GeneralBaseArray[Column].Copy(Remainder);

/*
 *    for( int Row = 0; Row < HowManyPrimes; Row++ )
 *      {
 *      This base value mod this prime?
 *
 *      SmallBasesArray[Row, Column] = what?
 *      }
 */

                // Done at the bottom for the next round of the
                // loop.
                BaseValue.Copy(Remainder);
                IntMath.Multiply(BaseValue, Base);
            }
        }
Ejemplo n.º 2
0
        internal void MakeRSAKeys()
        {
            int ShowBits = (PrimeIndex + 1) * 32;

            // int TestLoops = 0;
            Worker.ReportProgress(0, "Making RSA keys.");
            Worker.ReportProgress(0, "Bits size is: " + ShowBits.ToString());
            // ulong Loops = 0;
            while (true)
            {
                if (Worker.CancellationPending)
                {
                    return;
                }

                Thread.Sleep(1); // Let other things run.
                // Make two prime factors.
                // Normally you'd only make new primes when you pay the Certificate
                // Authority for a new certificate.
                if (!MakeAPrime(PrimeP, PrimeIndex, 20))
                {
                    return;
                }

                if (Worker.CancellationPending)
                {
                    return;
                }

                if (!MakeAPrime(PrimeQ, PrimeIndex, 20))
                {
                    return;
                }

                if (Worker.CancellationPending)
                {
                    return;
                }

                // This is extremely unlikely.
                Integer Gcd = new Integer();
                IntMath.GreatestCommonDivisor(PrimeP, PrimeQ, Gcd);
                if (!Gcd.IsOne())
                {
                    Worker.ReportProgress(0, "They had a GCD: " + IntMath.ToString10(Gcd));
                    continue;
                }

                if (Worker.CancellationPending)
                {
                    return;
                }

                IntMath.GreatestCommonDivisor(PrimeP, PubKeyExponent, Gcd);
                if (!Gcd.IsOne())
                {
                    Worker.ReportProgress(0, "They had a GCD with PubKeyExponent: " + IntMath.ToString10(Gcd));
                    continue;
                }

                if (Worker.CancellationPending)
                {
                    return;
                }

                IntMath.GreatestCommonDivisor(PrimeQ, PubKeyExponent, Gcd);
                if (!Gcd.IsOne())
                {
                    Worker.ReportProgress(0, "2) They had a GCD with PubKeyExponent: " + IntMath.ToString10(Gcd));
                    continue;
                }

                // For Modular Reduction.  This only has to be done
                // once, when P and Q are made.
                IntMathForP.ModReduction.SetupGeneralBaseArray(PrimeP);
                IntMathForQ.ModReduction.SetupGeneralBaseArray(PrimeQ);
                PrimePMinus1.Copy(PrimeP);
                IntMath.SubtractULong(PrimePMinus1, 1);
                PrimeQMinus1.Copy(PrimeQ);
                IntMath.SubtractULong(PrimeQMinus1, 1);

                if (Worker.CancellationPending)
                {
                    return;
                }

                // These checks should be more thorough to
                // make sure the primes P and Q are numbers
                // that can be used in a secure way.

                Worker.ReportProgress(0, "The Index of Prime P is: " + PrimeP.GetIndex().ToString());
                Worker.ReportProgress(0, "Prime P:");
                Worker.ReportProgress(0, IntMath.ToString10(PrimeP));
                Worker.ReportProgress(0, " ");
                Worker.ReportProgress(0, "Prime Q:");
                Worker.ReportProgress(0, IntMath.ToString10(PrimeQ));
                Worker.ReportProgress(0, " ");
                PubKeyN.Copy(PrimeP);
                IntMath.Multiply(PubKeyN, PrimeQ);
                Worker.ReportProgress(0, " ");
                Worker.ReportProgress(0, "PubKeyN:");
                Worker.ReportProgress(0, IntMath.ToString10(PubKeyN));
                Worker.ReportProgress(0, " ");

                // Test Division:
                Integer QuotientTest  = new Integer();
                Integer RemainderTest = new Integer();

                IntMath.Divider.Divide(PubKeyN, PrimeP, QuotientTest, RemainderTest);
                if (!RemainderTest.IsZero())
                {
                    throw(new Exception("RemainderTest should be zero after divide by PrimeP."));
                }

                IntMath.Multiply(QuotientTest, PrimeP);
                if (!QuotientTest.IsEqual(PubKeyN))
                {
                    throw(new Exception("QuotientTest didn't come out right."));
                }

                // Euler's Theorem:
                // https://en.wikipedia.org/wiki/Euler's_theorem

// ==========
// Work on the Least Common Multiple thing for
// P - 1 and Q - 1.
// =====

                IntMath.GreatestCommonDivisor(PrimePMinus1, PrimeQMinus1, Gcd);
                Worker.ReportProgress(0, "GCD of PrimePMinus1, PrimeQMinus1 is: " + IntMath.ToString10(Gcd));
                if (!Gcd.IsULong())
                {
                    Worker.ReportProgress(0, "This GCD number is too big: " + IntMath.ToString10(Gcd));
                    continue;
                }
                else
                {
                    ulong TooBig = Gcd.GetAsULong();
                    // How big of a GCD is too big?
// ==============

                    if (TooBig > 1234567)
                    {
                        // (P - 1)(Q - 1) + (P - 1) + (Q - 1) = PQ - 1
                        Worker.ReportProgress(0, "This GCD number is bigger than 1234567: " + IntMath.ToString10(Gcd));
                        continue;
                    }
                }

                Integer Temp1 = new Integer();
                PhiN.Copy(PrimePMinus1);
                Temp1.Copy(PrimeQMinus1);
                IntMath.Multiply(PhiN, Temp1);
                Worker.ReportProgress(0, " ");
                Worker.ReportProgress(0, "PhiN:");
                Worker.ReportProgress(0, IntMath.ToString10(PhiN));
                Worker.ReportProgress(0, " ");
                if (Worker.CancellationPending)
                {
                    return;
                }

                // In RFC 2437 there are commonly used letters/symbols to represent
                // the numbers used.  So the number e is the public exponent.
                // The number e that is used here is called PubKeyExponentUint = 65537.
                // In the RFC the private key d is the multiplicative inverse of
                // e mod PhiN.  Which is mod (P - 1)(Q - 1).  It's called
                // PrivKInverseExponent here.
                if (!IntMath.FindMultiplicativeInverseSmall(PrivKInverseExponent, PubKeyExponent, PhiN, Worker))
                {
                    return;
                }

                if (PrivKInverseExponent.IsZero())
                {
                    continue;
                }

                Worker.ReportProgress(0, " ");
                Worker.ReportProgress(0, "PrivKInverseExponent: " + IntMath.ToString10(PrivKInverseExponent));
                if (Worker.CancellationPending)
                {
                    return;
                }

                // In RFC 2437 it defines a number dP which is the multiplicative
                // inverse, mod (P - 1) of e.  That dP is named PrivKInverseExponentDP here.
                Worker.ReportProgress(0, " ");
                if (!IntMath.FindMultiplicativeInverseSmall(PrivKInverseExponentDP, PubKeyExponent, PrimePMinus1, Worker))
                {
                    return;
                }

                Worker.ReportProgress(0, " ");
                Worker.ReportProgress(0, "PrivKInverseExponentDP: " + IntMath.ToString10(PrivKInverseExponentDP));
                if (PrivKInverseExponentDP.IsZero())
                {
                    continue;
                }

                // PrivKInverseExponentDP is PrivKInverseExponent mod PrimePMinus1.
                Integer Test1 = new Integer();
                Test1.Copy(PrivKInverseExponent);
                IntMath.Divider.Divide(Test1, PrimePMinus1, Quotient, Remainder);
                Test1.Copy(Remainder);
                if (!Test1.IsEqual(PrivKInverseExponentDP))
                {
                    throw(new Exception("This does not match the definition of PrivKInverseExponentDP."));
                }

                if (Worker.CancellationPending)
                {
                    return;
                }

                // In RFC 2437 it defines a number dQ which is the multiplicative
                // inverse, mod (Q - 1) of e.  That dQ is named PrivKInverseExponentDQ here.
                Worker.ReportProgress(0, " ");
                if (!IntMath.FindMultiplicativeInverseSmall(PrivKInverseExponentDQ, PubKeyExponent, PrimeQMinus1, Worker))
                {
                    return;
                }

                if (PrivKInverseExponentDQ.IsZero())
                {
                    continue;
                }

                Worker.ReportProgress(0, " ");
                Worker.ReportProgress(0, "PrivKInverseExponentDQ: " + IntMath.ToString10(PrivKInverseExponentDQ));
                if (Worker.CancellationPending)
                {
                    return;
                }

                Test1.Copy(PrivKInverseExponent);
                IntMath.Divider.Divide(Test1, PrimeQMinus1, Quotient, Remainder);
                Test1.Copy(Remainder);
                if (!Test1.IsEqual(PrivKInverseExponentDQ))
                {
                    throw(new Exception("This does not match the definition of PrivKInverseExponentDQ."));
                }

                // Make a random number to test encryption/decryption.
                Integer ToEncrypt    = new Integer();
                int     HowManyBytes = PrimeIndex * 4;
                byte[]  RandBytes    = MakeRandomBytes(HowManyBytes);
                if (RandBytes == null)
                {
                    Worker.ReportProgress(0, "Error making random bytes in MakeRSAKeys().");
                    return;
                }

                if (!ToEncrypt.MakeRandomOdd(PrimeIndex - 1, RandBytes))
                {
                    Worker.ReportProgress(0, "Error making random number ToEncrypt.");
                    return;
                }

                Integer PlainTextNumber = new Integer();
                PlainTextNumber.Copy(ToEncrypt);
                Worker.ReportProgress(0, " ");
                Worker.ReportProgress(0, "Before encrypting number: " + IntMath.ToString10(ToEncrypt));
                Worker.ReportProgress(0, " ");
                IntMath.ModReduction.ModularPower(ToEncrypt, PubKeyExponent, PubKeyN, false);
                if (Worker.CancellationPending)
                {
                    return;
                }

                // Worker.ReportProgress( 0, IntMath.GetStatusString() );

                Integer CipherTextNumber = new Integer();
                CipherTextNumber.Copy(ToEncrypt);
                Worker.ReportProgress(0, " ");
                Worker.ReportProgress(0, "Encrypted number: " + IntMath.ToString10(CipherTextNumber));
                Worker.ReportProgress(0, " ");
                ECTime DecryptTime = new ECTime();
                DecryptTime.SetToNow();
                IntMath.ModReduction.ModularPower(ToEncrypt, PrivKInverseExponent, PubKeyN, false);
                Worker.ReportProgress(0, "Decrypted number: " + IntMath.ToString10(ToEncrypt));
                if (!PlainTextNumber.IsEqual(ToEncrypt))
                {
                    throw(new Exception("PlainTextNumber not equal to unencrypted value."));
                    // Because P or Q wasn't really a prime?
                    // Worker.ReportProgress( 0, "PlainTextNumber not equal to unencrypted value." );
                    // continue;
                }

                Worker.ReportProgress(0, " ");
                Worker.ReportProgress(0, "Decrypt time seconds: " + DecryptTime.GetSecondsToNow().ToString("N2"));
                Worker.ReportProgress(0, " ");
                if (Worker.CancellationPending)
                {
                    return;
                }

                // Test the standard optimized way of decrypting:
                if (!ToEncrypt.MakeRandomOdd(PrimeIndex - 1, RandBytes))
                {
                    Worker.ReportProgress(0, "Error making random number in MakeRSAKeys().");
                    return;
                }

                PlainTextNumber.Copy(ToEncrypt);
                IntMath.ModReduction.ModularPower(ToEncrypt, PubKeyExponent, PubKeyN, false);
                if (Worker.CancellationPending)
                {
                    return;
                }

                CipherTextNumber.Copy(ToEncrypt);
                // QInv is the multiplicative inverse of PrimeQ mod PrimeP.
                if (!IntMath.MultiplicativeInverse(PrimeQ, PrimeP, QInv, Worker))
                {
                    throw(new Exception("MultiplicativeInverse() returned false."));
                }

                if (QInv.IsNegative)
                {
                    throw(new Exception("QInv is negative."));
                }

                Worker.ReportProgress(0, "QInv is: " + IntMath.ToString10(QInv));
                DecryptWithQInverse(CipherTextNumber,
                                    ToEncrypt,       // Decrypt it to this.
                                    PlainTextNumber, // Test it against this.
                                    PubKeyN,
                                    PrivKInverseExponentDP,
                                    PrivKInverseExponentDQ,
                                    PrimeP,
                                    PrimeQ,
                                    Worker);

                Worker.ReportProgress(0, " ");
                Worker.ReportProgress(0, "Found the values:");
                Worker.ReportProgress(0, "Seconds: " + StartTime.GetSecondsToNow().ToString("N0"));
                Worker.ReportProgress(0, " ");
                Worker.ReportProgress(1, "Prime1: " + IntMath.ToString10(PrimeP));
                Worker.ReportProgress(0, " ");
                Worker.ReportProgress(1, "Prime2: " + IntMath.ToString10(PrimeQ));
                Worker.ReportProgress(0, " ");
                Worker.ReportProgress(1, "PubKeyN: " + IntMath.ToString10(PubKeyN));
                Worker.ReportProgress(0, " ");
                Worker.ReportProgress(1, "PrivKInverseExponent: " + IntMath.ToString10(PrivKInverseExponent));

                // return; // Comment this out to just leave it while( true ) for testing.
            }
        }
Ejemplo n.º 3
0
        private bool LongDivide1(Integer ToDivide,
                                 Integer DivideBy,
                                 Integer Quotient,
                                 Integer Remainder)
        {
            uint    Digit     = 0;
            Integer Test1     = new Integer();
            int     TestIndex = ToDivide.GetIndex() - DivideBy.GetIndex();

            if (TestIndex != 0)
            {
                // Is 1 too high?
                Test1.SetDigitAndClear(TestIndex, 1);
                IntMath.MultiplyTopOne(Test1, DivideBy);
                if (ToDivide.ParamIsGreater(Test1))
                {
                    TestIndex--;
                }
            }

            Quotient.SetDigitAndClear(TestIndex, 1);
            Quotient.SetD(TestIndex, 0);
            uint BitTest = 0x80000000;

            while (true)
            {
                // For-loop to test each bit:
                for (int BitCount = 31; BitCount >= 0; BitCount--)
                {
                    Test1.Copy(Quotient);
                    Digit = (uint)Test1.GetD(TestIndex) | BitTest;
                    Test1.SetD(TestIndex, Digit);
                    IntMath.Multiply(Test1, DivideBy);
                    if (Test1.ParamIsGreaterOrEq(ToDivide))
                    {
                        Digit = (uint)Quotient.GetD(TestIndex) | BitTest;
                        // I want to keep this bit because it
                        // passed the test.
                        Quotient.SetD(TestIndex, Digit);
                    }

                    BitTest >>= 1;
                }

                if (TestIndex == 0)
                {
                    break;
                }

                TestIndex--;
                BitTest = 0x80000000;
            }

            Test1.Copy(Quotient);
            IntMath.Multiply(Test1, DivideBy);
            if (Test1.IsEqual(ToDivide))
            {
                Remainder.SetToZero();
                return(true); // Divides exactly.
            }

            Remainder.Copy(ToDivide);
            IntMath.Subtract(Remainder, Test1);

            // Does not divide it exactly.
            return(false);
        }