Exp by squaring, now fast enough to actually use a 64 bit prime

This commit is contained in:
Sarah Jamie Lewis 2021-08-15 07:35:26 -07:00
parent 82825fad58
commit 67d16b35fe
2 changed files with 26 additions and 27 deletions

View File

@ -31,10 +31,8 @@ impl<const ORDER: u64> 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<const ORDER: u64> 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
}
}

View File

@ -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<Vec<usize>, ()> {
// 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]);
}
}