Пример #1
0
        private bool IsQuadResModProduct( uint Prime )
        {
            // Euler's Criterion:
            Integer Exponent = new Integer();
            Integer Result = new Integer();
            Integer Modulus = new Integer();

            Exponent.SetFromULong( Prime );
            IntMath.SubtractULong( Exponent, 1 );
            Exponent.ShiftRight( 1 ); // Divide by 2.

            Result.Copy( Product );
            Modulus.SetFromULong( Prime );

            IntMath.IntMathNew.ModularPower( Result, Exponent, Modulus, false );
            if( Result.IsOne() )
              return true;
            else
              return false; // Result should be Prime - 1.
        }
Пример #2
0
        private void SetupBaseValues()
        {
            try
            {
            Worker.ReportProgress( 0, " " );
            Worker.ReportProgress( 0, "Top of SetupBaseValues()." );

            // MakeQuadResDigitsArrayRec() sets up each record and its base,
            // so that base should already be set in this record.
            if( QuadResDigitsArray[0].Base == 0 )
              throw( new Exception( "Base was zero in SetupBaseValues() at: 0" ));

            Integer BigBase = new Integer();
            BigBase.SetFromULong( QuadResDigitsArray[0].Base );
            QuadResDigitsArray[0].BigBase = new Integer();
            QuadResDigitsArray[0].BigBase.Copy( BigBase );
            // Zero and one have the same base set here.

            // Count starts at 1, so it's the base at 1.
            int QRLength = QuadResDigitsArray.Length;
            for( int Count = 1; Count < QRLength; Count++ )
              {
              if( QuadResDigitsArray[Count].Base == 0 )
            throw( new Exception( "Base was zero in SetupBaseValues() at: " + Count.ToString() ));

              QuadResDigitsArray[Count].BigBase = new Integer();
              QuadResDigitsArray[Count].BigBase.Copy( BigBase );
              QuadResDigitsArray[Count].BigBaseBottomDigit = (uint)BigBase.GetD( 0 );
              QuadResDigitsArray[Count].BigBaseModCurrentBase = (uint)IntMath.GetMod32( QuadResDigitsArray[Count].BigBase, QuadResDigitsArray[Count].Base );

              // Multiply it by the current base for the next loop.
              IntMath.MultiplyUInt( BigBase, QuadResDigitsArray[Count].Base );
              }
            }
            catch( Exception Except )
              {
              throw( new Exception( "Exception in SetupCRTBaseValues(): " + Except.Message ));
              }
        }
Пример #3
0
        internal void SetFromTraditionalInteger( Integer SetFrom )
        {
            try
            {
            SetToZero();

            Integer WorkingCopy = new Integer();
            Integer Factor = new Integer();
            WorkingCopy.Copy( SetFrom );

            while( true )
              {
              // If WorkingCopy was 37, this would return 37, which is
              // the smallest prime in 37.  So dividing this number
              // by 37 would make a Quotient of 1.
              uint Prime = IntMath.IsDivisibleBySmallPrime( WorkingCopy );
              if( Prime == 0 )
            break;

              Factor.SetFromULong( Prime );
              IntMath.Divide( WorkingCopy, Factor, Quotient, Remainder );
              if( !Remainder.IsZero())
            throw( new Exception( "Bug. !Remainder.IsZero() in SetFromTraditionalInteger()." ));

              VectorValueRec Rec = GetVectorElement( Prime );
              Rec.Exponent++;
              UpdateVectorElement( Rec );

              if( Quotient.IsOne())
            return; // It has all the factors and it is B-smooth up to
                // IntegerMath.GetBiggestPrime().

              WorkingCopy.Copy( Quotient );
              }

            // This number is not B-smooth up to IntegerMath.GetBiggestPrime().
            ExtraValue.Copy( WorkingCopy );

            }
            catch( Exception Except )
              {
              throw( new Exception( "Exception in ExponentVectorNumber.SetFromTraditionalInteger(): " + Except.Message ));
              }
        }
Пример #4
0
        // 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 ));
              }
        }
Пример #5
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;
        }
