start of cursed gallois with non prime base

This commit is contained in:
Christoph J. Scherr 2023-05-30 12:59:08 +02:00
parent e3e122f066
commit 6460e939e8
Signed by: PlexSheep
GPG Key ID: 25B4ACF7D88186CC
5 changed files with 42 additions and 30 deletions

View File

@ -1,7 +1,7 @@
[package] [package]
name = "plexcryptool" name = "plexcryptool"
authors = ["Christoph J. Scherr <software@cscherr.de>"] authors = ["Christoph J. Scherr <software@cscherr.de>"]
version = "0.2.7" version = "0.2.8"
edition = "2021" edition = "2021"
readme = "README.md" readme = "README.md"
description = "Various tools for use with math and cryptology, includes executable and a library." description = "Various tools for use with math and cryptology, includes executable and a library."

View File

@ -87,10 +87,10 @@ pub struct ModexpArgs {
#[derive(Args, Clone, Debug, PartialEq, Eq)] #[derive(Args, Clone, Debug, PartialEq, Eq)]
pub struct ModredArgs { pub struct ModredArgs {
#[clap(value_parser=maybe_hex::<u64>)] #[clap(value_parser=maybe_hex::<u128>)]
pub polynomial: u64, pub polynomial: u128,
#[clap(value_parser=maybe_hex::<u64>)] #[clap(value_parser=maybe_hex::<u128>)]
pub relation: u64, pub relation: u128,
} }
#[derive(Args, Clone, Debug, PartialEq, Eq)] #[derive(Args, Clone, Debug, PartialEq, Eq)]
@ -105,6 +105,8 @@ pub struct PM1Args {
pub struct GalloisAction { pub struct GalloisAction {
#[clap(value_parser=maybe_hex::<u128>)] #[clap(value_parser=maybe_hex::<u128>)]
pub field: u128, pub field: u128,
#[clap(value_parser=maybe_hex::<u128>)]
pub relation: Option<u128>,
#[command(subcommand)] #[command(subcommand)]
pub action: GalloisActions pub action: GalloisActions
} }

View File

@ -61,7 +61,7 @@ pub fn main() {
cplex::printing::proc_result_vec(vec, args); cplex::printing::proc_result_vec(vec, args);
} }
MathActions::Gallois(gal_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 { match gal_args.action {
GalloisActions::Sqrt(gal_sqrt_args) => { GalloisActions::Sqrt(gal_sqrt_args) => {
let result = field.sqrt(gal_sqrt_args.a); let result = field.sqrt(gal_sqrt_args.a);

View File

@ -15,7 +15,7 @@
/// License: MIT /// License: MIT
/// Source: <https://git.cscherr.de/PlexSheep/plexcryptool/> /// Source: <https://git.cscherr.de/PlexSheep/plexcryptool/>
use crate::{math::modexp, cplex::printing::seperator}; use crate::{math::modexp, cplex::printing::seperator, math::modred::modred};
use core::fmt; use core::fmt;
@ -63,23 +63,25 @@ pub struct GalloisField {
base: u128, base: u128,
cha: u128, cha: u128,
verbose: bool, verbose: bool,
prime_base: bool prime_base: bool,
relation: Option<u128>
} }
/// implementations for the gallois field /// implementations for the gallois field
impl GalloisField { impl GalloisField {
/// make a new gallois field /// make a new gallois field
pub fn new(base: u128, verbose: bool) -> Self { pub fn new(base: u128, verbose: bool, relation: Option<u128>) -> Self {
let prime_base: bool = is_prime(base as u64); let prime_base: bool = is_prime(base as u64);
if !prime_base { if !prime_base {
println!("Non prime bases for a field are currently not supported. {} is not a prime.", base); println!("Non prime bases for a field are currently very experimental.\n
panic!("Non prime bases for a field are currently not supported."); Use them at your own risk! ({} is not a prime.)", base);
} }
let mut field = GalloisField{ let mut field = GalloisField{
base, base,
cha: base, cha: base,
verbose, verbose,
prime_base prime_base,
relation
}; };
if field.prime_base { if field.prime_base {
field.cha = base; field.cha = base;
@ -109,13 +111,21 @@ impl GalloisField {
T: num::cast::AsPrimitive<i128> T: num::cast::AsPrimitive<i128>
{ {
let mut n: i128 = num::cast::AsPrimitive::as_(n); let mut n: i128 = num::cast::AsPrimitive::as_(n);
if n < 0 { if self.prime_base {
while n < 0 { if n < 0 {
n += self.base as i128; 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 /// calculate the exponent of a base in the field
@ -352,8 +362,8 @@ impl GalloisField {
/// python wrappers for the gallois field /// python wrappers for the gallois field
impl GalloisField { impl GalloisField {
#[new] #[new]
pub fn py_new(base: u128, verbose: bool) -> Self { pub fn py_new(base: u128, verbose: bool, relation: Option<u128>) -> Self {
return GalloisField::new(base, verbose); return GalloisField::new(base, verbose, relation);
} }
#[pyo3(name="pow")] #[pyo3(name="pow")]
@ -405,7 +415,7 @@ impl GalloisField {
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
#[test] #[test]
fn test_gallois_sqrt() { 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(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(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)); 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] #[test]
fn test_gallois_inverse() { 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(12).unwrap(), 13);
assert_eq!(field.inverse(28).unwrap(), 10); assert_eq!(field.inverse(28).unwrap(), 10);
assert!(field.inverse(0).is_err()); 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(6).unwrap(), 14);
assert_eq!(field.inverse(54).unwrap(), 20); assert_eq!(field.inverse(54).unwrap(), 20);
assert!(field.inverse(0).is_err()); 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(17).unwrap(), 19);
assert_eq!(field.inverse(7).unwrap(), 10); assert_eq!(field.inverse(7).unwrap(), 10);
assert!(field.inverse(0).is_err()); assert!(field.inverse(0).is_err());
@ -436,9 +446,9 @@ fn test_gallois_inverse() {
#[test] #[test]
fn test_calc_char() { fn test_calc_char() {
assert_eq!(GalloisField::new(83, true).calc_char(), 83); assert_eq!(GalloisField::new(83, true, None).calc_char(), 83);
assert_eq!(GalloisField::new(1151, true).calc_char(), 1151); assert_eq!(GalloisField::new(1151, true, None).calc_char(), 1151);
assert_eq!(GalloisField::new(2, true).calc_char(), 2); assert_eq!(GalloisField::new(2, true, None).calc_char(), 2);
// only primes are supported right now. TODO // only primes are supported right now. TODO
//assert_eq!(GalloisField::new(8, true).calc_char(), 2); //assert_eq!(GalloisField::new(8, true).calc_char(), 2);

View File

@ -16,8 +16,8 @@ use pyo3::{prelude::*, exceptions::PyException};
#[test] #[test]
fn test_modred() { fn test_modred() {
let rel: u64 = 0x1053; let rel: u128 = 0x1053;
let pol0: u64 = 0x100001; let pol0: u128 = 0x100001;
assert_eq!(modred(pol0, rel, false).unwrap(), 0x21e); assert_eq!(modred(pol0, rel, false).unwrap(), 0x21e);
// test vectors by our professor // test vectors by our professor
// IDK why some of these don't work, but I am pretty sure that my algorithm and implementation // 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 /// modular reduction of a polynomial with a given relation
/// ///
/// (the function uses the integer representations) /// (the function uses the integer representations)
pub fn modred(mut poly: u64, relation: u64, verbose: bool) -> Result<u64, String> { pub fn modred(mut poly: u128, relation: u128, verbose: bool) -> Result<u128, String> {
let mut diffrence: u32; let mut diffrence: u32;
let mut index: usize = 0; let mut index: usize = 0;
@ -66,7 +66,7 @@ pub fn modred(mut poly: u64, relation: u64, verbose: bool) -> Result<u64, String
#[pyfunction] #[pyfunction]
#[pyo3(name="mordred")] #[pyo3(name="mordred")]
/// python wrapper for modred /// python wrapper for modred
pub fn py_modred(poly: u64, relation: u64, verbose: bool) -> PyResult<u64> { pub fn py_modred(poly: u128, relation: u128, verbose: bool) -> PyResult<u128> {
let res = modred(poly, relation, verbose); let res = modred(poly, relation, verbose);
match res { match res {
Ok(n) => { Ok(n) => {