Exemple #1
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;
			}
Exemple #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);
					}

					// the value of tempNum is required in the last loop
					if (pos < totalBits - 1) {
						Kernel.SquarePositive (tempNum, ref wkspace);
						Montgomery.Reduce (tempNum, mod, mPrime);
					}
				}

				Montgomery.Reduce (resultNum, mod, mPrime);
				return resultNum;
			}
Exemple #3
0
			private unsafe BigInteger EvenPow (uint b, BigInteger exp)
			{
				exp.Normalize ();
				uint [] wkspace = new uint [mod.length << 1 + 1];
				BigInteger resultNum = new BigInteger ((BigInteger)b, mod.length << 1 + 1);

				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);
					if (!(resultNum.length < mod.length))
						BarrettReduction (resultNum);

					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);

				return resultNum;
			}
Exemple #4
0
			public BigInteger Pow (BigInteger a, BigInteger k)
			{
				BigInteger b = new BigInteger (1);
				if (k == 0)
					return b;

				BigInteger A = a;
				if (k.TestBit (0))
					b = a;

				for (int i = 1; i < k.BitCount (); i++) {
					A = Multiply (A, A);
					if (k.TestBit (i))
						b = Multiply (A, b);
				}
				return b;
			}
Exemple #5
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;
			}
Exemple #6
0
		private void GenerateParams (int keyLength) 
		{
			byte[] seed = new byte[20];
			byte[] part1 = new byte[20];
			byte[] part2 = new byte[20];
			byte[] u = new byte[20];

			// TODO: a prime generator should be made for this

			SHA1 sha = SHA1.Create ();

			int n = (keyLength - 1) / 160;
			byte[] w = new byte [keyLength / 8];
			bool primesFound = false;

			while (!primesFound) {
				do {
					Random.GetBytes (seed);
					part1 = sha.ComputeHash (seed);
					Array.Copy(seed, 0, part2, 0, seed.Length);

					add (part2, seed, 1);

					part2 = sha.ComputeHash (part2);

					for (int i = 0; i != u.Length; i++)
						u [i] = (byte)(part1 [i] ^ part2 [i]);

					// first bit must be set (to respect key length)
					u[0] |= (byte)0x80;
					// last bit must be set (prime are all odds - except 2)
					u[19] |= (byte)0x01;

					q = new BigInteger (u);
				}
				while (!q.IsProbablePrime ());

				counter = 0;
				int offset = 2;
				while (counter < 4096) {
					for (int k = 0; k < n; k++) {
						add(part1, seed, offset + k);
						part1 = sha.ComputeHash (part1);
						Array.Copy (part1, 0, w, w.Length - (k + 1) * part1.Length, part1.Length);
					}

					add(part1, seed, offset + n);
					part1 = sha.ComputeHash (part1);
					Array.Copy (part1, part1.Length - ((w.Length - (n) * part1.Length)), w, 0, w.Length - n * part1.Length);

					w[0] |= (byte)0x80;
					BigInteger x = new BigInteger (w);

					BigInteger c = x % (q * 2);

					p = x - (c - 1);

					if (p.TestBit ((uint)(keyLength - 1))) {
						if (p.IsProbablePrime ()) {
							primesFound = true;
							break;
						}
					}

					counter += 1;
					offset += n + 1;
				}
			}

			// calculate the generator g
			BigInteger pMinusOneOverQ = (p - 1) / q;
			for (;;) {
				BigInteger h = BigInteger.GenerateRandom (keyLength);
				if ((h <= 1) || (h >= (p - 1)))
					continue;

				g = h.ModPow (pMinusOneOverQ, p);
				if (g <= 1)
					continue;
				break;
			}

			this.seed = new BigInteger (seed);
			j = (p - 1) / q;
		}
		protected override bool IsPrimeAcceptable (BigInteger bi, object Context)
		{
			return bi.TestBit (1);
		}
Exemple #8
0
			public BigInteger Pow (BigInteger a, BigInteger k)
			{
#if false
				BigInteger b = new BigInteger (1);
				if (k == 0)
					return b;

				BigInteger A = a;
				if (k.TestBit (0))
					b = a;

				for (int i = 1; i < k.BitCount (); i++) {
					A = Multiply (A, A);
					if (k.TestBit (i))
						b = Multiply (A, b);
				}
				return b;
#endif


                var result = System.Numerics.BigInteger.ModPow(
                    EncodeBigInteger(a),
                    EncodeBigInteger(k),
                    EncodeBigInteger(mod)
                );

                return DecodeBigInteger(result);
			}
Exemple #9
0
			private 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]);

				int bc = exp.BitCount () - 2;
				uint pos = (bc > 1 ? (uint) bc : 1);

				//
				// 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
						//

						uint u = 0;

						uint i = 0;
						ulong mc = 0;

						do
						{
							mc += (ulong)resultNum.data[u + i] * (ulong)b;
							resultNum.data[u + i] = (uint)mc;
							mc >>= 32;
						} while (++i < resultNum.length);

						if (resultNum.length < mod.length)
						{
							if (mc != 0)
							{
								resultNum.data[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;
							if (mod.data [mod.length - 1] < UInt32.MaxValue) {
								divEstimate = (uint) ((((ulong)cc << 32) | (ulong)resultNum.data[u + i - 1]) /
									(mod.data [mod.length-1] + 1));
							}
							else {
								// guess but don't divide by 0
								divEstimate = (uint) ((((ulong)cc << 32) | (ulong)resultNum.data[i - 1]) /
									(mod.data [mod.length-1]));
							}

							uint t;

							i = 0;
							mc = 0;
							do
							{
								mc += (ulong)mod.data[i] * (ulong)divEstimate;
								t = resultNum.data[u + i];
								resultNum.data[u + i] -= (uint)mc;
								mc >>= 32;
								if (resultNum.data[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) | ((resultNum.data[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;

			}
            public BigInteger Pow(BigInteger a, BigInteger k)
            {
                var b = new BigInteger(1);
                if (k == 0)
                    return b;

                var A = a;
                if (k.TestBit(0))
                    b = a;

                var bitCount = k.BitCount();
                for (var i = 1; i < bitCount; i++)
                {
                    A = Multiply(A, A);
                    if (k.TestBit(i))
                        b = Multiply(A, b);
                }
                return b;
            }