Пример #6
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." ));
        }
Пример #7
0
        // These bottom digits are 0 for each prime that gets
        // multiplied by the base.  So they keep getting one
        // more zero at the bottom of each one.
        // But the digits in BaseModArray only have the zeros
        // at the bottom on the ones that are smaller than the
        // modulus.
        // At BaseArray[0] it's 1, 1, 1, 1, 1, .... for all of them.
        // 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0
        // 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 0, 0
        // 30, 30, 30, 30, 1, 7, 11, 13, 4, 8, 2, 0, 0, 0
        private void SetupBaseArray()
        {
            // 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

            try
            {
            if( NumbersArray == null )
              throw( new Exception( "NumbersArray should have already been setup in SetupBaseArray()." ));

            BaseStringsArray = new string[ChineseRemainder.DigitsArraySize];
            BaseArray = new Integer[ChineseRemainder.DigitsArraySize];
            CRTBaseArray = new ChineseRemainder[ChineseRemainder.DigitsArraySize];

            Integer SetBase = new Integer();
            ChineseRemainder CRTSetBase = new ChineseRemainder( IntMath );

            Integer BigBase = new Integer();
            ChineseRemainder CRTBigBase = new ChineseRemainder( IntMath );

            BigBase.SetFromULong( 2 );
            CRTBigBase.SetFromUInt( 2 );
            string BaseS = "2";

            SetBase.SetToOne();
            CRTSetBase.SetToOne();

            // The base at zero is 1.
            BaseArray[0] = SetBase;
            CRTBaseArray[0] = CRTSetBase;
            BaseStringsArray[0] = "1";

            ChineseRemainder CRTTemp = new ChineseRemainder( IntMath );

            // The first time through the loop the base
            // is set to 2.
            // So BaseArray[0] = 1;
            // So BaseArray[1] = 2;
            // So BaseArray[2] = 6;
            // So BaseArray[3] = 30;
            // And so on...
            // In BaseArray[3] digits at 2, 3 and 5 are set to zero.
            // In BaseArray[4] digits at 2, 3, 5 and 7 are set to zero.
            for( int Count = 1; Count < ChineseRemainder.DigitsArraySize; Count++ )
              {
              SetBase = new Integer();
              CRTSetBase = new ChineseRemainder( IntMath );

              SetBase.Copy( BigBase );
              CRTSetBase.Copy( CRTBigBase );

              BaseStringsArray[Count] = BaseS;
              BaseArray[Count] = SetBase;
              CRTBaseArray[Count] = CRTSetBase;
              // if( Count < 50 )
            // Worker.ReportProgress( 0, CRTBaseArray[Count].GetString() );

              if( !IsEqualToInteger( CRTBaseArray[Count],
                             BaseArray[Count] ))
            throw( new Exception( "Bug.  The bases aren't equal." ));

              // Multiply it for the next BigBase.
              uint Prime = IntMath.GetPrimeAt( Count );
              BaseS = BaseS + "*" + Prime.ToString();
              IntMath.MultiplyUInt( BigBase, Prime );
              CRTBigBase.Multiply( NumbersArray[IntMath.GetPrimeAt( Count )] );
              }
            }
            catch( Exception Except )
              {
              throw( new Exception( "Exception in SetupBaseArray(): " + 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 ));
              }
        }
Пример #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 );
        }
