summaryrefslogtreecommitdiff
path: root/lab2/src/generate_window.rs
diff options
context:
space:
mode:
Diffstat (limited to 'lab2/src/generate_window.rs')
-rw-r--r--lab2/src/generate_window.rs156
1 files changed, 156 insertions, 0 deletions
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<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("Модуль 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);
+ }
+ }
+ }
+}