diff options
Diffstat (limited to 'lab5/src/generate_window.rs')
| -rw-r--r-- | lab5/src/generate_window.rs | 128 |
1 files changed, 128 insertions, 0 deletions
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<u64> { + 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); + } + } + } +} |