Beispiel #1
0
        internal void SetupGeneralBaseArray( Integer GeneralBase )
        {
            // The input to the accumulator can be twice the bit length of GeneralBase.
            int HowMany = ((GeneralBase.GetIndex() + 1) * 2) + 10; // Plus some extra for carries...
            if( GeneralBaseArray == null )
              {
              GeneralBaseArray = new Integer[HowMany];
              }

            if( GeneralBaseArray.Length < HowMany )
              {
              GeneralBaseArray = new Integer[HowMany];
              }

            Integer Base = new Integer();
            Integer BaseValue = 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.

            BaseValue.SetFromULong( 1 );
            for( int Count = 0; Count < HowMany; Count++ )
              {
              if( GeneralBaseArray[Count] == null )
            GeneralBaseArray[Count] = new Integer();

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

              // If this ever happened it would be a bug because
              // the point of copying the Remainder in to BaseValue
              // is to keep it down to a reasonable size.
              // And Base here is one bit bigger than a uint.
              if( Base.ParamIsGreater( Quotient ))
            throw( new Exception( "Bug. This never happens: Base.ParamIsGreater( Quotient )" ));

              // Keep it to mod GeneralBase so Divide() doesn't
              // have to do so much work.
              BaseValue.Copy( Remainder );
              IntMath.Multiply( BaseValue, Base );
              }
        }
Beispiel #2
0
        internal void MakeBaseNumbers()
        {
            try
            {
            MakeYBaseToPrimesArray();
            if( Worker.CancellationPending )
              return;

            Integer YTop = new Integer();
            Integer Y = new Integer();
            Integer XSquared = new Integer();
            Integer Test = new Integer();
            YTop.SetToZero();
            uint XSquaredBitLength = 1;

            ExponentVectorNumber ExpNumber = new ExponentVectorNumber( IntMath );

            uint Loops = 0;
            uint BSmoothCount = 0;
            uint BSmoothTestsCount = 0;
            uint IncrementYBy = 0;
            while( true )
              {
              if( Worker.CancellationPending )
            return;

              Loops++;
              if( (Loops & 0xF) == 0 )
            {
            Worker.ReportProgress( 0, " " );
            Worker.ReportProgress( 0, "Loops: " + Loops.ToString( "N0" ));
            Worker.ReportProgress( 0, "BSmoothCount: " + BSmoothCount.ToString( "N0" ));
            Worker.ReportProgress( 0, "BSmoothTestsCount: " + BSmoothTestsCount.ToString( "N0" ));
            if( BSmoothTestsCount != 0 )
              {
              double TestsRatio = (double)BSmoothCount / (double)BSmoothTestsCount;
              Worker.ReportProgress( 0, "TestsRatio: " + TestsRatio.ToString( "N3" ));
              }
            }

              /*
              if( (Loops & 0xFFFFF) == 0 )
            {
            // Use Task Manager to tweak the CPU Utilization if you want
            // it be below 100 percent.
            Thread.Sleep( 1 );
            }
            */

              // About 98 percent of the time it is running IncrementBy().
              IncrementYBy += IncrementConst;
              uint BitLength = IncrementBy();

              const uint SomeOptimumBitLength = 2;
              if( BitLength < SomeOptimumBitLength )
            continue;

              // This BitLength has to do with how many small factors you want
              // in the number.  But it doesn't limit your factor base at all.
              // You can still have any size prime in your factor base (up to
              // IntegerMath.PrimeArrayLength).  Compare the size of
              // YBaseToPrimesArrayLast to IntegerMath.PrimeArrayLength.
              BSmoothTestsCount++;
              YTop.AddULong( IncrementYBy );
              IncrementYBy = 0;
              Y.Copy( ProductSqrRoot );
              Y.Add( YTop );
              XSquared.Copy( Y );
              IntMath.DoSquare( XSquared );
              if( XSquared.ParamIsGreater( Product ))
            throw( new Exception( "Bug. XSquared.ParamIsGreater( Product )." ));

              IntMath.Subtract( XSquared, Product );

              XSquaredBitLength = (uint)(XSquared.GetIndex() * 32);
              uint TopDigit = (uint)XSquared.GetD( XSquared.GetIndex());
              uint TopLength = GetBitLength( TopDigit );
              XSquaredBitLength += TopLength;
              if( XSquaredBitLength == 0 )
            XSquaredBitLength = 1;

              // if( ItIsTheAnswerAlready( XSquared ))  It's too unlikely.
              // QuadResCombinatorics could run in parallel to check for that,
              // and it would be way ahead of this.

              GetOneMainFactor();
              if( OneMainFactor.IsEqual( XSquared ))
            {
            MakeFastExpNumber( ExpNumber );
            }
              else
            {
            if( OneMainFactor.IsZero())
              throw( new Exception( "OneMainFactor.IsZero()." ));

            IntMath.Divide( XSquared, OneMainFactor, Quotient, Remainder );
            ExpNumber.SetFromTraditionalInteger( Quotient );
            ExpNumber.Multiply( ExpOneMainFactor );
            ExpNumber.GetTraditionalInteger( Test );
            if( !Test.IsEqual( XSquared ))
              throw( new Exception( "!Test.IsEqual( XSquared )." ));

            }

              if( ExpNumber.IsBSmooth())
            {
            BSmoothCount++;
            string DelimS = IntMath.ToString10( Y ) + "\t" +
                        ExpNumber.ToDelimString();

            Worker.ReportProgress( 1, DelimS );

            if( (BSmoothCount & 0x3F) == 0 )
              {
              Worker.ReportProgress( 0, " " );
              Worker.ReportProgress( 0, "BitLength: " + BitLength.ToString());
              Worker.ReportProgress( 0, "XSquaredBitLength: " + XSquaredBitLength.ToString());
              Worker.ReportProgress( 0, ExpNumber.ToString() );

              // What should BSmoothLimit be?
              // (Since FactorDictionary.cs will reduce the final factor base.)
              if( BSmoothCount > BSmoothLimit )
            {
            Worker.ReportProgress( 0, "Found enough to make the matrix." );
            Worker.ReportProgress( 0, "BSmoothCount: " + BSmoothCount.ToString( "N0" ));
            Worker.ReportProgress( 0, "BSmoothLimit: " + BSmoothLimit.ToString( "N0" ));
            Worker.ReportProgress( 0, "Seconds: " + StartTime.GetSecondsToNow().ToString( "N1" ));
            double Seconds = StartTime.GetSecondsToNow();
            int Minutes = (int)Seconds / 60;
            int Hours = Minutes / 60;
            Minutes = Minutes % 60;
            Seconds = Seconds % 60;
            string ShowS = "Hours: " + Hours.ToString( "N0" ) +
                   "  Minutes: " + Minutes.ToString( "N0" ) +
                   "  Seconds: " + Seconds.ToString( "N0" );

            Worker.ReportProgress( 0, ShowS );

            return;
            }
              }
            }
              }
            }
            catch( Exception Except )
              {
              throw( new Exception( "Exception in MakeBaseNumbers():\r\n" + Except.Message ));
              }
        }
