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(); } }
internal RawNum Sqrt(RawNum left) { m_targetSquare = left; m_targetSquareNum = m_targetSquare.OmgWrapper(); m_rootAprox = OmgPool.GetRawZero(); m_buffer = OmgPool.GetRawZero(); _FillInitialApproximation(); while (!_AproxEqualToBuffer()) { var aproxCopy = OmgPool.GetRawZero(); aproxCopy.CopyFrom(m_rootAprox); var bufferCopy = OmgPool.GetRawZero(); bufferCopy.CopyFrom(m_buffer); _MakeGeronIteration(); if (OmgOp.Equal(aproxCopy.OmgWrapper(), m_buffer.OmgWrapper()) && OmgOp.Equal(bufferCopy.OmgWrapper(), m_rootAprox.OmgWrapper()) && OmgOp.Less(m_rootAprox.OmgWrapper(), m_buffer.OmgWrapper())) { break; } OmgPool.ReleaseNumber(bufferCopy); OmgPool.ReleaseNumber(aproxCopy); } OmgPool.ReleaseNumber(m_buffer); return(m_rootAprox); }
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 } }); }
public static IEnumerable <OmgNum> Encode(IEnumerable <OmgNum> message, PubKey key) { foreach (var num in message) { yield return(OmgOp.Pow(num, key.E, key.N)); } }
private static IEnumerable <OmgNum> Decode(IEnumerable <OmgNum> message, SignCertificate cert) { foreach (var num in message) { yield return(OmgOp.Pow(num, cert.D, cert.N)); } }
internal RawNum ExtendedGcd(RawNum left, RawNum right, out OmgNum x, out OmgNum y) { if (left.IsZero()) { x = 0.ToOmgNum(); y = 1.ToOmgNum(); RawNum gcd = OmgPool.GetRawZero(); gcd.CopyFrom(right); return(gcd); } var divModRes = OmgOp.DivMod(right.OmgWrapper(), left.OmgWrapper()); RawNum gcdRes = ExtendedGcd(divModRes.mod.Raw, left, out OmgNum x2, out OmgNum y2); divModRes.mod.Release(); OmgNum multRes = OmgOp.Multiply(divModRes.div, x2); divModRes.div.Release(); x = OmgOp.Subtract(y2, multRes); y2.Release(); multRes.Release(); y = x2; return(gcdRes); }
private bool _LeftAbsIsLess(OmgNum left, OmgNum right) { var absLeft = new OmgNum(left.Raw); var absRight = new OmgNum(right.Raw); return(OmgOp.Less(absLeft, absRight)); }
private static IEnumerable <OmgNum> Encode(IEnumerable <OmgNum> message, SignSecret secret) { foreach (var num in message) { yield return(OmgOp.Pow(num, secret.E, secret.N)); } }
private OmgNum _FindPow(ref OmgNum num, OmgNum factor) { OmgNum pow = 0.ToOmgNum(); while (true) { var divMod = OmgOp.DivMod(num, factor); if (!divMod.mod.IsZero()) { break; } pow.Inc(); divMod.mod.Release(); num.Release(); num = divMod.div; } if (pow.IsZero()) { throw new Exception(); } return(pow); }
public OmgNum EulerFunction(OmgNum num) { var factorization = Factorize(num); var one = 1.ToOmgNum(); OmgNum result = 1.ToOmgNum(); foreach (var factor in factorization) { OmgNum phiP = null; if (factor.Value.IsOne()) { phiP = OmgOp.Subtract(factor.Key, one); } else { var pTonMinusOne = OmgOp.Pow(factor.Key, OmgOp.Subtract(factor.Value, one)); phiP = OmgOp.Multiply(pTonMinusOne, OmgOp.Subtract(factor.Key, one)); pTonMinusOne.Release(); } var nwRes = OmgOp.Multiply(result, phiP); result.Release(); phiP.Release(); result = nwRes; } return(result); }
private bool _IsTrivial(RawNum left, RawNum right) { OmgNum absLeft = new OmgNum(left); OmgNum absRight = new OmgNum(right); return(OmgOp.Less(absLeft, absRight)); }
public (OmgNum div, OmgNum mod) DivMod(OmgNum left, OmgNum right) { _InitializeDivModResult(); if (OmgOp.Equal(right, s_two)) { _DivModByTwo(left); return(m_divRes, m_modRes); } bool isNegative = left.IsNegative != right.IsNegative; m_divRes.IsNegative = isNegative; _FindDivModSolution(left.Raw, right.Raw); if (isNegative) { m_divRaw.Inc(); _Subtract(right.Raw, m_modRaw); } _RemoveModLeadingZeros(); return(m_divRes, m_modRes); }
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; }
static void Main(string[] args) { var a = 234234.ToOmgNum(); var b = "85430534954938530495935803495482304983".ToOmgNum(); var c = "100000000000000000000000000000000".ToOmgNum(); var d = "-100000000000000000".ToOmgNum(); var a1 = OmgOp.Add(a, c); var a2 = OmgOp.Subtract(a, c); var a3 = OmgOp.Multiply(a, b); var a4 = OmgOp.DivMod(b, c); var a6 = OmgOp.Pow(b, c, a); var a7 = OmgOp.Sqrt(b); var sys1 = new OmgEqSys(); sys1.AddEq(1287.ToOmgNum(), 447.ToOmgNum(), 516.ToOmgNum()); bool success1 = sys1.TrySolve(out List <(OmgNum root, OmgNum mod)> solution1); var sys2 = new OmgEqSys(); bool success2 = sys2.TrySolve(out var solution2); }
private OmgNum _FermaFactorization(Dictionary <OmgNum, OmgNum> result, OmgNum num) { OmgNum factor = null; if (OmgOp.DivMod(num, 2.ToOmgNum()).mod.IsZero()) { factor = 2.ToOmgNum(); } if (factor == null) { OmgNum a = OmgOp.Sqrt(num); OmgNum aSq = OmgOp.Multiply(a, a); bool isSquare = OmgOp.Equal(num, aSq); if (isSquare) { factor = a; } a.Inc(); aSq = OmgOp.Multiply(a, a); var s = OmgOp.Subtract(aSq, num); while (factor == null) { var testSqrt = OmgOp.Sqrt(s); if (OmgOp.Equal(s, OmgOp.Multiply(testSqrt, testSqrt))) { factor = (OmgOp.Equal(testSqrt, a)) ? OmgOp.Add(a, a) : OmgOp.Subtract(a, testSqrt); break; } a.Inc(); aSq = OmgOp.Multiply(a, a); s = OmgOp.Subtract(aSq, num); } } if (factor == null || factor.IsOne()) { return(num); } OmgNum pow = _FindPow(ref num, factor); if (result.ContainsKey(factor)) { result[factor] = OmgOp.Add(result[factor], pow); } else { result[factor] = pow; } return(num); }
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); }
private OmgNum _Carmichael(OmgNum phiP, OmgNum phiQ) { OmgNum pq = OmgOp.Multiply(phiP, phiQ); OmgNum pqGCD = OmgOp.Gcd(phiP, phiQ); OmgNum lcm = OmgOp.Div(pq, pqGCD); pq.Release(); pqGCD.Release(); return(lcm); }
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); } }
private OmgNum _SelectExponent(OmgNum carmN) { OmgNum candidate = ((1 << 16) + 1).ToOmgNum(); OmgNum gcd = OmgOp.Gcd(candidate, carmN); while (!gcd.IsOne()) { gcd = OmgOp.Gcd(candidate.Inc(), carmN); } gcd.Release(); return(candidate); }
private bool _IsSmallPrime(Dictionary <OmgNum, OmgNum> result, OmgNum num) { smallPrimesOmg ??= smallPrimes.Select(x => x.ToOmgNum()).ToArray(); foreach (var prime in smallPrimesOmg) { if (OmgOp.Equal(prime, num)) { result[prime] = 1.ToOmgNum(); return(true); } } return(false); }
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); }
public OmgNum FindFactor(OmgNum n, int maxIterations = -1) { m_iterations = 0; m_current = n; OmgNum x = OmgOp.Random(1.ToOmgNum(), OmgOp.Subtract(n, 2.ToOmgNum())); OmgNum y = 1.ToOmgNum(); OmgNum i = 0.ToOmgNum(); OmgNum stage = 2.ToOmgNum(); OmgNum sub = OmgOp.Subtract(x, y).MakeAbs(); OmgNum gcd = OmgOp.Gcd(n, sub); sub.Release(); while (gcd.IsOne()) { if (maxIterations >= 0 && m_iterations++ > maxIterations) { return(null); } if (OmgOp.Equal(i, stage)) { y.Release(); y = new OmgNum(x); stage.MultByTwo(); } OmgNum xSquare = OmgOp.Multiply(x, x).Inc(); x.Release(); x = OmgOp.Mod(xSquare, n); xSquare.Release(); i.Inc(); sub = OmgOp.Subtract(x, y).MakeAbs(); gcd.Release(); gcd = OmgOp.Gcd(n, sub); sub.Release(); } return(gcd); }
private OmgNum _FindFactorsWithPollard(Dictionary <OmgNum, OmgNum> result, OmgNum num) { num = num.Copy(); while (!num.IsOne()) { OmgNum factor = m_polard.FindFactor(num, maxIterations: 100000); if (factor == null || factor.IsOne() || OmgOp.Equal(factor, num)) { return(num); } OmgNum pow = _FindPow(ref num, factor); result[factor] = pow; } return(num); }
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); }
private void _MakeGeronIteration() { OmgNum rootAprox = m_rootAprox.OmgWrapper(); var res = OmgOp.DivMod(m_targetSquareNum, rootAprox); res.mod.Release(); OmgNum sum = OmgOp.Add(rootAprox, res.div); res.div.Release(); sum.Raw.DivByTwo(); OmgPool.ReleaseNumber(m_buffer); m_buffer = m_rootAprox; m_rootAprox = sum.Raw; }
private OmgNum _MakeFastPow(OmgNum left, RawNum right, OmgNum mod) { if (right.IsZero()) { var res = OmgPool.GetRawZero(); res.Digits.Add(1); return(new OmgNum(res)); } var rightCopy = OmgPool.GetRawZero(); rightCopy.CopyFrom(right); bool even = (rightCopy.Digits[0] & 1) == 0; if (even) { rightCopy.DivByTwo(); var p = _MakeFastPow(left, rightCopy, mod); OmgNum powSquare = OmgOp.Multiply(p, p); OmgNum powSquareModded = OmgOp.Mod(powSquare, mod); powSquare.Release(); p.Release(); OmgPool.ReleaseNumber(rightCopy); return(powSquareModded); } else { _SubOne(rightCopy); var p = _MakeFastPow(left, rightCopy, mod); OmgNum powPlusOne = OmgOp.Multiply(p, left); OmgNum powPlusOneModded = OmgOp.Mod(powPlusOne, mod); powPlusOne.Release(); p.Release(); OmgPool.ReleaseNumber(rightCopy); return(powPlusOneModded); } }
internal RawNum FindGcd(RawNum left, RawNum right) { if (left.IsZero()) { RawNum gcd = OmgPool.GetRawZero(); gcd.CopyFrom(right); return(gcd); } var divModRes = OmgOp.DivMod(right.OmgWrapper(), left.OmgWrapper()); divModRes.div.Release(); RawNum gcdRes = FindGcd(divModRes.mod.Raw, left); divModRes.mod.Release(); return(gcdRes); }
static void Main(string[] args) { // Rho Pollard var primeA = "99194853094755497".ToOmgNum(); var primeB = "2971215073".ToOmgNum(); var primesProd = OmgOp.Multiply(primeA, primeB); var polard = new PolardFactorization(); var factor = polard.FindFactor(primesProd); Console.WriteLine($"factor: {factor}"); // Rho Discrete Log var rhoLogFinder = new RhoLog(); (OmgNum a, OmgNum b, OmgNum p)log = (5.ToOmgNum(), 3.ToOmgNum(), 2017.ToOmgNum()); var discreteLog = rhoLogFinder.FindLog(log.a, log.b, log.p); Console.WriteLine($"{discreteLog} : {OmgOp.Pow(log.a, discreteLog, log.p)}"); // Factorization var factorizer = new Factorization(); var factorization = factorizer.Factorize("63782453".ToOmgNum()); Console.WriteLine($"factorization: {String.Join(' ', factorization.Select(x => ($"{x.Key}^{x.Value}")))}"); // EulerF var euler = factorizer.EulerFunction("63782453".ToOmgNum()); Console.WriteLine($"euler: {euler}"); // MobiusF var mobius1 = factorizer.Mobius("63782453".ToOmgNum()); var mobius2 = factorizer.Mobius("4".ToOmgNum()); Console.WriteLine($"mobius1: {mobius1}"); Console.WriteLine($"mobius2: {mobius2}"); }
public bool IsPrime(OmgNum tested) { foreach (var prime in s_smallPrimes) { if (OmgOp.Less(tested, prime) || OmgOp.Equal(tested, prime)) { return(true); } var mod = OmgOp.Mod(tested, prime); bool isComposite = mod.IsZero(); mod.Release(); if (isComposite) { return(false); } } return(true); }
public static IEnumerable <OmgNum> Decode(IEnumerable <OmgNum> code, PrivKey key) { foreach (var num in code) { OmgNum m1 = OmgOp.Pow(num, key.dP, key.P); OmgNum m2 = OmgOp.Pow(num, key.dQ, key.Q); OmgNum mdif = OmgOp.Subtract(m1, m2); OmgNum h = OmgOp.Multiply(key.qInv, mdif, key.P); OmgNum hq = OmgOp.Multiply(h, key.Q); OmgNum m = OmgOp.Add(m2, hq); m1.Release(); m2.Release(); mdif.Release(); h.Release(); hq.Release(); yield return(m); } }