Пример #10
0
        // CRTBaseModArray doesn't have the pattern of zeros
        // down to the end like in CRTBaseArray.
        internal void SetupBaseModArray( Integer Modulus )
        {
            try
            {
            BaseModArrayModulus = Modulus;

            if( NumbersArray == null )
              throw( new Exception( "NumbersArray should have already been setup in SetupBaseModArray()." ));

            CRTBaseModArray = new ChineseRemainder[ChineseRemainder.DigitsArraySize];

            ChineseRemainder CRTSetBase = new ChineseRemainder( IntMath );

            Integer BigBase = new Integer();
            ChineseRemainder CRTBigBase = new ChineseRemainder( IntMath );

            BigBase.SetFromULong( 2 );
            CRTBigBase.SetFromUInt( 2 );

            CRTSetBase.SetToOne();
            CRTBaseModArray[0] = CRTSetBase;

            ChineseRemainder CRTTemp = new ChineseRemainder( IntMath );

            for( int Count = 1; Count < ChineseRemainder.DigitsArraySize; Count++ )
              {
              CRTSetBase = new ChineseRemainder( IntMath );
              CRTSetBase.Copy( CRTBigBase );
              CRTBaseModArray[Count] = CRTSetBase;

              // Multiply it for the next BigBase.
              IntMath.MultiplyUInt( BigBase, IntMath.GetPrimeAt( Count ));
              IntMath.Divide( BigBase, Modulus, Quotient, Remainder );
              BigBase.Copy( Remainder );
              CRTBigBase.SetFromTraditionalInteger( BigBase );
              }
            }
            catch( Exception Except )
              {
              throw( new Exception( "Exception in SetupBaseModArray(): " + Except.Message ));
              }
        }
Пример #11
0
        private void DoBaseLoop()
        {
            Worker.ReportProgress( 0, " " );
            Worker.ReportProgress( 0, "Top of DoBaseLoop." );

            Integer Left = new Integer();
            Integer B = new Integer();
            Integer Temp = new Integer();
            B.SetFromULong( Base );
            uint ProdMod = (uint)IntMath.GetMod32( Product, Base );
            int Loops = 0;
            for( ulong CountP = 0; CountP < (17 * 19); CountP++ )
              {
              if( Worker.CancellationPending )
            return;

              ulong BasePartP = SmallBase * CountP;
              for( int IndexP = 0; IndexP < EulerPhi; IndexP++ )
            {
            if( Worker.CancellationPending )
              return;

            ulong A = BasePartP + SmallPairsP[IndexP];

            if( (A % 17) == 0 )
              continue;

            if( (A % 19) == 0 )
              continue;

            for( ulong CountQ = 0; CountQ < (17 * 19); CountQ++ )
              {
              // Worker.ReportProgress( 0, "CountQ: " + CountQ.ToString());

              if( Worker.CancellationPending )
            return;

              ulong BasePartQ = SmallBase * CountQ;
              for( int IndexQ = 0; IndexQ < EulerPhi; IndexQ++ )
            {
            if( Worker.CancellationPending )
              return;

            ulong C = BasePartQ + SmallPairsQ[IndexQ];

            if( (C % 17) == 0 )
              continue;

            if( (C % 19) == 0 )
              continue;

            ulong Test = A * C;
            Test = Test % Base;
            if( Test != ProdMod )
              continue;

            // The number of loops that get here is BiggerEulerPhi.
            Loops++;
            // if( (Loops & 0x7F) == 0 )
              Worker.ReportProgress( 0, "Loops: " + Loops.ToString( "N0" ) + " out of " + BiggerEulerPhi.ToString( "N0" ));

            if( Loops > 100 )
              return;

            Temp.SetFromULong( A * C );
            // This could happen with small test numbers.
            if( Product.ParamIsGreater( Temp ))
              continue;

            // This could happen with small test numbers.
            if( A != 1 )
              {
              Temp.SetFromULong( A );
              IntMath.Divide( Product, Temp, Quotient, Remainder );
              if( Remainder.IsZero())
                {
                SolutionP.SetFromULong( A );
                SolutionQ.Copy( Quotient );
                return;
                }
              }

            // This could happen with small test numbers.
            if( C != 1 )
              {
              Temp.SetFromULong( C );
              IntMath.Divide( Product, Temp, Quotient, Remainder );
              if( Remainder.IsZero())
                {
                SolutionP.SetFromULong( C );
                SolutionQ.Copy( Quotient );
                return;
                }
              }

            FindFactorsFromLeft( A, C, Left, Temp, B );
            if( !SolutionP.IsZero())
              return;

            }
              }
            }
              }
        }
