Esempio n. 1
0
        internal bool FindTwoFactorsWithFermat( Integer Product, Integer P, Integer Q, ulong MinimumX )
        {
            ECTime StartTime = new ECTime();
            StartTime.SetToNow();

            Integer TestSqrt = new Integer();
            Integer TestSquared = new Integer();
            Integer SqrRoot = new Integer();

            TestSquared.Copy( Product );
            IntMath.Multiply( TestSquared, Product );
            IntMath.SquareRoot( TestSquared, SqrRoot );
            TestSqrt.Copy( SqrRoot );
            IntMath.DoSquare( TestSqrt );
            // IntMath.Multiply( TestSqrt, SqrRoot );
            if( !TestSqrt.IsEqual( TestSquared ))
              throw( new Exception( "The square test was bad." ));

            // Some primes:
            // 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,
            // 101, 103, 107

            P.SetToZero();
            Q.SetToZero();
            Integer TestX = new Integer();
            SetupQuadResArray( Product );

            ulong BaseTo37 = QuadResBigBase * 29UL * 31UL * 37UL;
            // ulong BaseTo31 = QuadResBigBase * 29UL * 31UL;
            ulong ProdModTo37 = IntMath.GetMod64( Product, BaseTo37 );
            // ulong ProdModTo31 = IntMath.GetMod64( Product, BaseTo31 );
            for( ulong BaseCount = 0; BaseCount < (29 * 31 * 37); BaseCount++ )
              {
              if( (BaseCount & 0xF) == 0 )
            Worker.ReportProgress( 0, "Find with Fermat BaseCount: " + BaseCount.ToString() );

              if( Worker.CancellationPending )
            return false;

              ulong Base = (BaseCount + 1) * QuadResBigBase; // BaseCount times 223,092,870.
              if( Base < MinimumX )
            continue;

              Base = BaseCount * QuadResBigBase; // BaseCount times 223,092,870.
              for( uint Count = 0; Count < QuadResArrayLast; Count++ )
            {
            // The maximum CountPart can be is just under half the size of
            // the Product. (Like if Y - X was equal to 1, and Y + X was
            // equal to the Product.)  If it got anywhere near that big it
            // would be inefficient to try and find it this way.
            ulong CountPart = Base + QuadResArray[Count];
            ulong Test = ProdModTo37 + (CountPart * CountPart);
            // ulong Test = ProdModTo31 + (CountPart * CountPart);
            Test = Test % BaseTo37;
            // Test = Test % BaseTo31;
            if( !IntegerMath.IsQuadResidue29( Test ))
              continue;

            if( !IntegerMath.IsQuadResidue31( Test ))
              continue;

            if( !IntegerMath.IsQuadResidue37( Test ))
              continue;

            ulong TestBytes = (CountPart & 0xFFFFF);
            TestBytes *= (CountPart & 0xFFFFF);
            ulong ProdBytes = Product.GetD( 1 );
            ProdBytes <<= 8;
            ProdBytes |= Product.GetD( 0 );

            uint FirstBytes = (uint)(TestBytes + ProdBytes);
            if( !IntegerMath.FirstBytesAreQuadRes( FirstBytes ))
              {
              // Worker.ReportProgress( 0, "First bytes aren't quad res." );
              continue;
              }

            TestX.SetFromULong( CountPart );
            IntMath.MultiplyULong( TestX, CountPart );
            TestX.Add( Product );

            // uint Mod37 = (uint)IntMath.GetMod32( TestX, 37 );
            // if( !IntegerMath.IsQuadResidue37( Mod37 ))
              // continue;

            // Do more of these tests with 41, 43, 47...
            // if( !IntegerMath.IsQuadResidue41( Mod37 ))
              // continue;

            // Avoid doing this square root at all costs.
            if( IntMath.SquareRoot( TestX, SqrRoot ))
              {
              Worker.ReportProgress( 0, " " );
              if( (CountPart & 1) == 0 )
            Worker.ReportProgress( 0, "CountPart was even." );
              else
            Worker.ReportProgress( 0, "CountPart was odd." );

              // Found an exact square root.
              // P + (CountPart * CountPart) = Y*Y
              // P = (Y + CountPart)Y - CountPart)

              P.Copy( SqrRoot );
              Integer ForSub = new Integer();
              ForSub.SetFromULong( CountPart );
              IntMath.Subtract( P, ForSub );

              // Make Q the bigger one and put them in order.
              Q.Copy( SqrRoot );
              Q.AddULong( CountPart );

              if( P.IsOne() || Q.IsOne())
            {
            // This happens when testing with small primes.
            Worker.ReportProgress( 0, " " );
            Worker.ReportProgress( 0, " " );
            Worker.ReportProgress( 0, "Went all the way to 1 in FindTwoFactorsWithFermat()." );
            Worker.ReportProgress( 0, " " );
            Worker.ReportProgress( 0, " " );
            P.SetToZero(); // It has no factors.
            Q.SetToZero();
            return true; // Tested everything, so it's a prime.
            }

              Worker.ReportProgress( 0, "Found P: " + IntMath.ToString10( P ) );
              Worker.ReportProgress( 0, "Found Q: " + IntMath.ToString10( Q ) );
              Worker.ReportProgress( 0, "Seconds: " + StartTime.GetSecondsToNow().ToString( "N1" ));
              Worker.ReportProgress( 0, " " );
              throw( new Exception( "Testing this." ));
              // return true; // With P and Q.
              }
            // else
              // Worker.ReportProgress( 0, "It was not an exact square root." );

            }
              }

            // P and Q would still be zero if it never found them.
            return false;
        }
