示例#1
0
			private unsafe BigInteger OddPow (uint b, BigInteger exp) {
				exp.Normalize ();
				uint [] wkspace = new uint [mod.length << 1 + 1];
				
				BigInteger resultNum = Montgomery.ToMont ((BigInteger)b, this.mod);
				resultNum = new BigInteger (resultNum, mod.length << 1 +1);
				
				uint mPrime = Montgomery.Inverse (mod.data [0]);
				
				uint pos = (uint)exp.bitCount () - 2;
				
				//
				// We know that the first itr will make the val b
				//
				
				do {
					//
					// r = r ^ 2 % m
					//
					Kernel.SquarePositive (resultNum, ref wkspace);
					resultNum = Montgomery.Reduce (resultNum, mod, mPrime);
					
					if (exp.testBit (pos)) {
						
						//
						// r = r * b % m
						//
						
						// TODO: Is Unsafe really speeding things up?
						fixed (uint* u = resultNum.data) {
							
							uint i = 0;
							ulong mc = 0;
							
							do {
								mc += (ulong)u [i] * (ulong)b;
								u [i] = (uint)mc;
								mc >>= 32;
							} while (++i < resultNum.length);
							
							if (resultNum.length < mod.length) {
								if (mc != 0) {
									u [i] = (uint)mc;
									resultNum.length++;
									while (resultNum >= mod)
										Kernel.MinusEq (resultNum, mod);
								}
							} else if (mc != 0) {
								
								//
								// First, we estimate the quotient by dividing
								// the first part of each of the numbers. Then
								// we correct this, if necessary, with a subtraction.
								//
								
								uint cc = (uint)mc;
								
								// We would rather have this estimate overshoot,
								// so we add one to the divisor
								uint divEstimate = (uint) ((((ulong)cc << 32) | (ulong) u [i -1]) /
									(mod.data [mod.length-1] + 1));
									
								uint t;
								
								i = 0;
								mc = 0;
								do {
									mc += (ulong)mod.data [i] * (ulong)divEstimate;
									t = u [i];
									u [i] -= (uint)mc;
									mc >>= 32;
									if (u [i] > t) mc++;
									i++;
								} while (i < resultNum.length);
								cc -= (uint)mc;
								
								if (cc != 0) {
									
									uint sc = 0, j = 0;
									uint [] s = mod.data;
									do {
										uint a = s [j];
										if (((a += sc) < sc) | ((u [j] -= a) > ~a)) sc = 1;
										else sc = 0;
										j++;
									} while (j < resultNum.length);
									cc -= sc;
								}
								while (resultNum >= mod)
									Kernel.MinusEq (resultNum, mod);
							} else {
								while (resultNum >= mod)
									Kernel.MinusEq (resultNum, mod);
							}
						}
					}
				} while (pos-- > 0);
				
				resultNum = Montgomery.Reduce (resultNum, mod, mPrime);
				return resultNum;
				
			}
示例#2
0
			private BigInteger OddPow (BigInteger b, BigInteger exp) {
				BigInteger resultNum = new BigInteger (Montgomery.ToMont (1, mod), mod.length << 1);
				BigInteger tempNum = new BigInteger (Montgomery.ToMont (b, mod), mod.length << 1);  // ensures (tempNum * tempNum) < b^ (2k)
				uint mPrime = Montgomery.Inverse (mod.data [0]);
				uint totalBits = (uint)exp.bitCount ();
				
				uint [] wkspace = new uint [mod.length << 1];
				
				// perform squaring and multiply exponentiation
				for (uint pos = 0; pos < totalBits; pos++) {
					if (exp.testBit (pos)) {
						
						Array.Clear (wkspace, 0, wkspace.Length);
						Kernel.Multiply (resultNum.data, 0, resultNum.length, tempNum.data, 0, tempNum.length, wkspace, 0);
						resultNum.length += tempNum.length;
						uint [] t = wkspace;
						wkspace = resultNum.data;
						resultNum.data = t;
						
						Montgomery.Reduce (resultNum, mod, mPrime);
					}
					
					Kernel.SquarePositive (tempNum, ref wkspace);
					Montgomery.Reduce (tempNum, mod, mPrime);
				}
				
				Montgomery.Reduce (resultNum, mod, mPrime);
				return resultNum;
			}
示例#3
0
			private unsafe BigInteger OddModTwoPow (BigInteger exp) {

				uint [] wkspace = new uint [mod.length << 1 + 1];

				BigInteger resultNum = Montgomery.ToMont ((BigInteger)2, this.mod);
				resultNum = new BigInteger (resultNum, mod.length << 1 +1);

				uint mPrime = Montgomery.Inverse (mod.data [0]);

				//
				// TODO: eat small bits, the ones we can do with no modular reduction
				//
				uint pos = (uint)exp.bitCount () - 2;

				do {
					Kernel.SquarePositive (resultNum, ref wkspace);
					resultNum = Montgomery.Reduce (resultNum, mod, mPrime);

					if (exp.testBit (pos)) {
						//
						// resultNum = (resultNum * 2) % mod
						//

						fixed (uint* u = resultNum.data) {
							//
							// Double
							//
							uint* uu = u;
							uint* uuE = u + resultNum.length;
							uint x, carry = 0;
							while (uu < uuE) {
								x = *uu;
								*uu = (x << 1) | carry;
								carry = x >> (32 - 1);
								uu++;
							}

							// subtraction inlined because we know it is square
							if (carry != 0 || resultNum >= mod) {
								fixed (uint* s = mod.data) {
									uu = u;
									uint c = 0;
									uint* ss = s;
									do {
										uint a = *ss++;
										if (((a += c) < c) | ((* (uu++) -= a) > ~a))
											c = 1;
										else
											c = 0;
									} while (uu < uuE);
								}
							}
						}
					}
				} while (pos-- > 0);

				resultNum = Montgomery.Reduce (resultNum, mod, mPrime);
				return resultNum;
			}
