IsProbablePrime() публичный Метод

public IsProbablePrime ( int certainty ) : bool
certainty int
Результат bool
        /// <summary>Choose a random prime value for use with RSA</summary>
        /// <param name="bitlength">the bit-length of the returned prime</param>
        /// <param name="e">the RSA public exponent</param>
        /// <returns>a prime p, with (p-1) relatively prime to e</returns>
        protected virtual BigInteger ChooseRandomPrime(int bitlength, BigInteger e)
        {
            for (;;)
            {
                BigInteger p = new BigInteger(bitlength, 1, param.Random);

                if (p.Mod(e).Equals(BigInteger.One))
                    continue;

                if (!p.IsProbablePrime(param.Certainty))
                    continue;

                if (!e.Gcd(p.Subtract(BigInteger.One)).Equals(BigInteger.One))
                    continue;

                return p;
            }
        }
Пример #2
1
		public AsymmetricCipherKeyPair GenerateKeyPair()
        {
            BigInteger p, q, n, d, e, pSub1, qSub1, phi;

            //
            // p and q values should have a length of half the strength in bits
            //
			int strength = param.Strength;
            int pbitlength = (strength + 1) / 2;
            int qbitlength = (strength - pbitlength);
			int mindiffbits = strength / 3;

			e = param.PublicExponent;

			// TODO Consider generating safe primes for p, q (see DHParametersHelper.generateSafePrimes)
			// (then p-1 and q-1 will not consist of only small factors - see "Pollard's algorithm")

			//
            // Generate p, prime and (p-1) relatively prime to e
            //
            for (;;)
            {
				p = new BigInteger(pbitlength, 1, param.Random);

				if (p.Mod(e).Equals(BigInteger.One))
					continue;

				if (!p.IsProbablePrime(param.Certainty))
					continue;

				if (e.Gcd(p.Subtract(BigInteger.One)).Equals(BigInteger.One)) 
					break;
			}

            //
            // Generate a modulus of the required length
            //
            for (;;)
            {
                // Generate q, prime and (q-1) relatively prime to e,
                // and not equal to p
                //
                for (;;)
                {
					q = new BigInteger(qbitlength, 1, param.Random);

					if (q.Subtract(p).Abs().BitLength < mindiffbits)
						continue;

					if (q.Mod(e).Equals(BigInteger.One))
						continue;

					if (!q.IsProbablePrime(param.Certainty))
						continue;

					if (e.Gcd(q.Subtract(BigInteger.One)).Equals(BigInteger.One)) 
						break;
				}

                //
                // calculate the modulus
                //
                n = p.Multiply(q);

                if (n.BitLength == param.Strength)
					break;

                //
                // if we Get here our primes aren't big enough, make the largest
                // of the two p and try again
                //
                p = p.Max(q);
            }

			if (p.CompareTo(q) < 0)
			{
				phi = p;
				p = q;
				q = phi;
			}

            pSub1 = p.Subtract(BigInteger.One);
            qSub1 = q.Subtract(BigInteger.One);
            phi = pSub1.Multiply(qSub1);

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

            //
            // calculate the CRT factors
            //
            BigInteger dP, dQ, qInv;

            dP = d.Remainder(pSub1);
            dQ = d.Remainder(qSub1);
            qInv = q.ModInverse(p);

            return new AsymmetricCipherKeyPair(
                new RsaKeyParameters(false, n, e),
                new RsaPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv));
        }
        /// <summary>
        /// Constructor used by the pre-approved groups in JPakePrimeOrderGroups.
        /// These pre-approved groups can avoid the expensive checks.
        /// User-specified groups should not use this constructor.
        /// </summary>
        public JPakePrimeOrderGroup(BigInteger p, BigInteger q, BigInteger g, bool skipChecks)
        {
            JPakeUtilities.ValidateNotNull(p, "p");
            JPakeUtilities.ValidateNotNull(q, "q");
            JPakeUtilities.ValidateNotNull(g, "g");

            if (!skipChecks)
            {
                if (!p.Subtract(JPakeUtilities.One).Mod(q).Equals(JPakeUtilities.Zero))
                    throw new ArgumentException("p-1 must be evenly divisible by q");
                if (g.CompareTo(BigInteger.Two) == -1 || g.CompareTo(p.Subtract(JPakeUtilities.One)) == 1)
                    throw new ArgumentException("g must be in [2, p-1]");
                if (!g.ModPow(q, p).Equals(JPakeUtilities.One))
                    throw new ArgumentException("g^q mod p must equal 1");

                // Note these checks do not guarantee that p and q are prime.
                // We just have reasonable certainty that they are prime.
                if (!p.IsProbablePrime(20))
                    throw new ArgumentException("p must be prime");
                if (!q.IsProbablePrime(20))
                    throw new ArgumentException("q must be prime");
            }

            this.p = p;
            this.q = q;
            this.g = g;
        }
		private DsaParameters GenerateParameters_FIPS186_2()
		{
            byte[] seed = new byte[20];
            byte[] part1 = new byte[20];
            byte[] part2 = new byte[20];
            byte[] u = new byte[20];
            Sha1Digest sha1 = new Sha1Digest();
			int n = (L - 1) / 160;
			byte[] w = new byte[L / 8];

			for (;;)
			{
				random.NextBytes(seed);

				Hash(sha1, seed, part1);
				Array.Copy(seed, 0, part2, 0, seed.Length);
				Inc(part2);
				Hash(sha1, part2, part2);

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

				u[0] |= (byte)0x80;
				u[19] |= (byte)0x01;

				BigInteger q = new BigInteger(1, u);

				if (!q.IsProbablePrime(certainty))
					continue;

				byte[] offset = Arrays.Clone(seed);
				Inc(offset);

				for (int counter = 0; counter < 4096; ++counter)
				{
					for (int k = 0; k < n; k++)
					{
						Inc(offset);
						Hash(sha1, offset, part1);
						Array.Copy(part1, 0, w, w.Length - (k + 1) * part1.Length, part1.Length);
					}

					Inc(offset);
					Hash(sha1, offset, 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(1, w);

					BigInteger c = x.Mod(q.ShiftLeft(1));

					BigInteger p = x.Subtract(c.Subtract(BigInteger.One));

					if (p.BitLength != L)
						continue;

					if (p.IsProbablePrime(certainty))
					{
						BigInteger g = CalculateGenerator_FIPS186_2(p, q, random);

						return new DsaParameters(p, q, g, new DsaValidationParameters(seed, counter));
					}
				}
			}
		}
Пример #5
0
        /*
         * Finds a pair of prime BigInteger's {p, q: p = 2q + 1}
         * 
         * (see: Handbook of Applied Cryptography 4.86)
         */
        internal static BigInteger[] GenerateSafePrimes(int size, int certainty, SecureRandom random)
        {
            BigInteger p, q;
            int qLength = size - 1;
            int minWeight = size >> 2;

            if (size <= 32)
            {
                for (;;)
                {
                    q = new BigInteger(qLength, 2, random);

                    p = q.ShiftLeft(1).Add(BigInteger.One);

                    if (!p.IsProbablePrime(certainty))
                        continue;

                    if (certainty > 2 && !q.IsProbablePrime(certainty - 2))
                        continue;

                    break;
                }
            }
            else
            {
                // Note: Modified from Java version for speed
                for (;;)
                {
                    q = new BigInteger(qLength, 0, random);

                retry:
                    for (int i = 0; i < primeLists.Length; ++i)
                    {
                        int test = q.Remainder(BigPrimeProducts[i]).IntValue;

                        if (i == 0)
                        {
                            int rem3 = test % 3;
                            if (rem3 != 2)
                            {
                                int diff = 2 * rem3 + 2;
                                q = q.Add(BigInteger.ValueOf(diff));
                                test = (test + diff) % primeProducts[i];
                            }
                        }

                        int[] primeList = primeLists[i];
                        for (int j = 0; j < primeList.Length; ++j)
                        {
                            int prime = primeList[j];
                            int qRem = test % prime;
                            if (qRem == 0 || qRem == (prime >> 1))
                            {
                                q = q.Add(Six);
                                goto retry;
                            }
                        }
                    }

                    if (q.BitLength != qLength)
                        continue;

                    if (!q.RabinMillerTest(2, random))
                        continue;

                    p = q.ShiftLeft(1).Add(BigInteger.One);

                    if (!p.RabinMillerTest(certainty, random))
                        continue;

                    if (certainty > 2 && !q.RabinMillerTest(certainty - 2, random))
                        continue;

                    /*
                     * Require a minimum weight of the NAF representation, since low-weight primes may be
                     * weak against a version of the number-field-sieve for the discrete-logarithm-problem.
                     * 
                     * See "The number field sieve for integers of low weight", Oliver Schirokauer.
                     */
                    if (WNafUtilities.GetNafWeight(p) < minWeight)
                        continue;

                    break;
                }
            }

            return new BigInteger[] { p, q };
        }
Пример #6
0
        /**
         * which Generates the p and g values from the given parameters,
         * returning the DsaParameters object.
         * <p>
         * Note: can take a while...</p>
         */
        public DsaParameters GenerateParameters()
        {
            byte[]          seed = new byte[20];
            byte[]          part1 = new byte[20];
            byte[]          part2 = new byte[20];
            byte[]          u = new byte[20];
            Sha1Digest      sha1 = new Sha1Digest();
            int             n = (size - 1) / 160;
            byte[]          w = new byte[size / 8];

            BigInteger      q = null, p = null, g = null;
            int             counter = 0;
            bool         primesFound = false;

            while (!primesFound)
            {
                do
                {
                    random.NextBytes(seed);

                    sha1.BlockUpdate(seed, 0, seed.Length);

                    sha1.DoFinal(part1, 0);

                    Array.Copy(seed, 0, part2, 0, seed.Length);

                    Add(part2, seed, 1);

                    sha1.BlockUpdate(part2, 0, part2.Length);

                    sha1.DoFinal(part2, 0);

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

                    u[0] |= (byte)0x80;
                    u[19] |= (byte)0x01;

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

                counter = 0;

                int offset = 2;

                while (counter < 4096)
                {
                    for (int k = 0; k < n; k++)
                    {
                        Add(part1, seed, offset + k);
                        sha1.BlockUpdate(part1, 0, part1.Length);
                        sha1.DoFinal(part1, 0);
                        Array.Copy(part1, 0, w, w.Length - (k + 1) * part1.Length, part1.Length);
                    }

                    Add(part1, seed, offset + n);
                    sha1.BlockUpdate(part1, 0, part1.Length);
                    sha1.DoFinal(part1, 0);
                    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(1, w);

                    BigInteger  c = x.Mod(q.ShiftLeft(1));

                    p = x.Subtract(c.Subtract(BigInteger.One));

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

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

            //
            // calculate the generator g
            //
            BigInteger  pMinusOneOverQ = p.Subtract(BigInteger.One).Divide(q);

            for (;;)
            {
                BigInteger h = new BigInteger(size, random);
                if (h.CompareTo(BigInteger.One) <= 0 || h.CompareTo(p.Subtract(BigInteger.One)) >= 0)
                {
                    continue;
                }

                g = h.ModPow(pMinusOneOverQ, p);
                if (g.CompareTo(BigInteger.One) <= 0)
                {
                    continue;
                }

                break;
            }

            return new DsaParameters(p, q, g, new DsaValidationParameters(seed, counter));
        }
        /*
         * Finds a pair of prime BigInteger's {p, q: p = 2q + 1}
         * 
         * (see: Handbook of Applied Cryptography 4.86)
         */
        internal static BigInteger[] GenerateSafePrimes(int size, int certainty, SecureRandom random)
		{
			BigInteger p, q;
			int qLength = size - 1;

			if (size <= 32)
			{
				for (;;)
				{
					q = new BigInteger(qLength, 2, random);

					p = q.ShiftLeft(1).Add(BigInteger.One);

					if (p.IsProbablePrime(certainty)
						&& (certainty <= 2 || q.IsProbablePrime(certainty)))
							break;
				}
			}
			else
			{
				// Note: Modified from Java version for speed
				for (;;)
				{
					q = new BigInteger(qLength, 0, random);

				retry:
					for (int i = 0; i < primeLists.Length; ++i)
					{
						int test = q.Remainder(BigPrimeProducts[i]).IntValue;

                        if (i == 0)
						{
							int rem3 = test % 3;
							if (rem3 != 2)
							{
								int diff = 2 * rem3 + 2;
								q = q.Add(BigInteger.ValueOf(diff));
								test = (test + diff) % primeProducts[i];
							}
						}

						int[] primeList = primeLists[i];
						for (int j = 0; j < primeList.Length; ++j)
						{
							int prime = primeList[j];
							int qRem = test % prime;
							if (qRem == 0 || qRem == (prime >> 1))
							{
								q = q.Add(Six);
								goto retry;
							}
						}
					}


					if (q.BitLength != qLength)
						continue;

					if (!q.RabinMillerTest(2, random))
						continue;

					p = q.ShiftLeft(1).Add(BigInteger.One);

					if (p.RabinMillerTest(certainty, random)
						&& (certainty <= 2 || q.RabinMillerTest(certainty - 2, random)))
						break;
				}
			}

			return new BigInteger[] { p, q };
		}
Пример #8
0
        /// <summary>Choose a random prime value for use with RSA</summary>
        /// <param name="bitlength">the bit-length of the returned prime</param>
        /// <param name="e">the RSA public exponent</param>
        /// <returns>a prime p, with (p-1) relatively prime to e</returns>
        protected virtual BigInteger ChooseRandomPrime(int bitlength, BigInteger e)
        {
            bool eIsKnownOddPrime = (e.BitLength <= SPECIAL_E_BITS) && Arrays.Contains(SPECIAL_E_VALUES, e.IntValue);

            for (;;)
            {
                BigInteger p = new BigInteger(bitlength, 1, parameters.Random);

                if (p.Mod(e).Equals(One))
                    continue;

                if (!p.IsProbablePrime(parameters.Certainty, true))
                    continue;

                if (!eIsKnownOddPrime && !e.Gcd(p.Subtract(One)).Equals(One))
                    continue;

                return p;
            }
        }
Пример #9
0
		private void processDHEKeyExchange(
			MemoryStream	inStr,
			ISigner			signer)
		{
			Stream sigIn = inStr;
			if (signer != null)
			{
				signer.Init(false, this.serverPublicKey);
				signer.BlockUpdate(this.clientRandom, 0, this.clientRandom.Length);
				signer.BlockUpdate(this.serverRandom, 0, this.serverRandom.Length);

				sigIn = new SignerStream(inStr, signer, null);
			}

			/*
			* Parse the Structure
			*/
			byte[] pByte = TlsUtilities.ReadOpaque16(sigIn);
			byte[] gByte = TlsUtilities.ReadOpaque16(sigIn);
			byte[] YsByte = TlsUtilities.ReadOpaque16(sigIn);

			if (signer != null)
			{
				byte[] sigByte = TlsUtilities.ReadOpaque16(sigIn);

				/*
				* Verify the Signature.
				*/
				if (!signer.VerifySignature(sigByte))
				{
					this.FailWithError(AL_fatal, AP_bad_certificate);
				}
			}

			this.AssertEmpty(inStr);

			/*
			* Do the DH calculation.
			*/
			BigInteger p = new BigInteger(1, pByte);
			BigInteger g = new BigInteger(1, gByte);
			BigInteger Ys = new BigInteger(1, YsByte);

			/*
			* Check the DH parameter values
			*/
			if (!p.IsProbablePrime(10))
			{
				this.FailWithError(AL_fatal, AP_illegal_parameter);
			}
			if (g.CompareTo(BigInteger.Two) < 0 || g.CompareTo(p.Subtract(BigInteger.Two)) > 0)
			{
				this.FailWithError(AL_fatal, AP_illegal_parameter);
			}
			// TODO For static DH public values, see additional checks in RFC 2631 2.1.5 
			if (Ys.CompareTo(BigInteger.Two) < 0 || Ys.CompareTo(p.Subtract(BigInteger.One)) > 0)
			{
				this.FailWithError(AL_fatal, AP_illegal_parameter);
			}

			/*
			* Diffie-Hellman basic key agreement
			*/
			DHParameters dhParams = new DHParameters(p, g);

			// Generate a keypair
			DHBasicKeyPairGenerator dhGen = new DHBasicKeyPairGenerator();
			dhGen.Init(new DHKeyGenerationParameters(random, dhParams));

			AsymmetricCipherKeyPair dhPair = dhGen.GenerateKeyPair();

			// Store the public value to send to server
			this.Yc = ((DHPublicKeyParameters)dhPair.Public).Y;

			// Calculate the shared secret
			DHBasicAgreement dhAgree = new DHBasicAgreement();
			dhAgree.Init(dhPair.Private);

			BigInteger agreement = dhAgree.CalculateAgreement(new DHPublicKeyParameters(Ys, dhParams));

			this.pms = BigIntegers.AsUnsignedByteArray(agreement);
		}
Пример #10
0
 /**
  * <summary>Tests whether a given string number is a prime number.</summary>
  * <param name="value">The string number to test if it is prime.</param>
  * <returns>Returns true if the string given value is prime else returns false.</returns>
  */
 public static bool IsPrime(string value, BackgroundWorker bw)
 {
     BigInteger b = new BigInteger(value);
     return b.IsProbablePrime(64);
 }
        /// <summary>
        /// Finds a pair of prime BigInteger's {p, q: p = 2q + 1}
        /// 
        /// (see: Handbook of Applied Cryptography 4.86)
        /// </summary>
        /// <param name="size">The size.</param>
        /// <param name="certainty">The certainty.</param>
        /// <param name="random">The random.</param>
        /// <returns></returns>
        internal static IBigInteger[] GenerateSafePrimes(int size, int certainty, ISecureRandom random)
        {
            IBigInteger p, q;
            var qLength = size - 1;

            if (size <= 32)
            {
                for (; ; )
                {
                    q = new BigInteger(qLength, 2, random);

                    p = q.ShiftLeft(1).Add(BigInteger.One);

                    if (p.IsProbablePrime(certainty)
                        && (certainty <= 2 || q.IsProbablePrime(certainty)))
                        break;
                }
            }
            else
            {
                // Note: Modified from Java version for speed
                for (; ; )
                {
                    q = new BigInteger(qLength, 0, random);

                retry:
                    for (var i = 0; i < _primeLists.Length; ++i)
                    {
                        var test = q.Remainder(_primeProductsBigs[i]).IntValue;

                        if (i == 0)
                        {
                            var rem3 = test % 3;
                            if (rem3 != 2)
                            {
                                var diff = 2 * rem3 + 2;
                                q = q.Add(BigInteger.ValueOf(diff));
                                test = (test + diff) % _primeProductsInts[i];
                            }
                        }

                        var primeList = _primeLists[i];
                        foreach (var prime in primeList)
                        {
                            var qRem = test % prime;
                            if (qRem != 0 && qRem != (prime >> 1))
                                continue;

                            q = q.Add(_six);
                            goto retry;
                        }
                    }

                    if (q.BitLength != qLength)
                        continue;

                    if (!((BigInteger)q).RabinMillerTest(2, random))
                        continue;

                    p = q.ShiftLeft(1).Add(BigInteger.One);

                    if (((BigInteger)p).RabinMillerTest(certainty, random)
                        && (certainty <= 2 || ((BigInteger)q).RabinMillerTest(certainty - 2, random)))
                        break;
                }
            }

            return new[] { p, q };
        }