improve prime check by getting rid of it

This commit is contained in:
jacekpoz 2024-05-14 12:13:07 +02:00
parent b7cc408f58
commit 98adfff871
Signed by: poz
SSH key fingerprint: SHA256:JyLeVWE4bF3tDnFeUpUaJsPsNlJyBldDGV/dIKSLyN8

View file

@ -1,6 +1,9 @@
use std::str::FromStr;
use rand::thread_rng; use rand::thread_rng;
use num_bigint::{BigInt, BigUint, RandBigInt, ToBigInt}; use num_bigint::{BigInt, BigUint, RandBigInt, ToBigInt};
use num_traits::{One, Zero}; use num_traits::{One, Zero};
use num_prime::nt_funcs::is_prime;
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
struct Key { struct Key {
@ -14,17 +17,6 @@ struct KeyPair {
public: Key, public: Key,
} }
fn is_prime(n: &BigUint) -> bool {
let mut i = BigUint::from(2u32);
while &i < &n.sqrt() {
if n % &i == 0u32.into() {
return false;
}
i += 1u32;
}
true
}
fn euclid(a: &BigUint, b: &BigUint) -> BigUint { fn euclid(a: &BigUint, b: &BigUint) -> BigUint {
let mut s0 = BigInt::one(); let mut s0 = BigInt::one();
let mut s1 = BigInt::zero(); let mut s1 = BigInt::zero();
@ -68,7 +60,7 @@ fn find_e(phi: &BigUint) -> BigUint {
} }
fn generate_key_pair(p: &BigUint, q: &BigUint) -> Option<KeyPair> { fn generate_key_pair(p: &BigUint, q: &BigUint) -> Option<KeyPair> {
if !is_prime(p) || !is_prime(q) || p == q { if !is_prime(p, None).probably() || !is_prime(q, None).probably() || p == q {
return None; return None;
} }
@ -120,7 +112,6 @@ fn find_private_key(n: &BigUint, e: &BigUint, d: &BigUint) -> (BigUint, BigUint)
let kphi = d * e - 1u32; let kphi = d * e - 1u32;
let mut t = kphi.clone(); let mut t = kphi.clone();
while &t % 2u32 == BigUint::zero() { while &t % 2u32 == BigUint::zero() {
// println!("t: {t}");
t /= 2u32; t /= 2u32;
} }
@ -130,16 +121,12 @@ fn find_private_key(n: &BigUint, e: &BigUint, d: &BigUint) -> (BigUint, BigUint)
while a < 100u32.into() { while a < 100u32.into() {
let mut k = t.clone(); let mut k = t.clone();
while k < kphi { while k < kphi {
// println!("a: {a}, kphi: {kphi}, k: {k}, n: {n}");
let x = pow_mod(&a, &k, n); let x = pow_mod(&a, &k, n);
// println!("x: {x}; n: {n}");
if x != BigUint::one() && if x != BigUint::one() &&
x != (n - 1u32) && x != (n - 1u32) &&
pow_mod(&x, &2u32.into(), n) == BigUint::one() pow_mod(&x, &2u32.into(), n) == BigUint::one()
{ {
// println!("x: {x}; n: {n}");
p = gcd(&(x - BigUint::one()), n); p = gcd(&(x - BigUint::one()), n);
// println!("p: {p}");
break; break;
} }
k *= 2u32; k *= 2u32;
@ -153,8 +140,12 @@ fn find_private_key(n: &BigUint, e: &BigUint, d: &BigUint) -> (BigUint, BigUint)
} }
fn main() { fn main() {
let p1 = BigUint::from(1234577u32); let p1 = BigUint::from_str(
let p2 = BigUint::from(1234567891u32); "4749005082931655265795279207137334688882888522100146336507022668451002460179375611672565276762330501"
).unwrap();
let p2 = BigUint::from_str(
"9310861498193275957242744132472955539605730477090317642199650992920633866919589011169367627123252973"
).unwrap();
let pair_a = generate_key_pair(&p1, &p2) let pair_a = generate_key_pair(&p1, &p2)
.expect("failed to generate key pair a"); .expect("failed to generate key pair a");