Exemple #1
0
            public static unsafe void SquarePositive( BigInteger bi, ref uint[] wkSpace )
            {
                uint[] t = wkSpace;
                wkSpace = bi.data;
                uint[] d = bi.data;
                uint dl = bi.length;
                bi.data = t;

                fixed ( uint* dd = d, tt = t )
                {

                    uint* ttE = tt + t.Length;
                    // Clear the dest
                    for ( uint* ttt = tt; ttt < ttE; ttt++ )
                        *ttt = 0;

                    uint* dP = dd, tP = tt;

                    for ( uint i = 0; i < dl; i++, dP++ )
                    {
                        if ( *dP == 0 )
                            continue;

                        ulong mcarry = 0;
                        uint bi1val = *dP;

                        uint* dP2 = dP + 1, tP2 = tP + 2 * i + 1;

                        for ( uint j = i + 1; j < dl; j++, tP2++, dP2++ )
                        {
                            // j = i + k
                            mcarry += ( ( ulong )bi1val * ( ulong )*dP2 ) + *tP2;

                            *tP2 = ( uint )mcarry;
                            mcarry >>= 32;
                        }

                        if ( mcarry != 0 )
                            *tP2 = ( uint )mcarry;
                    }

                    // Double thread. Inlined for speed.

                    tP = tt;

                    uint x, carry = 0;
                    while ( tP < ttE )
                    {
                        x = *tP;
                        *tP = ( x << 1 ) | carry;
                        carry = x >> ( 32 - 1 );
                        tP++;
                    }
                    if ( carry != 0 )
                        *tP = carry;

                    // Add in the diagnals

                    dP = dd;
                    tP = tt;
                    for ( uint* dE = dP + dl; ( dP < dE ); dP++, tP++ )
                    {
                        ulong val = ( ulong )*dP * ( ulong )*dP + *tP;
                        *tP = ( uint )val;
                        val >>= 32;
                        *( ++tP ) += ( uint )val;
                        if ( *tP < ( uint )val )
                        {
                            uint* tP3 = tP;
                            // Account for the first carry
                            ( *++tP3 )++;

                            // Keep adding until no carry
                            while ( ( *tP3++ ) == 0 )
                                ( *tP3 )++;
                        }

                    }

                    bi.length <<= 1;

                    // Normalize capacity
                    while ( tt[bi.length - 1] == 0 && bi.length > 1 )
                        bi.length--;

                }
            }
Exemple #2
0
 public static BigInteger Divid( BigInteger bi1, BigInteger bi2 )
 {
     return ( bi1 / bi2 );
 }
Exemple #3
0
 public static BigInteger Multiply( BigInteger bi, int i )
 {
     return ( bi * i );
 }
Exemple #4
0
 public static int Modulus( BigInteger bi, int i )
 {
     return ( bi % i );
 }
Exemple #5
0
 public static BigInteger Modulus( BigInteger bi1, BigInteger bi2 )
 {
     return ( bi1 % bi2 );
 }
Exemple #6
0
        /* This is the BigInteger.Parse method I use. This method works
        because BigInteger.ToString returns the input I gave to Parse. */
        public static BigInteger Parse( string number )
        {
            if ( number == null )
                throw new ArgumentNullException("number");

            int i = 0, len = number.Length;
            char c;
            bool digits_seen = false;
            BigInteger val = new BigInteger(0);
            if ( number[i] == '+' )
            {
                i++;
            }
            else if ( number[i] == '-' )
            {
                throw new FormatException(WouldReturnNegVal);
            }

            for ( ; i < len; i++ )
            {
                c = number[i];
                if ( c == '\0' )
                {
                    i = len;
                    continue;
                }
                if ( c >= '0' && c <= '9' )
                {
                    val = val * 10 + ( c - '0' );
                    digits_seen = true;
                }
                else
                {
                    if ( Char.IsWhiteSpace(c) )
                    {
                        for ( i++; i < len; i++ )
                        {
                            if ( !Char.IsWhiteSpace(number[i]) )
                                throw new FormatException();
                        }
                        break;
                    }
                    else
                        throw new FormatException();
                }
            }
            if ( !digits_seen )
                throw new FormatException();
            return val;
        }
