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; }
// 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 )); } }
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; } } }
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 )); } }
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; } }
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 ); } }
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 )); } }
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; }