Exp by squaring, now fast enough to actually use a 64 bit prime
This commit is contained in:
parent
82825fad58
commit
67d16b35fe
|
@ -31,10 +31,8 @@ impl<const ORDER: u64> PrimeOrderDomain<{ ORDER }> {
|
||||||
self.pow(ORDER - 2) // at least it is faster an iterating...
|
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 {
|
pub fn pow(&self, exp: u64) -> Self {
|
||||||
let mut ret = self.clone();
|
|
||||||
|
|
||||||
if exp == 0 {
|
if exp == 0 {
|
||||||
return PrimeOrderDomain::new(1);
|
return PrimeOrderDomain::new(1);
|
||||||
}
|
}
|
||||||
|
@ -42,10 +40,11 @@ impl<const ORDER: u64> PrimeOrderDomain<{ ORDER }> {
|
||||||
return self.clone();
|
return self.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
for _i in 1..exp {
|
if exp % 2 == 0 {
|
||||||
ret = self.clone() * ret;
|
(*self * *self).pow(exp / 2)
|
||||||
|
} else {
|
||||||
|
*self * self.pow(2).pow((exp - 1) / 2)
|
||||||
}
|
}
|
||||||
ret
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
42
src/lib.rs
42
src/lib.rs
|
@ -3,8 +3,7 @@ use crate::matrix::Matrix;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use rand_core::{CryptoRng, RngCore};
|
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 = 18446744073709551557; // picked because largest 64 bit prime...
|
||||||
pub const PRIME_ORDER: u64 = 63823; // technically a 64bit prime number..
|
|
||||||
|
|
||||||
pub mod domain;
|
pub mod domain;
|
||||||
pub mod matrix;
|
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)
|
/// 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>, ()> {
|
pub fn attempt_solve(&self) -> Result<Vec<usize>, ()> {
|
||||||
|
|
||||||
|
|
||||||
// Arrange the hashes into an augmented for matrix...
|
// Arrange the hashes into an augmented for matrix...
|
||||||
let m = (self.synthetic_max + self.threshold) as usize;
|
let m = (self.synthetic_max + self.threshold) as usize;
|
||||||
let mut augmented_matrix = Matrix::new(
|
let mut augmented_matrix =
|
||||||
m + self.expanded_hashes.len(),
|
Matrix::new(m + self.expanded_hashes.len(), self.expanded_hashes.len());
|
||||||
self.expanded_hashes.len(),
|
|
||||||
);
|
|
||||||
for j in 0..self.expanded_hashes.len() {
|
for j in 0..self.expanded_hashes.len() {
|
||||||
for i in 0..m {
|
for i in 0..m {
|
||||||
augmented_matrix.update(i, j, self.expanded_hashes[j as usize].0[i as usize]);
|
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...
|
// Transpose back to column form...
|
||||||
augmented_matrix = augmented_matrix.transpose();
|
augmented_matrix = augmented_matrix.transpose();
|
||||||
|
|
||||||
|
|
||||||
// Pretty Print for checking...
|
// Pretty Print for checking...
|
||||||
for i in 0..augmented_matrix.rows() {
|
for i in 0..augmented_matrix.rows() {
|
||||||
for j in 0..augmented_matrix.cols() {
|
for j in 0..augmented_matrix.cols() {
|
||||||
|
@ -228,26 +222,32 @@ mod tests {
|
||||||
use crate::{Generator, Solver, PRIME_ORDER};
|
use crate::{Generator, Solver, PRIME_ORDER};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use rand_core::OsRng;
|
use rand_core::OsRng;
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn it_works() {
|
fn it_works() {
|
||||||
let mut rng = OsRng;
|
let mut rng = OsRng;
|
||||||
let s = 4u64;
|
let s = 3u64;
|
||||||
let t = 6u64;
|
let t = 4u64;
|
||||||
let dhf = Generator::generate(&mut rng, s, t);
|
|
||||||
|
|
||||||
let mut solver = Solver::new(s, t);
|
let mut attempts = 0;
|
||||||
for i in 0..10 {
|
|
||||||
// These are the indexes which are to be random...you can try swapping them around..
|
loop {
|
||||||
if i != 5 && i != 2 && i != 9 {
|
let dhf = Generator::generate(&mut rng, s, t);
|
||||||
let x0: u64 = rng.gen_range(0..PRIME_ORDER);
|
|
||||||
|
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));
|
let hash = dhf.hash(PrimeOrderDomain::new(x0));
|
||||||
solver.add_hash(hash);
|
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]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue