diff --git a/res/03_baby_steps.bin b/res/03_baby_steps.bin new file mode 100644 index 0000000..df238dd Binary files /dev/null and b/res/03_baby_steps.bin differ diff --git a/res/03_giant_steps.bin b/res/03_giant_steps.bin new file mode 100644 index 0000000..c2753e0 Binary files /dev/null and b/res/03_giant_steps.bin differ diff --git a/src/bin/main.rs b/src/bin/main.rs index ab219a3..7e4d6af 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -1,7 +1,7 @@ use lib::submit_with_name; fn main() { - let name = "((ο)=>((o)=>o(((o(((ο*o([!+[]+!+"; + let name = "Яана"; let (n, x) = lib::challenges::c1_welcome::solve(); println!("n = {:?}\nx = {:?}\n{:?}\n", n, x, submit_with_name(name, n, x)); diff --git a/src/lib/challenges/c2_these_numbers_are_big.rs b/src/lib/challenges/c2_these_numbers_are_big.rs index 2dfe91b..d262c90 100644 --- a/src/lib/challenges/c2_these_numbers_are_big.rs +++ b/src/lib/challenges/c2_these_numbers_are_big.rs @@ -11,9 +11,8 @@ lazy_static!( pub fn solve(name: &str) -> (u64, Integer) { let mut x = sha256(name); - println!("sha256 = {x}"); x += 4; - for _ in tqdm::tqdm(0..10_000) { + for _ in 0..10_000 { for _ in 0..100 { x.pow_mod_mut(&E, &M).unwrap(); } diff --git a/src/lib/challenges/c3_are_you_still_doing_this_by_hand.rs b/src/lib/challenges/c3_are_you_still_doing_this_by_hand.rs index 5237bde..3062361 100644 --- a/src/lib/challenges/c3_are_you_still_doing_this_by_hand.rs +++ b/src/lib/challenges/c3_are_you_still_doing_this_by_hand.rs @@ -1,22 +1,86 @@ +use lazy_static::lazy_static; use rug::Integer; use std::collections::HashMap; +use std::io::{stdout, Write}; use tqdm::tqdm; const P: u64 = 12345679943u64; +lazy_static!( + static ref BABY_STEPS: Vec = std::fs::read("res/03_baby_steps.bin").unwrap() + .chunks_exact(8) + .map(|chunk| u64::from_be_bytes(chunk.try_into().unwrap())) + .collect(); + + static ref GIANT_STEPS: HashMap = std::fs::read("res/03_giant_steps.bin").unwrap() + .chunks_exact(8) + .map(|chunk| u64::from_be_bytes(chunk.try_into().unwrap())) + .enumerate() + .map(|(idx, step)| (step, idx)) + .collect(); +); + pub fn solve(n: u64, x: Integer) -> (u64, Integer) { let x = x.modulo(&Integer::from(P - 1)).to_u64().unwrap(); let mut n = n; let mut x = x.clone(); - for _ in tqdm(0..10_000) { + for _ in 0..10_000 { n += 1; - x = log(42, 1 + (x + n) % (P - 1), P).unwrap(); + x = log42_mod_p(1 + (x + n) % (P - 1)).unwrap(); } (n, Integer::from(x)) } +fn log42_mod_p(b: u64) -> Option { + if b % P == 1 { + return Some(0); + } + + let inv = pow(b, P - 2, P) as u128; + let s = GIANT_STEPS.len(); + for j in 1..=BABY_STEPS.len() { + let baby_step = BABY_STEPS[j - 1] as u128; + let search = ((baby_step * inv) % P as u128) as u64; + if let Some(i) = GIANT_STEPS.get(&search) { + return Some((j * s - i) as u64); + } + } + + None +} + +pub fn precompute() { + let g = 42u64; + let m = P; + let s = 5341666; + precompute_giant_steps(g, m, s); + precompute_baby_steps(g, m, s); +} + +fn precompute_giant_steps(g: u64, m: u64, s: u64) { + let g = g as u128; + let m = m as u128; + let mut a = 1u128; + for _ in tqdm(0..s) { + stdout().write_all(&(a as u64).to_be_bytes()).unwrap(); + a *= g; + a %= m; + } +} + +fn precompute_baby_steps(g: u64, m: u64, s: u64) { + let gs = pow(g, s, m) as u128; + let m= m as u128; + let mut a = gs; + for _ in tqdm(1..=(m as u64 / s + 1)) { + stdout().write_all(&(a as u64).to_be_bytes()).unwrap(); + a *= gs; + a %= m; + } +} + fn log(g: u64, b: u64, m: u64) -> Option { let g: u128 = g as u128; let b: u128 = b as u128; diff --git a/src/lib/lib.rs b/src/lib/lib.rs index 7bb5d8b..209100c 100644 --- a/src/lib/lib.rs +++ b/src/lib/lib.rs @@ -1,3 +1,4 @@ +#![allow(dead_code)] use anyhow::{anyhow, Result}; use json::JsonValue; use std::fmt::Display;