Beispiel #3
0
        // This is the standard modular power algorithm that
        // you could find in any reference, but its use of
        // the new modular reduction algorithm is new.
        // The square and multiply method is in Wikipedia:
        // https://en.wikipedia.org/wiki/Exponentiation_by_squaring
        // x^n = (x^2)^((n - 1)/2) if n is odd.
        // x^n = (x^2)^(n/2)       if n is even.
        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.Divide( Result, Modulus, Quotient, Remainder );
              Result.Copy( Remainder );
              }

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

            if( !UsePresetBaseArray )
              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.Multiply( Result, XForModPower );
            ModularReduction( TempForModPower, Result );
            Result.Copy( TempForModPower );
            }

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

              // Square it.
              IntMath.Multiply( XForModPower, XForModPower );
              ModularReduction( 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() ));

            if( HowBig > 2 )
              throw( new Exception( "The never happens. Diff: " + HowBig.ToString() ));

            ModularReduction( TempForModPower, Result );
            Result.Copy( TempForModPower );

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

            if( Quotient.GetIndex() > 1 )
              throw( new Exception( "This never happens. The quotient index is never more than 1." ));
        }
Beispiel #4
0
        /*
          internal void ModularPowerOld( Integer Result, Integer Exponent, Integer ModN )
        {
        if( Result.IsZero())
          return; // With Result still zero.

        if( Result.IsEqual( ModN ))
          {
          // It is congruent to zero % ModN.
          Result.SetToZero();
          return;
          }

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

        if( ModN.ParamIsGreater( Result ))
          {
          Divide( Result, ModN, Quotient, Remainder );
          Result.Copy( Remainder );
          }

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

        XForModPower.Copy( Result );
        ExponentCopy.Copy( Exponent );
        Result.SetFromULong( 1 );
        while( !ExponentCopy.IsZero())
          {
          // If the bit is 1, then do a lot more work here.
          if( (ExponentCopy.GetD( 0 ) & 1) == 1 )
        {
        // This is a multiplication for every _bit_.  So a 1024-bit
        // modulus means this gets called roughly 512 times.
        // The commonly used public exponent is 65537, which has
        // only two bits set to 1, the rest are all zeros.  But the
        // private key exponents are long randomish numbers.
        // (See: Hamming Weight.)
        Multiply( Result, XForModPower );
        SubtractULong( ExponentCopy, 1 );
        // Usually it's true that the Result is greater than ModN.
        if( ModN.ParamIsGreater( Result ))
          {
          // Here is where that really long division algorithm gets used a
          // lot in a loop.  And this Divide() gets called roughly about
          // 512 times.
          Divide( Result, ModN, Quotient, Remainder );
          Result.Copy( Remainder );
          }
        }

          // Square it.
          // This is a multiplication for every _bit_.  So a 1024-bit
          // modulus means this gets called 1024 times.
          Multiply( XForModPower, XForModPower );
          ExponentCopy.ShiftRight( 1 ); // Divide by 2.
          if( ModN.ParamIsGreater( XForModPower ))
        {
        // And this Divide() gets called about 1024 times.
        Divide( XForModPower, ModN, Quotient, Remainder );
        XForModPower.Copy( Remainder );
        }
          }
        }
        */
        internal void GreatestCommonDivisor( Integer X, Integer Y, Integer Gcd )
        {
            // This is the basic Euclidean Algorithm.
            if( X.IsZero())
              throw( new Exception( "Doing GCD with a parameter that is zero." ));

            if( Y.IsZero())
              throw( new Exception( "Doing GCD with a parameter that is zero." ));

            if( X.IsEqual( Y ))
              {
              Gcd.Copy( X );
              return;
              }

            // Don't change the original numbers that came in as parameters.
            if( X.ParamIsGreater( Y ))
              {
              GcdX.Copy( Y );
              GcdY.Copy( X );
              }
            else
              {
              GcdX.Copy( X );
              GcdY.Copy( Y );
              }

            while( true )
              {
              Divide( GcdX, GcdY, Quotient, Remainder );
              if( Remainder.IsZero())
            {
            Gcd.Copy( GcdY ); // It's the smaller one.
            // It can't return from this loop until the remainder is zero.
            return;
            }

              GcdX.Copy( GcdY );
              GcdY.Copy( Remainder );
              }
        }
