/** * Return a random IBigInteger 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 IBigInteger value in the range [min,max] */ public static IBigInteger CreateRandomInRange( IBigInteger min, IBigInteger max, // TODO Should have been just Random class ISecureRandom 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) { IBigInteger 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)); }
/** * Return a random IBigInteger 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 IBigInteger value in the range [min,max] */ public static IBigInteger CreateRandomInRange( IBigInteger min, IBigInteger max, // TODO Should have been just Random class ISecureRandom 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) { IBigInteger 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 IBigInteger CalculateGenerator_FIPS186_2(IBigInteger p, IBigInteger q, SecureRandom r) { IBigInteger e = p.Subtract(BigInteger.One).Divide(q); IBigInteger pSub2 = p.Subtract(BigInteger.Two); for (;;) { IBigInteger h = BigIntegers.CreateRandomInRange(BigInteger.Two, pSub2, r); IBigInteger g = h.ModPow(e, p); if (g.BitLength > 1) return g; } }
/** * Partial modular reduction modulo * <code>(τ<sup>m</sup> - 1)/(τ - 1)</code>. * @param k The integer to be reduced. * @param m The bitlength of the underlying finite field. * @param a The parameter <code>a</code> of the elliptic curve. * @param s The auxiliary values <code>s<sub>0</sub></code> and * <code>s<sub>1</sub></code>. * @param mu The parameter μ of the elliptic curve. * @param c The precision (number of bits of accuracy) of the partial * modular reduction. * @return <code>ρ := k partmod (τ<sup>m</sup> - 1)/(τ - 1)</code> */ public static ZTauElement PartModReduction(IBigInteger k, int m, sbyte a, IBigInteger[] s, sbyte mu, sbyte c) { // d0 = s[0] + mu*s[1]; mu is either 1 or -1 IBigInteger d0; if (mu == 1) { d0 = s[0].Add(s[1]); } else { d0 = s[0].Subtract(s[1]); } IBigInteger[] v = GetLucas(mu, m, true); IBigInteger vm = v[1]; SimpleBigDecimal lambda0 = ApproximateDivisionByN( k, s[0], vm, a, m, c); SimpleBigDecimal lambda1 = ApproximateDivisionByN( k, s[1], vm, a, m, c); ZTauElement q = Round(lambda0, lambda1, mu); // r0 = n - d0*q0 - 2*s1*q1 IBigInteger r0 = k.Subtract(d0.Multiply(q.u)).Subtract( BigInteger.ValueOf(2).Multiply(s[1]).Multiply(q.v)); // r1 = s1*q0 - s0*q1 IBigInteger r1 = s[1].Multiply(q.u).Subtract(s[0].Multiply(q.v)); return(new ZTauElement(r0, r1)); }
private static IBigInteger CalculateGenerator_FIPS186_3_Verifiable(IDigest d, IBigInteger p, IBigInteger q, byte[] seed, int index) { // A.2.3 Verifiable Canonical Generation of the Generator g IBigInteger e = p.Subtract(BigInteger.One).Divide(q); byte[] ggen = Hex.Decode("6767656E"); // 7. U = domain_parameter_seed || "ggen" || index || count. byte[] U = new byte[seed.Length + ggen.Length + 1 + 2]; Array.Copy(seed, 0, U, 0, seed.Length); Array.Copy(ggen, 0, U, seed.Length, ggen.Length); U[U.Length - 3] = (byte)index; byte[] w = new byte[d.GetDigestSize()]; for (int count = 1; count < (1 << 16); ++count) { Inc(U); Hash(d, U, w); IBigInteger W = new BigInteger(1, w); IBigInteger g = W.ModPow(e, p); if (g.CompareTo(BigInteger.Two) >= 0) { return(g); } } return(null); }
private static IBigInteger CalculateGenerator_FIPS186_2(IBigInteger p, IBigInteger q, SecureRandom r) { IBigInteger e = p.Subtract(BigInteger.One).Divide(q); IBigInteger pSub2 = p.Subtract(BigInteger.Two); for (;;) { IBigInteger h = BigIntegers.CreateRandomInRange(BigInteger.Two, pSub2, r); IBigInteger g = h.ModPow(e, p); if (g.BitLength > 1) { return(g); } } }
/** * Computes the norm of an element <code>λ</code> of * <code><b>Z</b>[τ]</code>. * @param mu The parameter <code>μ</code> of the elliptic curve. * @param lambda The element <code>λ</code> of * <code><b>Z</b>[τ]</code>. * @return The norm of <code>λ</code>. */ public static IBigInteger Norm(sbyte mu, ZTauElement lambda) { IBigInteger norm; // s1 = u^2 IBigInteger s1 = lambda.u.Multiply(lambda.u); // s2 = u * v IBigInteger s2 = lambda.u.Multiply(lambda.v); // s3 = 2 * v^2 IBigInteger s3 = lambda.v.Multiply(lambda.v).ShiftLeft(1); if (mu == 1) { norm = s1.Add(s2).Add(s3); } else if (mu == -1) { norm = s1.Subtract(s2).Add(s3); } else { throw new ArgumentException("mu must be 1 or -1"); } return(norm); }
internal IBigInteger CalculatePrivate( DHParameters dhParams, ISecureRandom random) { int limit = dhParams.L; if (limit != 0) { return(new BigInteger(limit, random).SetBit(limit - 1)); } IBigInteger min = BigInteger.Two; int m = dhParams.M; if (m != 0) { min = BigInteger.One.ShiftLeft(m - 1); } IBigInteger max = dhParams.P.Subtract(BigInteger.Two); IBigInteger q = dhParams.Q; if (q != null) { max = q.Subtract(BigInteger.Two); } return(BigIntegers.CreateRandomInRange(min, max, random)); }
protected internal override ECPoint DecompressPoint(int yTilde, IBigInteger x1) { var x = FromBigInteger(x1); var alpha = x.Multiply(x.Square().Add(this.A)).Add(this.B); var beta = alpha.Sqrt(); // // if we can't find a sqrt we haven't got a point on the // curve - run! // if (beta == null) { throw new ArithmeticException("Invalid point compression"); } var betaValue = beta.ToBigInteger(); var bit0 = betaValue.TestBit(0) ? 1 : 0; if (bit0 != yTilde) { // Use the other root beta = FromBigInteger(_q.Subtract(betaValue)); } return(new FPPoint(this, x, beta, true)); }
/// <summary> /// Select a high order element of the multiplicative group Z /// /// p and q must be s.t. p = 2*q + 1, where p and q are prime (see generateSafePrimes) /// </summary> /// <param name="p">The p.</param> /// <param name="q">The q.</param> /// <param name="random">The random.</param> /// <returns></returns> internal static IBigInteger SelectGenerator(IBigInteger p, IBigInteger q, SecureRandom random) { var pMinusTwo = p.Subtract(BigInteger.Two); IBigInteger 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 { var h = BigIntegers.CreateRandomInRange(BigInteger.Two, pMinusTwo, random); g = h.ModPow(BigInteger.Two, p); }while (g.Equals(BigInteger.One)); return(g); }
public DHParameters( IBigInteger p, IBigInteger g, IBigInteger q, int m, int l, IBigInteger 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; }
public RsaSecretBcpgKey(IBigInteger d, IBigInteger p, IBigInteger q) { // PGP requires (p < q) var cmp = p.CompareTo(q); if (cmp >= 0) { if (cmp == 0) { throw new ArgumentException("p and q cannot be equal"); } var tmp = p; p = q; q = tmp; } _d = new MPInteger(d); _p = new MPInteger(p); _q = new MPInteger(q); _u = new MPInteger(p.ModInverse(q)); _expP = d.Remainder(p.Subtract(BigInteger.One)); _expQ = d.Remainder(q.Subtract(BigInteger.One)); _crt = q.ModInverse(p); }
/** * Computes the Window NAF (non-adjacent Form) of an integer. * @param width The width <code>w</code> of the Window NAF. The width is * defined as the minimal number <code>w</code>, such that for any * <code>w</code> consecutive digits in the resulting representation, at * most one is non-zero. * @param k The integer of which the Window NAF is computed. * @return The Window NAF of the given width, such that the following holds: * <code>k = −<sub>i=0</sub><sup>l-1</sup> k<sub>i</sub>2<sup>i</sup> * </code>, where the <code>k<sub>i</sub></code> denote the elements of the * returned <code>sbyte[]</code>. */ public sbyte[] WindowNaf(sbyte width, IBigInteger k) { // The window NAF is at most 1 element longer than the binary // representation of the integer k. sbyte can be used instead of short or // int unless the window width is larger than 8. For larger width use // short or int. However, a width of more than 8 is not efficient for // m = log2(q) smaller than 2305 Bits. Note: Values for m larger than // 1000 Bits are currently not used in practice. sbyte[] wnaf = new sbyte[k.BitLength + 1]; // 2^width as short and BigInteger short pow2wB = (short)(1 << width); IBigInteger pow2wBI = BigInteger.ValueOf(pow2wB); int i = 0; // The actual length of the WNAF int length = 0; // while k >= 1 while (k.SignValue > 0) { // if k is odd if (k.TestBit(0)) { // k Mod 2^width IBigInteger remainder = k.Mod(pow2wBI); // if remainder > 2^(width - 1) - 1 if (remainder.TestBit(width - 1)) { wnaf[i] = (sbyte)(remainder.IntValue - pow2wB); } else { wnaf[i] = (sbyte)remainder.IntValue; } // wnaf[i] is now in [-2^(width-1), 2^(width-1)-1] k = k.Subtract(BigInteger.ValueOf(wnaf[i])); length = i; } else { wnaf[i] = 0; } // k = k/2 k = k.ShiftRight(1); i++; } length++; // Reduce the WNAF array to its actual length sbyte[] wnafShort = new sbyte[length]; Array.Copy(wnaf, 0, wnafShort, 0, length); return(wnafShort); }
private IBigInteger CalculateS() { IBigInteger k = Srp6Utilities.CalculateK(digest, N, g); IBigInteger exp = u.Multiply(x).Add(privA); IBigInteger tmp = g.ModPow(x, N).Multiply(k).Mod(N); return(B.Subtract(tmp).Mod(N).ModPow(exp, N)); }
public static IBigInteger GeneratePrivateValue(IDigest digest, IBigInteger N, IBigInteger g, SecureRandom random) { int minBits = System.Math.Min(256, N.BitLength / 2); IBigInteger min = BigInteger.One.ShiftLeft(minBits - 1); IBigInteger max = N.Subtract(BigInteger.One); return(BigIntegers.CreateRandomInRange(min, max, random)); }
public static IBigInteger GeneratePrivateValue(IDigest digest, IBigInteger N, IBigInteger g, SecureRandom random) { int minBits = System.Math.Min(256, N.BitLength / 2); IBigInteger min = BigInteger.One.ShiftLeft(minBits - 1); IBigInteger max = N.Subtract(BigInteger.One); return BigIntegers.CreateRandomInRange(min, max, random); }
private static IBigInteger GeneratePrivateKey(IBigInteger q, ISecureRandom random) { // TODO Prefer this method? (change test cases that used fixed random) // B.1.1 Key Pair Generation Using Extra Random Bits // IBigInteger c = new BigInteger(q.BitLength + 64, random); // return c.Mod(q.Subtract(BigInteger.One)).Add(BigInteger.One); // B.1.2 Key Pair Generation by Testing Candidates return(BigIntegers.CreateRandomInRange(BigInteger.One, q.Subtract(BigInteger.One), random)); }
private static IBigInteger GeneratePrivateKey(IBigInteger q, ISecureRandom random) { // TODO Prefer this method? (change test cases that used fixed random) // B.1.1 Key Pair Generation Using Extra Random Bits // IBigInteger c = new BigInteger(q.BitLength + 64, random); // return c.Mod(q.Subtract(BigInteger.One)).Add(BigInteger.One); // B.1.2 Key Pair Generation by Testing Candidates return BigIntegers.CreateRandomInRange(BigInteger.One, q.Subtract(BigInteger.One), random); }
// Section 7.2.5 ECSP-NR, pg 34 /** * generate a signature for the given message using the key we were * initialised with. 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. * * @param digest the digest to be signed. * @exception DataLengthException if the digest is longer than the key allows */ public IBigInteger[] GenerateSignature( byte[] message) { if (!this._forSigning) { // not properly initilaized... deal with it throw new InvalidOperationException("not initialised for signing"); } IBigInteger n = ((ECPrivateKeyParameters)this._key).Parameters.N; int nBitLength = n.BitLength; IBigInteger e = new BigInteger(1, message); int eBitLength = e.BitLength; ECPrivateKeyParameters privKey = (ECPrivateKeyParameters)_key; if (eBitLength > nBitLength) { throw new DataLengthException("input too large for ECNR key."); } IBigInteger r = null; IBigInteger s = null; IAsymmetricCipherKeyPair tempPair; do // generate r { // generate another, but very temporary, key pair using // the same EC parameters ECKeyPairGenerator keyGen = new ECKeyPairGenerator(); keyGen.Init(new ECKeyGenerationParameters(privKey.Parameters, _random)); tempPair = keyGen.GenerateKeyPair(); // IBigInteger Vx = tempPair.getPublic().getW().getAffineX(); ECPublicKeyParameters V = (ECPublicKeyParameters)tempPair.Public; // get temp's public key IBigInteger Vx = V.Q.X.ToBigInteger(); // get the point's x coordinate r = Vx.Add(e).Mod(n); }while (r.SignValue == 0); // generate s IBigInteger x = privKey.D; // private key value IBigInteger u = ((ECPrivateKeyParameters)tempPair.Private).D; // temp's private key value s = u.Subtract(r.Multiply(x)).Mod(n); return(new IBigInteger[] { r, s }); }
public void TestDivideAndRemainder() { // TODO More basic tests IBigInteger n = new BigInteger(48, _random); IBigInteger[] qr = n.DivideAndRemainder(one); Assert.AreEqual(n, qr[0]); Assert.AreEqual(zero, qr[1]); 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[] es = d.DivideAndRemainder(a); Assert.AreEqual(b, es[0]); Assert.AreEqual(c, es[1]); } // 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); IBigInteger bMod = b.And(a.Subtract(one)); string data = "shift=" + shift + ", b=" + b.ToString(16); qr = b.DivideAndRemainder(a); Assert.AreEqual(bShift, qr[0], data); Assert.AreEqual(bMod, qr[1], data); qr = b.DivideAndRemainder(a.Negate()); Assert.AreEqual(bShift.Negate(), qr[0], data); Assert.AreEqual(bMod, qr[1], data); qr = b.Negate().DivideAndRemainder(a); Assert.AreEqual(bShift.Negate(), qr[0], data); Assert.AreEqual(bMod.Negate(), qr[1], data); qr = b.Negate().DivideAndRemainder(a.Negate()); Assert.AreEqual(bShift, qr[0], data); Assert.AreEqual(bMod.Negate(), qr[1], data); } }
protected virtual DHPublicKeyParameters ValidateDHPublicKey(DHPublicKeyParameters key) { IBigInteger Y = key.Y; DHParameters parameters = key.Parameters; IBigInteger p = parameters.P; IBigInteger g = parameters.G; if (!p.IsProbablePrime(2)) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } if (g.CompareTo(BigInteger.Two) < 0 || g.CompareTo(p.Subtract(BigInteger.Two)) > 0) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } if (Y.CompareTo(BigInteger.Two) < 0 || Y.CompareTo(p.Subtract(BigInteger.One)) > 0) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } // TODO See RFC 2631 for more discussion of Diffie-Hellman validation return(key); }
// 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, IBigInteger r, IBigInteger s) { if (this._forSigning) { // not properly initilaized... deal with it throw new InvalidOperationException("not initialised for verifying"); } ECPublicKeyParameters pubKey = (ECPublicKeyParameters)_key; IBigInteger n = pubKey.Parameters.N; int nBitLength = n.BitLength; IBigInteger 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); } // TODO So why is this different from the spec? // 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); IBigInteger x = P.X.ToBigInteger(); IBigInteger t = r.Subtract(x).Mod(n); return(t.Equals(e)); }
/** * Calculates the Lucas Sequence elements <code>U<sub>k-1</sub></code> and * <code>U<sub>k</sub></code> or <code>V<sub>k-1</sub></code> and * <code>V<sub>k</sub></code>. * @param mu The parameter <code>μ</code> of the elliptic curve. * @param k The index of the second element of the Lucas Sequence to be * returned. * @param doV If set to true, computes <code>V<sub>k-1</sub></code> and * <code>V<sub>k</sub></code>, otherwise <code>U<sub>k-1</sub></code> and * <code>U<sub>k</sub></code>. * @return An array with 2 elements, containing <code>U<sub>k-1</sub></code> * and <code>U<sub>k</sub></code> or <code>V<sub>k-1</sub></code> * and <code>V<sub>k</sub></code>. */ public static IBigInteger[] GetLucas(sbyte mu, int k, bool doV) { if (!(mu == 1 || mu == -1)) { throw new ArgumentException("mu must be 1 or -1"); } IBigInteger u0; IBigInteger u1; IBigInteger u2; if (doV) { u0 = BigInteger.Two; u1 = BigInteger.ValueOf(mu); } else { u0 = BigInteger.Zero; u1 = BigInteger.One; } for (int i = 1; i < k; i++) { // u2 = mu*u1 - 2*u0; IBigInteger s = null; if (mu == 1) { s = u1; } else { // mu == -1 s = u1.Negate(); } u2 = s.Subtract(u0.ShiftLeft(1)); u0 = u1; u1 = u2; // System.out.println(i + ": " + u2); // System.out.println(); } IBigInteger[] retVal = { u0, u1 }; return(retVal); }
public void TestMod() { // TODO Basic tests for (int rep = 0; rep < 100; ++rep) { int diff = _random.Next(25); IBigInteger a = new BigInteger(100 - diff, 0, _random); IBigInteger b = new BigInteger(100 + diff, 0, _random); IBigInteger c = new BigInteger(10 + diff, 0, _random); IBigInteger d = a.Multiply(b).Add(c); IBigInteger e = d.Mod(a); Assert.AreEqual(c, e); IBigInteger pow2 = one.ShiftLeft(_random.Next(128)); Assert.AreEqual(b.And(pow2.Subtract(one)), b.Mod(pow2)); } }
public void TestModPow() { try { two.ModPow(one, zero); Assert.Fail("expected ArithmeticException"); } catch (ArithmeticException) {} Assert.AreEqual(zero, zero.ModPow(zero, one)); Assert.AreEqual(one, zero.ModPow(zero, two)); Assert.AreEqual(zero, two.ModPow(one, one)); Assert.AreEqual(one, two.ModPow(zero, two)); for (int i = 0; i < 10; ++i) { IBigInteger m = BigInteger.ProbablePrime(10 + i * 3, _random); IBigInteger x = new BigInteger(m.BitLength - 1, _random); Assert.AreEqual(x, x.ModPow(m, m)); if (x.SignValue != 0) { Assert.AreEqual(zero, zero.ModPow(x, m)); Assert.AreEqual(one, x.ModPow(m.Subtract(one), m)); } IBigInteger y = new BigInteger(m.BitLength - 1, _random); IBigInteger n = new BigInteger(m.BitLength - 1, _random); IBigInteger n3 = n.ModPow(three, m); IBigInteger resX = n.ModPow(x, m); IBigInteger resY = n.ModPow(y, m); IBigInteger res = resX.Multiply(resY).Mod(m); IBigInteger res3 = res.ModPow(three, m); Assert.AreEqual(res3, n3.ModPow(x.Add(y), m)); IBigInteger a = x.Add(one); // Make sure it's not zero IBigInteger b = y.Add(one); // Make sure it's not zero Assert.AreEqual(a.ModPow(b, m).ModInverse(m), a.ModPow(b.Negate(), m)); } }
public DHParameters( IBigInteger p, IBigInteger g, IBigInteger q, int m, int l, IBigInteger 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; }
/** * Process a single block using the basic RSA algorithm. * * @param inBuf the input array. * @param inOff the offset into the input buffer where the data starts. * @param inLen the length of the data to be processed. * @return the result of the RSA process. * @exception DataLengthException the input block is too large. */ public byte[] ProcessBlock( byte[] inBuf, int inOff, int inLen) { if (key == null) { throw new InvalidOperationException("RSA engine not initialised"); } IBigInteger input = core.ConvertInput(inBuf, inOff, inLen); IBigInteger result; if (key is RsaPrivateCrtKeyParameters) { RsaPrivateCrtKeyParameters k = (RsaPrivateCrtKeyParameters)key; IBigInteger e = k.PublicExponent; if (e != null) // can't do blinding without a public exponent { IBigInteger m = k.Modulus; IBigInteger r = BigIntegers.CreateRandomInRange( BigInteger.One, m.Subtract(BigInteger.One), random); IBigInteger blindedInput = r.ModPow(e, m).Multiply(input).Mod(m); IBigInteger blindedResult = core.ProcessBlock(blindedInput); IBigInteger rInv = r.ModInverse(m); result = blindedResult.Multiply(rInv).Mod(m); } else { result = core.ProcessBlock(input); } } else { result = core.ProcessBlock(input); } return(core.ConvertOutput(result)); }
public void TestMultiply() { IBigInteger one = BigInteger.One; Assert.AreEqual(one, one.Negate().Multiply(one.Negate())); for (int i = 0; i < 100; ++i) { int aLen = 64 + _random.Next(64); int bLen = 64 + _random.Next(64); IBigInteger a = new BigInteger(aLen, _random).SetBit(aLen); IBigInteger b = new BigInteger(bLen, _random).SetBit(bLen); IBigInteger c = new BigInteger(32, _random); IBigInteger ab = a.Multiply(b); IBigInteger bc = b.Multiply(c); Assert.AreEqual(ab.Add(bc), a.Add(c).Multiply(b)); Assert.AreEqual(ab.Subtract(bc), a.Subtract(c).Multiply(b)); } // 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.ShiftLeft(shift); Assert.AreEqual(bShift, a.Multiply(b)); Assert.AreEqual(bShift.Negate(), a.Multiply(b.Negate())); Assert.AreEqual(bShift.Negate(), a.Negate().Multiply(b)); Assert.AreEqual(bShift, a.Negate().Multiply(b.Negate())); Assert.AreEqual(bShift, b.Multiply(a)); Assert.AreEqual(bShift.Negate(), b.Multiply(a.Negate())); Assert.AreEqual(bShift.Negate(), b.Negate().Multiply(a)); Assert.AreEqual(bShift, b.Negate().Multiply(a.Negate())); } }
/** * 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); } } } }
/** * return true if the value r and s represent a GOST3410 signature for * the passed in message (for standard GOST3410 the message should be * a GOST3411 hash of the real message to be verified). */ public bool VerifySignature( byte[] message, IBigInteger r, IBigInteger s) { byte[] mRev = new byte[message.Length]; // conversion is little-endian for (int i = 0; i != mRev.Length; i++) { mRev[i] = message[mRev.Length - 1 - i]; } IBigInteger e = new BigInteger(1, mRev); IBigInteger n = key.Parameters.N; // r in the range [1,n-1] if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0) { return(false); } // s in the range [1,n-1] if (s.CompareTo(BigInteger.One) < 0 || s.CompareTo(n) >= 0) { return(false); } IBigInteger v = e.ModInverse(n); IBigInteger z1 = s.Multiply(v).Mod(n); IBigInteger z2 = (n.Subtract(r)).Multiply(v).Mod(n); ECPoint G = key.Parameters.G; // P ECPoint Q = ((ECPublicKeyParameters)key).Q; ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, z1, Q, z2); IBigInteger R = point.X.ToBigInteger().Mod(n); return(R.Equals(r)); }
public RsaSecretBcpgKey(IBigInteger d, IBigInteger p, IBigInteger q) { // PGP requires (p < q) var cmp = p.CompareTo(q); if (cmp >= 0) { if (cmp == 0) throw new ArgumentException("p and q cannot be equal"); var tmp = p; p = q; q = tmp; } _d = new MPInteger(d); _p = new MPInteger(p); _q = new MPInteger(q); _u = new MPInteger(p.ModInverse(q)); _expP = d.Remainder(p.Subtract(BigInteger.One)); _expQ = d.Remainder(q.Subtract(BigInteger.One)); _crt = q.ModInverse(p); }
public SimpleBigDecimal Subtract(IBigInteger b) { return(new SimpleBigDecimal(bigInt.Subtract(b.ShiftLeft(scale)), scale)); }
/** * Computes the <code>τ</code>-adic NAF (non-adjacent form) of an * element <code>λ</code> of <code><b>Z</b>[τ]</code>. * @param mu The parameter <code>μ</code> of the elliptic curve. * @param lambda The element <code>λ</code> of * <code><b>Z</b>[τ]</code>. * @return The <code>τ</code>-adic NAF of <code>λ</code>. */ public static sbyte[] TauAdicNaf(sbyte mu, ZTauElement lambda) { if (!((mu == 1) || (mu == -1))) { throw new ArgumentException("mu must be 1 or -1"); } IBigInteger norm = Norm(mu, lambda); // Ceiling of log2 of the norm int log2Norm = norm.BitLength; // If length(TNAF) > 30, then length(TNAF) < log2Norm + 3.52 int maxLength = log2Norm > 30 ? log2Norm + 4 : 34; // The array holding the TNAF sbyte[] u = new sbyte[maxLength]; int i = 0; // The actual length of the TNAF int length = 0; IBigInteger r0 = lambda.u; IBigInteger r1 = lambda.v; while (!((r0.Equals(BigInteger.Zero)) && (r1.Equals(BigInteger.Zero)))) { // If r0 is odd if (r0.TestBit(0)) { u[i] = (sbyte)BigInteger.Two.Subtract((r0.Subtract(r1.ShiftLeft(1))).Mod(Four)).IntValue; // r0 = r0 - u[i] if (u[i] == 1) { r0 = r0.ClearBit(0); } else { // u[i] == -1 r0 = r0.Add(BigInteger.One); } length = i; } else { u[i] = 0; } IBigInteger t = r0; IBigInteger s = r0.ShiftRight(1); if (mu == 1) { r0 = r1.Add(s); } else { // mu == -1 r0 = r1.Subtract(s); } r1 = t.ShiftRight(1).Negate(); i++; } length++; // Reduce the TNAF array to its actual length sbyte[] tnaf = new sbyte[length]; Array.Copy(u, 0, tnaf, 0, length); return(tnaf); }
/// <summary> /// Select a high order element of the multiplicative group Z /// /// p and q must be s.t. p = 2*q + 1, where p and q are prime (see generateSafePrimes) /// </summary> /// <param name="p">The p.</param> /// <param name="q">The q.</param> /// <param name="random">The random.</param> /// <returns></returns> internal static IBigInteger SelectGenerator(IBigInteger p, IBigInteger q, SecureRandom random) { var pMinusTwo = p.Subtract(BigInteger.Two); IBigInteger 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 { var h = BigIntegers.CreateRandomInRange(BigInteger.Two, pMinusTwo, random); g = h.ModPow(BigInteger.Two, p); } while (g.Equals(BigInteger.One)); return g; }
/** * @exception InvalidCipherTextException if the decrypted block is not a valid ISO 9796 bit string */ private byte[] DecodeBlock( byte[] input, int inOff, int inLen) { byte[] block = engine.ProcessBlock(input, inOff, inLen); int r = 1; int t = (bitSize + 13) / 16; IBigInteger iS = new BigInteger(1, block); IBigInteger iR; if (iS.Mod(Sixteen).Equals(Six)) { iR = iS; } else { iR = modulus.Subtract(iS); if (!iR.Mod(Sixteen).Equals(Six)) { throw new InvalidCipherTextException("resulting integer iS or (modulus - iS) is not congruent to 6 mod 16"); } } block = iR.ToByteArrayUnsigned(); if ((block[block.Length - 1] & 0x0f) != 0x6) { throw new InvalidCipherTextException("invalid forcing byte in block"); } block[block.Length - 1] = (byte)(((ushort)(block[block.Length - 1] & 0xff) >> 4) | ((inverse[(block[block.Length - 2] & 0xff) >> 4]) << 4)); block[0] = (byte)((shadows[(uint)(block[1] & 0xff) >> 4] << 4) | shadows[block[1] & 0x0f]); bool boundaryFound = false; int boundary = 0; for (int i = block.Length - 1; i >= block.Length - 2 * t; i -= 2) { int val = ((shadows[(uint)(block[i] & 0xff) >> 4] << 4) | shadows[block[i] & 0x0f]); if (((block[i - 1] ^ val) & 0xff) != 0) { if (!boundaryFound) { boundaryFound = true; r = (block[i - 1] ^ val) & 0xff; boundary = i - 1; } else { throw new InvalidCipherTextException("invalid tsums in block"); } } } block[boundary] = 0; byte[] nblock = new byte[(block.Length - boundary) / 2]; for (int i = 0; i < nblock.Length; i++) { nblock[i] = block[2 * i + boundary + 1]; } padBits = r - 1; return(nblock); }
/** * Computes the <code>[τ]</code>-adic window NAF of an element * <code>λ</code> of <code><b>Z</b>[τ]</code>. * @param mu The parameter μ of the elliptic curve. * @param lambda The element <code>λ</code> of * <code><b>Z</b>[τ]</code> of which to compute the * <code>[τ]</code>-adic NAF. * @param width The window width of the resulting WNAF. * @param pow2w 2<sup>width</sup>. * @param tw The auxiliary value <code>t<sub>w</sub></code>. * @param alpha The <code>α<sub>u</sub></code>'s for the window width. * @return The <code>[τ]</code>-adic window NAF of * <code>λ</code>. */ public static sbyte[] TauAdicWNaf(sbyte mu, ZTauElement lambda, sbyte width, IBigInteger pow2w, IBigInteger tw, ZTauElement[] alpha) { if (!((mu == 1) || (mu == -1))) { throw new ArgumentException("mu must be 1 or -1"); } IBigInteger norm = Norm(mu, lambda); // Ceiling of log2 of the norm int log2Norm = norm.BitLength; // If length(TNAF) > 30, then length(TNAF) < log2Norm + 3.52 int maxLength = log2Norm > 30 ? log2Norm + 4 + width : 34 + width; // The array holding the TNAF sbyte[] u = new sbyte[maxLength]; // 2^(width - 1) IBigInteger pow2wMin1 = pow2w.ShiftRight(1); // Split lambda into two BigIntegers to simplify calculations IBigInteger r0 = lambda.u; IBigInteger r1 = lambda.v; int i = 0; // while lambda <> (0, 0) while (!((r0.Equals(BigInteger.Zero)) && (r1.Equals(BigInteger.Zero)))) { // if r0 is odd if (r0.TestBit(0)) { // uUnMod = r0 + r1*tw Mod 2^width IBigInteger uUnMod = r0.Add(r1.Multiply(tw)).Mod(pow2w); sbyte uLocal; // if uUnMod >= 2^(width - 1) if (uUnMod.CompareTo(pow2wMin1) >= 0) { uLocal = (sbyte)uUnMod.Subtract(pow2w).IntValue; } else { uLocal = (sbyte)uUnMod.IntValue; } // uLocal is now in [-2^(width-1), 2^(width-1)-1] u[i] = uLocal; bool s = true; if (uLocal < 0) { s = false; uLocal = (sbyte)-uLocal; } // uLocal is now >= 0 if (s) { r0 = r0.Subtract(alpha[uLocal].u); r1 = r1.Subtract(alpha[uLocal].v); } else { r0 = r0.Add(alpha[uLocal].u); r1 = r1.Add(alpha[uLocal].v); } } else { u[i] = 0; } IBigInteger t = r0; if (mu == 1) { r0 = r1.Add(r0.ShiftRight(1)); } else { // mu == -1 r0 = r1.Subtract(r0.ShiftRight(1)); } r1 = t.ShiftRight(1).Negate(); i++; } return(u); }
private static IBigInteger CalculateGenerator_FIPS186_3_Verifiable(IDigest d, IBigInteger p, IBigInteger q, byte[] seed, int index) { // A.2.3 Verifiable Canonical Generation of the Generator g IBigInteger e = p.Subtract(BigInteger.One).Divide(q); byte[] ggen = Hex.Decode("6767656E"); // 7. U = domain_parameter_seed || "ggen" || index || count. byte[] U = new byte[seed.Length + ggen.Length + 1 + 2]; Array.Copy(seed, 0, U, 0, seed.Length); Array.Copy(ggen, 0, U, seed.Length, ggen.Length); U[U.Length - 3] = (byte)index; byte[] w = new byte[d.GetDigestSize()]; for (int count = 1; count < (1 << 16); ++count) { Inc(U); Hash(d, U, w); IBigInteger W = new BigInteger(1, w); IBigInteger g = W.ModPow(e, p); if (g.CompareTo(BigInteger.Two) >= 0) return g; } return null; }
// 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, IBigInteger r, IBigInteger s) { if (this._forSigning) { // not properly initilaized... deal with it throw new InvalidOperationException("not initialised for verifying"); } ECPublicKeyParameters pubKey = (ECPublicKeyParameters)_key; IBigInteger n = pubKey.Parameters.N; int nBitLength = n.BitLength; IBigInteger 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; } // TODO So why is this different from the spec? // 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); IBigInteger x = P.X.ToBigInteger(); IBigInteger t = r.Subtract(x).Mod(n); return t.Equals(e); }
/** * Partial modular reduction modulo * <code>(τ<sup>m</sup> - 1)/(τ - 1)</code>. * @param k The integer to be reduced. * @param m The bitlength of the underlying finite field. * @param a The parameter <code>a</code> of the elliptic curve. * @param s The auxiliary values <code>s<sub>0</sub></code> and * <code>s<sub>1</sub></code>. * @param mu The parameter μ of the elliptic curve. * @param c The precision (number of bits of accuracy) of the partial * modular reduction. * @return <code>ρ := k partmod (τ<sup>m</sup> - 1)/(τ - 1)</code> */ public static ZTauElement PartModReduction(IBigInteger k, int m, sbyte a, IBigInteger[] s, sbyte mu, sbyte c) { // d0 = s[0] + mu*s[1]; mu is either 1 or -1 IBigInteger d0; if (mu == 1) { d0 = s[0].Add(s[1]); } else { d0 = s[0].Subtract(s[1]); } IBigInteger[] v = GetLucas(mu, m, true); IBigInteger vm = v[1]; SimpleBigDecimal lambda0 = ApproximateDivisionByN( k, s[0], vm, a, m, c); SimpleBigDecimal lambda1 = ApproximateDivisionByN( k, s[1], vm, a, m, c); ZTauElement q = Round(lambda0, lambda1, mu); // r0 = n - d0*q0 - 2*s1*q1 IBigInteger r0 = k.Subtract(d0.Multiply(q.u)).Subtract( BigInteger.ValueOf(2).Multiply(s[1]).Multiply(q.v)); // r1 = s1*q0 - s0*q1 IBigInteger r1 = s[1].Multiply(q.u).Subtract(s[0].Multiply(q.v)); return new ZTauElement(r0, r1); }
/** * Computes the Window NAF (non-adjacent Form) of an integer. * @param width The width <code>w</code> of the Window NAF. The width is * defined as the minimal number <code>w</code>, such that for any * <code>w</code> consecutive digits in the resulting representation, at * most one is non-zero. * @param k The integer of which the Window NAF is computed. * @return The Window NAF of the given width, such that the following holds: * <code>k = −<sub>i=0</sub><sup>l-1</sup> k<sub>i</sub>2<sup>i</sup> * </code>, where the <code>k<sub>i</sub></code> denote the elements of the * returned <code>sbyte[]</code>. */ public sbyte[] WindowNaf(sbyte width, IBigInteger k) { // The window NAF is at most 1 element longer than the binary // representation of the integer k. sbyte can be used instead of short or // int unless the window width is larger than 8. For larger width use // short or int. However, a width of more than 8 is not efficient for // m = log2(q) smaller than 2305 Bits. Note: Values for m larger than // 1000 Bits are currently not used in practice. sbyte[] wnaf = new sbyte[k.BitLength + 1]; // 2^width as short and BigInteger short pow2wB = (short)(1 << width); IBigInteger pow2wBI = BigInteger.ValueOf(pow2wB); int i = 0; // The actual length of the WNAF int length = 0; // while k >= 1 while (k.SignValue > 0) { // if k is odd if (k.TestBit(0)) { // k Mod 2^width IBigInteger remainder = k.Mod(pow2wBI); // if remainder > 2^(width - 1) - 1 if (remainder.TestBit(width - 1)) { wnaf[i] = (sbyte)(remainder.IntValue - pow2wB); } else { wnaf[i] = (sbyte)remainder.IntValue; } // wnaf[i] is now in [-2^(width-1), 2^(width-1)-1] k = k.Subtract(BigInteger.ValueOf(wnaf[i])); length = i; } else { wnaf[i] = 0; } // k = k/2 k = k.ShiftRight(1); i++; } length++; // Reduce the WNAF array to its actual length sbyte[] wnafShort = new sbyte[length]; Array.Copy(wnaf, 0, wnafShort, 0, length); return wnafShort; }
public IBigInteger Add( IBigInteger value) { if (this.SignValue == 0) return value; if (this.SignValue != value.SignValue) { if (value.SignValue == 0) return this; if (value.SignValue < 0) return Subtract(value.Negate()); return value.Subtract(Negate()); } return AddToMagnitude(value.Magnitude); }
/// <summary> /// D.1.4 91 /// return a sqrt root - the routine verifies that the calculation /// returns the right value - if none exists it returns null. /// </summary> /// <returns></returns> public override ECFieldElement Sqrt() { if (!_q.TestBit(0)) { throw Platform.CreateNotImplementedException("even value of q"); } // p mod 4 == 3 if (_q.TestBit(1)) { // TODO Can this be optimised (inline the Square?) // z = g^(u+1) + p, p = 4u + 3 var z = new FPFieldElement(_q, _x.ModPow(_q.ShiftRight(2).Add(BigInteger.One), _q)); return(z.Square().Equals(this) ? z : null); } // p mod 4 == 1 var qMinusOne = _q.Subtract(BigInteger.One); var legendreExponent = qMinusOne.ShiftRight(1); if (!(_x.ModPow(legendreExponent, _q).Equals(BigInteger.One))) { return(null); } var u = qMinusOne.ShiftRight(2); var k = u.ShiftLeft(1).Add(BigInteger.One); var Q = _x; var fourQ = Q.ShiftLeft(2).Mod(_q); IBigInteger U; IBigInteger V; do { IRandom rand = new Random(); IBigInteger P; do { P = new BigInteger(_q.BitLength, rand); }while (P.CompareTo(_q) >= 0 || !(P.Multiply(P).Subtract(fourQ).ModPow(legendreExponent, _q).Equals(qMinusOne))); var result = FastLucasSequence(_q, P, Q, k); U = result[0]; V = result[1]; if (!V.Multiply(V).Mod(_q).Equals(fourQ)) { continue; } // Integer division by 2, mod q if (V.TestBit(0)) { V = V.Add(_q); } V = V.ShiftRight(1); Debug.Assert(V.Multiply(V).Mod(_q).Equals(_x)); return(new FPFieldElement(_q, V)); }while (U.Equals(BigInteger.One) || U.Equals(qMinusOne)); return(null); }
/** * 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; } } } }