From 4862c2cf3eafdb6fa017a4e86a6fad8b4fc64171 Mon Sep 17 00:00:00 2001 From: Andrew Guschin Date: Sun, 13 Nov 2022 11:50:28 +0400 Subject: =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0?= =?UTF-8?q?=20=D0=B2=D1=82=D0=BE=D1=80=D0=B0=D1=8F=20=D0=BB=D0=B0=D0=B1?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lab2/src/generate_window.rs | 156 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 lab2/src/generate_window.rs (limited to 'lab2/src/generate_window.rs') diff --git a/lab2/src/generate_window.rs b/lab2/src/generate_window.rs new file mode 100644 index 0000000..56a572a --- /dev/null +++ b/lab2/src/generate_window.rs @@ -0,0 +1,156 @@ +use crate::window_state::WindowState; +use eframe::egui; + +#[derive(PartialEq, Eq)] +enum State { + Idle, + Requested, + Generated, +} + +pub struct Window { + state: State, + n: u64, + e: u64, + d: u64, + k: u64, + phi: u64, +} + +impl Default for Window { + fn default() -> Self { + Self { + state: State::Idle, + n: 0, + e: 0, + d: 0, + k: 0, + phi: 0, + } + } +} + +impl Window { + fn generate(&mut self) { + let primes = erathosphene(10000); + let i = fastrand::usize(4..primes.len()); + let mut j = fastrand::usize(4..primes.len()); + while j == i { + j = fastrand::usize(..primes.len()); + } + + let p = primes[i as usize]; + let q = primes[j as usize]; + self.n = p * q; + + self.phi = (p - 1) * (q - 1); + let mut e = self.phi; + loop { + let (d, x, _) = extended_gcd(e as i64, self.phi as i64); + if d != 1 { + e = fastrand::u64(2..self.phi); + } else { + self.e = e; + self.d = if x < 0 { x + self.phi as i64 } else { x } as u64; + break; + } + } + + let mut i = e; + let mut order = 1; + loop { + if i == 1 { + break; + } else { + order += 1; + i = (i * e) % self.phi; + } + } + + self.k = order; + } +} + +fn extended_gcd(a: i64, b: i64) -> (i64, i64, i64) { + if a == 0 { + return (b, 0, 1); + } + let (d, x, y) = extended_gcd(b % a, a); + return (d, y - (b / a) * x, x); +} + +fn erathosphene(n: u64) -> Vec { + let mut is_prime = vec![true; n as usize]; + let mut p = 2; + while p * p < n { + let mut cur = p * p; + while cur < n { + is_prime[cur as usize] = false; + cur += p; + } + while !is_prime[(p + 1) as usize] { + p += 1; + } + p += 1 + } + let mut primes = Vec::new(); + is_prime.iter().enumerate().for_each(|(i, p)| { + if *p { + primes.push(i as u64); + } + }); + return primes; +} + +impl WindowState for Window { + fn get_name(&self) -> &str { + "Генерация ключей" + } + + fn update(&mut self, ui: &mut egui::Ui) { + if ui.button("Сгенерировать").clicked() { + self.state = State::Requested; + } + if self.state == State::Requested { + self.generate(); + self.state = State::Generated; + } + if self.state == State::Generated { + ui.horizontal(|ui| { + ui.label("Модуль n:"); + let mut tmp = self.n.to_string(); + ui.add_enabled(false, egui::TextEdit::singleline(&mut tmp)); + }); + ui.horizontal(|ui| { + ui.label("Открытая экспонента e:"); + let mut tmp = self.e.to_string(); + ui.add_enabled(false, egui::TextEdit::singleline(&mut tmp)); + }); + ui.horizontal(|ui| { + ui.label("Секретная экспонента d:"); + let mut tmp = self.d.to_string(); + ui.add_enabled(false, egui::TextEdit::singleline(&mut tmp)); + }); + if ui.button("Скопировать открытый ключ").clicked() { + ui.output().copied_text = format!("{},{}", self.e, self.n); + } + if ui.button("Скопировать закрытый ключ").clicked() { + ui.output().copied_text = format!("{},{}", self.d, self.n); + } + + ui.label("Порядок элемента e по модулю phi(n):"); + let mut tmp = self.k.to_string(); + ui.add_enabled(false, egui::TextEdit::singleline(&mut tmp)); + if ui.button("Скопировать открытую экспоненту e").clicked() + { + ui.output().copied_text = format!("{}", self.e); + } + if ui.button("Скопировать phi(n)").clicked() { + ui.output().copied_text = format!("{}", self.phi); + } + if ui.button("Скопировать порядок").clicked() { + ui.output().copied_text = format!("{}", self.k); + } + } + } +} -- cgit v1.2.3