Beispiel #5
0
        private Integer MakeBigBase( Integer Max )
        {
            Integer Base = new Integer();
            Base.SetFromULong( 2 );
            Integer LastBase = new Integer();
            // Start at the prime 3.
            for( int Count = 1; Count < IntegerMath.PrimeArrayLength; Count++ )
              {
              uint Prime = IntMath.GetPrimeAt( Count );
              IntMath.MultiplyULong( Base, Prime );
              if( Max.ParamIsGreater( Base ))
            return LastBase;

              LastBase.Copy( Base );
              }

            return null;
        }
Beispiel #6
0
        internal void Subtract( Integer Result, Integer ToSub )
        {
            // This checks that the sign is equal too.
            if( Result.IsEqual( ToSub ))
              {
              Result.SetToZero();
              return;
              }

            // ParamIsGreater() handles positive and negative values, so if the
            // parameter is more toward the positive side then it's true.  It's greater.

            // The most common form.  They are both positive.
            if( !Result.IsNegative && !ToSub.IsNegative )
              {
              if( ToSub.ParamIsGreater( Result ))
            {
            SubtractPositive( Result, ToSub );
            return;
            }

              // ToSub is bigger.
              TempSub1.Copy( Result );
              TempSub2.Copy( ToSub );
              SubtractPositive( TempSub2, TempSub1 );
              Result.Copy( TempSub2 );
              Result.IsNegative = true;
              return;
              }

            if( Result.IsNegative && !ToSub.IsNegative )
              {
              TempSub1.Copy( Result );
              TempSub1.IsNegative = false;
              TempSub1.Add( ToSub );
              Result.Copy( TempSub1 );
              Result.IsNegative = true;
              return;
              }

            if( !Result.IsNegative && ToSub.IsNegative )
              {
              TempSub1.Copy( ToSub );
              TempSub1.IsNegative = false;
              Result.Add( TempSub1 );
              return;
              }

            if( Result.IsNegative && ToSub.IsNegative )
              {
              TempSub1.Copy( Result );
              TempSub1.IsNegative = false;
              TempSub2.Copy( ToSub );
              TempSub2.IsNegative = false;

              // -12 - -7 = -12 + 7 = -5
              // Comparing the positive numbers here.
              if( TempSub2.ParamIsGreater( TempSub1 ))
            {
            SubtractPositive( TempSub1, TempSub2 );
            Result.Copy( TempSub1 );
            Result.IsNegative = true;
            return;
            }

              // -7 - -12 = -7 + 12 = 5
              SubtractPositive( TempSub2, TempSub1 );
              Result.Copy( TempSub2 );
              Result.IsNegative = false;
              return;
              }
        }