Esempio n. 2
0
        // Copyright Eric Chauvin 2015.
        private int ModularReduction( Integer Result, Integer ToReduce )
        {
            try
            {
            if( GeneralBaseArray == null )
              throw( new Exception( "SetupGeneralBaseArray() should have already been called." ));

            Result.SetToZero();

            int HowManyToAdd = ToReduce.GetIndex() + 1;
            if( HowManyToAdd > GeneralBaseArray.Length )
              throw( new Exception( "Bug. The Input number should have been reduced first. HowManyToAdd > GeneralBaseArray.Length" ));

            int BiggestIndex = 0;
            for( int Count = 0; Count < HowManyToAdd; Count++ )
              {
              // The size of the numbers in GeneralBaseArray are
              // all less than the size of GeneralBase.
              // This multiplication by a uint is with a number
              // that is not bigger than GeneralBase.  Compare
              // this with the two full Muliply() calls done on
              // each digit of the quotient in LongDivide3().

              // AccumulateBase is set to a new value here.
              int CheckIndex = IntMath.MultiplyUIntFromCopy( AccumulateBase, GeneralBaseArray[Count], ToReduce.GetD( Count ));

              if( CheckIndex > BiggestIndex )
            BiggestIndex = CheckIndex;

              Result.Add( AccumulateBase );
              }

            return Result.GetIndex();
            }
            catch( Exception Except )
              {
              throw( new Exception( "Exception in ModularReduction(): " + Except.Message ));
              }
        }