Exemple #7
0
        // with names suggested by FxCop 1.30

        public static BigInteger Add( BigInteger bi1, BigInteger bi2 )
        {
            return ( bi1 + bi2 );
        }
Exemple #8
0
        /// <summary>
        ///     Probabilistic prime test based on Rabin-Miller's test
        /// </summary>
        /// <param name="bi" type="BigInteger.BigInteger">
        ///     <para>
        ///         The number to test.
        ///     </para>
        /// </param>
        /// <param name="confidence" type="int">
        ///     <para>
        ///    The number of chosen bases. The test has at least a
        ///    1/4^confidence chance of falsely returning True.
        ///     </para>
        /// </param>
        /// <returns>
        ///    <para>
        ///        True if "this" is a strong pseudoprime to randomly chosen bases.
        ///    </para>
        ///    <para>
        ///        False if "this" is definitely NOT prime.
        ///    </para>
        /// </returns>
        public static bool RabinMillerTest( BigInteger bi, ConfidenceFactor confidence )
        {
            int Rounds = GetSPPRounds(bi, confidence);

            // calculate values of s and thread
            BigInteger p_sub1 = bi - 1;
            int s = p_sub1.LowestSetBit();

            BigInteger t = p_sub1 >> s;

            int bits = bi.BitCount();
            BigInteger a = null;
            BigInteger.ModulusRing mr = new BigInteger.ModulusRing(bi);

            // Applying optimization from HAC section 4.50 (base == 2)
            // not a really random base but an interesting (and speedy) one
            BigInteger b = mr.Pow(2, t);
            if ( b != 1 )
            {
                bool result = false;
                for ( int j = 0; j < s; j++ )
                {
                    if ( b == p_sub1 )
                    {         // a^((2^k)*thread) mod p = p-1 for some 0 <= k <= s-1
                        result = true;
                        break;
                    }

                    b = ( b * b ) % bi;
                }
                if ( !result )
                    return false;
            }

            // still here ? start at round 1 (round 0 was a == 2)
            for ( int round = 1; round < Rounds; round++ )
            {
                while ( true )
                {                   // generate a < n
                    a = BigInteger.GenerateRandom(bits);

                    // make sure "a" is not 0 (and not 2 as we have already tested that)
                    if ( a > 2 && a < bi )
                        break;
                }

                if ( a.GCD(bi) != 1 )
                    return false;

                b = mr.Pow(a, t);

                if ( b == 1 )
                    continue;              // a^thread mod p = 1

                bool result = false;
                for ( int j = 0; j < s; j++ )
                {

                    if ( b == p_sub1 )
                    {         // a^((2^k)*thread) mod p = p-1 for some 0 <= k <= s-1
                        result = true;
                        break;
                    }

                    b = ( b * b ) % bi;
                }

                if ( !result )
                    return false;
            }
            return true;
        }
Exemple #9
0
        public static bool SmallPrimeSppTest( BigInteger bi, ConfidenceFactor confidence )
        {
            int Rounds = GetSPPRounds(bi, confidence);

            // calculate values of s and thread
            BigInteger p_sub1 = bi - 1;
            int s = p_sub1.LowestSetBit();

            BigInteger t = p_sub1 >> s;


            BigInteger.ModulusRing mr = new BigInteger.ModulusRing(bi);

            for ( int round = 0; round < Rounds; round++ )
            {

                BigInteger b = mr.Pow(BigInteger.smallPrimes[round], t);

                if ( b == 1 )
                    continue;              // a^thread mod p = 1

                bool result = false;
                for ( int j = 0; j < s; j++ )
                {

                    if ( b == p_sub1 )
                    {         // a^((2^k)*thread) mod p = p-1 for some 0 <= k <= s-1
                        result = true;
                        break;
                    }

                    b = ( b * b ) % bi;
                }

                if ( result == false )
                    return false;
            }
            return true;
        }