Beispiel #7
0
        private void LongDivide3( Integer ToDivide,
                            Integer DivideBy,
                            Integer Quotient,
                            Integer Remainder )
        {
            int TestIndex = ToDivide.GetIndex() - DivideBy.GetIndex();
            if( TestIndex < 0 )
              throw( new Exception( "TestIndex < 0 in Divide3." ));

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

              }

            // Keep a copy of the originals.
            ToDivideKeep.Copy( ToDivide );
            DivideByKeep.Copy( DivideBy );

            ulong TestBits = DivideBy.GetD( DivideBy.GetIndex());
            int ShiftBy = FindShiftBy( TestBits );
            ToDivide.ShiftLeft( ShiftBy ); // Multiply the numerator and the denominator
            DivideBy.ShiftLeft( ShiftBy ); // by the same amount.

            ulong MaxValue;
            if( (ToDivide.GetIndex() - 1) > (DivideBy.GetIndex() + TestIndex) )
              {
              MaxValue = ToDivide.GetD( ToDivide.GetIndex());
              }
            else
              {
              MaxValue = ToDivide.GetD( ToDivide.GetIndex()) << 32;
              MaxValue |= ToDivide.GetD( ToDivide.GetIndex() - 1 );
              }

            ulong Denom = DivideBy.GetD( DivideBy.GetIndex());
            if( Denom != 0 )
              MaxValue = MaxValue / Denom;
            else
              MaxValue = 0xFFFFFFFF;

            if( MaxValue > 0xFFFFFFFF )
              MaxValue = 0xFFFFFFFF;

            if( MaxValue == 0 )
              throw( new Exception( "MaxValue is zero at the top in LongDivide3()." ));

            Quotient.SetDigitAndClear( TestIndex, 1 );
            Quotient.SetD( TestIndex, 0 );

            TestForDivide1.Copy( Quotient );
            TestForDivide1.SetD( TestIndex, MaxValue );
            MultiplyTop( TestForDivide1, DivideBy );

            /*
            Test2.Copy( Quotient );
            Test2.SetD( TestIndex, MaxValue );
            Multiply( Test2, DivideBy );
            if( !Test2.IsEqual( TestForDivide1 ))
              throw( new Exception( "In Divide3() !IsEqual( Test2, TestForDivide1 )" ));
            */

            if( TestForDivide1.ParamIsGreaterOrEq( ToDivide ))
              {
              // ToMatchExactCount++;
              // Most of the time (roughly 5 out of every 6 times)
              // this MaxValue estimate is exactly right:
              Quotient.SetD( TestIndex, MaxValue );
              }
            else
              {
              // MaxValue can't be zero here. If it was it would
              // already be low enough before it got here.
              MaxValue--;

              if( MaxValue == 0 )
            throw( new Exception( "After decrement: MaxValue is zero in LongDivide3()." ));

              TestForDivide1.Copy( Quotient );
              TestForDivide1.SetD( TestIndex, MaxValue );
              MultiplyTop( TestForDivide1, DivideBy );

              /*
              Test2.Copy( Quotient );
              Test2.SetD( TestIndex, MaxValue );
              Multiply( Test2, DivideBy );
              if( !Test2.IsEqual( Test1 ))
            throw( new Exception( "Top one. !Test2.IsEqual( Test1 ) in LongDivide3()" ));
              */

              if( TestForDivide1.ParamIsGreaterOrEq( ToDivide ))
            {
            // ToMatchDecCount++;
            Quotient.SetD( TestIndex, MaxValue );
            }
              else
            {
            // TestDivideBits is done as a last resort, but it's rare.
            // But it does at least limit it to a worst case scenario
            // of trying 32 bits, rather than 4 billion or so decrements.

            TestDivideBits( MaxValue,
                        true,
                        TestIndex,
                        ToDivide,
                        DivideBy,
                        Quotient,
                        Remainder );
            }

              // TestGap = MaxValue - LgQuotient.D[TestIndex];
              // if( TestGap > HighestToMatchGap )
            // HighestToMatchGap = TestGap;

              // HighestToMatchGap: 4,294,967,293
              // uint size:         4,294,967,295 uint
              }

            // If it's done.
            if( TestIndex == 0 )
              {
              TestForDivide1.Copy( Quotient );
              Multiply( TestForDivide1, DivideByKeep );
              Remainder.Copy( ToDivideKeep );
              Subtract( Remainder, TestForDivide1 );
              //if( DivideByKeep.ParamIsGreater( Remainder ))
            // throw( new Exception( "Remainder > DivideBy in LongDivide3()." ));

              return;
              }

            // Now do the rest of the digits.
            TestIndex--;
            while( true )
              {
              TestForDivide1.Copy( Quotient );
              // First Multiply() for each digit.
              Multiply( TestForDivide1, DivideBy );
              // if( ToDivide.ParamIsGreater( TestForDivide1 ))
              //   throw( new Exception( "Bug here in LongDivide3()." ));

              Remainder.Copy( ToDivide );
              Subtract( Remainder, TestForDivide1 );
              MaxValue = Remainder.GetD( Remainder.GetIndex()) << 32;

              int CheckIndex = Remainder.GetIndex() - 1;
              if( CheckIndex > 0 )
            MaxValue |= Remainder.GetD( CheckIndex );

              Denom = DivideBy.GetD( DivideBy.GetIndex());
              if( Denom != 0 )
            MaxValue = MaxValue / Denom;
              else
            MaxValue = 0xFFFFFFFF;

              if( MaxValue > 0xFFFFFFFF )
            MaxValue = 0xFFFFFFFF;

              TestForDivide1.Copy( Quotient );
              TestForDivide1.SetD( TestIndex, MaxValue );
              // There's a minimum of two full Multiply() operations per digit.
              Multiply( TestForDivide1, DivideBy );
              if( TestForDivide1.ParamIsGreaterOrEq( ToDivide ))
            {
            // Most of the time this MaxValue estimate is exactly right:
            // ToMatchExactCount++;
            Quotient.SetD( TestIndex, MaxValue );
            }
              else
            {
            MaxValue--;
            TestForDivide1.Copy( Quotient );
            TestForDivide1.SetD( TestIndex, MaxValue );
            Multiply( TestForDivide1, DivideBy );
            if( TestForDivide1.ParamIsGreaterOrEq( ToDivide ))
              {
              // ToMatchDecCount++;
              Quotient.SetD( TestIndex, MaxValue );
              }
            else
              {
              TestDivideBits( MaxValue,
                          false,
                          TestIndex,
                          ToDivide,
                          DivideBy,
                          Quotient,
                          Remainder );

              // TestGap = MaxValue - LgQuotient.D[TestIndex];
              // if( TestGap > HighestToMatchGap )
            // HighestToMatchGap = TestGap;

              }
            }

              if( TestIndex == 0 )
            break;

              TestIndex--;
              }

            TestForDivide1.Copy( Quotient );
            Multiply( TestForDivide1, DivideByKeep );
            Remainder.Copy( ToDivideKeep );
            Subtract( Remainder, TestForDivide1 );

            // if( DivideByKeep.ParamIsGreater( Remainder ))
              // throw( new Exception( "Remainder > DivideBy in LongDivide3()." ));
        }
