Esempio n. 1
0
        /// <summary>
        /// Constructs a new parse tree for an integer literal.
        /// </summary>
        /// <param name="literal">The literal value.</param>
        /// <param name="integerBase">The integer base of the literal.</param>
        /// <param name="typeCharacter">The type character on the literal.</param>
        /// <param name="span">The location of the parse tree.</param>
        public IntegerLiteralExpression(long literal, IntegerBase integerBase, TypeCharacter typeCharacter, Span span) : base(literal, typeCharacter, TreeType.IntegerLiteralExpression, span)
        {
            if (!Enum.IsDefined(typeof(IntegerBase), integerBase))
            {
                throw new ArgumentOutOfRangeException("integerBase");
            }

            _IntegerBase = integerBase;
        }
        /// <summary>
        /// Constructs a new integer literal.
        /// </summary>
        /// <param name="literal">The literal value.</param>
        /// <param name="integerBase">The integer base of the literal.</param>
        /// <param name="typeCharacter">The type character of the literal.</param>
        /// <param name="span">The location of the literal.</param>
        public IntegerLiteralToken(long literal, IntegerBase integerBase, TypeCharacter typeCharacter, Span span) : base(TokenType.IntegerLiteral, literal, span)
        {
            if (!Enum.IsDefined(typeof(IntegerBase), integerBase))
            {
                throw new ArgumentOutOfRangeException("integerBase");
            }

            if (typeCharacter != TypeCharacter.None && typeCharacter != TypeCharacter.IntegerSymbol && typeCharacter != TypeCharacter.IntegerChar && typeCharacter != TypeCharacter.ShortChar && typeCharacter != TypeCharacter.LongSymbol && typeCharacter != TypeCharacter.LongChar)
            {
                throw new ArgumentOutOfRangeException("typeCharacter");
            }

            _IntegerBase   = integerBase;
            _TypeCharacter = typeCharacter;
        }
Esempio n. 3
0
        public static LimitedIntegerToken Parse(string value, IntegerBase numBase, IntegerBitWidth bitWidth, bool isSigned, bool isNeg, string rawToken, SourcePosition position, IConfiguration configuration)
        {
            BigInteger val;

            switch (numBase)
            {
            case IntegerBase.Binary: val = value.Replace("b", "").Replace("B", "").BigIntegerFromBinary(); break;

            case IntegerBase.Octal: val = value.Replace("o", "").Replace("O", "").BigIntegerFromOctal(); break;

            case IntegerBase.Decimal: val = BigInteger.Parse(value, NumberStyles.Integer); break;

            case IntegerBase.Hexadecimal: val = BigInteger.Parse(value.Replace("0x", "00").Replace("0X", "00"), NumberStyles.HexNumber); break;

            default:
                throw new ParseException($"Unhandled integer base {numBase}.");
            }
            return(new LimitedIntegerToken(val, bitWidth, isSigned, isNeg, $"{(isNeg ? "-" : "")}{rawToken}", position, configuration));
        }