Exemple #10
0
        protected override BigInteger GenerateSearchBase( int bits, object Context )
        {
            if ( Context == null )
                throw new ArgumentNullException("Context");

            BigInteger ret = new BigInteger(( BigInteger )Context);
            ret.SetBit(0);
            return ret;
        }
Exemple #11
0
        private static int GetSPPRounds( BigInteger bi, ConfidenceFactor confidence )
        {
            int bc = bi.BitCount();

            int Rounds;

            // Data from HAC, 4.49
            if ( bc <= 100 )
                Rounds = 27;
            else if ( bc <= 150 )
                Rounds = 18;
            else if ( bc <= 200 )
                Rounds = 15;
            else if ( bc <= 250 )
                Rounds = 12;
            else if ( bc <= 300 )
                Rounds = 9;
            else if ( bc <= 350 )
                Rounds = 8;
            else if ( bc <= 400 )
                Rounds = 7;
            else if ( bc <= 500 )
                Rounds = 6;
            else if ( bc <= 600 )
                Rounds = 5;
            else if ( bc <= 800 )
                Rounds = 4;
            else if ( bc <= 1250 )
                Rounds = 3;
            else
                Rounds = 2;

            switch ( confidence )
            {
                case ConfidenceFactor.ExtraLow:
                    Rounds >>= 2;
                    return Rounds != 0 ? Rounds : 1;
                case ConfidenceFactor.Low:
                    Rounds >>= 1;
                    return Rounds != 0 ? Rounds : 1;
                case ConfidenceFactor.Medium:
                    return Rounds;
                case ConfidenceFactor.High:
                    return Rounds << 1;
                case ConfidenceFactor.ExtraHigh:
                    return Rounds << 2;
                case ConfidenceFactor.Provable:
                    throw new Exception("The Rabin-Miller test can not be executed in a way such that its results are provable");
                default:
                    throw new ArgumentOutOfRangeException("confidence");
            }
        }
Exemple #12
0
            public static BigInteger modInverse( BigInteger bi, BigInteger modulus )
            {
                if ( modulus.length == 1 )
                    return modInverse(bi, modulus.data[0]);

                BigInteger[] p = { 0, 1 };
                BigInteger[] q = new BigInteger[2];    // quotients
                BigInteger[] r = { 0, 0 };             // remainders

                int step = 0;

                BigInteger a = modulus;
                BigInteger b = bi;

                ModulusRing mr = new ModulusRing(modulus);

                while ( b != 0 )
                {

                    if ( step > 1 )
                    {

                        BigInteger pval = mr.Difference(p[0], p[1] * q[0]);
                        p[0] = p[1];
                        p[1] = pval;
                    }

                    BigInteger[] divret = multiByteDivide(a, b);

                    q[0] = q[1];
                    q[1] = divret[0];
                    r[0] = r[1];
                    r[1] = divret[1];
                    a = b;
                    b = divret[1];

                    step++;
                }

                if ( r[0] != 1 )
                    throw ( new ArithmeticException("No inverse!") );

                return mr.Difference(p[0], p[1] * q[0]);

            }
Exemple #13
0
            public static uint modInverse( BigInteger bi, uint modulus )
            {
                uint a = modulus, b = bi % modulus;
                uint p0 = 0, p1 = 1;

                while ( b != 0 )
                {
                    if ( b == 1 )
                        return p1;
                    p0 += ( a / b ) * p1;
                    a %= b;

                    if ( a == 0 )
                        break;
                    if ( a == 1 )
                        return modulus - p0;

                    p1 += ( b / a ) * p0;
                    b %= a;

                }
                return 0;
            }