Beispiel #8
0
        internal void ModularPower( ChineseRemainder CRTResult,
                              Integer Exponent,
                              ChineseRemainder CRTModulus,
                              bool UsePresetBaseArray )
        {
            // The square and multiply method is in Wikipedia:
            // https://en.wikipedia.org/wiki/Exponentiation_by_squaring

            if( Worker.CancellationPending )
              return;

            if( CRTResult.IsZero())
              return; // With CRTResult still zero.

            if( CRTResult.IsEqual( CRTModulus ))
              {
              // It is congruent to zero % ModN.
              CRTResult.SetToZero();
              return;
              }

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

            Integer Result = new Integer();
            CRTMath1.GetTraditionalInteger( Result, CRTResult );

            Integer Modulus = new Integer();
            CRTMath1.GetTraditionalInteger( Modulus, CRTModulus );

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

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

            if( !UsePresetBaseArray )
              SetupBaseModArray( Modulus );

            if( CRTBaseModArray == null )
              throw( new Exception( "SetupBaseModArray() should have already been done here." ));

            CRTXForModPower.Copy( CRTResult );
            ExponentCopy.Copy( Exponent );
            int TestIndex = 0;
            CRTResult.SetToOne();

            int LoopsTest = 0;
            while( true )
              {
              LoopsTest++;
              if( (ExponentCopy.GetD( 0 ) & 1) == 1 ) // If the bottom bit is 1.
            {
            CRTResult.Multiply( CRTXForModPower );
            ModularReduction( CRTResult, CRTAccumulate );
            CRTResult.Copy( CRTAccumulate );
            }

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

              // Square it.
              CRTCopyForSquare.Copy( CRTXForModPower );
              CRTXForModPower.Multiply( CRTCopyForSquare );
              ModularReduction( CRTXForModPower, CRTAccumulate );
              CRTXForModPower.Copy( CRTAccumulate );
              }

            ModularReduction( CRTResult, CRTAccumulate );
            CRTResult.Copy( CRTAccumulate );

            // Division is never used in the loop above.

            // This is a very small Quotient.
            // See SetupBaseMultiples() for a description of how to calculate
            // the maximum size of this quotient.
            CRTMath1.GetTraditionalInteger( Result, CRTResult );
            IntMath.Divide( Result, Modulus, Quotient, Remainder );

            // Is the Quotient bigger than a 32 bit integer?
            if( Quotient.GetIndex() > 0 )
              throw( new Exception( "I haven't ever seen this happen. Quotient.GetIndex() > 0.  It is: " + Quotient.GetIndex().ToString() ));

            QuotientForTest = Quotient.GetAsULong();
            if( QuotientForTest > 2097867 )
              throw( new Exception( "This can never happen unless I increase ChineseRemainder.DigitsArraySize." ));

            Result.Copy( Remainder );
            CRTResult.SetFromTraditionalInteger( Remainder );
        }
