diff --git a/Cargo.toml b/Cargo.toml index 098fd0f..1c9609a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "plexcryptool" -version = "0.2.1" +version = "0.2.3" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/main.rs b/src/main.rs index ab0cdc6..6c55dd9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -78,6 +78,7 @@ struct AlgoCommand { enum MathActions { #[command(name="modexp")] Modexp(ModexpArgs), + Modred(ModredArgs), Pm1(PM1Args), } @@ -88,9 +89,19 @@ struct ModexpArgs { field: String } +#[derive(Args, Clone, Debug, PartialEq, Eq)] +struct ModredArgs { + #[clap(value_parser=maybe_hex::)] + polynomial: u64, + #[clap(value_parser=maybe_hex::)] + relation: u64, +} + #[derive(Args, Clone, Debug, PartialEq, Eq)] struct PM1Args { + #[clap(value_parser=maybe_hex::)] n: u128, + #[clap(value_parser=maybe_hex::)] max_prime: u128, } @@ -106,13 +117,17 @@ enum BinaryActions { struct RotateArgs { #[arg(short, long, default_value_t = false)] left: bool, + #[clap(value_parser=maybe_hex::)] base: u32, + #[clap(value_parser=maybe_hex::)] shift_width: u32, } #[derive(Args, Clone, Debug, PartialEq, Eq)] struct XorArgs { + #[clap(value_parser=maybe_hex::)] a: u128, + #[clap(value_parser=maybe_hex::)] b: u128, } @@ -173,6 +188,29 @@ pub fn main() { println!("result is {}", result) } } + MathActions::Modred(mod_red_args) => { + let result = math::modred::modred(mod_red_args.polynomial, mod_red_args.relation, args.verbose); + match result { + Ok(res) => { + if args.machine { + println!("0x{:x}", res) + } + else { + println!("======================================================================="); + println!("result is 0x{:x}", res) + } + } + Err(e) => { + if args.machine { + println!("{:?}", e) + } + else { + println!("======================================================================="); + println!("could not compute: {:?}", e) + } + } + } + } MathActions::Pm1(pm1_args) => { let result: Result, String> = math::pm1::p_minus_one( pm1_args.n, diff --git a/src/math/mod.rs b/src/math/mod.rs index 65c4dca..6beca9c 100644 --- a/src/math/mod.rs +++ b/src/math/mod.rs @@ -8,3 +8,4 @@ /// Source: pub mod modexp; pub mod pm1; +pub mod modred; diff --git a/src/math/modred.rs b/src/math/modred.rs new file mode 100644 index 0000000..f496b95 --- /dev/null +++ b/src/math/modred.rs @@ -0,0 +1,46 @@ +#![allow(dead_code)] +/// modular reduction +/// +/// Implements automatic modular reduction in a field specified by a given relation. +/// +/// Basically, any binary number can be written as a polynomial. This polynomial can be reduced by +/// the relation that defines a field. In that field. This is what we call modular reduction. +/// +/// Author: Christoph J. Scherr +/// License: MIT +/// Source: + +#[test] +fn test_modred() { + let rel: u64 = 0x1053; + let pol0: u64 = 0x100001; + assert_eq!(modred(pol0, rel, false).unwrap(), 0x21e); +} + +pub fn modred(mut poly: u64, relation: u64, verbose: bool) -> Result { + + let mut diffrence: u32; + let mut index: usize = 0; + if verbose { + println!("relation:\t0x{:x}\t", relation); + println!("polynomial:\t0x{:x}\t", poly); + println!("======================================================================="); + } + while relation.leading_zeros() - poly.leading_zeros() != 0 { + diffrence = relation.leading_zeros() - poly.leading_zeros(); + poly = poly ^ (relation << diffrence); + if verbose { + println!("{index}:\tpoly: 0x{:x}\t", poly); + //println!("{index}:\tpoly: 0b{:b}\t", poly); + } + index += 1; + } + // one more time! + diffrence = relation.leading_zeros() - poly.leading_zeros(); + poly = poly ^ (relation << diffrence); + if verbose { + println!("{index}:\tpoly: 0x{:x}\t", poly); + //println!("{index}:\tpoly: 0b{:b}\t", poly); + } + return Ok(poly); +}