Example #1
0
        internal RSACryptoSystem(BackgroundWorker UseWorker, RSACryptoWorkerInfo UseWInfo)
        {
            Worker     = UseWorker;
            WorkerInfo = UseWInfo;
            StartTime  = new ECTime();
            StartTime.SetToNow();
            RngCsp  = new RNGCryptoServiceProvider();
            IntMath = new IntegerMath(null);

            IntMathForP = new IntegerMath(null);
            IntMathForQ = new IntegerMath(null);
            // Worker.ReportProgress( 0, IntMath.GetStatusString() );

            Quotient               = new Integer();
            Remainder              = new Integer();
            PrimeP                 = new Integer();
            PrimeQ                 = new Integer();
            PrimePMinus1           = new Integer();
            PrimeQMinus1           = new Integer();
            PubKeyN                = new Integer();
            PubKeyExponent         = new Integer();
            PrivKInverseExponent   = new Integer();
            PrivKInverseExponentDP = new Integer();
            PrivKInverseExponentDQ = new Integer();
            QInv           = new Integer();
            PhiN           = new Integer();
            TestForDecrypt = new Integer();
            M1ForInverse   = new Integer();
            M2ForInverse   = new Integer();
            HForQInv       = new Integer();
            M1MinusM2      = new Integer();
            M1M2SizeDiff   = new Integer();

            PubKeyExponent.SetFromULong(PubKeyExponentUint);
        }
Example #2
0
        internal void SetFromString(Integer Result, string InString)
        {
            if (InString == null)
            {
                throw(new Exception("InString was null in SetFromString()."));
            }

            if (InString.Length < 1)
            {
                Result.SetToZero();
                return;
            }

            Base10Number Base10N = new Base10Number();
            Integer      Tens    = new Integer();
            Integer      OnePart = new Integer();

            // This might throw an exception if the string is bad.
            Base10N.SetFromString(InString);
            Result.SetFromULong(Base10N.GetD(0));
            Tens.SetFromULong(10);
            for (int Count = 1; Count <= Base10N.GetIndex(); Count++)
            {
                OnePart.SetFromULong(Base10N.GetD(Count));
                Multiplier.Multiply(OnePart, Tens);
                Result.Add(OnePart);
                Multiplier.MultiplyULong(Tens, 10);
            }
        }
Example #3
0
        internal bool IsFermatPrimeForOneValue(Integer ToTest, ulong Base)
        {
            // Assume ToTest is not a small number.  (Not the size of a small prime.)
            // Normally it would be something like a 1024 bit number or bigger,
            // but I assume it's at least bigger than a 32 bit number.
            // Assume this has already been checked to see if it's divisible
            // by a small prime.
            // A has to be coprime to P and it is here because ToTest is not
            // divisible by a small prime.
            // Fermat's little theorem:
            // A ^ (P - 1) is congruent to 1 mod P if P is a prime.
            // Or: A^P - A is congrunt to A mod P.
            // If you multiply A by itself P times then divide it by P,
            // the remainder is A.  (A^P / P)
            // 5^3 = 125.  125 - 5 = 120.  A multiple of 5.
            // 2^7 = 128.  128 - 2 = 7 * 18 (a multiple of 7.)
            Fermat1.Copy(ToTest);
            IntMath.SubtractULong(Fermat1, 1);
            TestFermat.SetFromULong(Base);

            // ModularPower( Result, Exponent, Modulus, UsePresetBaseArray )
            ModularPower(TestFermat, Fermat1, ToTest, false);
            // if( !TestFermat.IsEqual( Fermat2 ))
            // throw( new Exception( "!TestFermat.IsEqual( Fermat2 )." ));

            if (TestFermat.IsOne())
            {
                return(true); // It passed the test. It _might_ be a prime.
            }
            else
            {
                return(false); // It is _definitely_ a composite number.
            }
        }
Example #4
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);
            }
        }