Esempio n. 3
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 ));
              }
        }
        internal void GetTraditionalInteger( Integer BigBase,
                                       Integer BasePart,
                                       Integer ToTest,
                                       Integer Accumulate )
        {
            // This takes several seconds for a large number.
            try
            {
            // The first few numbers for the base:
            // 2             2
            // 3             6
            // 5            30
            // 7           210
            // 11        2,310
            // 13       30,030
            // 17      510,510
            // 19    9,699,690
            // 23  223,092,870

            // This first one has the prime 2 as its base so it's going to
            // be set to either zero or one.
            Accumulate.SetFromULong( (uint)DigitsArray[0].Value );
            BigBase.SetFromULong( 2 );

            // Count starts at 1, so it's the prime 3.
            for( int Count = 1; Count < DigitsArraySize; Count++ )
              {
              for( uint CountPrime = 0; CountPrime < DigitsArray[Count].Prime; CountPrime++ )
            {
            ToTest.Copy( BigBase );
            IntMath.MultiplyUInt( ToTest, CountPrime );
            // Notice that the first time through this loop it's zero, so the
            // base part isn't added if it's already congruent to the Value.
            // So even though it goes all the way up through the DigitsArray,
            // this whole thing could add up to a small number like 7.
            // Compare this part with how GetMod32() is used in
            // SetFromTraditionalInteger().  And also, compare this with how
            // IntegerMath.NumberIsDivisibleByUInt() works.
            BasePart.Copy( ToTest );
            ToTest.Add( Accumulate );
            // If it's congruent to the Value mod Prime then it's the right number.
            if( (uint)DigitsArray[Count].Value == IntMath.GetMod32( ToTest, (uint)DigitsArray[Count].Prime ))
              {
              Accumulate.Add( BasePart );
              break;
              }
            }

              // The Integers have to be big enough to multiply this base.
              IntMath.MultiplyUInt( BigBase, (uint)DigitsArray[Count].Prime );
              }

            // Returns with Accumulate for the value.

            }
            catch( Exception Except )
              {
              throw( new Exception( "Exception in GetTraditionalInteger(): " + Except.Message ));
              }
        }
 private void CalculateLastAccumulatePart( Integer Accumulate )
 {
     try
     {
     Accumulate.Copy( LastAccumulateValue );
     uint CurrentBase = QuadResDigitsArray[DigitsArrayLength - 1].Base;
     // uint AccumulateDigit = GetMod32( Accumulate, CurrentBase );
     int DigitsIndex = QuadResDigitsArray[DigitsArrayLength - 1].DigitIndex;
     uint CountB = QuadResDigitsArray[DigitsArrayLength - 1].MatchingInverseArray[DigitsIndex, LastAccumulateDigit];
     GetValueBasePart.Copy( QuadResDigitsArray[DigitsArrayLength - 1].BigBase );
     IntMath.MultiplyUInt( GetValueBasePart, CountB );
     Accumulate.Add( GetValueBasePart );
     }
     catch( Exception Except )
       {
       throw( new Exception( "Exception in CalculateLastAccumulatePart(): " + Except.Message ));
       }
 }
        internal bool FindTheFactors()
        {
            MakeQuadResToPrimesArray();
            if( Worker.CancellationPending )
              return false;

            // ===========
            MakeQuadResDigitsArrayRec( 0, 0, 7 );
            MakeQuadResDigitsArrayRec( 1, 8, 9 );
            MakeQuadResDigitsArrayRec( 2, 10, 10 );
            // The last one should have an array that is
            // as large as possible because of
            // IncrementDigitsWithBitTest().
            MakeQuadResDigitsArrayRec( 3, 11, 12 );
            if( Worker.CancellationPending )
              return false;

            SetupBaseValues();
            if( Worker.CancellationPending )
              return false;

            MakeMatchingInverseArrays();
            if( Worker.CancellationPending )
              return false;

            Worker.ReportProgress( 0, "After MakeMatchingInverseArrays()." );

            Integer X = new Integer();
            Integer XSquared = new Integer();
            Integer SqrRoot = new Integer();
            Integer YSquared = new Integer();

            MakeGoodXBitsArray();
            Worker.ReportProgress( 0, "After MakeGoodXBitsArray();." );

            uint Loops = 0;
            while( true )
              {
              if( Worker.CancellationPending )
            return false;

              Loops++;
              if( (Loops & 0x3FFFFF) == 0 )
            {
            Worker.ReportProgress( 0, "Loops: " + Loops.ToString());
            }

              GetIntegerValue( X );
              if( !IsInGoodXBitsArray( (uint)X.GetD( 0 )))
            {
            // This happens with the increment bit test
            // because sometimes it just increments to the
            // next full accumulated value.

            if( !IncrementDigitsWithBitTest())
              {
              Worker.ReportProgress( 0, "Incremented to the end." );
              return false;
              }

            continue;
            }

              if( !IsGoodXForAllPrimes( X ))
            {
            if( !IncrementDigitsWithBitTest())
              {
              Worker.ReportProgress( 0, "Incremented to the end." );
              return false;
              }

            continue;
            }

              XSquared.Copy( X );
              IntMath.DoSquare( XSquared );
              YSquared.Copy( Product );
              YSquared.Add( XSquared );

              if( IntMath.SquareRoot( YSquared, SqrRoot ))
            {
            return IsSolution( X, SqrRoot );
            }

              if( !IncrementDigitsWithBitTest())
            {
            Worker.ReportProgress( 0, "Incremented to the end." );
            return false;
            }
              }
        }
