From 032e1fa27ff9faa9a5d82624dbfc5fe8a48c339c Mon Sep 17 00:00:00 2001 From: Andrew Guschin Date: Sun, 11 Dec 2022 12:43:48 +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?=205=20=D0=BB=D0=B0=D0=B1=D0=BE=D1=80=D0=B0=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=BD=D0=B0=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lab5/src/generate_window.rs | 128 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 lab5/src/generate_window.rs (limited to 'lab5/src/generate_window.rs') diff --git a/lab5/src/generate_window.rs b/lab5/src/generate_window.rs new file mode 100644 index 0000000..25beb22 --- /dev/null +++ b/lab5/src/generate_window.rs @@ -0,0 +1,128 @@ +use crate::utils::powmod; +use crate::window_state::WindowState; +use eframe::egui; + +#[derive(PartialEq, Eq)] +enum State { + Idle, + Requested, + Generated, +} + +pub struct Window { + state: State, + p: u64, + g: u64, + a: u64, + y: u64, +} + +impl Default for Window { + fn default() -> Self { + Self { + state: State::Idle, + p: 0, + g: 0, + a: 0, + y: 0, + } + } +} + +fn min_order(x: u64, order: u64) -> u64 { + let mut min = 0; + let mut pow = x; + for power in 1..order { + if pow == 1 { + min = power; + break; + } + pow = (pow * x) % order; + } + return min; +} + +impl Window { + fn generate(&mut self) { + let primes = erathosphene(10000); + let i = fastrand::usize(4..primes.len()); + self.p = primes[i as usize]; + + for i in 1..self.p { + if min_order(i, self.p) == self.p - 1 { + self.g = i; + break; + } + } + + self.a = fastrand::u64(1..=self.p - 1); + self.y = powmod(self.g, self.a, self.p); + } +} + +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("Модуль p:"); + let mut tmp = self.p.to_string(); + ui.add_enabled(false, egui::TextEdit::singleline(&mut tmp)); + }); + ui.horizontal(|ui| { + ui.label("Порождающий элемент g группы Z_p:"); + let mut tmp = self.g.to_string(); + ui.add_enabled(false, egui::TextEdit::singleline(&mut tmp)); + }); + ui.horizontal(|ui| { + ui.label("Секретный ключ a:"); + let mut tmp = self.a.to_string(); + ui.add_enabled(false, egui::TextEdit::singleline(&mut tmp)); + }); + ui.horizontal(|ui| { + ui.label("Публичный ключ y:"); + let mut tmp = self.y.to_string(); + ui.add_enabled(false, egui::TextEdit::singleline(&mut tmp)); + }); + if ui.button("Скопировать публичный ключ").clicked() { + ui.output().copied_text = format!("{},{}", self.y, self.p); + } + if ui.button("Скопировать секретный ключ").clicked() { + ui.output().copied_text = format!("{},{},{}", self.g, self.a, self.p); + } + } + } +} -- cgit v1.2.3