Example #5
0
        // This is a variation on ShortDivide that returns
        // the remainder.
        // Also, DivideBy is a ulong.
        internal ulong ShortDivideRem(Integer ToDivideOriginal,
                                      ulong DivideByU,
                                      Integer Quotient)
        {
            if (ToDivideOriginal.IsULong())
            {
                ulong ToDiv = ToDivideOriginal.GetAsULong();
                ulong Q     = ToDiv / DivideByU;
                Quotient.SetFromULong(Q);
                return(ToDiv % DivideByU);
            }

            ToDivide.Copy(ToDivideOriginal);
            Quotient.Copy(ToDivide);
            ulong RemainderU = 0;

            if (DivideByU > Quotient.GetD(Quotient.GetIndex()))
            {
                Quotient.SetD(Quotient.GetIndex(), 0);
            }
            else
            {
                ulong OneDigit = Quotient.GetD(Quotient.GetIndex());
                Quotient.SetD(Quotient.GetIndex(), OneDigit / DivideByU);
                RemainderU = OneDigit % DivideByU;
                ToDivide.SetD(ToDivide.GetIndex(), RemainderU);
            }

            for (int Count = Quotient.GetIndex(); Count >= 1; Count--)
            {
                ulong TwoDigits = ToDivide.GetD(Count);
                TwoDigits <<= 32;
                TwoDigits  |= ToDivide.GetD(Count - 1);
                Quotient.SetD(Count - 1, TwoDigits / DivideByU);
                RemainderU = TwoDigits % DivideByU;
                ToDivide.SetD(Count, 0);
                ToDivide.SetD(Count - 1, RemainderU);
            }

            for (int Count = Quotient.GetIndex(); Count >= 0; Count--)
            {
                if (Quotient.GetD(Count) != 0)
                {
                    Quotient.SetIndex(Count);
                    break;
                }
            }

            return(RemainderU);
        }
Example #6
0
        internal void Divide(Integer ToDivideOriginal,
                             Integer DivideByOriginal,
                             Integer Quotient,
                             Integer Remainder)
        {
            if (ToDivideOriginal.IsNegative)
            {
                throw(new Exception("Divide() can't be called with negative numbers."));
            }

            if (DivideByOriginal.IsNegative)
            {
                throw(new Exception("Divide() can't be called with negative numbers."));
            }

            // Returns true if it divides exactly with zero remainder.
            // This first checks for some basics before trying to divide it:
            if (DivideByOriginal.IsZero())
            {
                throw(new Exception("Divide() dividing by zero."));
            }

            ToDivide.Copy(ToDivideOriginal);
            DivideBy.Copy(DivideByOriginal);
            if (ToDivide.ParamIsGreater(DivideBy))
            {
                Quotient.SetToZero();
                Remainder.Copy(ToDivide);
                return; //  false;
            }

            if (ToDivide.IsEqual(DivideBy))
            {
                Quotient.SetFromULong(1);
                Remainder.SetToZero();
                return; //  true;
            }

            // At this point DivideBy is smaller than ToDivide.
            if (ToDivide.IsULong())
            {
                ulong ToDivideU  = ToDivide.GetAsULong();
                ulong DivideByU  = DivideBy.GetAsULong();
                ulong QuotientU  = ToDivideU / DivideByU;
                ulong RemainderU = ToDivideU % DivideByU;
                Quotient.SetFromULong(QuotientU);
                Remainder.SetFromULong(RemainderU);
                // if( RemainderU == 0 )
                return; //  true;
                // else
                // return false;
            }

            if (DivideBy.GetIndex() == 0)
            {
                ShortDivide(ToDivide, DivideBy, Quotient, Remainder);
                return;
            }

            Integer ToDivideTest2  = new Integer();
            Integer DivideByTest2  = new Integer();
            Integer QuotientTest2  = new Integer();
            Integer RemainderTest2 = new Integer();

            Integer ToDivideTest3  = new Integer();
            Integer DivideByTest3  = new Integer();
            Integer QuotientTest3  = new Integer();
            Integer RemainderTest3 = new Integer();

            ToDivideTest2.Copy(ToDivide);
            ToDivideTest3.Copy(ToDivide);

            DivideByTest2.Copy(DivideBy);
            DivideByTest3.Copy(DivideBy);

            LongDivide1(ToDivideTest2, DivideByTest2, QuotientTest2, RemainderTest2);
            LongDivide2(ToDivideTest3, DivideByTest3, QuotientTest3, RemainderTest3);
            LongDivide3(ToDivide, DivideBy, Quotient, Remainder);

            if (!Quotient.IsEqual(QuotientTest2))
            {
                throw(new Exception("!Quotient.IsEqual( QuotientTest2 )"));
            }

            if (!Quotient.IsEqual(QuotientTest3))
            {
                throw(new Exception("!Quotient.IsEqual( QuotientTest3 )"));
            }

            if (!Remainder.IsEqual(RemainderTest2))
            {
                throw(new Exception("!Remainder.IsEqual( RemainderTest2 )"));
            }

            if (!Remainder.IsEqual(RemainderTest3))
            {
                throw(new Exception("!Remainder.IsEqual( RemainderTest3 )"));
            }
        }