Exemple #14
0
            /*
             * Never called in BigInteger (and part of a private class)
             *             public static bool Double (uint [] u, int k)
                        {
                            uint x, carry = 0;
                            uint i = 0;
                            while (i < k) {
                                x = u [i];
                                u [i] = (x << 1) | carry;
                                carry = x >> (32 - 1);
                                i++;
                            }
                            if (carry != 0) u [k] = carry;
                            return carry != 0;
                        }*/

            #endregion

            #region Number Theory

            public static BigInteger gcd( BigInteger a, BigInteger b )
            {
                BigInteger x = a;
                BigInteger y = b;

                BigInteger g = y;

                while ( x.length > 1 )
                {
                    g = x;
                    x = y % x;
                    y = g;

                }
                if ( x == 0 )
                    return g;

                // TODO: should we have something here if we can convert to long?

                //
                // Now we can just do it with single precision. I am using the binary gcd method,
                // as it should be faster.
                //

                uint yy = x.data[0];
                uint xx = y % yy;

                int t = 0;

                while ( ( ( xx | yy ) & 1 ) == 0 )
                {
                    xx >>= 1;
                    yy >>= 1;
                    t++;
                }
                while ( xx != 0 )
                {
                    while ( ( xx & 1 ) == 0 )
                        xx >>= 1;
                    while ( ( yy & 1 ) == 0 )
                        yy >>= 1;
                    if ( xx >= yy )
                        xx = ( xx - yy ) >> 1;
                    else
                        yy = ( yy - xx ) >> 1;
                }

                return yy << t;
            }
Exemple #15
0
 /// <summary>
 /// Create new instance of BihInteger
 /// </summary>
 /// <param name="bi"></param>
 public BigInteger( BigInteger bi )
 {
     this.data = ( uint[] )bi.data.Clone();
     this.length = bi.length;
 }
Exemple #16
0
 /// <summary>
 /// Performs primality tests on bi, assumes trial division has been done.
 /// </summary>
 /// <param name="bi">A BigInteger that has been subjected to and passed trial division</param>
 /// <returns>False if bi is composite, true if it may be prime.</returns>
 /// <remarks>The speed of this method is dependent on Confidence</remarks>
 protected bool PostTrialDivisionTests( BigInteger bi )
 {
     return PrimalityTest(bi, this.Confidence);
 }
Exemple #17
0
        //        [CLSCompliant (false)]
#endif
        /// <summary>
        /// Create new instance of BihInteger
        /// </summary>
        /// <param name="bi"></param>
        /// <param name="len"></param>
        public BigInteger( BigInteger bi, uint len )
        {

            this.data = new uint[len];

            for ( uint i = 0; i < bi.length; i++ )
                this.data[i] = bi.data[i];

            this.length = bi.length;
        }
Exemple #18
0
        private void GenerateKeyPair()
        {
            // p and q values should have a capacity of half the strength in bits
            int bitlength = ( ( KeySize + 1 ) >> 1 );
            //            int qbitlength = (KeySize - pbitlength);
            const uint uint_e = 65537;
            e = uint_e; // fixed

            // generate p, prime and (p-1) relatively prime to e
            for ( ; ; )
            {
                p = BigInteger.GeneratePseudoPrime(bitlength);
                if ( p % uint_e != 1 )
                    break;
            }
            // generate a modulus of the required capacity
            for ( ; ; )
            {
                // generate q, prime and (q-1) relatively prime to e,
                // and not equal to p
                for ( ; ; )
                {
                    q = BigInteger.GeneratePseudoPrime(bitlength);
                    if ( ( q % uint_e != 1 ) && ( p != q ) )
                        break;
                }

                // calculate the modulus
                n = p * q;
                if ( n.BitCount() == KeySize )
                    break;

                // if we get here our primes aren'thread big enough, make the largest
                // of the two p and try again
                if ( p < q )
                    p = q;
            }

            BigInteger pSub1 = ( p - 1 );
            BigInteger qSub1 = ( q - 1 );
            BigInteger phi = pSub1 * qSub1;

            //while (phi.GCD(e) != 1) e+=2;

            // calculate the private exponent
            d = e.ModInverse(phi);

            // calculate the CRT factors
            dp = d % pSub1;
            dq = d % qSub1;
            qInv = q.ModInverse(p);

            keypairGenerated = true;
            isCRTpossible = true;

            if ( KeyGenerated != null )
                KeyGenerated(this, null);
        }
