summaryrefslogtreecommitdiff
path: root/lab5/src/generate_window.rs
diff options
context:
space:
mode:
Diffstat (limited to 'lab5/src/generate_window.rs')
-rw-r--r--lab5/src/generate_window.rs128
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);
+ }
+ }
+ }
+}