/* * Create a new random prime with a specific length (in bits). The * returned prime will have its two top bits set, _and_ its two * least significant bits set as well. The size parameter must be * greater than or equal to 9 (that is, the unsigned encoding of * the prime will need at least two bytes). */ public static byte[] RandPrime(int size) { if (size < 9) { throw new CryptoException( "Invalid size for prime generation"); } int len = (size + 7) >> 3; byte[] buf = new byte[len]; int hm1 = 0xFFFF >> ((len << 3) - size); int hm2 = 0xC000 >> ((len << 3) - size); for (;;) { RNG.GetBytes(buf); buf[len - 1] |= (byte)0x03; int x = (buf[0] << 8) | buf[1]; x &= hm1; x |= hm2; buf[0] = (byte)(x >> 8); buf[1] = (byte)x; if (IsPrime(buf)) { return(buf); } } }
static byte[] RandInt(byte[] max, bool notZero) { int mlen = BitLength(max); if (mlen == 0 || (notZero && mlen == 1)) { throw new CryptoException( "Null maximum for random generation"); } byte[] x = new byte[(mlen + 7) >> 3]; byte hm = (byte)(0xFF >> ((8 - mlen) & 7)); for (;;) { RNG.GetBytes(x); x[0] &= hm; if (notZero && IsZero(x)) { continue; } if (CompareCT(x, max) >= 0) { continue; } return(x); } }
public override byte[] MakeRandomSecret() { /* * For Curve25519, we simply generate a random 32-byte * array, to which we apply the "clamping" that will * be done for point multiplication anyway. */ byte[] x = new byte[32]; RNG.GetBytes(x); x[0] &= 0x7F; x[0] |= 0x40; x[31] &= 0xF8; return(x); }
internal RFC6979(IDigest h, byte[] q, byte[] x, byte[] hv, int hvOff, int hvLen, bool deterministic) { if (h == null) { h = new SHA256(); } else { h = h.Dup(); h.Reset(); } drbg = new HMAC_DRBG(h); mh = new ModInt(q); qlen = mh.ModBitLength; int qolen = (qlen + 7) >> 3; this.q = new byte[qolen]; Array.Copy(q, q.Length - qolen, this.q, 0, qolen); int hlen = hvLen << 3; if (hlen > qlen) { byte[] htmp = new byte[hvLen]; Array.Copy(hv, hvOff, htmp, 0, hv.Length); BigInt.RShift(htmp, hlen - qlen); hv = htmp; hvOff = 0; } mh.DecodeReduce(hv, hvOff, hvLen); ModInt mx = mh.Dup(); mx.Decode(x); byte[] seed = new byte[(qolen << 1) + (deterministic ? 0 : 32)]; mx.Encode(seed, 0, qolen); mh.Encode(seed, qolen, qolen); if (!deterministic) { RNG.GetBytes(seed, qolen << 1, seed.Length - (qolen << 1)); } drbg.SetSeed(seed); }
/* obsolete * public override uint Mul(byte[] G, byte[] x, byte[] D, bool compressed) * { * MutableECPointPrime P = new MutableECPointPrime(this); * uint good = P.DecodeCT(G); * good &= ~P.IsInfinityCT; * good &= P.MulSpecCT(x); * good &= P.Encode(D, compressed); * return good; * } * * public override uint MulAdd(byte[] A, byte[] x, byte[] B, byte[] y, * byte[] D, bool compressed) * { * MutableECPointPrime P = new MutableECPointPrime(this); * MutableECPointPrime Q = new MutableECPointPrime(this); * * uint good = P.DecodeCT(A); * good &= Q.DecodeCT(B); * good &= ~P.IsInfinityCT & ~Q.IsInfinityCT; * * good &= P.MulSpecCT(x); * good &= Q.MulSpecCT(y); * good &= ~P.IsInfinityCT & ~Q.IsInfinityCT; * * uint z = P.AddCT(Q); * Q.DoubleCT(); * P.Set(Q, ~z); * * good &= P.Encode(D, compressed); * return good; * } */ public override byte[] MakeRandomSecret() { /* * We force the top bits to 0 to guarantee that the value * is less than the subgroup order; and we force the * least significant bit to 0 so that the value is not null. * This is good enough for ECDH. */ byte[] q = SubgroupOrder; byte[] x = new byte[q.Length]; int mask = 0xFF; while (mask >= q[0]) { mask >>= 1; } RNG.GetBytes(x); x[0] &= (byte)mask; x[x.Length - 1] |= (byte)0x01; return(x); }
/* * Test an integer for primality. This function runs up to 50 * Miller-Rabin rounds, which is a lot of overkill but ensures * that non-primes will be reliably detected (with overwhelming * probability) even with maliciously crafted inputs. "Normal" * non-primes will be detected most of the time at the first * iteration. * * This function is not constant-time. */ public static bool IsPrime(byte[] x) { x = NormalizeBE(x); /* * Handle easy cases: * 0 is not prime * small primes (one byte) are known in a constant bit-field * even numbers (larger than one byte) are non-primes */ if (x.Length == 0) { return(false); } if (x.Length == 1) { return(IsSmallPrime(x[0])); } if ((x[x.Length - 1] & 0x01) == 0) { return(false); } /* * Perform some trial divisions by small primes. */ for (int sp = 3; sp < 256; sp += 2) { if (!IsSmallPrime(sp)) { continue; } int z = 0; foreach (byte b in x) { z = ((z << 8) + b) % sp; } if (z == 0) { return(false); } } /* * Run some Miller-Rabin rounds. We use as basis random * integers that are one byte smaller than the modulus. */ ModInt xm1 = new ModInt(x); ModInt y = xm1.Dup(); y.Set(1); xm1.Sub(y); byte[] e = xm1.Encode(); ModInt a = new ModInt(x); byte[] buf = new byte[x.Length - 1]; for (int i = 0; i < 50; i++) { RNG.GetBytes(buf); a.Decode(buf); a.Pow(e); if (!a.IsOne) { return(false); } } return(true); }