diff --git a/Cargo.toml b/Cargo.toml index b77b96a..cdc0aa0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "plexcryptool" authors = ["Christoph J. Scherr "] -version = "0.2.7" +version = "0.2.8" edition = "2021" readme = "README.md" description = "Various tools for use with math and cryptology, includes executable and a library." diff --git a/src/cplex/cli.rs b/src/cplex/cli.rs index 7e69baa..5086474 100644 --- a/src/cplex/cli.rs +++ b/src/cplex/cli.rs @@ -87,10 +87,10 @@ pub struct ModexpArgs { #[derive(Args, Clone, Debug, PartialEq, Eq)] pub struct ModredArgs { - #[clap(value_parser=maybe_hex::)] - pub polynomial: u64, - #[clap(value_parser=maybe_hex::)] - pub relation: u64, + #[clap(value_parser=maybe_hex::)] + pub polynomial: u128, + #[clap(value_parser=maybe_hex::)] + pub relation: u128, } #[derive(Args, Clone, Debug, PartialEq, Eq)] @@ -105,6 +105,8 @@ pub struct PM1Args { pub struct GalloisAction { #[clap(value_parser=maybe_hex::)] pub field: u128, + #[clap(value_parser=maybe_hex::)] + pub relation: Option, #[command(subcommand)] pub action: GalloisActions } diff --git a/src/main.rs b/src/main.rs index e010dc7..67c0a18 100644 --- a/src/main.rs +++ b/src/main.rs @@ -61,7 +61,7 @@ pub fn main() { cplex::printing::proc_result_vec(vec, args); } MathActions::Gallois(gal_args) => { - let field = math::gallois::GalloisField::new(gal_args.field, args.verbose); + let field = math::gallois::GalloisField::new(gal_args.field, args.verbose, gal_args.relation); match gal_args.action { GalloisActions::Sqrt(gal_sqrt_args) => { let result = field.sqrt(gal_sqrt_args.a); diff --git a/src/math/gallois.rs b/src/math/gallois.rs index a46ea70..c42678f 100644 --- a/src/math/gallois.rs +++ b/src/math/gallois.rs @@ -15,7 +15,7 @@ /// License: MIT /// Source: -use crate::{math::modexp, cplex::printing::seperator}; +use crate::{math::modexp, cplex::printing::seperator, math::modred::modred}; use core::fmt; @@ -63,23 +63,25 @@ pub struct GalloisField { base: u128, cha: u128, verbose: bool, - prime_base: bool + prime_base: bool, + relation: Option } /// implementations for the gallois field impl GalloisField { /// make a new gallois field - pub fn new(base: u128, verbose: bool) -> Self { + pub fn new(base: u128, verbose: bool, relation: Option) -> Self { let prime_base: bool = is_prime(base as u64); if !prime_base { - println!("Non prime bases for a field are currently not supported. {} is not a prime.", base); - panic!("Non prime bases for a field are currently not supported."); + println!("Non prime bases for a field are currently very experimental.\n + Use them at your own risk! ({} is not a prime.)", base); } let mut field = GalloisField{ base, cha: base, verbose, - prime_base + prime_base, + relation }; if field.prime_base { field.cha = base; @@ -109,13 +111,21 @@ impl GalloisField { T: num::cast::AsPrimitive { let mut n: i128 = num::cast::AsPrimitive::as_(n); - if n < 0 { - while n < 0 { - n += self.base as i128; + if self.prime_base { + if n < 0 { + while n < 0 { + n += self.base as i128; + } } + n %= self.base as i128; + return n as u128; + } + else { + if n < 0 { + panic!("reduction for negative numbers not implemented."); + } + modred(n as u128, self.relation.unwrap(), self.verbose).expect("modular reduction didn't work") } - n %= self.base as i128; - return n as u128; } /// calculate the exponent of a base in the field @@ -352,8 +362,8 @@ impl GalloisField { /// python wrappers for the gallois field impl GalloisField { #[new] - pub fn py_new(base: u128, verbose: bool) -> Self { - return GalloisField::new(base, verbose); + pub fn py_new(base: u128, verbose: bool, relation: Option) -> Self { + return GalloisField::new(base, verbose, relation); } #[pyo3(name="pow")] @@ -405,7 +415,7 @@ impl GalloisField { /////////////////////////////////////////////////////////////////////////////////////////////////// #[test] fn test_gallois_sqrt() { - let field = GalloisField::new(977, true); + let field = GalloisField::new(977, true, None); assert_eq!(field.sqrt(269).expect("function says there is no root but there is"), (313, 664)); assert_eq!(field.sqrt(524).expect("function says there is no root but there is"), (115, 862)); assert_eq!(field.sqrt(275).expect("function says there is no root but there is"), (585, 392)); @@ -413,17 +423,17 @@ fn test_gallois_sqrt() { #[test] fn test_gallois_inverse() { - let field = GalloisField::new(31, true); + let field = GalloisField::new(31, true, None); assert_eq!(field.inverse(12).unwrap(), 13); assert_eq!(field.inverse(28).unwrap(), 10); assert!(field.inverse(0).is_err()); - let field = GalloisField::new(83, true); + let field = GalloisField::new(83, true, None); assert_eq!(field.inverse(6).unwrap(), 14); assert_eq!(field.inverse(54).unwrap(), 20); assert!(field.inverse(0).is_err()); - let field = GalloisField::new(23, true); + let field = GalloisField::new(23, true, None); assert_eq!(field.inverse(17).unwrap(), 19); assert_eq!(field.inverse(7).unwrap(), 10); assert!(field.inverse(0).is_err()); @@ -436,9 +446,9 @@ fn test_gallois_inverse() { #[test] fn test_calc_char() { - assert_eq!(GalloisField::new(83, true).calc_char(), 83); - assert_eq!(GalloisField::new(1151, true).calc_char(), 1151); - assert_eq!(GalloisField::new(2, true).calc_char(), 2); + assert_eq!(GalloisField::new(83, true, None).calc_char(), 83); + assert_eq!(GalloisField::new(1151, true, None).calc_char(), 1151); + assert_eq!(GalloisField::new(2, true, None).calc_char(), 2); // only primes are supported right now. TODO //assert_eq!(GalloisField::new(8, true).calc_char(), 2); diff --git a/src/math/modred.rs b/src/math/modred.rs index 9f772ed..fe50672 100644 --- a/src/math/modred.rs +++ b/src/math/modred.rs @@ -16,8 +16,8 @@ use pyo3::{prelude::*, exceptions::PyException}; #[test] fn test_modred() { - let rel: u64 = 0x1053; - let pol0: u64 = 0x100001; + let rel: u128 = 0x1053; + let pol0: u128 = 0x100001; assert_eq!(modred(pol0, rel, false).unwrap(), 0x21e); // test vectors by our professor // IDK why some of these don't work, but I am pretty sure that my algorithm and implementation @@ -37,7 +37,7 @@ fn test_modred() { /// modular reduction of a polynomial with a given relation /// /// (the function uses the integer representations) -pub fn modred(mut poly: u64, relation: u64, verbose: bool) -> Result { +pub fn modred(mut poly: u128, relation: u128, verbose: bool) -> Result { let mut diffrence: u32; let mut index: usize = 0; @@ -66,7 +66,7 @@ pub fn modred(mut poly: u64, relation: u64, verbose: bool) -> Result PyResult { +pub fn py_modred(poly: u128, relation: u128, verbose: bool) -> PyResult { let res = modred(poly, relation, verbose); match res { Ok(n) => {