示例#4
0
			public BigInteger EvenPow (BigInteger b, BigInteger exp) {
				BigInteger resultNum = new BigInteger ((BigInteger)1, mod.length << 1);
				BigInteger tempNum = new BigInteger (b % mod, mod.length << 1);  // ensures (tempNum * tempNum) < b^ (2k)
				
				uint totalBits = (uint)exp.bitCount ();
				
				uint [] wkspace = new uint [mod.length << 1];
				
				// perform squaring and multiply exponentiation
				for (uint pos = 0; pos < totalBits; pos++) {
					if (exp.testBit (pos)) {
						
						Array.Clear (wkspace, 0, wkspace.Length);
						Kernel.Multiply (resultNum.data, 0, resultNum.length, tempNum.data, 0, tempNum.length, wkspace, 0);
						resultNum.length += tempNum.length;
						uint [] t = wkspace;
						wkspace = resultNum.data;
						resultNum.data = t;
						
						BarrettReduction (resultNum);
					}
					
					Kernel.SquarePositive (tempNum, ref wkspace);
					BarrettReduction (tempNum);
					
					if (tempNum == 1) {
						return resultNum;
					}
				}
				
				return resultNum;
			}
示例#5
0
        /// <summary>
        /// Creates a new RSA secret key and returns it as a
        /// 2 dimensional array of biginteger. return[0] holds
        /// the public values of the key and return[1] all the
        /// secret values.
        /// </summary>
        /// <remarks>
        /// Creates a new RSA secret key and returns it as a
        /// 2 dimensional array of biginteger. return[0] holds
        /// the public values of the key and return[1] all the
        /// secret values.<br></br>
        /// The order of the public components is n, e.
        /// The order of the secret components is d, p,
        /// q and u.
        /// </remarks>
        /// <param name="nbits">The size of the key in bits.</param>
        /// <returns>A new RSA secret key as a
        /// 2 dimensional array of biginteger. return[0] holds
        /// the public values of the key and return[1] all the
        /// secret values.<br></br>
        /// The order of the public components is n, e.
        /// The order of the secret components is d, p,
        /// q and u.</returns>
        /// <exception cref="System.ArgumentException">Throws an
        /// Argumentexception if the keysize is not between 768
        /// and 4096 bits.</exception>
        public override BigInteger[][] Generate(int nbits)
        {
            BigInteger p, q; /* the two primes */
            BigInteger d;    /* the private key */
            BigInteger u;
            BigInteger t1, t2;
            BigInteger n = new BigInteger();    /* the public key */
            BigInteger e;    /* the exponent */
            BigInteger phi;  /* helper: (p-1)(q-1) */
            BigInteger g;
            BigInteger f;
            Random rand = new Random();

            if ((nbits < 768) || (nbits > 4096))
                throw new ArgumentException("Only keysizes betwen 768 and 4096 bit are allowed!");

            /* make sure that nbits is even so that we generate p, q of equal size */
            if ( (nbits&1)==1 )
                nbits++;

            do {
                /* select two (very secret) primes */
                p = new BigInteger();
                q = new BigInteger();

                p = BigInteger.genPseudoPrime(nbits / 2);
                q = BigInteger.genPseudoPrime(nbits / 2);

                /* p shall be smaller than q (for calc of u)*/
                if (q > p) {
                    BigInteger tmp = p;
                    p = q;
                    q = tmp;
                }

                /* calculate the modulus */
                n = p * q;
            } while ( n.bitCount() != nbits );

            /* calculate Euler totient: phi = (p-1)(q-1) */
            t1 = p - new BigInteger(1);
            t2 = q - new BigInteger(1);
            phi = t1 * t2;

            g = t1.gcd(t2);
            f = phi / g;

            /* find an public exponent.
            We use 41 as this is quite fast and more secure than the
            commonly used 17.
            */

            e = new BigInteger(41);
            t1 = e.gcd(phi);
            if( t1 != new BigInteger(1) ) {
                e = new BigInteger(257);
                t1 = e.gcd(phi);
                if( t1 != new BigInteger(1) ) {
                    e = new BigInteger(65537);
                    t1 = e.gcd(phi);

                    /* (while gcd is not 1) */
                    while( t1 != new BigInteger(1) ) {
                        e += 2;
                        t1 = e.gcd(phi);
                    }
                }
            }

            /* calculate the secret key d = e^1 mod phi */
            d = e.modInverse(f);

            /* calculate the inverse of p and q (used for chinese remainder theorem)*/
            u = p.modInverse(q);

            RSA_Secret_Key sk = new RSA_Secret_Key();

            sk.n = n;
            sk.e = e;
            sk.p = p;
            sk.q = q;
            sk.d = d;
            sk.u = u;

            this.biGeneratedKey = ParseSecretKey(sk);

            return this.biGeneratedKey;

            /* now we can test our keys (this should never fail!) */
            // test_keys( sk, nbits - 64 );
        }