From 50fe259b577249b8e93be2a6dfcc1f4fd0ad8581 Mon Sep 17 00:00:00 2001 From: PlexSheep Date: Tue, 2 May 2023 15:17:17 +0200 Subject: [PATCH] working modular exponentiation (fast) --- src/lib.rs | 10 ++++++- src/main.rs | 13 +++++----- ..._squaring.rs => modular_exponentiation.rs} | 26 ++++++++++++++----- 3 files changed, 34 insertions(+), 15 deletions(-) rename src/{iterated_squaring.rs => modular_exponentiation.rs} (72%) diff --git a/src/lib.rs b/src/lib.rs index f6e0153..dbabba6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ use pyo3::prelude::*; mod binary; -mod iterated_squaring; +mod modular_exponentiation; #[pymodule] fn register_binary_module(py: Python, parent_module: &PyModule) -> PyResult<()> { @@ -12,9 +12,17 @@ fn register_binary_module(py: Python, parent_module: &PyModule) -> PyResult<()> Ok(()) } +#[pymodule] +fn register_math_module(py: Python, parent_module: &PyModule) -> PyResult<()> { + let math_module = PyModule::new(py, "math")?; + parent_module.add_submodule(math_module)?; + Ok(()) +} + /// A Python module implemented in Rust. #[pymodule] fn plexcryptool(py: Python, m: &PyModule) -> PyResult<()> { register_binary_module(py, m)?; + register_math_module(py, m)?; Ok(()) } diff --git a/src/main.rs b/src/main.rs index 6cd05e3..e9ef188 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,17 +1,16 @@ mod binary; -mod iterated_squaring; +mod modular_exponentiation; use std::str::FromStr; -use iterated_squaring::calc_exp_in_field; +use modular_exponentiation::modular_exponentiation; use num_bigint; pub fn main() { - let b = num_bigint::BigInt::from_str("17").expect("a"); - let e = num_bigint::BigInt::from_str("1011201391039").expect("a"); - let f = num_bigint::BigInt::from_str("101").expect("a"); - let r = calc_exp_in_field(b.clone(), e, f); - assert_eq!(r, b); + let b = num_bigint::BigInt::from_str("17010010101018924824").expect("a"); + let e = num_bigint::BigInt::from_str("2024254424298472398479283759238759375392875932875928375932875239857329857923889289282975291").expect("a"); + let f = num_bigint::BigInt::from_str("101012").expect("a"); + let r = modular_exponentiation(b.clone(), e, f); print!("res is {}\n", r) } diff --git a/src/iterated_squaring.rs b/src/modular_exponentiation.rs similarity index 72% rename from src/iterated_squaring.rs rename to src/modular_exponentiation.rs index a96e1aa..b46cd47 100644 --- a/src/iterated_squaring.rs +++ b/src/modular_exponentiation.rs @@ -11,6 +11,8 @@ pub fn calc_exp_in_field_lib( } /** + * modular exponentiation algorithm with big numbers. + * * Umwandlung des Exponenten k in die zugehörige Binärdarstellung. * Ersetzen jeder 0 durch Q und jeder 1 durch QM. * Nun wird Q als Anweisung zum Quadrieren und M als Anweisung zum Multiplizieren aufgefasst. @@ -18,20 +20,30 @@ pub fn calc_exp_in_field_lib( * Man beginne mit 1, quadriere für jedes gelesene Q das bisherige Zwischenergebnis und * multipliziere es für jedes gelesene M mit x . */ -pub fn calc_exp_in_field( +pub fn modular_exponentiation( base: BigInt, - exp: BigInt, + orig_exp: BigInt, field: BigInt) -> BigInt { - let binary_repr = exp.to_bytes_be(); - dump_bin(&binary_repr.1); - + let binary_repr = orig_exp.to_bytes_be(); let instructions: Vec = bytes_to_bools(&binary_repr.1); - dbg!(instructions); - return base; + let mut exp = BigInt::from(1); + for instr in instructions { + if instr { + // square + exp = (exp.pow(2) * &base) % &field; + } + else { + // square and multiply + exp = exp.pow(2) % &field; + } + } + + return exp; } +// Vec to Vec ( binary representation interpreted otherwise ) fn bytes_to_bools(bytes: &Vec) -> Vec { let mut result: Vec = Vec::new(); for byte in bytes {