//генерация большого числа, размеров определенного количества бит public static BigInteger GetBigNumber(KeyAmount keyAmount) { int nBits = (int)keyAmount; byte[] bytes = new byte[nBits / 8]; rnd.NextBytes(bytes); return(BigInteger.Abs(new BigInteger(bytes))); }
//получить простое число, размерностью b бит public static BigInteger GetSimpleNumber(KeyAmount b = KeyAmount.b1024) { BigInteger result; while (true) { result = GetBigNumber(b); if (checkSimplicity(result, b)) { break; } } return(result); }
private void Start() { Canvas = GameObject.FindGameObjectWithTag("Canvas"); Keys = Canvas.GetComponentInChildren <KeyAmount>(); }
//генерация ключей для алгоритма Эль-Гамаля public static Tuple <Tuple <BigInteger, BigInteger, BigInteger>, Tuple <BigInteger> > GetElGamalKeys(KeyAmount b = KeyAmount.b1024) { BigInteger p = GetSimpleNumber(b); BigInteger g = GetPrimitiveRoot(p); BigInteger x = rnd.NextBigInteger(p - 3) + 2; BigInteger y = BigInteger.ModPow(g, x, p); return(new Tuple <Tuple <BigInteger, BigInteger, BigInteger>, Tuple <BigInteger> >( new Tuple <BigInteger, BigInteger, BigInteger>(p, g, y), new Tuple <BigInteger>(x) )); }
//проверка простоты методом Миллера — Рабина public static bool checkSimplicity(BigInteger n, KeyAmount keyAmount) { int k = (int)keyAmount; //размерность ключа //исключаем числа делимые на простые числа от 2 до 256 либо к int[] simpleNumberForCheck = getSimplicityNumbers(k <= 256 ? 256 : k); for (int i = 0; i < simpleNumberForCheck.Length; i++) { BigInteger remainder; BigInteger.DivRem(n, new BigInteger(simpleNumberForCheck[i]), out remainder); if (remainder.IsZero || n.CompareTo(new BigInteger(simpleNumberForCheck[i])) == 0) { return(false); } } Random rnd = new Random(); int s = 0; BigInteger nmm = BigInteger.Subtract(n, BigInteger.One); BigInteger t = nmm; //вычисляем коэффициенты t и s do { t = BigInteger.Divide(t, new BigInteger(2)); s++; BigInteger remainder; BigInteger.DivRem(t, new BigInteger(2), out remainder); if (remainder != 0) { break; } } while (true); //проверяем условия простоты int kk = 30720 / k; for (int i = 0; i < kk; i++) { BigInteger a; for (;;) { a = rnd.NextBigInteger(n); if (nmm.CompareTo(a) > 0 && a.CompareTo(new BigInteger(2)) >= 0) { break; } } //проверяем сравнимость по модулю BigInteger x = BigInteger.ModPow(a, t, n); if (x.IsOne || x.CompareTo(nmm) == 0) { continue; } for (int j = 1; j < s; j++) { x = BigInteger.ModPow(x, new BigInteger(2), n); if (x.IsOne) { return(false); //составное } if (x.CompareTo(nmm) == 0) { goto ff; //перейти на следующую проверку } } return(false); //составное ff :; } return(true); }
//генерация ключей для алгоритма RSA public static Tuple <Tuple <BigInteger, BigInteger>, Tuple <BigInteger, BigInteger> > GetRSAKeys(KeyAmount b = KeyAmount.b1024) { BigInteger p = GetSimpleNumber(b); BigInteger q = GetSimpleNumber(b); BigInteger n = BigInteger.Multiply(p, q); BigInteger phin = BigInteger.Multiply(BigInteger.Subtract(p, BigInteger.One), BigInteger.Subtract(q, BigInteger.One)); BigInteger d; BigInteger e; do { e = BigInteger.Add(rnd.NextBigInteger(BigInteger.Subtract(phin, BigInteger.One)), BigInteger.One); var nod = EuclidEx(phin, e); if (nod.Item3.IsOne) { if (nod.Item2 < 0) { d = BigInteger.Add(nod.Item2, phin); } else { d = nod.Item2; } break; } } while (true); if (e == d) { return(GetRSAKeys(b)); } return(new Tuple <Tuple <BigInteger, BigInteger>, Tuple <BigInteger, BigInteger> >( new Tuple <BigInteger, BigInteger>(e, n), //open new Tuple <BigInteger, BigInteger>(d, n))); //close }
//генерация ключей DSA public static Tuple <Tuple <BigInteger, BigInteger, BigInteger, BigInteger>, Tuple <BigInteger> > DSAKeys(KeyAmount b) { BigInteger q = AsymmetricEncryption.AsymmetricEncryption.GetSimpleNumber(b); BigInteger p; BigInteger reminder; BigInteger a = BigInteger.Zero; do { p = AsymmetricEncryption.AsymmetricEncryption.GetSimpleNumber((KeyAmount)((int)b * 2)); BigInteger.DivRem(BigInteger.Subtract(p, BigInteger.One), q, out reminder); if (++a == 100) { a = BigInteger.Zero; q = AsymmetricEncryption.AsymmetricEncryption.GetSimpleNumber(b); } } while (!reminder.IsZero); Random rnd = new Random(); BigInteger h = rnd.NextBigInteger(p - 3) + 2; BigInteger g; while (true) { g = BigInteger.ModPow(h, BigInteger.Divide(BigInteger.Subtract(p, BigInteger.One), q), p); if (!g.IsOne) { break; } } BigInteger x = rnd.NextBigInteger(q); BigInteger y = BigInteger.ModPow(g, x, p); return(new Tuple <Tuple <BigInteger, BigInteger, BigInteger, BigInteger>, Tuple <BigInteger> >( new Tuple <BigInteger, BigInteger, BigInteger, BigInteger>(q, p, g, y), new Tuple <BigInteger>(x) )); }
private void Update() { Cooldown = Cooldown - Time.deltaTime; Canvas = GameObject.FindGameObjectWithTag("Canvas"); KA = Canvas.GetComponentInChildren <KeyAmount>(); }