/// <summary> /// Uses the fermat test a given amount of times to test whether or not a supplied interger is probably prime. /// </summary> /// <param name="b">Value to test primality of</param> /// <param name="provider">Random provider used to generate values to test b against</param> /// <param name="certainty">How many times the test should be performed. More iterations means higher certainty, but at the cost of performance!</param> /// <returns>Whether or not the given value is probably prime or not</returns> public static bool IsProbablePrime(BigInteger b, RandomProvider provider, int certainty) { BigInteger e = b - 1; byte[] b1 = b.ToByteArray(); byte last = b1[b1.Length - 1]; int len = b1.Length - 1; for (int i = 0; i < certainty; ++i) { byte[] gen = new byte[provider.NextInt(len) + 1]; provider.GetBytes(gen); if (last != 0 && gen.Length == len + 1) { gen[gen.Length - 1] %= last; } else { gen[gen.Length - 1] &= 127; } BigInteger test = new BigInteger(gen); if (ModExp(test, e, b) != 1) { return(false); } } return(true); }
private byte[] GenerateSequence() { // Generate between 0 and maxLen random bytes to be used as padding byte[] padding = provider.GetBytes(provider.NextUShort((ushort)(maxLen + 1))); // Remove instances of the delimiter sequence from the padding int idx; while ((idx = Support.ArrayContains(padding, delimiter)) != -1) { foreach (byte val in provider.GetBytes(delimiter.Length)) { padding[idx++] = val; } } return(padding); }
/// <summary> /// Generate a prime number using with a given approximate length and byte length margin /// </summary> /// <param name="threads">How many threads to use to generate primes</param> /// <param name="approximateByteCount">The byte array length around which the prime generator will select lengths</param> /// <param name="byteMargin">Allowed deviation of byte length from approximateByteCount</param> /// <param name="certainty">How many iterations of the fermat test should be run to test primailty for each generated number</param> /// <param name="provider">Random provider that will be used to generate random primes</param> /// <returns>A prime number that is aproximately approximateByteCount long</returns> public static BigInteger GeneratePrime(int threads, int approximateByteCount, int byteMargin, int certainty, RandomProvider provider) { var found = false; BigInteger result = BigInteger.Zero; for (int i = 0; i < threads; ++i) { Task.Factory.StartNew(() => { char left = '\0'; byte rand = 0; BigInteger b = BigInteger.Zero; while (!found) { if (left == 0) { rand = provider.GetBytes(1)[0]; left = (char)8; } byte[] b1 = provider.GetBytes(approximateByteCount + (provider.GetBytes(1)[0] % byteMargin) * (rand % 2 == 1 ? 1 : -1)); b1[0] |= 1; // Always odd b1[b1.Length - 1] &= 127; // Always positive b = new BigInteger(b1); rand >>= 1; --left; if (IsProbablePrime(b, provider, certainty)) { found = true; result = b; } } }); } while (!found) { System.Threading.Thread.Sleep(125); } return(result); }
public static BigInteger GenerateBoundedRandom(BigInteger max, RandomProvider provider) { byte[] b = max.ToByteArray(); byte maxLast = b[b.Length - 1]; provider.GetBytes(b); if (maxLast != 0) { b[b.Length - 1] %= maxLast; } b[b.Length - 1] |= 127; return(new BigInteger(b)); }
public static BigInteger GenerateRandom(this RandomProvider provider, BigInteger bound) { byte[] b = bound.ToByteArray(); if (b.Length == 0) { return(0); } byte b1 = b[b.Length - 1]; provider.GetBytes(b); b[b.Length - 1] %= b1; return(new BigInteger(b)); }
public byte[] Pad(byte[] message) { if (message.Length % determiner != 0) { byte[] result = new byte[message.Length + increments]; Array.Copy(message, result, message.Length); Array.Copy(provider.GetBytes(increments), 0, result, message.Length, increments); return(result); } else { return(message); } }