// also checks if GCD(result - 1, f) == 1 /// <summary> /// Gets next prime number that is greater /// equal than Min, and less, than Max and /// GCD(number - 1, f) = 1 /// </summary> /// <param name="Min">Lower bound of interval</param> /// <param name="Max">Upper bound of interval</param> /// <param name="f">Number f</param> /// <returns>Prime long number</returns> public ULongIntB Next(ULongIntB Min, ULongIntB Max, SLongIntB f) { if (Min > Max) throw new ArgumentException("Lower bound is less, that upper bound!"); if (LongMath.IsEven(f)) throw new ArgumentException("Argument 'f' cannot be even!"); ULongIntB p = new ULongIntB(rand.Next(Min, Max), ConstructorMode.Assign); ULongIntB t = Max - Min; if (LongMath.IsEven(p)) ++p; if (p > Max) p = Min + (p % (t + 1)); while (CryptoMath.TestPrimeMillerRabin(p, RoundsNumber.Rounds25) == PrimeTestResult.Composite || (CryptoMath.GCD((SLongIntB)p - 1, f) == 1)) { ++p; ++p; while (p > Max) { p = Min + (p % (t + 1)); if (LongMath.IsEven(p)) ++p; } } return p; }
public void PowerTest3() { SLongIntB A = new SLongIntB("-98276598235872"); short r = 12, s = 31; Assert.AreEqual(LongMath.Exp(A, (ulong)(r + s)), LongMath.Exp(A, (ulong)r) * LongMath.Exp(A, (ulong)s)); }
public static SLongIntB ChineRem(SLongIntB[] coefs, SLongIntB[] modules) { if (coefs.Length != modules.Length) throw new ArgumentException("Input parameters have different sizes."); int i = 0; SLongIntB m = modules[i]; SLongIntB x = coefs[i]; SLongIntB U = null; SLongIntB V = null; while (i < coefs.Length - 1) { ++i; SLongIntB gcd = eXtendedGCD(m, modules[i], out U, out V); if (gcd != 1) throw new WrondResultException("Modules are not coprime!"); SLongIntB temp = U*m*coefs[i] + V*modules[i]*x; m = m*modules[i]; x = temp % m; x.LongSign = SignTransformer.GetLSign(temp.Sign*m.Sign); } return x; }
/// <summary> /// Provides all operations needed to /// get public and private RSA keys. Must /// be called before other methods of this class /// </summary> /// <param name="bitLength">Length of key</param> public void GenerateRSAKey(BitLength bitLength) { key = new RSAKey(); // find prime numbers p and q CalculatePQ(bitLength); // n is product of found numbers key.N = (SLongIntB)(p * q); --p; --q; // eiler number equals (p - 1)*(q - 1) eilerNumber = (SLongIntB) (p * q); ++p; ++q; SLongIntB tempEiler = eilerNumber - 1; SLongIntB e = new SLongIntB(rand.NextPQ(p, q), ConstructorMode.Assign); while ((CryptoMath.GCD(e, eilerNumber) != 1) || (e > tempEiler)) { e = new SLongIntB(rand.NextPQ(p, q), ConstructorMode.Assign); } key.E = e; SLongIntB d = null; CryptoMath.eXGCDInvertedSafe(e, eilerNumber, out d); key.D = d; generated = true; }
public void PowerTest1() { SLongIntB A = new SLongIntB("-98276598235872"); SLongIntB B = (SLongIntB)1; short k = 120; for (int i = 0; i < (int)k; ++i) B *= A; Assert.AreEqual(LongMath.Exp(A, (ulong)k), B); }
public void TestAddition2() { SLongIntB A = new SLongIntB("-982"); SLongIntB B = new SLongIntB(A); for (int i = 1; i < 1000; ++i) { A++; Assert.AreEqual(A, B + (short)i); } }
public void TestAddition1() { SLongIntB A = new SLongIntB("-98276598235872687523562056"); SLongIntB B = (SLongIntB)0; short k = 120; for (int i = 0; i < (int)k; ++i) B += A; Assert.AreEqual(k*A, B); A *= -1; B = (SLongIntB)0; for (int i = 0; i < (int)k; ++i) B += A; Assert.AreEqual(k*A, B); }
public void TestSubstraction2() { SLongIntB A = new SLongIntB("239"); SLongIntB B = new SLongIntB(A); for (int i = 1; i < 1000; ++i) { --A; Assert.AreEqual(A, B - (short)i); } }
public void TestSubstraction3() { SLongIntB N = new SLongIntB("2945729752935981200000005151659293467923476293623"); RandomLong rand = new RandomLong((ulong)DateTime.Now.Millisecond); for (int i = 0; i < 1000; ++i) { SLongIntB A = new SLongIntB(rand.Next(N), ConstructorMode.Assign); SLongIntB B = new SLongIntB(rand.Next(N), ConstructorMode.Assign); SLongIntB C = A - B; Assert.AreEqual(C + B, A); Assert.AreEqual(LongMath.Abs(C - A), B); Assert.AreEqual(C - 0, C); Assert.AreEqual(C - C, (SLongIntB)0); } }
public void TestSquare2() { SLongIntB N = new SLongIntB("2945729752935981200000005151659293467923476293623"); RandomLong rand = new RandomLong((ulong)DateTime.Now.Millisecond); for (int i = 0; i < 1000; ++i) { SLongIntB temp = new SLongIntB(rand.Next(N), ConstructorMode.Assign); Assert.AreEqual(temp*temp, LongMath.Sqr(temp)); } }
public void TestSubstraction1() { SLongIntB N = new SLongIntB("2945729752935981200000005151659293467923476293623"); RandomLong rand = new RandomLong((ulong)DateTime.Now.Millisecond); for (int i = 0; i < 1000; ++i) { SLongIntB A = new SLongIntB(rand.Next(N), ConstructorMode.Assign); SLongIntB B = new SLongIntB(rand.Next(N), ConstructorMode.Assign); SLongIntB C = A + B; Assert.AreEqual(C - B, A, C.ToString() + " " + B.ToString()); Assert.AreEqual(C - A, B, C.ToString() + " " + A.ToString()); Assert.AreEqual(C - 0, C); Assert.AreEqual(C - C, (SLongIntB)0); } }
public void TestShifts2() { SLongIntB A = new SLongIntB("-98276598235872"); SLongIntB B = new SLongIntB(A); for (int i = 1; i < 11; ++i) { SLongIntB C = new SLongIntB(A); C.ShR((uint)i); B /= 2; Assert.AreEqual(C, B); } }
public void TestShifts4() { SLongIntB A = new SLongIntB("-98276598235872"); SLongIntB B = new SLongIntB(A); A.Mod2n(10); ushort b = B % 1024; Assert.AreEqual(A, (SLongIntB)b); }
public RSAPrivateKey(SLongIntB dKey, SLongIntB nKey) { d = new SLongIntB(dKey); n = new SLongIntB(nKey); }
public void TestDivision1() { SLongIntB N = new SLongIntB("2945729752935981200000005151659293467923476293623"); RandomLong rand = new RandomLong((ulong)DateTime.Now.Millisecond); for (int i = 0; i < 1000; ++i) { SLongIntB A = new SLongIntB(rand.Next(N), ConstructorMode.Assign); SLongIntB B = new SLongIntB(rand.Next(N), ConstructorMode.Assign); SLongIntB C = A*B; if (C == 0) continue; Assert.AreEqual(C / B, A); Assert.AreEqual(C / A, B); } }
/// <summary> /// Divides input number by 2 while can /// </summary> /// <param name="A">Input number</param> /// <param name="k">Number of times, that value is diveded by 2</param> public static void SelfTwoFact(SLongIntB A, out int k) { k = 0; if (A == 0) return; while (LongMath.IsEven(A)) { A.Shr(); ++k; } }
/// <summary> /// Calculates square of input signed number N times by modulo /// </summary> /// <param name="a">Input number</param> /// <param name="n">Number of times to calculate square</param> /// <param name="m">Modulo</param> /// <returns>[ a ^ (2*n) ] % m</returns> public static SLongIntB NSquareMod(SLongIntB a, uint n, SLongIntB m) { SLongIntB res = a % m; for (int i = 0; i < n; ++i) res = LongMath.Sqr(res) % m; return res; }
//[Test()] public void TestExtendedGCD() { SLongIntB N = new SLongIntB("2945729752935981200000005151659293467923476293623"); RandomLong rand = new RandomLong((ulong)DateTime.Now.Millisecond); SLongIntB U = null, V = null; for (int i = 0; i < 1000; ++i) { SLongIntB temp1 = new SLongIntB(rand.Next(N), ConstructorMode.Assign); SLongIntB temp2 = new SLongIntB(rand.Next(N), ConstructorMode.Assign); SLongIntB gcd = CryptoMath.eXtendedGCD(temp1, temp2, out U, out V); SLongIntB gcdB = CryptoMath.GCD(temp1, temp2); Assert.AreEqual(gcd, temp1*U + temp2*V); Assert.AreEqual(gcd, gcdB, temp1.ToString() + " " + temp2.ToString() + " " + gcd.ToString() + " " + gcdB.ToString()); } }
/// <summary> /// Calculates square of input signed number by modulo /// </summary> /// <param name="a">Input number</param> /// <param name="m">Modulo</param> /// <returns>(a*a) % m</returns> public static SLongIntB SquareMod(SLongIntB a, SLongIntB m) { return LongMath.Sqr(a) % m; }
public void TestDivision2() { SLongIntB N = new SLongIntB("2945729752935981200000005151659293467923476293623"); RandomLong rand = new RandomLong((ulong)DateTime.Now.Millisecond); for (int i = 0; i < 1000; ++i) { SLongIntB A = new SLongIntB(rand.Next(N), ConstructorMode.Assign); SLongIntB B = new SLongIntB(rand.Next(N), ConstructorMode.Assign); if (B == 0) continue; if ((B * (A / B)) + (A % B) != A) { Console.WriteLine(A); Console.WriteLine(B); Console.WriteLine((A/B).ToString()); Console.WriteLine((A%B).ToString()); } Assert.AreEqual((B * (A / B)) + (A % B), A, string.Join(" ", new string[]{ A.ToString(), B.ToString(), (A/B).ToString(), (A%B).ToString() })); } }
public static SLongIntB LCM(SLongIntB A, SLongIntB B) { return (A*B) / GCD(A, B); }
/// <summary> /// Calculates Jacobi symbol for long numbers A and B - (A/B) /// </summary> /// <param name="A"></param> /// <param name="B"></param> /// <returns></returns> public static int JacobiSymbol(SLongIntB a, SLongIntB b) { if (b.IsZero()) { if (a == 1 || a == -1) return 1; else return 0; } if (LongMath.IsEven(a) && LongMath.IsEven(b)) return 0; SLongIntB A = new SLongIntB(a); SLongIntB B = new SLongIntB(b); sbyte[] mods = new sbyte[] { 0, 1, 0, -1, 0, -1, 0, 1 }; int v = 0; SelfTwoFact(B, out v); int k = 1; if (v % 2 == 1) k = mods[A[0] & 7]; LongMath.SelfAbs(B); if (A < 0) k = -k; while (A > 0) { SelfTwoFact(A, out v); if (v % 2 == 1) k = mods[B[0] & 7] * k; if ((A[0] & B[0] & 2) != 0) k = -k; SLongIntB r = LongMath.Abs(A); A.Assign(B % r); B.Assign(r); } if (B > 1) return 0; else return k; }
public void TestMul1() { SLongIntB N = new SLongIntB("2945729752935981200000005151659293467923476293623"); RandomLong rand = new RandomLong((ulong)DateTime.Now.Millisecond); for (int i = 0; i < 1000; ++i) { SLongIntB temp1 = new SLongIntB(rand.Next(N), ConstructorMode.Assign); SLongIntB temp2 = new SLongIntB(rand.Next(N), ConstructorMode.Assign); SLongIntB temp3 = new SLongIntB(rand.Next(N), ConstructorMode.Assign); Assert.AreEqual((temp1*temp2)*temp3, temp1*(temp2*temp3)); } }
public static void TwoFact(SLongIntB A, out SLongIntB u, out int k) { k = 0; u = new SLongIntB(A); if (A == 0) return; while (LongMath.IsEven(u)) { ++k; u.Shr(); } }
public void TestBinaryDecimalCast() { SLongIntB A = new SLongIntB("-20976982698769825692774362798672976276668754000000000000000765700000000"); SLongIntD B = (SLongIntD)A; Assert.AreEqual(A.ToString(), B.ToString()); Assert.AreEqual((SLongIntD)A, B); Assert.AreEqual(A, (SLongIntB)B); }
public void TestPower() { SLongIntB N = new SLongIntB("2945"); RandomLong rand = new RandomLong((ulong)DateTime.Now.Millisecond); Random rand32 = new Random(DateTime.Now.Millisecond); SLongIntB m = new SLongIntB("98696766574783"); for (int i = 0; i < 100; ++i) { SLongIntB temp = new SLongIntB(rand.Next(N), ConstructorMode.Assign); int power = rand32.Next(ushort.MaxValue) % 10000; Assert.AreEqual(CryptoMath.ExpMod5((ULongIntB)temp, (ULongIntB)power, (ULongIntB)m), LongMath.Exp((ULongIntB)temp, (ulong)power) % (ULongIntB)m, temp.ToString() + "^" + power.ToString()); } }
public static SLongIntB StupidGCD(SLongIntB a, SLongIntB b) { while (b != 0) { SLongIntB r = a % b; a.Assign(b); b.Assign(r); } return a; }
public void TestShiftRight() { SLongIntB N = new SLongIntB("2945729752935981200000005151659293467923476293623"); RandomLong rand = new RandomLong((ulong)DateTime.Now.Millisecond); for (int i = 0; i < 1000; ++i) { SLongIntB temp1 = new SLongIntB(rand.Next(N), ConstructorMode.Assign); SLongIntB temp3 = new SLongIntB(temp1); temp1.Shr(); SLongIntB temp2 = new SLongIntB(temp1); temp2.Shl(); Assert.AreEqual(temp1 * 2, temp2); Assert.AreEqual(temp1, temp3 / 2); } }
public RSAPublicKey(SLongIntB eKey, SLongIntB nKey) { e = new SLongIntB(eKey); n = new SLongIntB(nKey); }
public void TestShifts1() { SLongIntB A = new SLongIntB("-98276598235872"); SLongIntB B = new SLongIntB(A); for (int i = 0; i < 10; ++i) { A.Shr(); B /= 2; Assert.AreEqual(A, B); } for (int i = 0; i < 10; ++i) { A.Shl(); B *= 2; Assert.AreEqual(A, B); } }