start of cursed gallois with non prime base
This commit is contained in:
parent
e3e122f066
commit
6460e939e8
|
@ -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."
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) => {
|
||||||
|
|
Loading…
Reference in New Issue