Beispiel #1
0
        private PrimeGeneratorResult GeneratePrimes(PrimeGeneratorParameters param)
        {
            BigInteger p, p1, p2, q, q1, q2, xp, xq;

            // 1, 2, 3, 4 covered by guards

            // 5
            var p1Result = PrimeGen186_4.ShaweTaylorRandomPrime(param.BitLens[0], param.Seed.ToPositiveBigInteger(), _sha);

            if (!p1Result.Success)
            {
                return(new PrimeGeneratorResult($"Failed to generate p1: {p1Result.ErrorMessage}"));
            }

            var p2Result = PrimeGen186_4.ShaweTaylorRandomPrime(param.BitLens[1], p1Result.PrimeSeed, _sha);

            if (!p2Result.Success)
            {
                return(new PrimeGeneratorResult($"Failed to generate p2: {p2Result.ErrorMessage}"));
            }

            p1 = p1Result.Prime;
            p2 = p2Result.Prime;

            var pResult = PrimeGeneratorHelper.ProbablePrimeFactor(_primeTest, _entropyProvider, _pBound, param.A, p1, p2, param.Modulus, param.PublicE);

            if (!pResult.Success)
            {
                return(new PrimeGeneratorResult($"Failed to generate p: {pResult.ErrorMessage}"));
            }

            p  = pResult.Prime;
            xp = pResult.XPrime;

            do
            {
                // 6
                var q1Result = PrimeGen186_4.ShaweTaylorRandomPrime(param.BitLens[2], p2Result.PrimeSeed, _sha);
                if (!q1Result.Success)
                {
                    return(new PrimeGeneratorResult($"Failed to generate q1: {q1Result.ErrorMessage}"));
                }

                var q2Result = PrimeGen186_4.ShaweTaylorRandomPrime(param.BitLens[3], q1Result.PrimeSeed, _sha);
                if (!q2Result.Success)
                {
                    return(new PrimeGeneratorResult($"Failed to generate q2: {q2Result.ErrorMessage}"));
                }

                q1 = q1Result.Prime;
                q2 = q2Result.Prime;

                var qResult = PrimeGeneratorHelper.ProbablePrimeFactor(_primeTest, _entropyProvider, _pBound, param.B, q1, q2, param.Modulus, param.PublicE);
                if (!qResult.Success)
                {
                    return(new PrimeGeneratorResult($"Failed to generate q: {qResult.ErrorMessage}"));
                }

                q  = qResult.Prime;
                xq = qResult.XPrime;

                // 7
            } while (BigInteger.Abs(p - q) <= NumberTheory.Pow2(param.Modulus / 2 - 100) ||
                     BigInteger.Abs(xp - xq) <= NumberTheory.Pow2(param.Modulus / 2 - 100));

            var auxValues = new AuxiliaryResult {
                XP = xp, XQ = xq
            };
            var primePair = new PrimePair {
                P = p, Q = q
            };

            return(new PrimeGeneratorResult(primePair, auxValues));
        }
Beispiel #2
0
        /// <summary>
        /// A.1.2.1.2
        /// </summary>
        /// <param name="L"></param>
        /// <param name="N"></param>
        /// <param name="firstSeed"></param>
        /// <returns></returns>
        private PQGenerateResult Generate(int L, int N, BigInteger firstSeed)
        {
            // 1
            if (!DSAHelper.VerifyLenPair(L, N))
            {
                return(new PQGenerateResult("Bad L, N pair"));
            }

            // 2
            var qResult = PrimeGen186_4.ShaweTaylorRandomPrime(N, firstSeed, _sha);

            if (!qResult.Success)
            {
                return(new PQGenerateResult("Failed to generate q from ShaweTaylor"));
            }
            var q        = qResult.Prime;
            var qSeed    = qResult.PrimeSeed;
            var qCounter = qResult.PrimeGenCounter;

            // 3
            var pLen    = L.CeilingDivide(2) + 1;
            var pResult = PrimeGen186_4.ShaweTaylorRandomPrime(pLen, qSeed, _sha);

            if (!pResult.Success)
            {
                return(new PQGenerateResult("Failed to generate p0 from ShaweTaylor"));
            }
            var p0       = pResult.Prime;
            var pSeed    = pResult.PrimeSeed;
            var pCounter = pResult.PrimeGenCounter;

            // 4, 5
            var outLen     = _sha.HashFunction.OutputLen;
            var iterations = L.CeilingDivide(outLen) - 1;
            var oldCounter = pCounter;

            // 6, 7
            BigInteger x = 0;

            for (var i = 0; i <= iterations; i++)
            {
                x += _sha.HashNumber(pSeed + i).ToBigInteger() * NumberTheory.Pow2(i * outLen);
            }

            // 8
            pSeed += iterations + 1;

            // 9
            x = NumberTheory.Pow2(L - 1) + (x % NumberTheory.Pow2(L - 1));

            // 10
            var t = x.CeilingDivide(2 * q * p0);

            do
            {
                // 11
                if (2 * t * q * p0 + 1 > NumberTheory.Pow2(L))
                {
                    t = NumberTheory.Pow2(L - 1).CeilingDivide(2 * q * p0);
                }

                // 12, 13
                var p = 2 * t * q * p0 + 1;
                pCounter++;

                // 14, 15
                BigInteger a = 0;
                for (var i = 0; i <= iterations; i++)
                {
                    a += _sha.HashNumber(pSeed + i).ToBigInteger() * NumberTheory.Pow2(i * outLen);
                }

                // 16
                pSeed += iterations + 1;

                // 17
                a = 2 + (a % (p - 3));

                // 18
                var z = BigInteger.ModPow(a, 2 * t * q, p);

                // 19
                if (1 == NumberTheory.GCD(z - 1, p) && 1 == BigInteger.ModPow(z, p0, p))
                {
                    return(new PQGenerateResult(p, q, new DomainSeed(firstSeed, pSeed, qSeed), new Counter(pCounter, qCounter)));
                }

                // 20
                if (pCounter > 4 * L + oldCounter)
                {
                    return(new PQGenerateResult("Too many iterations"));
                }

                // 21
                t++;

                // 22
            } while (true);
        }