add miller arbin test + fast modular exponent

This commit is contained in:
vandechat96
2022-10-11 22:27:09 +02:00
parent 18ef4a0515
commit ff08afe5e0
7 changed files with 142 additions and 29 deletions

View File

@@ -1,5 +1,5 @@
[package]
name = "TPNSM"
name = "crypto_test"
version = "0.1.0"
edition = "2021"
@@ -7,4 +7,5 @@ edition = "2021"
[dependencies]
num = "0.4"
rayon = "1.5.3"
rayon = "1.5"
rand = "0.8"

View File

@@ -1,2 +1,22 @@
Elliptic_curve_primality
![image](./pictures/ecp.png)
# Primality tests
<details>
<summary>Elliptic curve
</summary>
![image](./pictures/ecp.png)
</details>
<details>
<summary>MillerRabin
</summary>
![image](./pictures/mrp.png)
</details>
BailliePSW
AKS
AdlemanPomeranceRumely

BIN
rust/pictures/mrp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

View File

@@ -1,2 +1,2 @@
pub mod prime;
pub mod utils;
pub mod utils;

View File

@@ -1,15 +1,3 @@
use TPNSM::prime::{prime_classical, prime_dumb_rayon};
fn main() {
println!("Hello, world!");
let max = 1000000;
find_prime(prime_classical(max));
//find_prime(prime_dumb_rayon(max));
}
fn find_prime(primes: Vec<u32>) {
//println!("{:?}", primes);
println!("{:?}", primes.last());
println!("{}", primes.len());
}

View File

@@ -1,17 +1,60 @@
use crate::utils::fast_exp;
use num::integer::sqrt;
use rand::{thread_rng, Rng};
use rayon::prelude::*;
pub fn miller_rabbin_gen(max: u32, acr: u32) -> Vec<u32> {
let method = |n| miller_rabbin_test(n, acr);
prime_gen(max, method)
}
pub fn miller_rabbin_test(n: u32, acr: u32) -> bool {
if n % 2 == 0 {
false
} else {
let (k, q) = find_2_k_q(n - 1);
let mut random = thread_rng();
'l: for _ in 0..acr {
let a = random.gen_range(1..n - 1);
let mut x = fast_exp(a, q, n);
if x != 1 && x != n - 1 {
for _ in 0..k - 1 {
x = fast_exp(x, 2, n);
if x == n - 1 {
continue 'l;
}
}
return false;
}
}
true
}
}
fn find_2_k_q(mut n: u32) -> (u32, u32) {
let mut k = 0;
while n % 2 == 0 {
n /= 2;
k += 1;
}
(k, n)
}
fn prime_gen<F>(max: u32, method: F) -> Vec<u32>
where F: Fn(u32) -> bool {
where
F: Fn(u32) -> bool,
{
let mut primes = vec![2_u32];
let mut i = 1;
let mut i = 3;
while i < max {
i += 2;
let prime = method(i);
if prime {
primes.push(i);
}
i += 2;
}
primes
}
@@ -19,7 +62,7 @@ fn prime_gen<F>(max: u32, method: F) -> Vec<u32>
pub fn prime_classical(max: u32) -> Vec<u32> {
let mut primes = vec![2_u32];
let mut i = 1;
'l: while i < max {
'l: while i + 2 < max {
i += 2;
for p in &primes {
if i % p == 0 {
@@ -35,16 +78,53 @@ pub fn prime_classical(max: u32) -> Vec<u32> {
pub fn prime_dumb_rayon(max: u32) -> Vec<u32> {
let mut primes = vec![2_u32];
let mut i = 1;
let mut i = 3;
while i < max {
i += 2;
let found = primes.par_iter()
.filter(|x| { **x <= sqrt(i) })
.any(|x| { i % *x == 0 });
let found = primes
.par_iter()
.filter(|x| **x <= sqrt(i))
.any(|x| i % *x == 0);
if !found {
primes.push(i);
}
i += 2;
}
primes
}
}
#[cfg(test)]
mod tests {
use super::*;
const PRIME_TEST: [(u32, u32); 6] = [
(10, 7),
(100, 97),
(500, 499),
(1000, 997),
(8300, 8297),
(10000, 9973),
];
#[test]
fn test_prime_classical() {
for (max, prem) in PRIME_TEST {
assert_eq!(prime_classical(max).last(), Some(&prem));
}
}
#[test]
fn test_prime_dumb_rayon() {
for (max, prem) in PRIME_TEST {
assert_eq!(prime_dumb_rayon(max).last(), Some(&prem));
}
}
#[test]
fn test_miller_rabbin() {
for (max, prem) in PRIME_TEST {
assert_eq!(miller_rabbin_gen(max, 10).last(), Some(&prem));
}
assert!(!miller_rabbin_test(2147483649, 10));
assert!(miller_rabbin_test(2147483647, 10));
}
}

View File

@@ -48,7 +48,6 @@ pub fn congruent(a: i32, b: i32, n: i32) -> bool {
(a - b) % n == 0
}
pub fn gcd_euclid(mut a: u32, mut b: u32) -> u32 {
let mut r = a % b;
while r != 0 {
@@ -79,6 +78,23 @@ pub fn modular_inverse(a: u32, n: u32) -> Option<u32> {
Some(t as u32)
}
pub fn fast_exp(mut b: u32, mut e: u32, m: u32) -> u32 {
if m == 1 {
return 0;
}
let mut result = 1;
b %= m;
while e > 0 {
if e % 2 == 1 {
result = (result as u64 * b as u64 % m as u64) as u32;
}
e >>= 1;
b = (b as u64 * b as u64 % m as u64) as u32;
}
result
}
#[cfg(test)]
mod tests {
use super::*;
@@ -124,4 +140,12 @@ mod tests {
assert_eq!(modular_inverse(10, 19), Some(2));
assert_eq!(modular_inverse(4, 6), None);
}
}
#[test]
fn test_fast_exp() {
assert_eq!(fast_exp(5, 3, 13), 8);
assert_eq!(fast_exp(11, 13, 19), 11);
assert_eq!(fast_exp(1234, 754, 452), 392);
assert_eq!(fast_exp(76158, 24586, 5364), 576);
}
}