Esempio n. 7
0
        internal void Add( Integer Result, Integer ToAdd )
        {
            if( ToAdd.IsZero())
              return;

            // The most common form.  They are both positive.
            if( !Result.IsNegative && !ToAdd.IsNegative )
              {
              Result.Add( ToAdd );
              return;
              }

            if( !Result.IsNegative && ToAdd.IsNegative )
              {
              TempAdd1.Copy( ToAdd );
              TempAdd1.IsNegative = false;
              if( TempAdd1.ParamIsGreater( Result ))
            {
            Subtract( Result, TempAdd1 );
            return;
            }
              else
            {
            Subtract( TempAdd1, Result );
            Result.Copy( TempAdd1 );
            Result.IsNegative = true;
            return;
            }
              }

            if( Result.IsNegative && !ToAdd.IsNegative )
              {
              TempAdd1.Copy( Result );
              TempAdd1.IsNegative = false;
              TempAdd2.Copy( ToAdd );

              if( TempAdd1.ParamIsGreater( TempAdd2 ))
            {
            Subtract( TempAdd2, TempAdd1 );
            Result.Copy( TempAdd2 );
            return;
            }
              else
            {
            Subtract( TempAdd1, TempAdd2 );
            Result.Copy( TempAdd2 );
            Result.IsNegative = true;
            return;
            }
              }

            if( Result.IsNegative && ToAdd.IsNegative )
              {
              TempAdd1.Copy( Result );
              TempAdd1.IsNegative = false;
              TempAdd2.Copy( ToAdd );
              TempAdd2.IsNegative = false;
              TempAdd1.Add( TempAdd2 );
              Result.Copy( TempAdd1 );
              Result.IsNegative = true;
              return;
              }
        }
        // See CRTMath.GetTraditionalInteger() for more on how this works.
        internal void GetIntegerValue( Integer Accumulate )
        {
            try
            {
            if( LastIncrementIndex == (QuadResDigitsArray.Length - 1))
              {
              CalculateLastAccumulatePart( Accumulate );
              return;
              }

            int DigitIndex = QuadResDigitsArray[0].DigitIndex;
            Accumulate.SetFromULong( QuadResDigitsArray[0].DigitsArray[DigitIndex] );

            // Count starts at 1, so it's the base at 1.
            for( int Count = 1; Count < DigitsArrayLength; Count++ )
              {
              uint CurrentBase = QuadResDigitsArray[Count].Base;
              uint AccumulateDigit = (uint)IntMath.GetMod32( Accumulate, CurrentBase );
              DigitIndex = QuadResDigitsArray[Count].DigitIndex;
              uint CountB = QuadResDigitsArray[Count].MatchingInverseArray[DigitIndex, AccumulateDigit];
              GetValueBasePart.Copy( QuadResDigitsArray[Count].BigBase );
              IntMath.MultiplyUInt( GetValueBasePart, CountB );
              Accumulate.Add( GetValueBasePart );

              if( Count == (QuadResDigitsArray.Length - 2))
            {
            LastAccumulateValue.Copy( Accumulate );

            int Index = QuadResDigitsArray.Length - 1;
            CurrentBase = QuadResDigitsArray[Index].Base;
            LastAccumulateDigit = GetMod32( LastAccumulateValue, CurrentBase );
            LastAccumulateBottomDigit = (uint)LastAccumulateValue.GetD( 0 );
            }
              }
            }
            catch( Exception Except )
              {
              throw( new Exception( "Exception in GetIntegerValue(): " + Except.Message ));
              }
        }
Esempio n. 9
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;
              }
        }
Esempio n. 10
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 ));
              Multiply( OnePart, Tens );
              Result.Add( OnePart );
              MultiplyULong( Tens, 10 );
              }
        }
Esempio n. 11
0
        internal void GetTraditionalInteger( CRTBase ToGetFrom, Integer ToSet )
        {
            try
            {
            if( CRTBaseArray == null )
              throw( new Exception( "Bug: The BaseArray should have been set up already." ));

            // This first one has the prime 2 as its base so
            // it's going to be set to either zero or one.
            if( ToGetFrom.GetDigitAt( 0 ) == 1 )
              ToSet.SetToOne();
            else
              ToSet.SetToZero();

            Integer WorkingBase = new Integer();
            for( int Count = 1; Count < ChineseRemainder.DigitsArraySize; Count++ )
              {
              int BaseMult = ToGetFrom.GetDigitAt( Count );
              WorkingBase.Copy( BaseArray[Count] );
              IntMath.MultiplyUInt( WorkingBase, (uint)BaseMult );
              ToSet.Add( WorkingBase );
              }
            }
            catch( Exception Except )
              {
              throw( new Exception( "Exception in GetTraditionalInteger(): " + Except.Message ));
              }
        }
Esempio n. 12
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;
        }
Esempio n. 13
0
        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;
        }