/// <summary> /// Преобразует строковое представление числа в эквивалентное ему длинное целое число со знаком. /// </summary> /// <param name="s">Строка, содержащая преобразуемое число.</param> /// <returns>Длинное целое число со знаком, эквивалентное числу, заданному в параметре s.</returns> public static LongArithmetic Parse(string s) { LongArithmetic res = new LongArithmetic(); res._number = new List <ushort>(); for (int i = s.Length - 1; i >= 0;) { StringBuilder sb = new StringBuilder(); for (int j = 0; j < _baselen && i >= 0; j++, i--) { if (i == 0 && s[i] == '-') { res._isPositive = false; continue; } sb.Append(s[i]); } string news = new string(sb.ToString().ToCharArray().Reverse().ToArray()); if (news != "") { res._number.Add(ushort.Parse(news)); } } return(res); }
public void TestCompare() { int expectedCompare = BigInteger.Compare(expectedResult1, expectedResult2); int actualCompare = LongArithmetic.Compare(actualResult1, actualResult2)[2][0]; Assert.AreEqual(expectedCompare, actualCompare); }
public static bool ferma(LongArithmetic x) { //Random rnd = new Random(); LaggedFibRandom rnd = new LaggedFibRandom((int)(DateTime.UtcNow.ToBinary() % 1000000000)); for (int j = 2; j < 100; j++) { if (x % j == 0 && x != j) { return(false); } } for (int i = 0; i < 20; i++) { LongArithmetic a = (rnd.Next() % (x - 2)) + 2; if (gcd(a, x) != 1) { return(false); } Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Проверка {0} на простоту. Тест {1}:", x.ToString(), i + 1); Console.ForegroundColor = ConsoleColor.White; if (mypows(a, x - 1, x) != 1) { return(false); } } return(true); }
public static LongArithmetic mypows(LongArithmetic a, LongArithmetic b, LongArithmetic m) { /*List<bool> bc = new List<bool>(); * * LongArithmetic test = b; * * while (test != 0) * { * bc.Add(test % 2 == 1); * test /= 2; * }*/ LongArithmetic tb = b; LongArithmetic t = a; LongArithmetic d = 1; for (int i = 0; !tb.IsZero(); i++) { //Console.WriteLine("i'm on {0}", i); if (LongArithmetic.ModS(tb, 2) == 1) { d = (d * t) % m; } tb = LongArithmetic.DivS(tb, 2); t *= t; t %= m; } return(d); }
static void Main(string[] args) { //Начало цикла do { Console.WriteLine("START"); BigInteger expectedResult2 = BigInteger.Pow(10, 1); BigInteger expectedResult1 = BigInteger.Pow(9, 1); Console.WriteLine(BigInteger.Compare(expectedResult1, expectedResult1)); int[] input = GetInput(); var a = LongArithmetic.Compare( LongArithmetic.Pow(input[0], input[1]), LongArithmetic.Pow(input[2], input[3]) ); Console.Write("Число: "); foreach (var m in a[0]) { Console.Write(m); } Console.Write("\nБольше на "); foreach (var m in a[1]) { Console.Write(m); } Console.WriteLine("\n#Enter any character to complete"); } while (Console.ReadLine().Length != 1); }
private LongArithmetic GetRandom(string name) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Вычисление {0}:", name); Console.ForegroundColor = ConsoleColor.White; bool exit = false; LongArithmetic j = new LongArithmetic();; LongArithmetic pr = new LongArithmetic(); for (int i = 0; !exit; i++) { j = global::RSA.Random(); if (j == pr) { continue; } pr = j; exit = global::RSA.ferma(j); if (exit) { Console.ForegroundColor = ConsoleColor.Red; } Console.WriteLine(String.Format("{2}{0}{1}простое число", j, exit ? " " : " не ", exit ? name + "=" : "")); Console.ForegroundColor = ConsoleColor.White; } return(j); }
Int64 CreateKeys(int number) { Console.WriteLine("Создание общего ключа № {0}...", number); Random random = new Random(); Int64 g = LongArithmetic.NextInt64(random); Int64 p = LongArithmetic.NextInt64(random); Console.WriteLine("Отправка параметров g = " + g + " p = " + p); string message = ""; message = "g = " + g.ToString() + " p = " + p.ToString(); SendInformation(message, stream); Int64 a = LongArithmetic.NextInt64(random); BigInteger A = BigInteger.ModPow(g, a, p); Console.WriteLine("Отправка параметра A = " + A); message = "A = " + A; SendInformation(message, stream); message = ReceiveInformation(stream); message += ' '; BigInteger B = BigInteger.Parse(LongArithmetic.GiveLong(ref message)); Console.WriteLine("Получен параметр B = {0}", B); Int64 Key = Convert.ToInt64(BigInteger.ModPow(B, a, p).ToString()); Key = LongArithmetic.GetFormatKey(Key); Console.WriteLine("Получен общий ключ № {0}: Key = {1}", number, Key); var buffer = new byte[8]; buffer = BitConverter.GetBytes(Key); return(Key); }
public static LongArithmetic gcd(LongArithmetic a, LongArithmetic b) { if (b == 0) { return(a); } return(gcd(b, a % b)); }
/// <summary> /// Умножение /// </summary> /// <param name="left">Левый множитель</param> /// <param name="right">Правый множитель</param> /// <returns>Произведение</returns> public static LongArithmetic operator *(LongArithmetic left, LongArithmetic right) { LongArithmetic res = new LongArithmetic(); res._number = new List <ushort>(left._number.Count + right._number.Count); if (left._isPositive == right._isPositive) { res._isPositive = true; } else { res._isPositive = false; } int t; int i; for (i = 0; i < left._number.Count; i++) { int j; t = 0; for (j = 0; j < right._number.Count; j++) { if (i + j >= res._number.Count) { res._number.Add(0); } t = left._number[i] * right._number[j] + t + res._number[i + j]; res._number[i + j] = ((ushort)(t % _base)); t /= _base; } for (int k = 0; t != 0; k++) { if (i + j + k >= res._number.Count) { res._number.Add(0); } t += res._number[i + j + k]; res._number[i + j + k] = ((ushort)(t % _base)); t /= _base; } } for (i = res._number.Count - 1; i >= 0 && res._number[i] == 0; i--) { res._number.RemoveAt(i); } if (res._number.Count == 0) { res._number.Add(0); } return(res); }
private void button2_Click(object sender, EventArgs e) { if (textBox3.Text == "") { MessageBox.Show("Введите n"); return; } if (textBox6.Text == "") { MessageBox.Show("Введите d"); return; } LongArithmetic _n = new LongArithmetic(); LongArithmetic _d = new LongArithmetic(); try { _n = LongArithmetic.Parse(textBox3.Text); _d = LongArithmetic.Parse(textBox6.Text); } catch { MessageBox.Show("Числа невозможно считать!"); return; } Console.WriteLine("Начало дешифровки!"); StringBuilder sbtext = new StringBuilder(); foreach (string stext in richTextBox2.Lines) { if (stext == null || stext == "") { continue; } LongArithmetic criptedtext = LongArithmetic.Parse(stext); LongArithmetic text = global::RSA.mypows(criptedtext, _d, _n); StringBuilder sb = new StringBuilder(); foreach (ushort x in text) { sb.Append(((char)x).ToString()); } sbtext.Append(sb.ToString()); } richTextBox1.Text = sbtext.ToString(); Console.WriteLine("Дешифровка закончена!"); }
/// <summary> /// Деление /// </summary> /// <param name="left">Делимое</param> /// <param name="right">Делитель</param> /// <returns>Частое</returns> public static LongArithmetic operator /(LongArithmetic left, LongArithmetic right) { if (right == 0) { throw new DivideByZeroException(); } bool leftpos = left._isPositive; bool rightpos = right._isPositive; if (!leftpos) { left._isPositive = true; } if (!rightpos) { right._isPositive = true; } LongArithmetic l = 0; LongArithmetic r = left + 1; LongArithmetic m; while (l + 1 != r) { m = DivS(l + r, 2); LongArithmetic mr = m * right; if (mr > left) { r = m; } else if (mr < left) { l = m; } else { return(m); } } if (leftpos == rightpos) { l._isPositive = true; } else { l._isPositive = false; } left._isPositive = leftpos; right._isPositive = rightpos; return(l); }
private static LongArithmetic Pow(LongArithmetic n, LongArithmetic power) { LongArithmetic res = 1; for (int i = 0; i < power; i++) { res *= n; } return(res); }
/// <summary> /// Возвращает значение, указывающее, равен ли этот экземпляр заданному значению типа LongArithmetic /// </summary> /// <param name="obj">Значение типа LongArithmetic для сравнения с данным экземпляром.</param> /// <returns>true, если значение параметра obj совпадает со значением данного экземпляра. в противном случае — false.</returns> public override bool Equals(object obj) { if ((obj == null) || !this.GetType().Equals(obj.GetType())) { return(false); } else { LongArithmetic ml = (LongArithmetic)obj; return(this == ml); } }
/// <summary> /// Сложение /// </summary> /// <param name="left">Левое слагаемое</param> /// <param name="right">Правое слагаемое</param> /// <returns>Сумма</returns> public static LongArithmetic operator +(LongArithmetic left, LongArithmetic right) { LongArithmetic res = new LongArithmetic(); if (left._isPositive == right._isPositive) { res._isPositive = left._isPositive; res._number = new List <ushort>(); int i; ushort t = 0; for (i = 0; i < left._number.Count && i < right._number.Count; i++) { t = (ushort)(left._number[i] + right._number[i] + t); res._number.Add((ushort)(t % _base)); t /= _base; } for (; i < left._number.Count; i++) { t = (ushort)(left._number[i] + t); res._number.Add((ushort)(t % _base)); t /= _base; } for (; i < right._number.Count; i++) { t = (ushort)(right._number[i] + t); res._number.Add((ushort)(t % _base)); t /= _base; } if (t != 0) { res._number.Add(t); } } else if (!left._isPositive) { left._isPositive = true; res = right - left; left._isPositive = false; } else { right._isPositive = true; res = left - right; right._isPositive = false; } return(res); }
/// <summary> /// Остаток /// </summary> /// <param name="left">Делимое</param> /// <param name="right">Делитель</param> /// <returns>Остаток</returns> public static LongArithmetic operator %(LongArithmetic left, LongArithmetic right) { LongArithmetic res = left - ((left / right) * right); if (res < 0) { bool rightsign = right._isPositive; right._isPositive = true; res += right; right._isPositive = rightsign; } return(res); }
public static LongArithmetic egcd(LongArithmetic a, LongArithmetic b, ref LongArithmetic x, ref LongArithmetic y) { if (a == 0) { x = 0; y = 1; return(b); } LongArithmetic x1 = new LongArithmetic(), y1 = new LongArithmetic(); LongArithmetic d = egcd(b % a, a, ref x1, ref y1); x = y1 - (b / a) * x1; y = x1; return(d); }
public static LongArithmetic ModS(LongArithmetic left, int right) { LongArithmetic res = left - ((DivS(left, right)) * right); if (res < 0) { bool rightsign = right >= 0; if (!rightsign) { right *= -1; } res += right; } return(res); }
private static LongArithmetic binpow(LongArithmetic a, LongArithmetic n) { if (n == 0) { return(1); } if (n % 2 == 1) { return(binpow(a, n - 1) * a); } else { LongArithmetic b = binpow(a, n / 2); return(b * b); } }
public static LongArithmetic Random() { //Random rnd = new Random(); LaggedFibRandom rnd = new LaggedFibRandom((int)(DateTime.UtcNow.ToBinary() % 1000000000)); StringBuilder sb = new StringBuilder(); for (int i = 0; i < Times; i++) { sb.Append(rnd.Next() % 10000); } LongArithmetic res = LongArithmetic.Parse(sb.ToString()); return(res); }
static Int64 CreateKey(int number) { Int64 g = 0, p = 0, b = 0, Key = 0; string message = ""; for (int i = 0; i < 3; i++) { switch (i) { case 0: message = ReceiveInformation(stream); message += ' '; g = Convert.ToInt64(LongArithmetic.GiveLong(ref message)); p = Convert.ToInt64(LongArithmetic.GiveLong(ref message)); Console.WriteLine("Получены параметры g = {0} и p = {1}", g, p); Random random = new Random(); b = LongArithmetic.NextInt64(random); BigInteger B = BigInteger.ModPow(g, b, p); Console.WriteLine("Отправка параметра B = " + B); message = "B = " + B; SendInformation(message, stream); break; case 1: message = ReceiveInformation(stream); message += ' '; BigInteger A = BigInteger.Parse(LongArithmetic.GiveLong(ref message)); Console.WriteLine("Получен параметр A = {0}", A); Key = Convert.ToInt64(BigInteger.ModPow(A, b, p).ToString()); Key = LongArithmetic.GetFormatKey(Key); Console.WriteLine("Получен общий ключ № {0}: Key = {1}", number, Key); break; } } return(Key); }
/// <summary> /// Деление для коротких чисел /// </summary> /// <param name="left">Делимое</param> /// <param name="right">Делитель</param> /// <returns>Частное</returns> public static LongArithmetic DivS(LongArithmetic left, int right) { LongArithmetic res = new LongArithmetic(); res._isPositive = left._isPositive; res._number = new List <ushort>(); if (right < 0) { res._isPositive = !res._isPositive; } int t = 0, r; for (int i = left._number.Count - 1; i >= 0; i--) { r = (left._number[i] + t) / right; res._number.Add((ushort)r); t = left._number[i] + t - r * right; t *= _base; } res._number.Reverse(); for (int i = res._number.Count - 1; i >= 0 && res._number[i] == 0; i--) { res._number.RemoveAt(i); } if (res._number.Count == 0) { res._number.Add(0); } return(res); }
private void button3_Click(object sender, EventArgs e) { int bits = int.Parse(comboBox1.Text.Substring(0, comboBox1.Text.IndexOf(' '))); LongArithmetic bitsla = 1; for (int i = 0; i < bits; i++) { bitsla *= 2; } global::RSA.Times = bitsla.ToString().Count() / _base; LongArithmetic p = GetRandom("p"); Console.WriteLine(); LongArithmetic q = GetRandom("q"); Console.WriteLine(); textBox1.Text = p.ToString(); textBox2.Text = q.ToString(); Console.ForegroundColor = ConsoleColor.Red; textBox3.Text = (p * q).ToString(); Console.WriteLine("n=" + textBox3.Text); LongArithmetic fn = (p - 1) * (q - 1); Console.WriteLine("ф(n)=" + fn.ToString()); textBox4.Text = fn.ToString(); LongArithmetic _e = 1, d = 1; bool got = false; LongArithmetic x = new LongArithmetic(); LongArithmetic y = new LongArithmetic(); global::RSA.Times = global::RSA.Times * 5 / 4; Console.WriteLine("Вычисление e и k:"); while (!got) { _e = global::RSA.Random(); LongArithmetic z = global::RSA.egcd(fn, _e, ref x, ref y); if (z == 1 && y > 0 && (_e * y) % fn == 1) { d = y; //Console.WriteLine(d * _e % fn); got = true; } } if (!got) { Console.WriteLine("Вычислить e и k не удалось:"); } else { Console.WriteLine("e={0}", _e); Console.WriteLine("k={0}", d); textBox5.Text = _e.ToString(); textBox6.Text = d.ToString(); } }
private void button1_Click(object sender, EventArgs e) { if (textBox3.Text == "") { MessageBox.Show("Введите n"); return; } if (textBox5.Text == "") { MessageBox.Show("Введите e"); return; } LongArithmetic _n = new LongArithmetic(); LongArithmetic _e = new LongArithmetic(); try { _n = LongArithmetic.Parse(textBox3.Text); _e = LongArithmetic.Parse(textBox5.Text); } catch { MessageBox.Show("Числа невозможно считать!"); return; } Console.WriteLine("Начало шифрования!"); StringBuilder sb = new StringBuilder(); List <ushort> list = new List <ushort>(); LongArithmetic text = new LongArithmetic(); LongArithmetic criptedtext = new LongArithmetic(); richTextBox2.Clear(); foreach (var c in richTextBox1.Text) { if ((int)c > 9999 || (int)c < 0) { MessageBox.Show("Этот текст содержить невозможные для чтения символы!"); return; } list.Add((ushort)c); if (list.Count == 6) { text = new LongArithmetic(list); criptedtext = global::RSA.mypows(text, _e, _n); richTextBox2.AppendText(criptedtext.ToString() + "\n"); list.Clear(); } } if (list.Count > 0) { text = new LongArithmetic(list); criptedtext = global::RSA.mypows(text, _e, _n); richTextBox2.AppendText(criptedtext.ToString() + "\n"); } Console.WriteLine("Шифровка закончена!"); }
/// <summary> /// Вычитание /// </summary> /// <param name="left">Уменьшаемое</param> /// <param name="right">Вычитаемое</param> /// <returns>Разность</returns> public static LongArithmetic operator -(LongArithmetic left, LongArithmetic right) { LongArithmetic res = new LongArithmetic(); if (left._isPositive && right._isPositive) { if (left < right) { res = right - left; res._isPositive = false; } else { res._isPositive = true; res._number = new List <ushort>(); int i; int t = 0; for (i = 0; i < left._number.Count && i < right._number.Count; i++) { t = (t + left._number[i] - right._number[i]); res._number.Add((ushort)((t + _base) % _base)); t = (t + _base) / _base - 1; } for (; i < left._number.Count; i++) { t = (t + left._number[i]); res._number.Add((ushort)((t + _base) % _base)); t = (t + _base) / _base - 1; } for (i = res._number.Count - 1; i >= 0 && res._number[i] == 0; i--) { res._number.RemoveAt(i); } if (res._number.Count == 0) { res._number.Add(0); } } } else if (!left._isPositive && !right._isPositive) { left._isPositive = right._isPositive = true; res = right - left; left._isPositive = right._isPositive = false; } else if (!left._isPositive) { right._isPositive = false; res = left + right; right._isPositive = true; } else { right._isPositive = true; res = left + right; right._isPositive = false; } return(res); }
/// <summary> /// Конструктор с параметром /// </summary> /// <param name="num">Число длинной арифметики</param> public LongArithmetic(LongArithmetic num) { _isPositive = num._isPositive; _number = new List <ushort>(num._number); }