Esempio n. 4
0
        internal void MakeRSAKeys()
        {
            int ShowBits = (PrimeIndex + 1) * 32;
            // int TestLoops = 0;

            Worker.ReportProgress( 0, "Making RSA keys." );
            Worker.ReportProgress( 0, "Bits size is: " + ShowBits.ToString());

            // ulong Loops = 0;
            while( true )
              {
              if( Worker.CancellationPending )
            return;

              Thread.Sleep( 1 ); // Give up the time slice.  Let other things on the server run.

              // Make two prime factors.
              // Normally you'd only make new primes when you pay the Certificate
              // Authority for a new certificate.
              if( !MakeAPrime( PrimeP, PrimeIndex, 20 ))
            return;

              IntegerBase TestP = new IntegerBase();
              IntegerBaseMath IntBaseMath = new IntegerBaseMath( IntMath );
              string TestS = IntMath.ToString10( PrimeP );
              IntBaseMath.SetFromString( TestP, TestS );
              string TestS2 = IntBaseMath.ToString10( TestP );
              if( TestS != TestS2 )
            throw( new Exception( "TestS != TestS2 for IntegerBase." ));

              if( Worker.CancellationPending )
            return;

              if( !MakeAPrime( PrimeQ, PrimeIndex, 20 ))
            return;

              if( Worker.CancellationPending )
            return;

              // This is extremely unlikely.
              Integer Gcd = new Integer();
              IntMath.GreatestCommonDivisor( PrimeP, PrimeQ, Gcd );
              if( !Gcd.IsOne())
            {
            Worker.ReportProgress( 0, "They had a GCD: " + IntMath.ToString10( Gcd ));
            continue;
            }

              if( Worker.CancellationPending )
            return;

              // This would never happen since the public key exponent used here
              // is one of the small primes in the array in IntegerMath that it
              // was checked against.  But it does show here in the code that
              // they have to be co-prime to each other.  And in the future it
              // might be found that the public key exponent has to be much larger
              // than the one used here.
              IntMath.GreatestCommonDivisor( PrimeP, PubKeyExponent, Gcd );
              if( !Gcd.IsOne())
            {
            Worker.ReportProgress( 0, "They had a GCD with PubKeyExponent: " + IntMath.ToString10( Gcd ));
            continue;
            }

              if( Worker.CancellationPending )
            return;

              IntMath.GreatestCommonDivisor( PrimeQ, PubKeyExponent, Gcd );
              if( !Gcd.IsOne())
            {
            Worker.ReportProgress( 0, "2) They had a GCD with PubKeyExponent: " + IntMath.ToString10( Gcd ));
            continue;
            }

              // For Modular Reduction.  This only has to be done
              // once, when P and Q are made.
              IntMathNewForP.SetupGeneralBaseArray( PrimeP );
              IntMathNewForQ.SetupGeneralBaseArray( PrimeQ );

              PrimePMinus1.Copy( PrimeP );
              IntMath.SubtractULong( PrimePMinus1, 1 );
              PrimeQMinus1.Copy( PrimeQ );
              IntMath.SubtractULong( PrimeQMinus1, 1 );

              // These checks should be more thorough.

              if( Worker.CancellationPending )
            return;

              Worker.ReportProgress( 0, "The Index of Prime P is: " + PrimeP.GetIndex().ToString() );
              Worker.ReportProgress( 0, "Prime P:" );
              Worker.ReportProgress( 0, IntMath.ToString10( PrimeP ));
              Worker.ReportProgress( 0, " " );
              Worker.ReportProgress( 0, "Prime Q:" );
              Worker.ReportProgress( 0, IntMath.ToString10( PrimeQ ));
              Worker.ReportProgress( 0, " " );

              PubKeyN.Copy( PrimeP );
              IntMath.Multiply( PubKeyN, PrimeQ );

              Worker.ReportProgress( 0, " " );
              Worker.ReportProgress( 0, "PubKeyN:" );
              Worker.ReportProgress( 0, IntMath.ToString10( PubKeyN ));
              Worker.ReportProgress( 0, " " );

              // Euler's Theorem:
              // https://en.wikipedia.org/wiki/Euler's_theorem
              // if x ≡ y (mod φ(n)),
              // then a^x ≡ a^y (mod n).

              // Euler's Phi function (aka Euler's Totient function) is calculated
              // next.

              // PhiN is made from the two factors: (P - 1)(Q - 1)
              // PhiN is: (P - 1)(Q - 1) = PQ - P - Q + 1
              // If I add (P - 1) to PhiN I get:
              // PQ - P - Q + 1 + (P - 1) = PQ - Q.
              // If I add (Q - 1) to that I get:
              // PQ - Q + (Q - 1) = PQ - 1.
              // (P - 1)(Q - 1) + (P - 1) + (Q - 1) = PQ - 1

              // If (P - 1) and (Q - 1) had a larger GCD then PQ - 1 would have
              // that same factor too.

              IntMath.GreatestCommonDivisor( PrimePMinus1, PrimeQMinus1, Gcd );
              Worker.ReportProgress( 0, "GCD of PrimePMinus1, PrimeQMinus1 is: " + IntMath.ToString10( Gcd ));

              if( !Gcd.IsULong())
            {
            Worker.ReportProgress( 0, "This GCD number is too big: " + IntMath.ToString10( Gcd ));
            continue;
            }
              else
            {
            ulong TooBig = Gcd.GetAsULong();
            // How big of a GCD is too big?
            if( TooBig > 1234567 )
              {
              // (P - 1)(Q - 1) + (P - 1) + (Q - 1) = PQ - 1
              Worker.ReportProgress( 0, "This GCD number is bigger than 1234567: " + IntMath.ToString10( Gcd ));
              continue;
              }
            }

              Integer Temp1 = new Integer();

              PhiN.Copy( PrimePMinus1 );
              Temp1.Copy( PrimeQMinus1 );
              IntMath.Multiply( PhiN, Temp1 );

              Worker.ReportProgress( 0, " " );
              Worker.ReportProgress( 0, "PhiN:" );
              Worker.ReportProgress( 0, IntMath.ToString10( PhiN ));
              Worker.ReportProgress( 0, " " );
              if( Worker.CancellationPending )
            return;

              // In RFC 2437 there are commonly used letters/symbols to represent
              // the numbers used.  So the number e is the public exponent.
              // The number e that is used here is called PubKeyExponentUint = 65537.
              // In the RFC the private key d is the multiplicative inverse of
              // e mod PhiN.  Which is mod (P - 1)(Q - 1).  It's called
              // PrivKInverseExponent here.

              if( !IntMath.IntMathNew.FindMultiplicativeInverseSmall( PrivKInverseExponent, PubKeyExponent, PhiN, Worker ))
            return;

              if( PrivKInverseExponent.IsZero())
            continue;

              Worker.ReportProgress( 0, " " );
              Worker.ReportProgress( 0, "PrivKInverseExponent: " + IntMath.ToString10( PrivKInverseExponent ));

              if( Worker.CancellationPending )
            return;

              // In RFC 2437 it defines a number dP which is the multiplicative
              // inverse, mod (P - 1) of e.  That dP is named PrivKInverseExponentDP here.
              Worker.ReportProgress( 0, " " );
              if( !IntMath.IntMathNew.FindMultiplicativeInverseSmall( PrivKInverseExponentDP, PubKeyExponent, PrimePMinus1, Worker ))
            return;

              Worker.ReportProgress( 0, " " );
              Worker.ReportProgress( 0, "PrivKInverseExponentDP: " + IntMath.ToString10( PrivKInverseExponentDP ));
              if( PrivKInverseExponentDP.IsZero())
            continue;

              // PrivKInverseExponentDP is PrivKInverseExponent mod PrimePMinus1.
              Integer Test1 = new Integer();
              Test1.Copy( PrivKInverseExponent );
              IntMath.Divide( Test1, PrimePMinus1, Quotient, Remainder );
              Test1.Copy( Remainder );
              if( !Test1.IsEqual( PrivKInverseExponentDP ))
            throw( new Exception( "Bug. This does not match the definition of PrivKInverseExponentDP." ));

              if( Worker.CancellationPending )
            return;

              // In RFC 2437 it defines a number dQ which is the multiplicative
              // inverse, mod (Q - 1) of e.  That dQ is named PrivKInverseExponentDQ here.
              Worker.ReportProgress( 0, " " );
              if( !IntMath.IntMathNew.FindMultiplicativeInverseSmall( PrivKInverseExponentDQ, PubKeyExponent, PrimeQMinus1, Worker ))
            return;

              if( PrivKInverseExponentDQ.IsZero())
            continue;

              Worker.ReportProgress( 0, " " );
              Worker.ReportProgress( 0, "PrivKInverseExponentDQ: " + IntMath.ToString10( PrivKInverseExponentDQ ));
              if( Worker.CancellationPending )
            return;

              Test1.Copy( PrivKInverseExponent );
              IntMath.Divide( Test1, PrimeQMinus1, Quotient, Remainder );
              Test1.Copy( Remainder );
              if( !Test1.IsEqual( PrivKInverseExponentDQ ))
            throw( new Exception( "Bug. This does not match the definition of PrivKInverseExponentDQ." ));

              // Make a random number to test encryption/decryption.
              Integer ToEncrypt = new Integer();
              int HowManyBytes = PrimeIndex * 4;
              byte[] RandBytes = MakeRandomBytes( HowManyBytes );
              if( RandBytes == null )
            {
            Worker.ReportProgress( 0, "Error making random bytes in MakeRSAKeys()." );
            return;
            }

              if( !ToEncrypt.MakeRandomOdd( PrimeIndex - 1, RandBytes ))
            {
            Worker.ReportProgress( 0, "Error making random number ToEncrypt." );
            return;
            }

              Integer PlainTextNumber = new Integer();
              PlainTextNumber.Copy( ToEncrypt );

              Worker.ReportProgress( 0, " " );
              Worker.ReportProgress( 0, "Before encrypting number: " + IntMath.ToString10( ToEncrypt ));
              Worker.ReportProgress( 0, " " );

              IntMath.IntMathNew.ModularPower( ToEncrypt, PubKeyExponent, PubKeyN, false );
              if( Worker.CancellationPending )
            return;

              Worker.ReportProgress( 0, IntMath.GetStatusString() );

              Integer CipherTextNumber = new Integer();
              CipherTextNumber.Copy( ToEncrypt );

              Worker.ReportProgress( 0, " " );
              Worker.ReportProgress( 0, "Encrypted number: " + IntMath.ToString10( CipherTextNumber ));
              Worker.ReportProgress( 0, " " );

              ECTime DecryptTime = new ECTime();
              DecryptTime.SetToNow();
              IntMath.IntMathNew.ModularPower( ToEncrypt, PrivKInverseExponent, PubKeyN, false );
              Worker.ReportProgress( 0, "Decrypted number: " + IntMath.ToString10( ToEncrypt ));

              if( !PlainTextNumber.IsEqual( ToEncrypt ))
            {
            throw( new Exception( "PlainTextNumber not equal to unencrypted value." ));
            // Because P or Q wasn't really a prime?
            // Worker.ReportProgress( 0, "PlainTextNumber not equal to unencrypted value." );
            // continue;
            }

              Worker.ReportProgress( 0, " " );
              Worker.ReportProgress( 0, "Decrypt time seconds: " + DecryptTime.GetSecondsToNow().ToString( "N2" ));
              Worker.ReportProgress( 0, " " );
              if( Worker.CancellationPending )
            return;

              // Test the standard optimized way of decrypting:
              if( !ToEncrypt.MakeRandomOdd( PrimeIndex - 1, RandBytes ))
            {
            Worker.ReportProgress( 0, "Error making random number in MakeRSAKeys()." );
            return;
            }

              PlainTextNumber.Copy( ToEncrypt );
              IntMath.IntMathNew.ModularPower( ToEncrypt, PubKeyExponent, PubKeyN, false );
              if( Worker.CancellationPending )
            return;

              CipherTextNumber.Copy( ToEncrypt );

              // QInv is the multiplicative inverse of PrimeQ mod PrimeP.
              if( !IntMath.MultiplicativeInverse( PrimeQ, PrimeP, QInv, Worker ))
            throw( new Exception( "MultiplicativeInverse() returned false." ));

              if( QInv.IsNegative )
            throw( new Exception( "This is a bug. QInv is negative." ));

              Worker.ReportProgress( 0, "QInv is: " + IntMath.ToString10( QInv ));

              DecryptWithQInverse( CipherTextNumber,
                           ToEncrypt, // Decrypt it to this.
                           PlainTextNumber, // Test it against this.
                           PubKeyN,
                           PrivKInverseExponentDP,
                           PrivKInverseExponentDQ,
                           PrimeP,
                           PrimeQ,
                           Worker );

              Worker.ReportProgress( 0, " " );
              Worker.ReportProgress( 0, "Found the values:" );
              Worker.ReportProgress( 0, "Seconds: " + StartTime.GetSecondsToNow().ToString( "N0" ));
              Worker.ReportProgress( 0, " " );

              Worker.ReportProgress( 1, "Prime1: " + IntMath.ToString10( PrimeP ));
              Worker.ReportProgress( 0, " " );
              Worker.ReportProgress( 1, "Prime2: " + IntMath.ToString10( PrimeQ ));
              Worker.ReportProgress( 0, " " );
              Worker.ReportProgress( 1, "PubKeyN: " + IntMath.ToString10( PubKeyN ));
              Worker.ReportProgress( 0, " " );
              Worker.ReportProgress( 1, "PrivKInverseExponent: " + IntMath.ToString10( PrivKInverseExponent ));

              /*
              Worker.ReportProgress( 0, " " );
              Worker.ReportProgress( 0, " " );
              Worker.ReportProgress( 0, " " );
              DoCRTTest( PrivKInverseExponent );
              Worker.ReportProgress( 0, "Finished CRT test." );
              Worker.ReportProgress( 0, " " );
              */

              return; // Comment this out to just leave it while( true ) for testing.
              }
        }