コード例 #1
0
        private static STOutput ImplSTRandomPrime(IDigest d, int length, byte[] primeSeed)
        {
            int dLen = d.GetDigestSize();

            if (length < 33)
            {
                int primeGenCounter = 0;

                byte[] c0 = new byte[dLen];
                byte[] c1 = new byte[dLen];

                for (;;)
                {
                    Hash(d, primeSeed, c0, 0);
                    Inc(primeSeed, 1);

                    Hash(d, primeSeed, c1, 0);
                    Inc(primeSeed, 1);

                    uint c = Extract32(c0) ^ Extract32(c1);
                    c &= (uint.MaxValue >> (32 - length));
                    c |= (1U << (length - 1)) | 1U;

                    ++primeGenCounter;

                    if (IsPrime32(c))
                    {
                        return(new STOutput(BigInteger.ValueOf((long)c), primeSeed, primeGenCounter));
                    }

                    if (primeGenCounter > (4 * length))
                    {
                        throw new InvalidOperationException("Too many iterations in Shawe-Taylor Random_Prime Routine");
                    }
                }
            }

            STOutput rec = ImplSTRandomPrime(d, (length + 3) / 2, primeSeed);

            {
                BigInteger c0 = rec.Prime;
                primeSeed = rec.PrimeSeed;
                int primeGenCounter = rec.PrimeGenCounter;

                int outlen     = 8 * dLen;
                int iterations = (length - 1) / outlen;

                int oldCounter = primeGenCounter;

                BigInteger x = HashGen(d, primeSeed, iterations + 1);
                x = x.Mod(One.ShiftLeft(length - 1)).SetBit(length - 1);

                BigInteger c0x2 = c0.ShiftLeft(1);
                BigInteger tx2  = x.Subtract(One).Divide(c0x2).Add(One).ShiftLeft(1);
                int        dt   = 0;

                BigInteger c = tx2.Multiply(c0).Add(One);

                /*
                 * TODO Since the candidate primes are generated by constant steps ('c0x2'),
                 * sieving could be used here in place of the 'HasAnySmallFactors' approach.
                 */
                for (;;)
                {
                    if (c.BitLength > length)
                    {
                        tx2 = One.ShiftLeft(length - 1).Subtract(One).Divide(c0x2).Add(One).ShiftLeft(1);
                        c   = tx2.Multiply(c0).Add(One);
                    }

                    ++primeGenCounter;

                    /*
                     * This is an optimization of the original algorithm, using trial division to screen out
                     * many non-primes quickly.
                     *
                     * NOTE: 'primeSeed' is still incremented as if we performed the full check!
                     */
                    if (!ImplHasAnySmallFactors(c))
                    {
                        BigInteger a = HashGen(d, primeSeed, iterations + 1);
                        a = a.Mod(c.Subtract(Three)).Add(Two);

                        tx2 = tx2.Add(BigInteger.ValueOf(dt));
                        dt  = 0;

                        BigInteger z = a.ModPow(tx2, c);

                        if (c.Gcd(z.Subtract(One)).Equals(One) && z.ModPow(c0, c).Equals(One))
                        {
                            return(new STOutput(c, primeSeed, primeGenCounter));
                        }
                    }
                    else
                    {
                        Inc(primeSeed, iterations + 1);
                    }

                    if (primeGenCounter >= ((4 * length) + oldCounter))
                    {
                        throw new InvalidOperationException("Too many iterations in Shawe-Taylor Random_Prime Routine");
                    }

                    dt += 2;
                    c   = c.Add(c0x2);
                }
            }
        }
コード例 #2
0
        private static STOutput ImplSTRandomPrime(IDigest d, int length, byte[] primeSeed)
        {
            //IL_0093: Unknown result type (might be due to invalid IL or missing references)
            //IL_024d: Unknown result type (might be due to invalid IL or missing references)
            int digestSize = d.GetDigestSize();

            if (length < 33)
            {
                int    num    = 0;
                byte[] array  = new byte[digestSize];
                byte[] array2 = new byte[digestSize];
                do
                {
                    Hash(d, primeSeed, array, 0);
                    Inc(primeSeed, 1);
                    Hash(d, primeSeed, array2, 0);
                    Inc(primeSeed, 1);
                    uint num2 = Extract32(array) ^ Extract32(array2);
                    num2 &= 4294967295u >> 32 - length;
                    num2 |= (uint)(1 << length - 1) | 1u;
                    num++;
                    if (IsPrime32(num2))
                    {
                        return(new STOutput(BigInteger.ValueOf(num2), primeSeed, num));
                    }
                }while (num <= 4 * length);
                throw new InvalidOperationException("Too many iterations in Shawe-Taylor Random_Prime Routine");
            }
            STOutput   sTOutput = ImplSTRandomPrime(d, (length + 3) / 2, primeSeed);
            BigInteger prime    = sTOutput.Prime;

            primeSeed = sTOutput.PrimeSeed;
            int        num3       = sTOutput.PrimeGenCounter;
            int        num4       = 8 * digestSize;
            int        num5       = (length - 1) / num4;
            int        num6       = num3;
            BigInteger bigInteger = HashGen(d, primeSeed, num5 + 1);

            bigInteger = bigInteger.Mod(One.ShiftLeft(length - 1)).SetBit(length - 1);
            BigInteger bigInteger2 = prime.ShiftLeft(1);
            BigInteger bigInteger3 = bigInteger.Subtract(One).Divide(bigInteger2).Add(One)
                                     .ShiftLeft(1);
            int        num7        = 0;
            BigInteger bigInteger4 = bigInteger3.Multiply(prime).Add(One);

            while (true)
            {
                if (bigInteger4.BitLength > length)
                {
                    bigInteger3 = One.ShiftLeft(length - 1).Subtract(One).Divide(bigInteger2)
                                  .Add(One)
                                  .ShiftLeft(1);
                    bigInteger4 = bigInteger3.Multiply(prime).Add(One);
                }
                num3++;
                if (!ImplHasAnySmallFactors(bigInteger4))
                {
                    BigInteger bigInteger5 = HashGen(d, primeSeed, num5 + 1);
                    bigInteger5 = bigInteger5.Mod(bigInteger4.Subtract(Three)).Add(Two);
                    bigInteger3 = bigInteger3.Add(BigInteger.ValueOf(num7));
                    num7        = 0;
                    BigInteger bigInteger6 = bigInteger5.ModPow(bigInteger3, bigInteger4);
                    if (bigInteger4.Gcd(bigInteger6.Subtract(One)).Equals(One) && bigInteger6.ModPow(prime, bigInteger4).Equals(One))
                    {
                        return(new STOutput(bigInteger4, primeSeed, num3));
                    }
                }
                else
                {
                    Inc(primeSeed, num5 + 1);
                }
                if (num3 >= 4 * length + num6)
                {
                    break;
                }
                num7       += 2;
                bigInteger4 = bigInteger4.Add(bigInteger2);
            }
            throw new InvalidOperationException("Too many iterations in Shawe-Taylor Random_Prime Routine");
        }