Exemple #19
0
        public static BigInteger operator *( BigInteger bi1, BigInteger bi2 )
        {
            if ( bi1 == 0 || bi2 == 0 )
                return 0;

            //
            // Validate pointers
            //
            if ( bi1.data.Length < bi1.length )
                throw new IndexOutOfRangeException("bi1 out of range");
            if ( bi2.data.Length < bi2.length )
                throw new IndexOutOfRangeException("bi2 out of range");

            BigInteger ret = new BigInteger(Sign.Positive, bi1.length + bi2.length);

            Kernel.Multiply(bi1.data, 0, bi1.length, bi2.data, 0, bi2.length, ret.data, 0);

            ret.Normalize();
            return ret;
        }
Exemple #20
0
        public override byte[] DecryptValue( byte[] rgb )
        {
            if ( m_disposed )
                throw new ObjectDisposedException("private key");

            // decrypt operation is used for signature
            if ( !keypairGenerated )
                GenerateKeyPair();

            BigInteger input = new BigInteger(rgb);
            BigInteger r = null;

            // we use key blinding (by default) against timing attacks
            if ( keyBlinding )
            {
                // x = (r^e * g) mod n
                // *new* random number (so it's timing is also random)
                r = BigInteger.GenerateRandom(n.BitCount());
                input = r.ModPow(e, n) * input % n;
            }

            BigInteger output;
            // decrypt (which uses the private key) can be
            // optimized by using CRT (Chinese Remainder Theorem)
            if ( isCRTpossible )
            {
                // m1 = c^dp mod p
                BigInteger m1 = input.ModPow(dp, p);
                // m2 = c^dq mod q
                BigInteger m2 = input.ModPow(dq, q);
                BigInteger h;
                if ( m2 > m1 )
                {
                    // thanks to benm!
                    h = p - ( ( m2 - m1 ) * qInv % p );
                    output = m2 + q * h;
                }
                else
                {
                    // h = (m1 - m2) * qInv mod p
                    h = ( m1 - m2 ) * qInv % p;
                    // m = m2 + q * h;
                    output = m2 + q * h;
                }
            }
            else
            {
                // m = c^i mod n
                output = input.ModPow(d, n);
            }

            if ( keyBlinding )
            {
                // Complete blinding
                // x^e / r mod n
                output = output * r.ModInverse(n) % n;
                r.Clear();
            }

            byte[] result = output.GetBytes();
            // zeroize values
            input.Clear();
            output.Clear();
            return result;
        }
Exemple #21
0
 public static BigInteger Subtract( BigInteger bi1, BigInteger bi2 )
 {
     return ( bi1 - bi2 );
 }
Exemple #22
0
        public override byte[] EncryptValue( byte[] rgb )
        {
            if ( m_disposed )
                throw new ObjectDisposedException("public key");

            if ( !keypairGenerated )
                GenerateKeyPair();

            BigInteger input = new BigInteger(rgb);
            BigInteger output = input.ModPow(e, n);
            byte[] result = output.GetBytes();
            // zeroize value
            input.Clear();
            output.Clear();
            return result;
        }
Exemple #23
0
        //        [CLSCompliant (false)]
#endif

        public static uint Modulus( BigInteger bi, uint ui )
        {
            return ( bi % ui );
        }
