public SimpleBigDecimal Divide(SimpleBigDecimal b) { CheckScale(b); IBigInteger dividend = bigInt.ShiftLeft(scale); return(new SimpleBigDecimal(dividend.Divide(b.bigInt), scale)); }
/** * 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)); } } } }
/** * 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))); }