Пример #12
0
        internal RSACryptoSystem( BackgroundWorker UseWorker, RSACryptoWorkerInfo UseWInfo )
        {
            Worker = UseWorker;
            WorkerInfo = UseWInfo;
            StartTime = new ECTime();
            StartTime.SetToNow();

            RngCsp = new RNGCryptoServiceProvider();
            IntMath = new IntegerMath();
            IntMathNewForP = new IntegerMathNew( IntMath );
            IntMathNewForQ = new IntegerMathNew( IntMath );

            Worker.ReportProgress( 0, IntMath.GetStatusString() );
            Quotient = new Integer();
            Remainder = new Integer();
            PrimeP = new Integer();
            PrimeQ = new Integer();
            PrimePMinus1 = new Integer();
            PrimeQMinus1 = new Integer();
            PubKeyN = new Integer();
            PubKeyExponent = new Integer();
            PrivKInverseExponent = new Integer();
            PrivKInverseExponentDP = new Integer();
            PrivKInverseExponentDQ = new Integer();
            QInv = new Integer();
            PhiN = new Integer();
            TestForDecrypt = new Integer();
            M1ForInverse = new Integer();
            M2ForInverse = new Integer();
            HForQInv = new Integer();
            M1MinusM2 = new Integer();
            M1M2SizeDiff = new Integer();

            PubKeyExponent.SetFromULong( PubKeyExponentUint );
        }
