internal FactorBase( QuadResWorkerInfo UseWInfo, BackgroundWorker UseWorker ) { WInfo = UseWInfo; Worker = UseWorker; IntMath = new IntegerMath(); Quotient = new Integer(); Remainder = new Integer(); Product = new Integer(); ProductSqrRoot = new Integer(); EulerExponent = new Integer(); EulerResult = new Integer(); EulerModulus = new Integer(); OneMainFactor = new Integer(); ExpOneMainFactor = new ExponentVectorNumber( IntMath ); StartTime = new ECTime(); StartTime.SetToNow(); IntMath.SetFromString( Product, WInfo.PublicKeyModulus ); IntMath.SquareRoot( Product, ProductSqrRoot ); }
internal void AddDelimString( string ToAdd ) { // string DelimS = IntMath.ToString10( Y ) + "\t" + // ExpNumber.ToDelimString(); string[] SplitS = ToAdd.Split( new Char[] { '\t' } ); if( SplitS.Length < 2 ) return; // MForm.ShowStatus( "Adding: " + ToAdd ); Integer Y = new Integer(); IntMath.SetFromString( Y, SplitS[0] ); ExponentVectorNumber X = new ExponentVectorNumber( IntMath ); X.SetFromDelimString( SplitS[1] ); for( int Count = 0; ; Count++ ) { VectorValueRec Rec = X.GetValueRecordAt( Count ); if( Rec.Prime == 0 ) break; // The one X number is being added as a reference in every // dictionary it belongs to. NumberRec NRec = new NumberRec(); NRec.Y = Y; NRec.X = X; NumberList.Add( NRec ); if( MainDictionary.ContainsKey( Rec.Prime )) { MainDictionary[Rec.Prime].OnePrimeList.Add( NRec ); } else { ListRec LRec = new ListRec(); LRec.OnePrimeList = new List<NumberRec>(); LRec.OnePrimeList.Add( NRec ); MainDictionary[Rec.Prime] = LRec; } } }
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 )); } }
private void MakeFastExpNumber( ExponentVectorNumber ExpNumber ) { ExpNumber.SetToZero(); for( int Count = 0; Count < YBaseToPrimesArrayLast; Count++ ) { uint XValue = YBaseToPrimesArray[Count].YToX[YBaseToPrimesArray[Count].Digit]; if( XValue == 0 ) ExpNumber.AddOneFastVectorElement( YBaseToPrimesArray[Count].Prime ); } }
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; }
// Adding the vectors is the same as multiplying the numbers. internal void Multiply( ExponentVectorNumber ToAdd ) { try { for( int Count = 0; Count < ToAdd.VectorValuesArrayLast; Count++ ) { VectorValueRec ToAddRec = ToAdd.VectorValuesArray[Count]; VectorValueRec Rec = GetVectorElement( ToAddRec.Prime ); Rec.Exponent += ToAddRec.Exponent; UpdateVectorElement( Rec ); } if( !ToAdd.ExtraValue.IsZero()) ExtraValue.Add( ToAdd.ExtraValue ); // Like distributing out the two parts of extra. So // they are added together. // Factors * (Extra1 + Extra2); } catch( Exception Except ) { throw( new Exception( "Exception in ExponentVectorNumber.Multiply(): " + Except.Message )); } }
internal bool IsEqual( ExponentVectorNumber ToTest ) { try { if( ToTest.VectorValuesArrayLast >= VectorValuesArray.Length ) return false; // These have to be in the right sorted order for this to work. for( int Count = 0; Count < VectorValuesArrayLast; Count++ ) { if( VectorValuesArray[Count].Prime != ToTest.VectorValuesArray[Count].Prime ) return false; if( VectorValuesArray[Count].Exponent != ToTest.VectorValuesArray[Count].Exponent ) return false; } return true; } catch( Exception Except ) { throw( new Exception( "Exception in ExponentVectorNumber.IsEqual(): " + Except.Message )); } }
internal void Copy( ExponentVectorNumber ToCopy ) { try { VectorValuesArrayLast = ToCopy.VectorValuesArrayLast; Array.Resize( ref VectorValuesArray, VectorValuesArrayLast + IncreaseArraySizeBy ); for( int Count = 0; Count < VectorValuesArrayLast; Count++ ) VectorValuesArray[Count] = ToCopy.VectorValuesArray[Count]; ExtraValue.Copy( ToCopy.ExtraValue ); } catch( Exception Except ) { throw( new Exception( "Exception in ExponentVectorNumber.Copy(): " + Except.Message )); } }
internal void Add( ExponentVectorNumber ToAdd ) { try { PartAForAdd.SetToOne(); for( int Count = 0; Count < VectorValuesArrayLast; Count++ ) { uint Exponent = VectorValuesArray[Count].Exponent; uint Prime = VectorValuesArray[Count].Prime; for( int ExpCount = 0; ExpCount < Exponent; ExpCount++ ) IntMath.MultiplyULong( PartAForAdd, Prime ); } if( !ExtraValue.IsZero()) IntMath.Multiply( PartAForAdd, ExtraValue ); PartBForAdd.SetToOne(); for( int Count = 0; Count < VectorValuesArrayLast; Count++ ) { uint Exponent = ToAdd.VectorValuesArray[Count].Exponent; uint Prime = ToAdd.VectorValuesArray[Count].Prime; for( int ExpCount = 0; ExpCount < Exponent; ExpCount++ ) IntMath.MultiplyULong( PartBForAdd, Prime ); } if( !ToAdd.ExtraValue.IsZero()) IntMath.Multiply( PartBForAdd, ToAdd.ExtraValue ); PartAForAdd.Add( PartBForAdd ); // This is the bad part: SetFromTraditionalInteger( PartAForAdd ); } catch( Exception Except ) { throw( new Exception( "Exception in ExponentVectorNumber.AddWithNoFactorsInCommon(): " + Except.Message )); } }