示例#1
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 ));
              }
        }
示例#2
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 ));
              }
        }
示例#3
0
        internal void ModularPower( ChineseRemainder CRTResult,
                              Integer Exponent,
                              ChineseRemainder CRTModulus,
                              bool UsePresetBaseArray )
        {
            // The square and multiply method is in Wikipedia:
            // https://en.wikipedia.org/wiki/Exponentiation_by_squaring

            if( Worker.CancellationPending )
              return;

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

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

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

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

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

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

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

            if( !UsePresetBaseArray )
              SetupBaseModArray( Modulus );

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

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

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

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

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

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

            // Division is never used in the loop above.

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

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

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

            Result.Copy( Remainder );
            CRTResult.SetFromTraditionalInteger( Remainder );
        }