Пример #13
0
        private void DoCRTTest( Integer StartingNumber )
        {
            CRTMath CRTMath1 = new CRTMath( Worker );
            ECTime CRTTestTime = new ECTime();
            ChineseRemainder CRTTest = new ChineseRemainder( IntMath );
            ChineseRemainder CRTTest2 = new ChineseRemainder( IntMath );
            ChineseRemainder CRTAccumulate = new ChineseRemainder( IntMath );
            ChineseRemainder CRTToTest = new ChineseRemainder( IntMath );
            ChineseRemainder CRTTempEqual = new ChineseRemainder( IntMath );
            ChineseRemainder CRTTestEqual = new ChineseRemainder( IntMath );
            Integer BigBase = new Integer();
            Integer ToTest = new Integer();
            Integer Accumulate = new Integer();
            Integer Test1 = new Integer();
            Integer Test2 = new Integer();

            CRTTest.SetFromTraditionalInteger( StartingNumber );
            // If the digit array size isn't set right in relation to
            // Integer.DigitArraySize then it can cause an error here.
            CRTMath1.GetTraditionalInteger( Accumulate, CRTTest );

            if( !Accumulate.IsEqual( StartingNumber ))
              throw( new Exception( "  !Accumulate.IsEqual( Result )." ));

            CRTTestEqual.SetFromTraditionalInteger( Accumulate );
            if( !CRTMath1.IsEqualToInteger( CRTTestEqual, Accumulate ))
              throw( new Exception( "IsEqualToInteger() didn't work." ));

            // Make sure it works with even numbers too.
            Test1.Copy( StartingNumber );
            Test1.SetD( 0, Test1.GetD( 0 ) & 0xFE );
            CRTTest.SetFromTraditionalInteger( Test1 );
            CRTMath1.GetTraditionalInteger( Accumulate, CRTTest );

            if( !Accumulate.IsEqual( Test1 ))
              throw( new Exception( "For even numbers.  !Accumulate.IsEqual( Test )." ));
            ////////////

            // Make sure the size of this works with the Integer size because
            // an overflow is hard to find.
            CRTTestTime.SetToNow();
            Test1.SetToMaxValueForCRT();
            CRTTest.SetFromTraditionalInteger( Test1 );
            CRTMath1.GetTraditionalInteger( Accumulate, CRTTest );

            if( !Accumulate.IsEqual( Test1 ))
              throw( new Exception( "For the max value. !Accumulate.IsEqual( Test1 )." ));

            // Worker.ReportProgress( 0, "CRT Max test seconds: " + CRTTestTime.GetSecondsToNow().ToString( "N1" ));
            // Worker.ReportProgress( 0, "MaxValue: " + IntMath.ToString10( Accumulate ));
            // Worker.ReportProgress( 0, "MaxValue.Index: " + Accumulate.GetIndex().ToString());

            // Multiplicative Inverse test:
            Integer TestDivideBy = new Integer();
            Integer TestProduct = new Integer();
            ChineseRemainder CRTTestDivideBy = new ChineseRemainder( IntMath );
            ChineseRemainder CRTTestProduct = new ChineseRemainder( IntMath );

            TestDivideBy.Copy( StartingNumber );
            TestProduct.Copy( StartingNumber );
            IntMath.Multiply( TestProduct, TestDivideBy );

            CRTTestDivideBy.SetFromTraditionalInteger( TestDivideBy );
            CRTTestProduct.SetFromTraditionalInteger( TestDivideBy );
            CRTTestProduct.Multiply( CRTTestDivideBy );

            CRTMath1.GetTraditionalInteger( Accumulate, CRTTestProduct );

            if( !Accumulate.IsEqual( TestProduct ))
              throw( new Exception( "Multiply test was bad." ));

            IntMath.Divide( TestProduct, TestDivideBy, Quotient, Remainder );
            if( !Remainder.IsZero())
              throw( new Exception( "This test won't work unless it divides it exactly." ));

            ChineseRemainder CRTTestQuotient = new ChineseRemainder( IntMath );
            CRTMath1.MultiplicativeInverse( CRTTestProduct, CRTTestDivideBy, CRTTestQuotient );

            // Yes, multiplicative inverse is the same number
            // as with regular division.
            Integer TestQuotient = new Integer();
            CRTMath1.GetTraditionalInteger( TestQuotient, CRTTestQuotient );
            if( !TestQuotient.IsEqual( Quotient ))
              throw( new Exception( "Modular Inverse in DoCRTTest didn't work." ));

            // Subtract
            Test1.Copy( StartingNumber );
            IntMath.SetFromString( Test2, "12345678901234567890123456789012345" );

            CRTTest.SetFromTraditionalInteger( Test1 );
            CRTTest2.SetFromTraditionalInteger( Test2 );

            CRTTest.Subtract( CRTTest2 );
            IntMath.Subtract( Test1, Test2 );

            CRTMath1.GetTraditionalInteger( Accumulate, CRTTest );

            if( !Accumulate.IsEqual( Test1 ))
              throw( new Exception( "Subtract test was bad." ));

            // Add
            Test1.Copy( StartingNumber );
            IntMath.SetFromString( Test2, "12345678901234567890123456789012345" );

            CRTTest.SetFromTraditionalInteger( Test1 );
            CRTTest2.SetFromTraditionalInteger( Test2 );

            CRTTest.Add( CRTTest2 );
            IntMath.Add( Test1, Test2 );

            CRTMath1.GetTraditionalInteger( Accumulate, CRTTest );

            if( !Accumulate.IsEqual( Test1 ))
              throw( new Exception( "Add test was bad." ));

            /////////
            CRTBaseMath CBaseMath = new CRTBaseMath( Worker, CRTMath1 );

            ChineseRemainder CRTInput = new ChineseRemainder( IntMath );
            CRTInput.SetFromTraditionalInteger( StartingNumber );

            Test1.Copy( StartingNumber );
            IntMath.SetFromString( Test2, "12345678901234567890123456789012345" );
            IntMath.Add( Test1, Test2 );

            Integer TestModulus = new Integer();
            TestModulus.Copy( Test1 );
            ChineseRemainder CRTTestModulus = new ChineseRemainder( IntMath );
            CRTTestModulus.SetFromTraditionalInteger( TestModulus );

            Integer Exponent = new Integer();
            Exponent.SetFromULong( PubKeyExponentUint );

            CBaseMath.ModularPower( CRTInput, Exponent, CRTTestModulus, false );
            IntMath.IntMathNew.ModularPower( StartingNumber, Exponent, TestModulus, false );

            if( !CRTMath1.IsEqualToInteger( CRTInput, StartingNumber ))
              throw( new Exception( "CRTBase ModularPower() didn't work." ));

            CRTBase ExpTest = new CRTBase( IntMath );
            CBaseMath.SetFromCRTNumber( ExpTest, CRTInput );
            CBaseMath.GetExponentForm( ExpTest, 37 );

            // Worker.ReportProgress( 0, "CRT was good." );
        }
