From 67d16b35fe3d3fc709020dc166c000c0a36305fd Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Sun, 15 Aug 2021 07:35:26 -0700 Subject: [PATCH] Exp by squaring, now fast enough to actually use a 64 bit prime --- src/domain.rs | 11 +++++------ src/lib.rs | 42 +++++++++++++++++++++--------------------- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/src/domain.rs b/src/domain.rs index 393e31f..6b1e59d 100644 --- a/src/domain.rs +++ b/src/domain.rs @@ -31,10 +31,8 @@ impl PrimeOrderDomain<{ ORDER }> { self.pow(ORDER - 2) // at least it is faster an iterating... } - // seriously I never said this was gonna be fast... + // exponentiation by squaring pub fn pow(&self, exp: u64) -> Self { - let mut ret = self.clone(); - if exp == 0 { return PrimeOrderDomain::new(1); } @@ -42,10 +40,11 @@ impl PrimeOrderDomain<{ ORDER }> { return self.clone(); } - for _i in 1..exp { - ret = self.clone() * ret; + if exp % 2 == 0 { + (*self * *self).pow(exp / 2) + } else { + *self * self.pow(2).pow((exp - 1) / 2) } - ret } } diff --git a/src/lib.rs b/src/lib.rs index 0855e9f..560a8b7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,8 +3,7 @@ use crate::matrix::Matrix; use rand::Rng; use rand_core::{CryptoRng, RngCore}; -// One of the many reasons you should not be using the package for anything serious... -pub const PRIME_ORDER: u64 = 63823; // technically a 64bit prime number.. +pub const PRIME_ORDER: u64 = 18446744073709551557; // picked because largest 64 bit prime... pub mod domain; pub mod matrix; @@ -97,14 +96,10 @@ impl Solver { /// Solve the system and return the indexes of the true hashes (or error if the system is unsolvable) pub fn attempt_solve(&self) -> Result, ()> { - - // Arrange the hashes into an augmented for matrix... let m = (self.synthetic_max + self.threshold) as usize; - let mut augmented_matrix = Matrix::new( - m + self.expanded_hashes.len(), - self.expanded_hashes.len(), - ); + let mut augmented_matrix = + Matrix::new(m + self.expanded_hashes.len(), self.expanded_hashes.len()); for j in 0..self.expanded_hashes.len() { for i in 0..m { augmented_matrix.update(i, j, self.expanded_hashes[j as usize].0[i as usize]); @@ -166,7 +161,6 @@ impl Solver { // Transpose back to column form... augmented_matrix = augmented_matrix.transpose(); - // Pretty Print for checking... for i in 0..augmented_matrix.rows() { for j in 0..augmented_matrix.cols() { @@ -228,26 +222,32 @@ mod tests { use crate::{Generator, Solver, PRIME_ORDER}; use rand::Rng; use rand_core::OsRng; + use std::collections::HashSet; #[test] fn it_works() { let mut rng = OsRng; - let s = 4u64; - let t = 6u64; - let dhf = Generator::generate(&mut rng, s, t); + let s = 3u64; + let t = 4u64; - let mut solver = Solver::new(s, t); - for i in 0..10 { - // These are the indexes which are to be random...you can try swapping them around.. - if i != 5 && i != 2 && i != 9 { - let x0: u64 = rng.gen_range(0..PRIME_ORDER); + let mut attempts = 0; + + loop { + let dhf = Generator::generate(&mut rng, s, t); + + let mut solver = Solver::new(s, t); + for i in 0..5 { + let mut x0: u64 = rng.gen_range(0..PRIME_ORDER); let hash = dhf.hash(PrimeOrderDomain::new(x0)); solver.add_hash(hash); - } else { - solver.add_hash(dhf.random(&mut rng)); } + solver.add_hash(dhf.random(&mut rng)); + solver.add_hash(dhf.random(&mut rng)); + if solver.attempt_solve().is_ok() { + println!("Attempts: {}", attempts); + return; + } + attempts += 1; } - - assert_eq!(solver.attempt_solve().unwrap(), vec![0, 1, 3, 4, 6, 7, 8]); } }