/** * Return a random BigInteger not less than 'min' and not greater than 'max' * * @param min the least value that may be generated * @param max the greatest value that may be generated * @param random the source of randomness * @return a random BigInteger value in the range [min,max] */ public static BigInteger CreateRandomInRange( BigInteger min, BigInteger max, // TODO Should have been just Random class SecureRandom random) { int cmp = min.CompareTo(max); if (cmp >= 0) { if (cmp > 0) throw new ArgumentException("'min' may not be greater than 'max'"); return min; } if (min.BitLength > max.BitLength / 2) { return CreateRandomInRange(BigInteger.Zero, max.Subtract(min), random).Add(min); } for (int i = 0; i < MaxIterations; ++i) { BigInteger x = new BigInteger(max.BitLength, random); if (x.CompareTo(min) >= 0 && x.CompareTo(max) <= 0) { return x; } } // fall back to a faster (restricted) method return new BigInteger(max.Subtract(min).BitLength - 1, random).Add(min); }
private static BigInteger GeneratePrivateKey(BigInteger q, SecureRandom random) { // B.1.2 Key Pair Generation by Testing Candidates int minWeight = q.BitLength >> 2; for (;;) { // TODO Prefer this method? (change test cases that used fixed random) // B.1.1 Key Pair Generation Using Extra Random Bits //BigInteger x = new BigInteger(q.BitLength + 64, random).Mod(q.Subtract(One)).Add(One); BigInteger x = BigIntegers.CreateRandomInRange(One, q.Subtract(One), random); if (WNafUtilities.GetNafWeight(x) >= minWeight) { return x; } } }
public DHParameters( BigInteger p, BigInteger g, BigInteger q, int m, int l, BigInteger j, DHValidationParameters validation) { if (p == null) throw new ArgumentNullException("p"); if (g == null) throw new ArgumentNullException("g"); if (!p.TestBit(0)) throw new ArgumentException("field must be an odd prime", "p"); if (g.CompareTo(BigInteger.Two) < 0 || g.CompareTo(p.Subtract(BigInteger.Two)) > 0) throw new ArgumentException("generator must in the range [2, p - 2]", "g"); if (q != null && q.BitLength >= p.BitLength) throw new ArgumentException("q too big to be a factor of (p-1)", "q"); if (m >= p.BitLength) throw new ArgumentException("m value must be < bitlength of p", "m"); if (l != 0) { if (l >= p.BitLength) throw new ArgumentException("when l value specified, it must be less than bitlength(p)", "l"); if (l < m) throw new ArgumentException("when l value specified, it may not be less than m value", "l"); } if (j != null && j.CompareTo(BigInteger.Two) < 0) throw new ArgumentException("subgroup factor must be >= 2", "j"); // TODO If q, j both provided, validate p = jq + 1 ? this.p = p; this.g = g; this.q = q; this.m = m; this.l = l; this.j = j; this.validation = validation; }
// Section 7.2.6 ECVP-NR, pg 35 /** * return true if the value r and s represent a signature for the * message passed in. Generally, the order of the curve should be at * least as long as the hash of the message of interest, and with * ECNR, it *must* be at least as long. But just in case the signer * applied mod(n) to the longer digest, this implementation will * apply mod(n) during verification. * * @param digest the digest to be verified. * @param r the r value of the signature. * @param s the s value of the signature. * @exception DataLengthException if the digest is longer than the key allows */ public bool VerifySignature( byte[] message, BigInteger r, BigInteger s) { if (this.forSigning) { // not properly initilaized... deal with it throw new InvalidOperationException("not initialised for verifying"); } ECPublicKeyParameters pubKey = (ECPublicKeyParameters)key; BigInteger n = pubKey.Parameters.N; int nBitLength = n.BitLength; BigInteger e = new BigInteger(1, message); int eBitLength = e.BitLength; if (eBitLength > nBitLength) { throw new DataLengthException("input too large for ECNR key."); } // r in the range [1,n-1] if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0) { return false; } // s in the range [0,n-1] NB: ECNR spec says 0 if (s.CompareTo(BigInteger.Zero) < 0 || s.CompareTo(n) >= 0) { return false; } // compute P = sG + rW ECPoint G = pubKey.Parameters.G; ECPoint W = pubKey.Q; // calculate P using Bouncy math ECPoint P = ECAlgorithms.SumOfTwoMultiplies(G, s, W, r).Normalize(); if (P.IsInfinity) return false; BigInteger x = P.AffineXCoord.ToBigInteger(); BigInteger t = r.Subtract(x).Mod(n); return t.Equals(e); }
/** * Procedure C * procedure generates the a value from the given p,q, * returning the a value. */ private BigInteger procedure_C(BigInteger p, BigInteger q) { BigInteger pSub1 = p.Subtract(BigInteger.One); BigInteger pSub1Divq = pSub1.Divide(q); for(;;) { BigInteger d = new BigInteger(p.BitLength, init_random); // 1 < d < p-1 if (d.CompareTo(BigInteger.One) > 0 && d.CompareTo(pSub1) < 0) { BigInteger a = d.ModPow(pSub1Divq, p); if (a.CompareTo(BigInteger.One) != 0) { return a; } } } }
/// <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; } }
/* * Select a high order element of the multiplicative group Zp* * * p and q must be s.t. p = 2*q + 1, where p and q are prime (see generateSafePrimes) */ internal static BigInteger SelectGenerator(BigInteger p, BigInteger q, SecureRandom random) { BigInteger pMinusTwo = p.Subtract(BigInteger.Two); BigInteger g; /* * (see: Handbook of Applied Cryptography 4.80) */ // do // { // g = BigIntegers.CreateRandomInRange(BigInteger.Two, pMinusTwo, random); // } // while (g.ModPow(BigInteger.Two, p).Equals(BigInteger.One) // || g.ModPow(q, p).Equals(BigInteger.One)); /* * RFC 2631 2.2.1.2 (and see: Handbook of Applied Cryptography 4.81) */ do { BigInteger h = BigIntegers.CreateRandomInRange(BigInteger.Two, pMinusTwo, random); g = h.ModPow(BigInteger.Two, p); } while (g.Equals(BigInteger.One)); return g; }
public BigInteger Add( BigInteger value) { if (this.sign == 0) return value; if (this.sign != value.sign) { if (value.sign == 0) return this; if (value.sign < 0) return Subtract(value.Negate()); return value.Subtract(Negate()); } return AddToMagnitude(value.magnitude); }
private static BigInteger ReduceBarrett(BigInteger x, BigInteger m, BigInteger mr, BigInteger yu) { int xLen = x.BitLength, mLen = m.BitLength; if (xLen < mLen) return x; if (xLen - mLen > 1) { int k = m.magnitude.Length; BigInteger q1 = x.DivideWords(k - 1); BigInteger q2 = q1.Multiply(yu); // TODO Only need partial multiplication here BigInteger q3 = q2.DivideWords(k + 1); BigInteger r1 = x.RemainderWords(k + 1); BigInteger r2 = q3.Multiply(m); // TODO Only need partial multiplication here BigInteger r3 = r2.RemainderWords(k + 1); x = r1.Subtract(r3); if (x.sign < 0) { x = x.Add(mr); } } while (x.CompareTo(m) >= 0) { x = x.Subtract(m); } return x; }