Exemple #24
0
        public override void ImportParameters( RSAParameters parameters )
        {
            if ( m_disposed )
                throw new ObjectDisposedException("");

            // if missing "mandatory" parameters
            if ( parameters.Exponent == null )
                throw new CryptographicException("Missing Exponent");
            if ( parameters.Modulus == null )
                throw new CryptographicException("Missing Modulus");

            e = new BigInteger(parameters.Exponent);
            n = new BigInteger(parameters.Modulus);
            // only if the private key is present
            if ( parameters.D != null )
                d = new BigInteger(parameters.D);
            if ( parameters.DP != null )
                dp = new BigInteger(parameters.DP);
            if ( parameters.DQ != null )
                dq = new BigInteger(parameters.DQ);
            if ( parameters.InverseQ != null )
                qInv = new BigInteger(parameters.InverseQ);
            if ( parameters.P != null )
                p = new BigInteger(parameters.P);
            if ( parameters.Q != null )
                q = new BigInteger(parameters.Q);

            // we now have a keypair
            keypairGenerated = true;
            isCRTpossible = ( ( p != null ) && ( q != null ) && ( dp != null ) && ( dq != null ) && ( qInv != null ) );
        }
Exemple #25
0
 public static BigInteger Divid( BigInteger bi, int i )
 {
     return ( bi / i );
 }
Exemple #26
0
        protected override void Dispose( bool disposing )
        {
            if ( !m_disposed )
            {
                // Always zeroize private key
                if ( d != null )
                {
                    d.Clear();
                    d = null;
                }
                if ( p != null )
                {
                    p.Clear();
                    p = null;
                }
                if ( q != null )
                {
                    q.Clear();
                    q = null;
                }
                if ( dp != null )
                {
                    dp.Clear();
                    dp = null;
                }
                if ( dq != null )
                {
                    dq.Clear();
                    dq = null;
                }
                if ( qInv != null )
                {
                    qInv.Clear();
                    qInv = null;
                }

                if ( disposing )
                {
                    // clear public key
                    if ( e != null )
                    {
                        e.Clear();
                        e = null;
                    }
                    if ( n != null )
                    {
                        n.Clear();
                        n = null;
                    }
                }
            }
            // call base class
            // no need as they all are abstract before us
            m_disposed = true;
        }
Exemple #27
0
 public static BigInteger Multiply( BigInteger bi1, BigInteger bi2 )
 {
     return ( bi1 * bi2 );
 }
Exemple #28
0
 protected virtual bool IsPrimeAcceptable( BigInteger bi, object context )
 {
     return true;
 }
Exemple #29
0
        /// <summary>
        /// Generates a new, random BigInteger of the specified capacity.
        /// </summary>
        /// <param name="bits">The number of bits for the new number.</param>
        /// <param name="rng">A random number generator to use to obtain the bits.</param>
        /// <returns>A random number of the specified capacity.</returns>
        public static BigInteger GenerateRandom( int bits, RandomNumberGenerator rng )
        {
            int dwords = bits >> 5;
            int remBits = bits & 0x1F;

            if ( remBits != 0 )
                dwords++;

            BigInteger ret = new BigInteger(Sign.Positive, ( uint )dwords + 1);
            byte[] random = new byte[dwords << 2];

            rng.GetBytes(random);
            Buffer.BlockCopy(random, 0, ret.data, 0, ( int )dwords << 2);

            if ( remBits != 0 )
            {
                uint mask = ( uint )( 0x01 << ( remBits - 1 ) );
                ret.data[dwords - 1] |= mask;

                mask = ( uint )( 0xFFFFFFFF >> ( 32 - remBits ) );
                ret.data[dwords - 1] &= mask;
            }
            else
                ret.data[dwords - 1] |= 0x80000000;

            ret.Normalize();
            return ret;
        }
Exemple #30
0
            public static BigInteger MultiplyByDword( BigInteger n, uint f )
            {
                BigInteger ret = new BigInteger(Sign.Positive, n.length + 1);

                uint i = 0;
                ulong c = 0;

                do
                {
                    c += ( ulong )n.data[i] * ( ulong )f;
                    ret.data[i] = ( uint )c;
                    c >>= 32;
                } while ( ++i < n.length );
                ret.data[i] = ( uint )c;
                ret.Normalize();
                return ret;

            }