working modular exponentiation (fast)

This commit is contained in:
Christoph J. Scherr 2023-05-02 15:17:17 +02:00
parent bcc7aad826
commit 50fe259b57
Signed by: PlexSheep
GPG Key ID: 25B4ACF7D88186CC
3 changed files with 34 additions and 15 deletions

View File

@ -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(())
}

View File

@ -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)
}

View File

@ -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<bool> = 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<u8> to Vec<bool> ( binary representation interpreted otherwise )
fn bytes_to_bools(bytes: &Vec<u8>) -> Vec<bool> {
let mut result: Vec<bool> = Vec::new();
for byte in bytes {