public SimpleBigDecimal Divide(SimpleBigDecimal b)
        {
            CheckScale(b);
            IBigInteger dividend = bigInt.ShiftLeft(scale);

            return(new SimpleBigDecimal(dividend.Divide(b.bigInt), scale));
        }
Esempio n. 2
0
        /**
         * Initializes this algorithm. Must be called before all other Functions.
         *
         * @see org.bouncycastle.crypto.AsymmetricBlockCipher#init(bool,
         *      org.bouncycastle.crypto.CipherParameters)
         */
        public void Init(
            bool forEncryption,
            ICipherParameters parameters)
        {
            this.forEncryption = forEncryption;

            if (parameters is ParametersWithRandom)
            {
                parameters = ((ParametersWithRandom)parameters).Parameters;
            }

            key = (NaccacheSternKeyParameters)parameters;

            // construct lookup table for faster decryption if necessary
            if (!this.forEncryption)
            {
#if !NETFX_CORE
                if (debug)
                {
                    Console.WriteLine("Constructing lookup Array");
                }
#endif
                NaccacheSternPrivateKeyParameters priv = (NaccacheSternPrivateKeyParameters)key;
                IList primes = priv.SmallPrimesList;
                lookup = new IList[primes.Count];
                for (int i = 0; i < primes.Count; i++)
                {
                    IBigInteger actualPrime      = (BigInteger)primes[i];
                    int         actualPrimeValue = actualPrime.IntValue;

                    lookup[i] = Platform.CreateArrayList(actualPrimeValue);
                    lookup[i].Add(BigInteger.One);

#if !NETFX_CORE
                    if (debug)
                    {
                        Console.WriteLine("Constructing lookup ArrayList for " + actualPrimeValue);
                    }
#endif

                    IBigInteger accJ = BigInteger.Zero;

                    for (int j = 1; j < actualPrimeValue; j++)
                    {
                        //						IBigInteger bigJ = BigInteger.ValueOf(j);
                        //						accJ = priv.PhiN.Multiply(bigJ);
                        accJ = accJ.Add(priv.PhiN);
                        IBigInteger comp = accJ.Divide(actualPrime);
                        lookup[i].Add(priv.G.ModPow(comp, priv.Modulus));
                    }
                }
            }
        }
