using System; namespace Mono.Math.Prime { // Token: 0x02000098 RID: 152 internal sealed class PrimalityTests { // Token: 0x0600084A RID: 2122 RVA: 0x0001E4B4 File Offset: 0x0001C6B4 private PrimalityTests() { } // Token: 0x0600084B RID: 2123 RVA: 0x0001E4BC File Offset: 0x0001C6BC private static int GetSPPRounds(BigInteger bi, ConfidenceFactor confidence) { int num = bi.BitCount(); int num2; if (num <= 100) { num2 = 27; } else if (num <= 150) { num2 = 18; } else if (num <= 200) { num2 = 15; } else if (num <= 250) { num2 = 12; } else if (num <= 300) { num2 = 9; } else if (num <= 350) { num2 = 8; } else if (num <= 400) { num2 = 7; } else if (num <= 500) { num2 = 6; } else if (num <= 600) { num2 = 5; } else if (num <= 800) { num2 = 4; } else if (num <= 1250) { num2 = 3; } else { num2 = 2; } switch (confidence) { case ConfidenceFactor.ExtraLow: num2 >>= 2; return (num2 == 0) ? 1 : num2; case ConfidenceFactor.Low: num2 >>= 1; return (num2 == 0) ? 1 : num2; case ConfidenceFactor.Medium: return num2; case ConfidenceFactor.High: return num2 << 1; case ConfidenceFactor.ExtraHigh: return num2 << 2; case ConfidenceFactor.Provable: throw new Exception("The Rabin-Miller test can not be executed in a way such that its results are provable"); default: throw new ArgumentOutOfRangeException("confidence"); } } // Token: 0x0600084C RID: 2124 RVA: 0x0001E604 File Offset: 0x0001C804 public static bool Test(BigInteger n, ConfidenceFactor confidence) { if (n.BitCount() < 33) { return PrimalityTests.SmallPrimeSppTest(n, confidence); } return PrimalityTests.RabinMillerTest(n, confidence); } // Token: 0x0600084D RID: 2125 RVA: 0x0001E624 File Offset: 0x0001C824 public static bool RabinMillerTest(BigInteger n, ConfidenceFactor confidence) { int num = n.BitCount(); int spprounds = PrimalityTests.GetSPPRounds(num, confidence); BigInteger bigInteger = n - 1; int num2 = bigInteger.LowestSetBit(); BigInteger bigInteger2 = bigInteger >> num2; BigInteger.ModulusRing modulusRing = new BigInteger.ModulusRing(n); BigInteger bigInteger3 = null; if (n.BitCount() > 100) { bigInteger3 = modulusRing.Pow(2U, bigInteger2); } for (int i = 0; i < spprounds; i++) { if (i > 0 || bigInteger3 == null) { BigInteger bigInteger4; do { bigInteger4 = BigInteger.GenerateRandom(num); } while (bigInteger4 <= 2 && bigInteger4 >= bigInteger); bigInteger3 = modulusRing.Pow(bigInteger4, bigInteger2); } if (!(bigInteger3 == 1U)) { int num3 = 0; while (num3 < num2 && bigInteger3 != bigInteger) { bigInteger3 = modulusRing.Pow(bigInteger3, 2); if (bigInteger3 == 1U) { return false; } num3++; } if (bigInteger3 != bigInteger) { return false; } } } return true; } // Token: 0x0600084E RID: 2126 RVA: 0x0001E750 File Offset: 0x0001C950 public static bool SmallPrimeSppTest(BigInteger bi, ConfidenceFactor confidence) { int spprounds = PrimalityTests.GetSPPRounds(bi, confidence); BigInteger bigInteger = bi - 1; int num = bigInteger.LowestSetBit(); BigInteger bigInteger2 = bigInteger >> num; BigInteger.ModulusRing modulusRing = new BigInteger.ModulusRing(bi); for (int i = 0; i < spprounds; i++) { BigInteger bigInteger3 = modulusRing.Pow(BigInteger.smallPrimes[i], bigInteger2); if (!(bigInteger3 == 1U)) { bool flag = false; for (int j = 0; j < num; j++) { if (bigInteger3 == bigInteger) { flag = true; break; } bigInteger3 = bigInteger3 * bigInteger3 % bi; } if (!flag) { return false; } } } return true; } } }