Beispiel #9
0
        private void FindFactorsFromLeft( ulong A,
                                    ulong C,
                                    Integer Left,
                                    Integer Temp,
                                    Integer B )
        {
            if( Worker.CancellationPending )
              return;

            /*
            // (323 - 2*4 / 5) = xy5 + 2y + 4x
            // (315 / 5) = xy5 + 2y + 4x
            // 63 = xy5 + 2y + 4x
            // 21 * 3 = xy5 + 2y + 4x
            // 3*7*3 = xy5 + 2y + 4x
            // 3*7*3 = 3y5 + 2y + 4*3
            // 3*7*3 = 15y + 2y + 12
            // 3*7*3 - 12 = y(15 + 2)
            // 3*7*3 - 3*4 = y(15 + 2)
            // 51 = 3 * 17

            // (323 - 1*3 / 5) = xy5 + 1y + 3x
            // (320 / 5) = xy5 + 1y + 3x
            // 64 = xy5 + 1y + 3x
            // 64 - 3x = xy5 + 1y
            // 64 - 3x = y(x5 + 1)
            // 64 - 3x = y(x5 + 1)
            1 = y(x5 + 1) mod 3
            */

            Left.Copy( Product );
            Temp.SetFromULong( A * C );
            IntMath.Subtract( Left, Temp );
            IntMath.Divide( Left, B, Quotient, Remainder );
            if( !Remainder.IsZero())
              throw( new Exception( "Remainder is not zero for Left." ));

            Left.Copy( Quotient );
            // Worker.ReportProgress( 0, "Left: " + IntMath.ToString10( Left ));
            // Worker.ReportProgress( 0, "A: " + A.ToString() + "  C: " + C.ToString());

            FindFactors1.FindSmallPrimeFactorsOnly( Left );
            FindFactors1.ShowAllFactors();

            MaxX.Copy( ProductSqrRoot );
            Temp.SetFromULong( A );
            if( MaxX.ParamIsGreater( Temp ))
              return; // MaxX would be less than zero.

            IntMath.Subtract( MaxX, Temp );
            IntMath.Divide( MaxX, B, Quotient, Remainder );
            MaxX.Copy( Quotient );
            // Worker.ReportProgress( 0, "MaxX: " + IntMath.ToString10( MaxX ));

            Temp.Copy( MaxX );
            IntMath.MultiplyULong( Temp, C );
            if( Left.ParamIsGreater( Temp ))
              {
              throw( new Exception( "Does this happen?  MaxX can't be that big." ));
              /*
              Worker.ReportProgress( 0, "MaxX can't be that big." );
              MaxX.Copy( Left );
              Temp.SetFromULong( C );
              IntMath.Divide( MaxX, Temp, Quotient, Remainder );
              MaxX.Copy( Quotient );
              Worker.ReportProgress( 0, "MaxX was set to: " + IntMath.ToString10( MaxX ));
              */
              }

            // P = (xB + a)(yB + c)
            // P = (xB + a)(yB + c)
            // P - ac = xyBB + ayB + xBc
            // ((P - ac) / B) = xyB + ay + xc
            // ((P - ac) / B) = y(xB + a) + xc

            // This is congruent to zero mod one really big prime.
            // ((P - ac) / B) - xc = y(xB + a)

            // BottomPart is when x is at max in:
            // ((P - ac) / B) - xc
            Integer BottomPart = new Integer();
            BottomPart.Copy( Left );
            Temp.Copy( MaxX );
            IntMath.MultiplyULong( Temp, C );
            IntMath.Subtract( BottomPart, Temp );
            if( BottomPart.IsNegative )
              throw( new Exception( "Bug.  BottomPart is negative." ));

            // Worker.ReportProgress( 0, "BottomPart: " + IntMath.ToString10( BottomPart ));

            Integer Gcd = new Integer();
            Temp.SetFromULong( C );
            IntMath.GreatestCommonDivisor( BottomPart, Temp, Gcd );
            if( !Gcd.IsOne())
              throw( new Exception( "This can't happen with the GCD." ));

            // FindFactors1.FindSmallPrimeFactorsOnly( BottomPart );
            // Temp.SetFromULong( C );
            // FindFactors1.FindSmallPrimeFactorsOnly( Temp );
            // FindFactors1.ShowAllFactors();

            MakeXYRecArray( Left, B, A, C );

            FindXTheHardWay( B, Temp, A );
        }
