private bool _MakeTest(OmgNum testBase) { OmgNum numDec = (new OmgNum(m_tested)).Dec(); OmgNum tested = OmgOp.Pow(testBase, m_initialTested, m_tested); OmgNum iterationsLeft = new OmgNum(m_powerOfTwo); try { if (OmgOp.Equal(tested, OmgNum.GetConst(1)) || OmgOp.Equal(tested, numDec)) { return(true); } while (!iterationsLeft.IsZero()) { iterationsLeft.Dec(); var nwTested = OmgOp.Multiply(tested, tested, m_tested); tested.Release(); tested = nwTested; if (OmgOp.Equal(tested, numDec)) { return(true); } } return(false); } finally { numDec.Release(); tested.Release(); iterationsLeft.Release(); } }
public Key GenerateKey(int keyByteLength) { int componentLength = keyByteLength * 8 / 2; OmgNum p = m_primeSource.GeneratePrime(componentLength); OmgNum q = m_primeSource.GeneratePrime(componentLength); OmgNum n = OmgOp.Multiply(p, q); OmgNum phiP = OmgOp.Subtract(p, OmgNum.GetConst(1)); OmgNum phiQ = OmgOp.Subtract(q, OmgNum.GetConst(1)); OmgNum carmN = _Carmichael(phiP, phiQ); OmgNum e = _SelectExponent(carmN); bool dpExists = OmgOp.TryInverseByMod(e, phiP, out OmgNum dP); bool dQExists = OmgOp.TryInverseByMod(e, phiQ, out OmgNum dQ); bool qInvExists = OmgOp.TryInverseByMod(q, p, out OmgNum qInv); if (!dpExists || !dQExists || !qInvExists) { throw new OmgFailException("Inverse is impossible"); } return(new Key { pub = new PubKey { N = n, E = e }, priv = new PrivKey { P = p, Q = q, dP = dP, dQ = dQ, qInv = qInv } }); }
private void _FactorPowerOfTwo(OmgNum num) { m_powerOfTwo?.Release(); m_initialTested?.Release(); var n = OmgOp.Subtract(num, OmgNum.GetConst(1)); m_powerOfTwo = 0.ToOmgNum(); (OmgNum div, OmgNum mod)divMod = OmgOp.DivMod(n, OmgNum.GetConst(2)); while (divMod.mod.IsZero()) { n.Release(); divMod.mod.Release(); n = divMod.div; m_powerOfTwo.Inc(); divMod = OmgOp.DivMod(n, OmgNum.GetConst(2)); } divMod.div.Release(); divMod.mod.Release(); m_initialTested = n; }
private OmgNum _SelectRandomExponent(OmgNum carmN, out OmgNum D) { OmgNum e = OmgOp.Random(OmgNum.GetConst(0), carmN); while (!OmgOp.TryInverseByMod(e, carmN, out D)) { e = OmgOp.Random(OmgNum.GetConst(0), carmN); } return(e); }
public void SetTestedNumber(OmgNum num) { m_tested?.Release(); m_tested = num; m_shurelyNotAPrime = OmgOp.Less(num, OmgNum.GetConst(2)); m_shurelyNotAPrime = m_shurelyNotAPrime || !m_smallPrimeTester.IsPrime(m_tested); if (!m_shurelyNotAPrime && OmgOp.Greater(num, OmgNum.GetConst(1))) { _FactorPowerOfTwo(num); } }
public void NumberOfPrimesLessThen10000base2and3() { int count = 0; for (int i = 1; i < 10000; i++) { m_millerRabin.SetTestedNumber(i.ToOmgNum()); if (m_millerRabin.IsPrimeToBase(OmgNum.GetConst(2)) && m_millerRabin.IsPrimeToBase(OmgNum.GetConst(3))) { count++; } } Assert.AreEqual(count, 1227); }
public bool IsPrimeToBase(OmgNum testBase) { if (OmgOp.Less(m_tested, OmgNum.GetConst(1))) { return(false); } if (m_shurelyNotAPrime) { return(false); } bool result = _MakeTest(testBase); return(result); }
private bool _TestFailed(OmgNum num) { m_primeTester.SetTestedNumber(num.Copy()); for (int i = 0; i < m_testsPerNumber; i++) { OmgNum testBase = OmgOp.Random(OmgNum.GetConst(2), num); bool isPrime = m_primeTester.IsPrimeToBase(testBase); testBase.Release(); if (!isPrime) { return(true); } } return(false); }