Пример #14
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;
        }
Пример #15
0
 private void SetupNumbersArray()
 {
     try
     {
     uint BiggestPrime = IntMath.GetPrimeAt( CRTBase.DigitsArraySize + 1 );
     NumbersArray = new ChineseRemainder[BiggestPrime];
     Integer SetNumber = new Integer();
     for( uint Count = 0; Count < BiggestPrime; Count++ )
       {
       SetNumber.SetFromULong( Count );
       ChineseRemainder CRTSetNumber = new ChineseRemainder( IntMath );
       CRTSetNumber.SetFromTraditionalInteger( SetNumber );
       NumbersArray[Count] = CRTSetNumber;
       }
     }
     catch( Exception Except )
       {
       throw( new Exception( "Exception in SetupNumbersArray(): " + Except.Message ));
       }
 }
Пример #16
0
        internal void TestBigDigits()
        {
            try
            {
            uint Base = 2 * 3 * 5;
            Integer BigBase = new Integer();
            Integer Minus1 = new Integer();
            Integer IntExponent = new Integer();
            Integer IntBase = new Integer();
            Integer Gcd = new Integer();

            BigBase.SetFromULong( Base );
            IntBase.SetFromULong( Base );

            for( uint Count = 2; Count < 200; Count++ )
              {
              // At Count = 2 BigBase will be 100, or 10^2.
              IntMath.MultiplyULong( BigBase, Base );
              uint Exponent = Count + 1;
              IntExponent.SetFromULong( Exponent );
              IntMath.GreatestCommonDivisor( IntBase, IntExponent, Gcd );
              if( !Gcd.IsOne() )
            {
            // ShowStatus( Exponent.ToString() + " has a factor in common with base." );
            continue;
            }

              Minus1.Copy( BigBase );
              IntMath.SubtractULong( Minus1, 1 );

              ShowStatus( " " );
              ulong ModExponent = IntMath.GetMod32( Minus1, Exponent );
              if( ModExponent != 0 )
            ShowStatus( Exponent.ToString() + " is not a prime." );
              else
            ShowStatus( Exponent.ToString() + " might or might not be a prime." );

              uint FirstFactor = IntMath.GetFirstPrimeFactor( Exponent );
              if( (FirstFactor == 0) ||
              (FirstFactor == Exponent))
            {
            ShowStatus( Exponent.ToString() + " is a prime." );
            }
              else
            {
            ShowStatus( Exponent.ToString() + " is composite with a factor of " + FirstFactor.ToString() );
            }
              }

            }
            catch( Exception Except )
              {
              ShowStatus( "Exception in TestDigits()." );
              ShowStatus( Except.Message );
              }
        }
Пример #17
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 );
              }
        }
Пример #18
0
        internal void FindSmallPrimeFactorsOnly( Integer FindFromNotChanged )
        {
            OriginalFindFrom.Copy( FindFromNotChanged );
            FindFrom.Copy( FindFromNotChanged );
            ClearFactorsArray();
            Integer OneFactor;
            OneFactorRec Rec;

            // while( not forever )
            for( int Count = 0; Count < 1000; Count++ )
              {
              if( Worker.CancellationPending )
            return;

              uint SmallPrime = IntMath.IsDivisibleBySmallPrime( FindFrom );
              if( SmallPrime == 0 )
            break; // No more small primes.

              // Worker.ReportProgress( 0, "Found a small prime factor: " + SmallPrime.ToString() );
              OneFactor = new Integer();
              OneFactor.SetFromULong( SmallPrime );
              Rec = new OneFactorRec();
              Rec.Factor = OneFactor;
              Rec.IsDefinitelyAPrime = true;
              AddFactorRec( Rec );
              if( FindFrom.IsULong())
            {
            ulong CheckLast = FindFrom.GetAsULong();
            if( CheckLast == SmallPrime )
              {
              // Worker.ReportProgress( 0, "It only had small prime factors." );
              VerifyFactors();
              return; // It had only small prime factors.
              }
            }

              IntMath.Divide( FindFrom, OneFactor, Quotient, Remainder );
              if( !Remainder.IsZero())
            throw( new Exception( "Bug in FindSmallPrimeFactorsOnly(). Remainder is not zero." ));

              FindFrom.Copy( Quotient );
              if( FindFrom.IsOne())
            throw( new Exception( "Bug in FindSmallPrimeFactorsOnly(). This was already checked for 1." ));

              }

            // Worker.ReportProgress( 0, "One factor was not a small prime." );
            OneFactor = new Integer();
            OneFactor.Copy( FindFrom );
            Rec = new OneFactorRec();
            Rec.Factor = OneFactor;
            AddFactorRec( Rec );

            // Worker.ReportProgress( 0, "No more small primes." );
        }