Beispiel #10
0
        internal bool DecryptWithQInverse( Integer EncryptedNumber,
                                     Integer DecryptedNumber,
                                     Integer TestDecryptedNumber,
                                     Integer PubKeyN,
                                     Integer PrivKInverseExponentDP,
                                     Integer PrivKInverseExponentDQ,
                                     Integer PrimeP,
                                     Integer PrimeQ,
                                     BackgroundWorker Worker )
        {
            Worker.ReportProgress( 0, " " );
            Worker.ReportProgress( 0, "Top of DecryptWithQInverse()." );

            // QInv and the dP and dQ numbers are normally already set up before
            // you start your listening socket.
            ECTime DecryptTime = new ECTime();
            DecryptTime.SetToNow();

            // See section 5.1.2 of RFC 2437 for these steps:
            // http://tools.ietf.org/html/rfc2437
            //      2.2 Let m_1 = c^dP mod p.
            //      2.3 Let m_2 = c^dQ mod q.
            //      2.4 Let h = qInv ( m_1 - m_2 ) mod p.
            //      2.5 Let m = m_2 + hq.

            Worker.ReportProgress( 0, "EncryptedNumber: " + IntMath.ToString10( EncryptedNumber ));

            //      2.2 Let m_1 = c^dP mod p.
            TestForDecrypt.Copy( EncryptedNumber );
            IntMathNewForP.ModularPower( TestForDecrypt, PrivKInverseExponentDP, PrimeP, true );
            if( Worker.CancellationPending )
              return false;

            M1ForInverse.Copy( TestForDecrypt );

            //      2.3 Let m_2 = c^dQ mod q.
            TestForDecrypt.Copy( EncryptedNumber );
            IntMathNewForQ.ModularPower( TestForDecrypt, PrivKInverseExponentDQ, PrimeQ, true );

            if( Worker.CancellationPending )
              return false;

            M2ForInverse.Copy( TestForDecrypt );

            //      2.4 Let h = qInv ( m_1 - m_2 ) mod p.

            // How many is optimal to avoid the division?
            int HowManyIsOptimal = (PrimeP.GetIndex() * 3);
            for( int Count = 0; Count < HowManyIsOptimal; Count++ )
              {
              if( M1ForInverse.ParamIsGreater( M2ForInverse ))
            M1ForInverse.Add( PrimeP );
              else
            break;

              }

            if( M1ForInverse.ParamIsGreater( M2ForInverse ))
              {
              M1M2SizeDiff.Copy( M2ForInverse );
              IntMath.Subtract( M1M2SizeDiff, M1ForInverse );
              // Unfortunately this long Divide() has to be done.
              IntMath.Divide( M1M2SizeDiff, PrimeP, Quotient, Remainder );
              Quotient.AddULong( 1 );
              Worker.ReportProgress( 0, "The Quotient for M1M2SizeDiff is: " + IntMath.ToString10( Quotient ));
              IntMath.Multiply( Quotient, PrimeP );
              M1ForInverse.Add( Quotient );
              }

            M1MinusM2.Copy( M1ForInverse );
            IntMath.Subtract( M1MinusM2, M2ForInverse );

            if( M1MinusM2.IsNegative )
              throw( new Exception( "This is a bug. M1MinusM2.IsNegative is true." ));

            if( QInv.IsNegative )
              throw( new Exception( "This is a bug. QInv.IsNegative is true." ));

            HForQInv.Copy( M1MinusM2 );
            IntMath.Multiply( HForQInv, QInv );

            if( HForQInv.IsNegative )
              throw( new Exception( "This is a bug. HForQInv.IsNegative is true." ));

            if( PrimeP.ParamIsGreater( HForQInv ))
              {
              IntMath.Divide( HForQInv, PrimeP, Quotient, Remainder );
              HForQInv.Copy( Remainder );
              }

            //      2.5 Let m = m_2 + hq.
            DecryptedNumber.Copy( HForQInv );
            IntMath.Multiply( DecryptedNumber, PrimeQ );
            DecryptedNumber.Add( M2ForInverse );
            if( !TestDecryptedNumber.IsEqual( DecryptedNumber ))
              throw( new Exception( "!TestDecryptedNumber.IsEqual( DecryptedNumber )." ));

            Worker.ReportProgress( 0, " " );
            Worker.ReportProgress( 0, "DecryptedNumber: " + IntMath.ToString10( DecryptedNumber ));
            Worker.ReportProgress( 0, " " );
            Worker.ReportProgress( 0, "TestDecryptedNumber: " + IntMath.ToString10( TestDecryptedNumber ));
            Worker.ReportProgress( 0, " " );
            Worker.ReportProgress( 0, "Decrypt with QInv time seconds: " + DecryptTime.GetSecondsToNow().ToString( "N2" ));
            Worker.ReportProgress( 0, " " );
            return true;
        }
        private bool GetFactors( Integer Y, ExponentVectorNumber XExp )
        {
            Integer XRoot = new Integer();
            Integer X = new Integer();
            Integer XwithY = new Integer();
            Integer Gcd = new Integer();
            XExp.GetTraditionalInteger( X );
            if( !IntMath.SquareRoot( X, XRoot ))
              throw( new Exception( "Bug. X should have an exact square root." ));

            XwithY.Copy( Y );
            XwithY.Add( XRoot );
            IntMath.GreatestCommonDivisor( Product, XwithY, Gcd );
            if( !Gcd.IsOne())
              {
              if( !Gcd.IsEqual( Product ))
            {
            SolutionP.Copy( Gcd );
            IntMath.Divide( Product, SolutionP, Quotient, Remainder );
            if( !Remainder.IsZero())
              throw( new Exception( "The Remainder with SolutionP can't be zero." ));

            SolutionQ.Copy( Quotient );
            MForm.ShowStatus( "SolutionP: " + IntMath.ToString10( SolutionP ));
            MForm.ShowStatus( "SolutionQ: " + IntMath.ToString10( SolutionQ ));
            return true;
            }
              else
            {
            MForm.ShowStatus( "GCD was Product." );
            }
              }
            else
              {
              MForm.ShowStatus( "GCD was one." );
              }

            MForm.ShowStatus( "XRoot: " + IntMath.ToString10( XRoot ));
            MForm.ShowStatus( "Y: " + IntMath.ToString10( Y ));

            XwithY.Copy( Y );
            if( Y.ParamIsGreater( XRoot ))
              throw( new Exception( "This can't be right. XRoot is bigger than Y." ));

            IntMath.Subtract( Y, XRoot );
            IntMath.GreatestCommonDivisor( Product, XwithY, Gcd );
            if( !Gcd.IsOne())
              {
              if( !Gcd.IsEqual( Product ))
            {
            SolutionP.Copy( Gcd );
            IntMath.Divide( Product, SolutionP, Quotient, Remainder );
            if( !Remainder.IsZero())
              throw( new Exception( "The Remainder with SolutionP can't be zero." ));

            SolutionQ.Copy( Quotient );
            MForm.ShowStatus( "SolutionP: " + IntMath.ToString10( SolutionP ));
            MForm.ShowStatus( "SolutionQ: " + IntMath.ToString10( SolutionQ ));
            return true;
            }
              else
            {
            MForm.ShowStatus( "GCD was Product." );
            }
              }
            else
              {
              MForm.ShowStatus( "GCD was one." );
              }

            return false;
        }
        internal void ModularPower( Integer Result, Integer Exponent, Integer GeneralBase )
        {
            // The square and multiply method is in Wikipedia:
            // https://en.wikipedia.org/wiki/Exponentiation_by_squaring
            // x^n = (x^2)^((n - 1)/2) if n is odd.
            // x^n = (x^2)^(n/2)       if n is even.

            if( Result.IsZero())
              return; // With Result still zero.

            if( Result.IsEqual( GeneralBase ))
              {
              // It is congruent to zero % ModN.
              Result.SetToZero();
              return;
              }

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

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

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

            // This could also be called ahead of time if the base (the modulus)
            // doesn't change.  Like when your public key doesn't change.
            SetupGeneralBaseArray( GeneralBase );

            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.Multiply( Result, XForModPower );

            // Modular Reduction:
            AddByGeneralBaseArrays( TempForModPower, Result );
            Result.Copy( TempForModPower );
            }

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

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

              // Modular Reduction:
              AddByGeneralBaseArrays( TempForModPower, XForModPower );
              XForModPower.Copy( TempForModPower );
              }

            // When AddByGeneralBaseArrays() gets called it multiplies a 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.
            // If by chance you got a carry bit on _every_ addition that was done
            // in AddByGeneralBaseArrays() then this number could increase in size
            // by 1 bit for each addition that was done.  It would take 32 bits of
            // carrying for HowBig to increase by 1.
            // See HowManyToAdd in AddByGeneralBaseArrays() for why this check is done.
            int HowBig = Result.GetIndex() - GeneralBase.GetIndex();
            if( HowBig > 2 ) // I have not seen this happen yet.
              throw( new Exception( "The difference in index size was more than 2. Diff: " + HowBig.ToString() ));

            // So this Quotient has only one or two 32-bit digits in it.
            // And this Divide() is only called once at the end.  Not in the loop.
            IntMath.Divide( Result, GeneralBase, Quotient, Remainder );
            Result.Copy( Remainder );
        }