Esempio n. 3
0
        /**
         * Computes the integer x that is expressed through the given primes and the
         * congruences with the chinese remainder theorem (CRT).
         *
         * @param congruences
         *            the congruences c_i
         * @param primes
         *            the primes p_i
         * @return an integer x for that x % p_i == c_i
         */
        private static IBigInteger chineseRemainder(IList congruences, IList primes)
        {
            IBigInteger retval = BigInteger.Zero;
            IBigInteger all    = BigInteger.One;

            for (int i = 0; i < primes.Count; i++)
            {
                all = all.Multiply((BigInteger)primes[i]);
            }
            for (int i = 0; i < primes.Count; i++)
            {
                IBigInteger a   = (BigInteger)primes[i];
                IBigInteger b   = all.Divide(a);
                IBigInteger b2  = b.ModInverse(a);
                IBigInteger tmp = b.Multiply(b2);
                tmp    = tmp.Multiply((BigInteger)congruences[i]);
                retval = retval.Add(tmp);
            }

            return(retval.Mod(all));
        }
        /**
         * Procedure C
         * procedure generates the a value from the given p,q,
         * returning the a value.
         */
        private IBigInteger procedure_C(IBigInteger p, IBigInteger q)
        {
            IBigInteger pSub1     = p.Subtract(BigInteger.One);
            IBigInteger pSub1Divq = pSub1.Divide(q);

            for (;;)
            {
                IBigInteger d = new BigInteger(p.BitLength, init_random);

                // 1 < d < p-1
                if (d.CompareTo(BigInteger.One) > 0 && d.CompareTo(pSub1) < 0)
                {
                    IBigInteger a = d.ModPow(pSub1Divq, p);

                    if (a.CompareTo(BigInteger.One) != 0)
                    {
                        return(a);
                    }
                }
            }
        }
 public SimpleBigDecimal Divide(IBigInteger b)
 {
     return(new SimpleBigDecimal(bigInt.Divide(b), scale));
 }
        public void TestDivide()
        {
            for (int i = -5; i <= 5; ++i)
            {
                try
                {
                    val(i).Divide(zero);
                    Assert.Fail("expected ArithmeticException");
                }
                catch (ArithmeticException) {}
            }

            int product     = 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9;
            int productPlus = product + 1;

            IBigInteger bigProduct     = val(product);
            IBigInteger bigProductPlus = val(productPlus);

            for (int divisor = 1; divisor < 10; ++divisor)
            {
                // Exact division
                IBigInteger expected = val(product / divisor);

                Assert.AreEqual(expected, bigProduct.Divide(val(divisor)));
                Assert.AreEqual(expected.Negate(), bigProduct.Negate().Divide(val(divisor)));
                Assert.AreEqual(expected.Negate(), bigProduct.Divide(val(divisor).Negate()));
                Assert.AreEqual(expected, bigProduct.Negate().Divide(val(divisor).Negate()));

                expected = val((product + 1) / divisor);

                Assert.AreEqual(expected, bigProductPlus.Divide(val(divisor)));
                Assert.AreEqual(expected.Negate(), bigProductPlus.Negate().Divide(val(divisor)));
                Assert.AreEqual(expected.Negate(), bigProductPlus.Divide(val(divisor).Negate()));
                Assert.AreEqual(expected, bigProductPlus.Negate().Divide(val(divisor).Negate()));
            }

            for (int rep = 0; rep < 10; ++rep)
            {
                IBigInteger a = new BigInteger(100 - rep, 0, _random);
                IBigInteger b = new BigInteger(100 + rep, 0, _random);
                IBigInteger c = new BigInteger(10 + rep, 0, _random);
                IBigInteger d = a.Multiply(b).Add(c);
                IBigInteger e = d.Divide(a);

                Assert.AreEqual(b, e);
            }

            // Special tests for power of two since uses different code path internally
            for (int i = 0; i < 100; ++i)
            {
                int         shift  = _random.Next(64);
                IBigInteger a      = one.ShiftLeft(shift);
                IBigInteger b      = new BigInteger(64 + _random.Next(64), _random);
                IBigInteger bShift = b.ShiftRight(shift);

                string data = "shift=" + shift + ", b=" + b.ToString(16);

                Assert.AreEqual(bShift, b.Divide(a), data);
                Assert.AreEqual(bShift.Negate(), b.Divide(a.Negate()), data);
                Assert.AreEqual(bShift.Negate(), b.Negate().Divide(a), data);
                Assert.AreEqual(bShift, b.Negate().Divide(a.Negate()), data);
            }

            // Regression
            {
                int         shift  = 63;
                IBigInteger a      = one.ShiftLeft(shift);
                IBigInteger b      = new BigInteger(1, Hex.Decode("2504b470dc188499"));
                IBigInteger bShift = b.ShiftRight(shift);

                string data = "shift=" + shift + ", b=" + b.ToString(16);

                Assert.AreEqual(bShift, b.Divide(a), data);
                Assert.AreEqual(bShift.Negate(), b.Divide(a.Negate()), data);
//				Assert.AreEqual(bShift.Negate(), b.Negate().Divide(a), data);
                Assert.AreEqual(bShift, b.Negate().Divide(a.Negate()), data);
            }
        }
        /*
         * (non-Javadoc)
         *
         * @see org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator#generateKeyPair()
         */
        public IAsymmetricCipherKeyPair GenerateKeyPair()
        {
            int           strength  = param.Strength;
            ISecureRandom rand      = param.Random;
            int           certainty = param.Certainty;
            bool          debug     = param.IsDebug;

#if !NETFX_CORE
            if (debug)
            {
                Console.WriteLine("Fetching first " + param.CountSmallPrimes + " primes.");
            }
#endif

            IList smallPrimes = findFirstPrimes(param.CountSmallPrimes);

            smallPrimes = PermuteList(smallPrimes, rand);

            IBigInteger u = BigInteger.One;
            IBigInteger v = BigInteger.One;

            for (int i = 0; i < smallPrimes.Count / 2; i++)
            {
                u = u.Multiply((BigInteger)smallPrimes[i]);
            }
            for (int i = smallPrimes.Count / 2; i < smallPrimes.Count; i++)
            {
                v = v.Multiply((BigInteger)smallPrimes[i]);
            }

            IBigInteger sigma = u.Multiply(v);

            // n = (2 a u _p + 1 ) ( 2 b v _q + 1)
            // -> |n| = strength
            // |2| = 1 in bits
            // -> |a| * |b| = |n| - |u| - |v| - |_p| - |_q| - |2| -|2|
            // remainingStrength = strength - sigma.bitLength() - _p.bitLength() -
            // _q.bitLength() - 1 -1
            int         remainingStrength = strength - sigma.BitLength - 48;
            IBigInteger a = GeneratePrime(remainingStrength / 2 + 1, certainty, rand);
            IBigInteger b = GeneratePrime(remainingStrength / 2 + 1, certainty, rand);

            IBigInteger _p;
            IBigInteger _q;
            IBigInteger p;
            IBigInteger q;

            long tries = 0;
#if !NETFX_CORE
            if (debug)
            {
                Console.WriteLine("generating p and q");
            }
#endif

            IBigInteger _2au = a.Multiply(u).ShiftLeft(1);
            IBigInteger _2bv = b.Multiply(v).ShiftLeft(1);

            for (; ;)
            {
                tries++;

                _p = GeneratePrime(24, certainty, rand);

                p = _p.Multiply(_2au).Add(BigInteger.One);

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

                for (; ;)
                {
                    _q = GeneratePrime(24, certainty, rand);

                    if (_p.Equals(_q))
                    {
                        continue;
                    }

                    q = _q.Multiply(_2bv).Add(BigInteger.One);

                    if (q.IsProbablePrime(certainty))
                    {
                        break;
                    }
                }

                if (!sigma.Gcd(_p.Multiply(_q)).Equals(BigInteger.One))
                {
#if !NETFX_CORE
                    Console.WriteLine("sigma.gcd(_p.mult(_q)) != 1!\n _p: " + _p + "\n _q: " + _q);
#endif
                    continue;
                }

                if (p.Multiply(q).BitLength < strength)
                {
#if !NETFX_CORE
                    if (debug)
                    {
                        Console.WriteLine("key size too small. Should be " + strength + " but is actually "
                                          + p.Multiply(q).BitLength);
                    }
#endif
                    continue;
                }
                break;
            }

#if !NETFX_CORE
            if (debug)
            {
                Console.WriteLine("needed " + tries + " tries to generate p and q.");
            }
#endif

            IBigInteger n     = p.Multiply(q);
            IBigInteger phi_n = p.Subtract(BigInteger.One).Multiply(q.Subtract(BigInteger.One));
            IBigInteger g;
            tries = 0;
#if !NETFX_CORE
            if (debug)
            {
                Console.WriteLine("generating g");
            }
#endif
            for (; ;)
            {
                // TODO After the first loop, just regenerate one randomly-selected gPart each time?
                IList gParts = Platform.CreateArrayList();
                for (int ind = 0; ind != smallPrimes.Count; ind++)
                {
                    IBigInteger i = (BigInteger)smallPrimes[ind];
                    IBigInteger e = phi_n.Divide(i);

                    for (; ;)
                    {
                        tries++;

                        g = GeneratePrime(strength, certainty, rand);

                        if (!g.ModPow(e, n).Equals(BigInteger.One))
                        {
                            gParts.Add(g);
                            break;
                        }
                    }
                }
                g = BigInteger.One;
                for (int i = 0; i < smallPrimes.Count; i++)
                {
                    IBigInteger gPart      = (BigInteger)gParts[i];
                    IBigInteger smallPrime = (BigInteger)smallPrimes[i];
                    g = g.Multiply(gPart.ModPow(sigma.Divide(smallPrime), n)).Mod(n);
                }

                // make sure that g is not divisible by p_i or q_i
                bool divisible = false;
                for (int i = 0; i < smallPrimes.Count; i++)
                {
                    if (g.ModPow(phi_n.Divide((BigInteger)smallPrimes[i]), n).Equals(BigInteger.One))
                    {
#if !NETFX_CORE
                        if (debug)
                        {
                            Console.WriteLine("g has order phi(n)/" + smallPrimes[i] + "\n g: " + g);
                        }
#endif
                        divisible = true;
                        break;
                    }
                }

                if (divisible)
                {
                    continue;
                }

                // make sure that g has order > phi_n/4

                //if (g.ModPow(phi_n.Divide(BigInteger.ValueOf(4)), n).Equals(BigInteger.One))
                if (g.ModPow(phi_n.ShiftRight(2), n).Equals(BigInteger.One))
                {
#if !NETFX_CORE
                    if (debug)
                    {
                        Console.WriteLine("g has order phi(n)/4\n g:" + g);
                    }
#endif
                    continue;
                }

                if (g.ModPow(phi_n.Divide(_p), n).Equals(BigInteger.One))
                {
#if !NETFX_CORE
                    if (debug)
                    {
                        Console.WriteLine("g has order phi(n)/p'\n g: " + g);
                    }
#endif
                    continue;
                }
                if (g.ModPow(phi_n.Divide(_q), n).Equals(BigInteger.One))
                {
#if !NETFX_CORE
                    if (debug)
                    {
                        Console.WriteLine("g has order phi(n)/q'\n g: " + g);
                    }
#endif
                    continue;
                }
                if (g.ModPow(phi_n.Divide(a), n).Equals(BigInteger.One))
                {
#if !NETFX_CORE
                    if (debug)
                    {
                        Console.WriteLine("g has order phi(n)/a\n g: " + g);
                    }
#endif
                    continue;
                }
                if (g.ModPow(phi_n.Divide(b), n).Equals(BigInteger.One))
                {
#if !NETFX_CORE
                    if (debug)
                    {
                        Console.WriteLine("g has order phi(n)/b\n g: " + g);
                    }
#endif
                    continue;
                }
                break;
            }
#if !NETFX_CORE
            if (debug)
            {
                Console.WriteLine("needed " + tries + " tries to generate g");
                Console.WriteLine();
                Console.WriteLine("found new NaccacheStern cipher variables:");
                Console.WriteLine("smallPrimes: " + CollectionUtilities.ToString(smallPrimes));
                Console.WriteLine("sigma:...... " + sigma + " (" + sigma.BitLength + " bits)");
                Console.WriteLine("a:.......... " + a);
                Console.WriteLine("b:.......... " + b);
                Console.WriteLine("p':......... " + _p);
                Console.WriteLine("q':......... " + _q);
                Console.WriteLine("p:.......... " + p);
                Console.WriteLine("q:.......... " + q);
                Console.WriteLine("n:.......... " + n);
                Console.WriteLine("phi(n):..... " + phi_n);
                Console.WriteLine("g:.......... " + g);
                Console.WriteLine();
            }
#endif

            return(new AsymmetricCipherKeyPair(new NaccacheSternKeyParameters(false, g, n, sigma.BitLength),
                                               new NaccacheSternPrivateKeyParameters(g, n, sigma.BitLength, smallPrimes, phi_n)));
        }