working modular exponentiation (fast)
This commit is contained in:
parent
bcc7aad826
commit
50fe259b57
10
src/lib.rs
10
src/lib.rs
|
@ -1,7 +1,7 @@
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
mod binary;
|
mod binary;
|
||||||
mod iterated_squaring;
|
mod modular_exponentiation;
|
||||||
|
|
||||||
#[pymodule]
|
#[pymodule]
|
||||||
fn register_binary_module(py: Python, parent_module: &PyModule) -> PyResult<()> {
|
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(())
|
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.
|
/// A Python module implemented in Rust.
|
||||||
#[pymodule]
|
#[pymodule]
|
||||||
fn plexcryptool(py: Python, m: &PyModule) -> PyResult<()> {
|
fn plexcryptool(py: Python, m: &PyModule) -> PyResult<()> {
|
||||||
register_binary_module(py, m)?;
|
register_binary_module(py, m)?;
|
||||||
|
register_math_module(py, m)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
13
src/main.rs
13
src/main.rs
|
@ -1,17 +1,16 @@
|
||||||
mod binary;
|
mod binary;
|
||||||
mod iterated_squaring;
|
mod modular_exponentiation;
|
||||||
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use iterated_squaring::calc_exp_in_field;
|
use modular_exponentiation::modular_exponentiation;
|
||||||
|
|
||||||
use num_bigint;
|
use num_bigint;
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let b = num_bigint::BigInt::from_str("17").expect("a");
|
let b = num_bigint::BigInt::from_str("17010010101018924824").expect("a");
|
||||||
let e = num_bigint::BigInt::from_str("1011201391039").expect("a");
|
let e = num_bigint::BigInt::from_str("2024254424298472398479283759238759375392875932875928375932875239857329857923889289282975291").expect("a");
|
||||||
let f = num_bigint::BigInt::from_str("101").expect("a");
|
let f = num_bigint::BigInt::from_str("101012").expect("a");
|
||||||
let r = calc_exp_in_field(b.clone(), e, f);
|
let r = modular_exponentiation(b.clone(), e, f);
|
||||||
assert_eq!(r, b);
|
|
||||||
print!("res is {}\n", r)
|
print!("res is {}\n", r)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
* Umwandlung des Exponenten k in die zugehörige Binärdarstellung.
|
||||||
* Ersetzen jeder 0 durch Q und jeder 1 durch QM.
|
* Ersetzen jeder 0 durch Q und jeder 1 durch QM.
|
||||||
* Nun wird Q als Anweisung zum Quadrieren und M als Anweisung zum Multiplizieren aufgefasst.
|
* 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
|
* Man beginne mit 1, quadriere für jedes gelesene Q das bisherige Zwischenergebnis und
|
||||||
* multipliziere es für jedes gelesene M mit x .
|
* multipliziere es für jedes gelesene M mit x .
|
||||||
*/
|
*/
|
||||||
pub fn calc_exp_in_field(
|
pub fn modular_exponentiation(
|
||||||
base: BigInt,
|
base: BigInt,
|
||||||
exp: BigInt,
|
orig_exp: BigInt,
|
||||||
field: BigInt) -> BigInt {
|
field: BigInt) -> BigInt {
|
||||||
let binary_repr = exp.to_bytes_be();
|
let binary_repr = orig_exp.to_bytes_be();
|
||||||
dump_bin(&binary_repr.1);
|
|
||||||
|
|
||||||
|
|
||||||
let instructions: Vec<bool> = bytes_to_bools(&binary_repr.1);
|
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> {
|
fn bytes_to_bools(bytes: &Vec<u8>) -> Vec<bool> {
|
||||||
let mut result: Vec<bool> = Vec::new();
|
let mut result: Vec<bool> = Vec::new();
|
||||||
for byte in bytes {
|
for byte in bytes {
|
Loading…
Reference in New Issue