Example #7
0
        // This is the standard modular power algorithm that
        // you could find in any reference, but its use of
        // my modular reduction algorithm in it is new (in 2015).
        // (I mean as opposed to using some other modular reduction
        // algorithm.)
        // The square and multiply method is in Wikipedia:
        // https://en.wikipedia.org/wiki/Exponentiation_by_squaring
        internal void ModularPower(Integer Result, Integer Exponent, Integer Modulus, bool UsePresetBaseArray)
        {
            if (Result.IsZero())
            {
                return; // With Result still zero.
            }
            if (Result.IsEqual(Modulus))
            {
                // It is congruent to zero % ModN.
                Result.SetToZero();
                return;
            }

            // Result is not zero at this point.
            if (Exponent.IsZero())
            {
                Result.SetFromULong(1);
                return;
            }

            if (Modulus.ParamIsGreater(Result))
            {
                // throw( new Exception( "This is not supposed to be input for RSA plain text." ));
                IntMath.Divider.Divide(Result, Modulus, Quotient, Remainder);
                Result.Copy(Remainder);
            }

            if (Exponent.IsOne())
            {
                // Result stays the same.
                return;
            }

            if (!UsePresetBaseArray)
            {
                IntMath.ModReduction.SetupGeneralBaseArray(Modulus);
            }

            XForModPower.Copy(Result);
            ExponentCopy.Copy(Exponent);
            // int TestIndex = 0;
            Result.SetFromULong(1);
            while (true)
            {
                if ((ExponentCopy.GetD(0) & 1) == 1) // If the bottom bit is 1.
                {
                    IntMath.Multiplier.Multiply(Result, XForModPower);

                    // if( Result.ParamIsGreater( CurrentModReductionBase ))
                    // TestForModReduction2.Copy( Result );

                    IntMath.ModReduction.Reduce(TempForModPower, Result);
                    // ModularReduction2( TestForModReduction2ForModPower, TestForModReduction2 );
                    // if( !TestForModReduction2ForModPower.IsEqual( TempForModPower ))
                    // {
                    // throw( new Exception( "Mod Reduction 2 is not right." ));
                    // }

                    Result.Copy(TempForModPower);
                }

                ExponentCopy.ShiftRight(1); // Divide by 2.
                if (ExponentCopy.IsZero())
                {
                    break;
                }

                // Square it.
                IntMath.Multiplier.Multiply(XForModPower, XForModPower);

                // if( XForModPower.ParamIsGreater( CurrentModReductionBase ))
                IntMath.ModReduction.Reduce(TempForModPower, XForModPower);
                XForModPower.Copy(TempForModPower);
            }

            // When ModularReduction() gets called it multiplies a base number
            // by a uint sized digit.  So that can make the result one digit bigger
            // than GeneralBase.  Then when they are added up you can get carry
            // bits that can make it a little bigger.
            int HowBig = Result.GetIndex() - Modulus.GetIndex();

            // if( HowBig > 1 )
            // throw( new Exception( "This does happen. Diff: " + HowBig.ToString() ));

            // Do a proof for how big this can be.
            if (HowBig > 2)
            {
                throw(new Exception("This never happens. Diff: " + HowBig.ToString()));
            }

            IntMath.ModReduction.Reduce(TempForModPower, Result);
            Result.Copy(TempForModPower);

            // Notice that this Divide() is done once.  Not
            // a thousand or two thousand times.

/*
 *  Integer ResultTest = new Integer();
 *  Integer ModulusTest = new Integer();
 *  Integer QuotientTest = new Integer();
 *  Integer RemainderTest = new Integer();
 *
 *  ResultTest.Copy( Result );
 *  ModulusTest.Copy( Modulus );
 *  IntMath.Divider.DivideForSmallQuotient( ResultTest,
 *                          ModulusTest,
 *                          QuotientTest,
 *                          RemainderTest );
 *
 */

            IntMath.Divider.Divide(Result, Modulus, Quotient, Remainder);

            // if( !RemainderTest.IsEqual( Remainder ))
            // throw( new Exception( "DivideForSmallQuotient() !RemainderTest.IsEqual( Remainder )." ));

            // if( !QuotientTest.IsEqual( Quotient ))
            // throw( new Exception( "DivideForSmallQuotient() !QuotientTest.IsEqual( Quotient )." ));


            Result.Copy(Remainder);
            if (Quotient.GetIndex() > 1)
            {
                throw(new Exception("This never happens. The quotient index is never more than 1."));
            }
        }