internal bool IsEqual( CRTBase ToCheck ) { for( int Count = 0; Count < DigitsArraySize; Count++ ) { if( DigitsArray[Count] != ToCheck.DigitsArray[Count] ) return false; } return true; }
internal bool ParamIsGreater( CRTBase ToCheck ) { for( int Count = DigitsArraySize - 1; Count >= 0; Count-- ) { // Usually a lot of upper values will both be zero until it // gets down to smaller magnitudes. So a 1024-bit number // would go to a Count of about 130 or 131 (depending on what // it's congruent to) to find its first non-zero BaseMultiple // here. if( ToCheck.DigitsArray[Count] == DigitsArray[Count] ) continue; // The first one it finds that's not equal. if( ToCheck.DigitsArray[Count] > DigitsArray[Count] ) return true; if( ToCheck.DigitsArray[Count] < DigitsArray[Count] ) return false; } return false; // It's equal but not greater. }
internal void Copy( CRTBase ToCopy ) { for( int Count = 0; Count < DigitsArraySize; Count++ ) DigitsArray[Count] = ToCopy.DigitsArray[Count]; }
internal void GetExponentForm( CRTBase ToGetFrom, uint BaseVal ) { try { if( CRTBaseArray == null ) throw( new Exception( "Bug: The BaseArray should have been set up already." )); StringBuilder SBuilder = new StringBuilder(); string BaseS = BaseVal.ToString(); // 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 ) SBuilder.Append( "(" + BaseS + "^1) " ); else SBuilder.Append( "(" + BaseS + "^0) " ); Integer WorkingBase = new Integer(); for( int Count = 1; Count < ChineseRemainder.DigitsArraySize; Count++ ) { int BaseMult = ToGetFrom.GetDigitAt( Count ); if( BaseMult == 0 ) continue; // WorkingBase.Copy( BaseArray[Count] ); SBuilder.Append( "(" + BaseS + "^(" + BaseMult.ToString() + "*(" + BaseStringsArray[Count] + "))) " ); // IntMath.MultiplyUInt( WorkingBase, (uint)BaseMult ); // ToSet.Add( WorkingBase ); } Worker.ReportProgress( 0, SBuilder.ToString() ); } catch( Exception Except ) { throw( new Exception( "Exception in GetExponentForm(): " + Except.Message )); } }
internal int SetFromCRTNumber( CRTBase ToSet, ChineseRemainder SetFrom ) { try { if( NumbersArray == null ) throw( new Exception( "Bug: The NumbersArray should have been set up already." )); // ToSet.SetToZero(); // CRTBaseArray[0] is 1. if( SetFrom.GetDigitAt( 0 ) == 1 ) { ToSet.SetToOne(); // 1 times 1 for this base. CRTAccumulateForBaseMultiples.SetToOne(); } else { ToSet.SetToZero(); CRTAccumulateForBaseMultiples.SetToZero(); } int HighestNonZeroDigit = 1; // Count starts at 1, so it's at the prime 3. for( int Count = 1; Count < ChineseRemainder.DigitsArraySize; Count++ ) { int Prime = (int)IntMath.GetPrimeAt( Count ); int AccumulateDigit = CRTAccumulateForBaseMultiples.GetDigitAt( Count ); int CRTInputTestDigit = SetFrom.GetDigitAt( Count ); int BaseDigit = CRTBaseArray[Count].GetDigitAt( Count ); if( BaseDigit == 0 ) throw( new Exception( "This never happens. BaseDigit == 0." )); int BaseMult = CRTInputTestDigit; if( BaseMult < AccumulateDigit ) BaseMult += Prime; BaseMult -= AccumulateDigit; int Inverse = MultInverseArray[Count, BaseDigit]; BaseMult = (BaseMult * Inverse) % Prime; ToSet.SetDigitAt( BaseMult, Count ); if( BaseMult != 0 ) HighestNonZeroDigit = Count; // Notice that this is using CRTBaseArray and not // CRTBaseModArray. // This would be very fast in parallel hardware, // but not in software that has to do each digit // one at a time. CRTAccumulatePart.Copy( CRTBaseArray[Count] ); CRTAccumulatePart.Multiply( NumbersArray[BaseMult] ); CRTAccumulateForBaseMultiples.Add( CRTAccumulatePart ); } return HighestNonZeroDigit; } catch( Exception Except ) { throw( new Exception( "Exception in SetFromCRTNumber(): " + Except.Message )); } }
// Copyright Eric Chauvin. internal void ModularReduction( ChineseRemainder CRTInput, ChineseRemainder CRTAccumulate ) { try { if( NumbersArray == null ) throw( new Exception( "Bug: The NumbersArray should have been set up already." )); if( CRTBaseModArray == null ) throw( new Exception( "Bug: The BaseModArray 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( CRTInput.GetDigitAt( 0 ) == 1 ) { CRTAccumulate.SetToOne(); } else { CRTAccumulate.SetToZero(); } CRTBase CRTBaseInput = new CRTBase( IntMath ); int HowManyToAdd = SetFromCRTNumber( CRTBaseInput, CRTInput ); // Integer Test = new Integer(); // ChineseRemainder CRTTest = new ChineseRemainder( IntMath ); // GetTraditionalInteger( CRTBaseInput, Test ); // CRTTest.SetFromTraditionalInteger( Test ); // if( !CRTTest.IsEqual( CRTInput )) // throw( new Exception( "CRTTest for CRTInput isn't right." )); // Count starts at 1, so it's the prime 3. for( int Count = 1; Count <= HowManyToAdd; Count++ ) { // BaseMultiple is a number that is not bigger // than the prime at this point. (The prime at: // IntMath.GetPrimeAt( Count ).) uint BaseMultiple = (uint)CRTBaseInput.GetDigitAt( Count ); // It uses the CRTBaseModArray here: CRTWorkingTemp.Copy( CRTBaseModArray[Count] ); CRTWorkingTemp.Multiply( NumbersArray[BaseMultiple] ); CRTAccumulate.Add( CRTWorkingTemp ); } } catch( Exception Except ) { throw( new Exception( "Exception in ModularReduction(): " + Except.Message )); } }
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 )); } }
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." ); }