Пример #19
0
        // This is a variation on ShortDivide that returns the remainder.
        // Also, DivideBy is a ulong.
        internal ulong ShortDivideRem( Integer ToDivideOriginal,
                               ulong DivideByU,
                               Integer Quotient )
        {
            if( ToDivideOriginal.IsULong())
              {
              ulong ToDiv = ToDivideOriginal.GetAsULong();
              ulong Q = ToDiv / DivideByU;
              Quotient.SetFromULong( Q );
              return ToDiv % DivideByU;
              }

            ToDivide.Copy( ToDivideOriginal );
            Quotient.Copy( ToDivide );

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

            for( int Count = Quotient.GetIndex(); Count >= 1; Count-- )
              {
              ulong TwoDigits = ToDivide.GetD( Count );
              TwoDigits <<= 32;
              TwoDigits |= ToDivide.GetD( Count - 1 );

              Quotient.SetD( Count - 1, TwoDigits / DivideByU );
              RemainderU = TwoDigits % DivideByU;

              ToDivide.SetD( Count, 0 );
              ToDivide.SetD( Count - 1, RemainderU );
              }

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

            return RemainderU;
        }
Пример #20
0
        internal void FindAllFactors( Integer FindFromNotChanged )
        {
            // ShowStats(); // So far.

            OriginalFindFrom.Copy( FindFromNotChanged );
            FindFrom.Copy( FindFromNotChanged );

            NumbersTested++;
            ClearFactorsArray();
            Integer OneFactor;
            OneFactorRec Rec;

            // while( not forever )
            for( int Count = 0; Count < 1000; Count++ )
              {
              if( Worker.CancellationPending )
            return;

              uint SmallPrime = IntMath.IsDivisibleBySmallPrime( FindFrom );
              if( SmallPrime == 0 )
            break; // No more small primes.

              // Worker.ReportProgress( 0, "Found a small prime factor: " + SmallPrime.ToString() );
              AddToStats( SmallPrime );
              OneFactor = new Integer();
              OneFactor.SetFromULong( SmallPrime );
              Rec = new OneFactorRec();
              Rec.Factor = OneFactor;
              Rec.IsDefinitelyAPrime = true;
              AddFactorRec( Rec );
              if( FindFrom.IsULong())
            {
            ulong CheckLast = FindFrom.GetAsULong();
            if( CheckLast == SmallPrime )
              {
              Worker.ReportProgress( 0, "It only had small prime factors." );
              VerifyFactors();
              return; // It had only small prime factors.
              }
            }

              IntMath.Divide( FindFrom, OneFactor, Quotient, Remainder );
              if( !Remainder.IsZero())
            throw( new Exception( "Bug in FindAllFactors. Remainder is not zero." ));

              FindFrom.Copy( Quotient );
              if( FindFrom.IsOne())
            throw( new Exception( "Bug in FindAllFactors. This was already checked for 1." ));

              }

            // Worker.ReportProgress( 0, "No more small primes." );

            if( IsFermatPrimeAdded( FindFrom ))
              {
              VerifyFactors();
              return;
              }

            // while( not forever )
            for( int Count = 0; Count < 1000; Count++ )
              {
              if( Worker.CancellationPending )
            return;

              // If FindFrom is a ulong then this will go up to the square root of
              // FindFrom and return zero if it doesn't find it there.  So it can't
              // go up to the whole value of FindFrom.
              uint SmallFactor = NumberIsDivisibleByUInt( FindFrom );
              if( SmallFactor == 0 )
            break;

              // This is necessarily a prime because it was the smallest one found.
              AddToStats( SmallFactor );

              // Worker.ReportProgress( 0, "Found a small factor: " + SmallFactor.ToString( "N0" ));
              OneFactor = new Integer();
              OneFactor.SetFromULong( SmallFactor );
              Rec = new OneFactorRec();
              Rec.Factor = OneFactor;
              Rec.IsDefinitelyAPrime = true; // The smallest factor.  It is necessarily a prime.
              AddFactorRec( Rec );

              IntMath.Divide( FindFrom, OneFactor, Quotient, Remainder );
              if( !Remainder.IsZero())
            throw( new Exception( "Bug in FindAllFactors. Remainder is not zero. Second part." ));

              if( Quotient.IsOne())
            throw( new Exception( "This can't happen here.  It can't go that high." ));

              FindFrom.Copy( Quotient );

              if( IsFermatPrimeAdded( FindFrom ))
            {
            VerifyFactors();
            return;
            }
              }

            if( IsFermatPrimeAdded( FindFrom ))
              {
              VerifyFactors();
              return;
              }

            // If it got this far then it's definitely composite or definitely
            // small enough to factor.
            Integer P = new Integer();
            Integer Q = new Integer();
            bool TestedAllTheWay = FindTwoFactorsWithFermat( FindFrom, P, Q, 0 );

            if( !P.IsZero())
              {
              // Q is necessarily prime because it's bigger than the square root.
              // But P is not necessarily prime.
              // P is the smaller one, so add it first.
              if( IsFermatPrimeAdded( P ))
            {
            Worker.ReportProgress( 0, "P from Fermat method was probably a prime." );
            }
              else
            {
            OneFactor = new Integer();
            OneFactor.Copy( P );
            Rec = new OneFactorRec();
            Rec.Factor = OneFactor;
            Rec.IsDefinitelyNotAPrime = true;
            AddFactorRec( Rec );
            }

              Worker.ReportProgress( 0, "Q is necessarily prime." );
              OneFactor = new Integer();
              OneFactor.Copy( Q );
              Rec = new OneFactorRec();
              Rec.Factor = OneFactor;
              Rec.IsDefinitelyAPrime = true;
              AddFactorRec( Rec );
              }
            else
              {
              // Didn't find any with Fermat.
              OneFactor = new Integer();
              OneFactor.Copy( FindFrom );
              Rec = new OneFactorRec();
              Rec.Factor = OneFactor;
              if( TestedAllTheWay )
            Rec.IsDefinitelyAPrime = true;
              else
            Rec.IsDefinitelyNotAPrime = true;

              AddFactorRec( Rec );
              }

            Worker.ReportProgress( 0, "That's all it could find." );
            VerifyFactors();
        }
Пример #21
0
        internal void Divide( Integer ToDivideOriginal,
                        Integer DivideByOriginal,
                        Integer Quotient,
                        Integer Remainder )
        {
            if( ToDivideOriginal.IsNegative )
              throw( new Exception( "Divide() can't be called with negative numbers." ));

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

            // Returns true if it divides exactly with zero remainder.
            // This first checks for some basics before trying to divide it:

            if( DivideByOriginal.IsZero() )
              throw( new Exception( "Divide() dividing by zero." ));

            ToDivide.Copy( ToDivideOriginal );
            DivideBy.Copy( DivideByOriginal );

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

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

            // At this point DivideBy is smaller than ToDivide.

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

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

            // return LongDivide1( ToDivide, DivideBy, Quotient, Remainder );
            // return LongDivide2( ToDivide, DivideBy, Quotient, Remainder );
            LongDivide3( ToDivide, DivideBy, Quotient, Remainder );
        }
Пример #22
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 );
              }
        }
Пример #23
0
        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 );
        }