python integration of ecc, code cleanup
This commit is contained in:
parent
8a0d41b134
commit
ea28bbf30b
|
@ -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.9"
|
version = "0.2.10"
|
||||||
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."
|
||||||
|
|
|
@ -57,6 +57,8 @@ fn register_math_module(py: Python, parent_module: &PyModule) -> PyResult<()> {
|
||||||
math_module.add_function(wrap_pyfunction!(math::gcd::alt_egcd, math_module)?)?;
|
math_module.add_function(wrap_pyfunction!(math::gcd::alt_egcd, math_module)?)?;
|
||||||
math_module.add_function(wrap_pyfunction!(math::factorise::prime_factors , math_module)?)?;
|
math_module.add_function(wrap_pyfunction!(math::factorise::prime_factors , math_module)?)?;
|
||||||
math_module.add_class::<math::gallois::GalloisField>()?;
|
math_module.add_class::<math::gallois::GalloisField>()?;
|
||||||
|
math_module.add_class::<math::ecc::ElipticCurve>()?;
|
||||||
|
math_module.add_class::<math::ecc::ElipticCurvePoint>()?;
|
||||||
parent_module.add_submodule(math_module)?;
|
parent_module.add_submodule(math_module)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
185
src/math/ecc.rs
185
src/math/ecc.rs
|
@ -12,14 +12,15 @@ use crate::cplex::printing::seperator;
|
||||||
|
|
||||||
use super::gallois::GalloisField;
|
use super::gallois::GalloisField;
|
||||||
|
|
||||||
use std::{ops::{Mul, Neg}, fmt::{Debug, Display}, f32::consts::PI};
|
use std::fmt::Debug;
|
||||||
|
|
||||||
use num::{Integer, Unsigned, NumCast};
|
use num::{Integer, Unsigned, NumCast};
|
||||||
|
|
||||||
use bitvec::prelude::*;
|
use bitvec::prelude::*;
|
||||||
|
|
||||||
use pyo3::prelude::*;
|
use pyo3::{prelude::*, exceptions::PyValueError};
|
||||||
|
|
||||||
|
#[pyclass]
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
/// represent a specific eliptic curve
|
/// represent a specific eliptic curve
|
||||||
|
@ -69,7 +70,7 @@ impl ElipticCurve {
|
||||||
Check for Diskriminante passed", field.reduce::<_, u128>(d));
|
Check for Diskriminante passed", field.reduce::<_, u128>(d));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut infty = ElipticCurvePoint::new(0, 0, field, false);
|
let mut infty = ElipticCurvePoint::new(0, 0);
|
||||||
infty.is_infinity_point = true;
|
infty.is_infinity_point = true;
|
||||||
let infty = infty;
|
let infty = infty;
|
||||||
let e = ElipticCurve {
|
let e = ElipticCurve {
|
||||||
|
@ -85,7 +86,7 @@ impl ElipticCurve {
|
||||||
|
|
||||||
/// build a new point in the EC
|
/// build a new point in the EC
|
||||||
pub fn new_point(&self, r: u128, s: u128) -> Result<ElipticCurvePoint, String> {
|
pub fn new_point(&self, r: u128, s: u128) -> Result<ElipticCurvePoint, String> {
|
||||||
let p = ElipticCurvePoint::new(r, s, self.field, self.verbose);
|
let p = ElipticCurvePoint::new(r, s);
|
||||||
if self.verbose {
|
if self.verbose {
|
||||||
println!("{p}")
|
println!("{p}")
|
||||||
}
|
}
|
||||||
|
@ -103,13 +104,9 @@ impl ElipticCurve {
|
||||||
pub fn poly<T>(&self, r: T, s: T) -> i128
|
pub fn poly<T>(&self, r: T, s: T) -> i128
|
||||||
where
|
where
|
||||||
T: Integer,
|
T: Integer,
|
||||||
T: Mul,
|
|
||||||
T: Debug,
|
T: Debug,
|
||||||
T: num::cast::AsPrimitive<u128>,
|
T: num::cast::AsPrimitive<u128>,
|
||||||
T: Neg
|
|
||||||
{
|
{
|
||||||
dbg!(&r);
|
|
||||||
dbg!(&s);
|
|
||||||
let r: u128 = num::cast::AsPrimitive::as_(r);
|
let r: u128 = num::cast::AsPrimitive::as_(r);
|
||||||
let s: u128 = num::cast::AsPrimitive::as_(s);
|
let s: u128 = num::cast::AsPrimitive::as_(s);
|
||||||
let res = (s.pow(2) as u128) - (r.pow(3) as u128) - (self.a * r) - self.b;
|
let res = (s.pow(2) as u128) - (r.pow(3) as u128) - (self.a * r) - self.b;
|
||||||
|
@ -123,6 +120,10 @@ impl ElipticCurve {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_point(&self, p: ElipticCurvePoint, verbose: bool) -> bool {
|
pub fn check_point(&self, p: ElipticCurvePoint, verbose: bool) -> bool {
|
||||||
|
if p.is_infinity_point {
|
||||||
|
println!("p is infinity: {p}");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
let mut valid = true;
|
let mut valid = true;
|
||||||
|
|
||||||
// insert into poly
|
// insert into poly
|
||||||
|
@ -158,23 +159,20 @@ impl ElipticCurve {
|
||||||
println!("adding {p1} + {p2}");
|
println!("adding {p1} + {p2}");
|
||||||
seperator();
|
seperator();
|
||||||
}
|
}
|
||||||
if p1.field != p2.field {
|
if !self.check_point(p1, false) {
|
||||||
return Err(String::from("Points are not on the same field"));
|
|
||||||
}
|
|
||||||
if !self.check_point(p1, self.verbose) {
|
|
||||||
return Err(String::from("{p1} is not a valid point"));
|
return Err(String::from("{p1} is not a valid point"));
|
||||||
}
|
}
|
||||||
if !self.check_point(p2, self.verbose) {
|
if !self.check_point(p2, false) {
|
||||||
return Err(String::from("{p2} is not a valid point"));
|
return Err(String::from("{p2} is not a valid point"));
|
||||||
}
|
}
|
||||||
if p1.field.prime_base {
|
if self.field.prime_base {
|
||||||
// verbisity stuff
|
// verbisity stuff
|
||||||
if self.verbose {
|
//if self.verbose {
|
||||||
println!("{} = {}; {} = -{} = {} <=> {}",
|
// println!("{} = {}; {} = -{} = {} <=> {}",
|
||||||
p1.r, p2.r, p1.s, p2.s, self.neg(p2).s,
|
// p1.r, p2.r, p1.s, p2.s, self.neg(p2).s,
|
||||||
p1.r == p2.r && p1.s == self.neg(p2).s,
|
// p1.r == p2.r && p1.s == self.neg(p2).s,
|
||||||
);
|
// );
|
||||||
}
|
//}
|
||||||
// case 1: both infty
|
// case 1: both infty
|
||||||
if p1.is_infinity_point && p2.is_infinity_point {
|
if p1.is_infinity_point && p2.is_infinity_point {
|
||||||
if self.verbose {
|
if self.verbose {
|
||||||
|
@ -204,14 +202,14 @@ impl ElipticCurve {
|
||||||
let m: i128 = m as i128;
|
let m: i128 = m as i128;
|
||||||
if self.verbose {
|
if self.verbose {
|
||||||
println!("m = [s_2 - s_1]/[r_2 - r_1] = [{} - {}]/[{} - {}] = {} = {}",
|
println!("m = [s_2 - s_1]/[r_2 - r_1] = [{} - {}]/[{} - {}] = {} = {}",
|
||||||
p2.s, p1.s, p2.r, p1.r, m, p1.field.reduce::<_, u128>(m))
|
p2.s, p1.s, p2.r, p1.r, m, self.field.reduce::<_, u128>(m))
|
||||||
}
|
}
|
||||||
let m: i128 = self.field.reduce(m);
|
let m: i128 = self.field.reduce(m);
|
||||||
|
|
||||||
let r3 = m.pow(2) - p1.r as i128 - p2.r as i128;
|
let r3 = m.pow(2) - p1.r as i128 - p2.r as i128;
|
||||||
if self.verbose {
|
if self.verbose {
|
||||||
println!("r_3 = m² - r_1 - r_2 = {} - {} - {} = {} = {}",
|
println!("r_3 = m² - r_1 - r_2 = {} - {} - {} = {} = {}",
|
||||||
m.pow(2), p1.r, p2.r, r3, p1.field.reduce::<_, u128>(r3));
|
m.pow(2), p1.r, p2.r, r3, self.field.reduce::<_, u128>(r3));
|
||||||
}
|
}
|
||||||
let r3 = self.field.reduce::<_, u128>(r3);
|
let r3 = self.field.reduce::<_, u128>(r3);
|
||||||
|
|
||||||
|
@ -225,9 +223,9 @@ impl ElipticCurve {
|
||||||
let s3 = self.field.reduce::<_, u128>(s3) as i128;
|
let s3 = self.field.reduce::<_, u128>(s3) as i128;
|
||||||
if self.verbose {
|
if self.verbose {
|
||||||
println!("-s_3 = - {s3} = {}", self.field.reduce::<_, u128>(-s3));
|
println!("-s_3 = - {s3} = {}", self.field.reduce::<_, u128>(-s3));
|
||||||
|
println!("Q = ({}, {})", r3, s3);
|
||||||
}
|
}
|
||||||
let p3 = ElipticCurvePoint::new(r3, self.field.reduce::<_, u128>(-s3),
|
let p3 = self.new_point(r3, self.field.reduce::<_, u128>(-s3)).expect("calculated point does not exist");
|
||||||
self.field, self.verbose);
|
|
||||||
|
|
||||||
if self.verbose {
|
if self.verbose {
|
||||||
seperator();
|
seperator();
|
||||||
|
@ -286,19 +284,18 @@ impl ElipticCurve {
|
||||||
let r3: i128 = self.field.reduce::<_, i128>(m.pow(2)) - p1.r as i128 - p2.r as i128;
|
let r3: i128 = self.field.reduce::<_, i128>(m.pow(2)) - p1.r as i128 - p2.r as i128;
|
||||||
if self.verbose {
|
if self.verbose {
|
||||||
println!("r_3 = m² - r_1 - r_2 = {} - {} - {} = {} = {}",
|
println!("r_3 = m² - r_1 - r_2 = {} - {} - {} = {} = {}",
|
||||||
m.pow(2), p1.r, p2.r, r3, p1.field.reduce::<_, u128>(r3));
|
m.pow(2), p1.r, p2.r, r3, self.field.reduce::<_, u128>(r3));
|
||||||
}
|
}
|
||||||
let r3: i128 = self.field.reduce(r3);
|
let r3: i128 = self.field.reduce(r3);
|
||||||
|
|
||||||
let s3: i128 = m.pow(3) - 2*m*p1.r as i128 - m*p2.r as i128 + p1.s as i128;
|
let s3: i128 = m.pow(3) - 2*m*p1.r as i128 - m*p2.r as i128 + p1.s as i128;
|
||||||
if self.verbose || p2.verbose {
|
if self.verbose {
|
||||||
println!("s_3 = m³ − 2*m*r_1 − m*r_2 + s1 = {} - 2*{m}*{} - {m}*{} + {} = \
|
println!("s_3 = m³ − 2*m*r_1 − m*r_2 + s1 = {} - 2*{m}*{} - {m}*{} + {} = \
|
||||||
{} = {}",
|
{} = {}",
|
||||||
m.pow(3), p1.r, p2.r, p1.s, s3, self.field.reduce::<_, u128>(s3));
|
m.pow(3), p1.r, p2.r, p1.s, s3, self.field.reduce::<_, u128>(s3));
|
||||||
}
|
}
|
||||||
let s3: i128 = self.field.reduce(s3);
|
let s3: i128 = self.field.reduce(s3);
|
||||||
let p3 = ElipticCurvePoint::new(r3 as u128, self.field.reduce::<_, u128>(-s3),
|
let p3 = self.new_point(r3 as u128, self.field.reduce::<_, u128>(-s3)).expect("calculated point does not exist in curve");
|
||||||
self.field, self.verbose);
|
|
||||||
|
|
||||||
if self.verbose {
|
if self.verbose {
|
||||||
seperator();
|
seperator();
|
||||||
|
@ -337,7 +334,7 @@ impl ElipticCurve {
|
||||||
T: Debug,
|
T: Debug,
|
||||||
T: Unsigned,
|
T: Unsigned,
|
||||||
{
|
{
|
||||||
if !self.check_point(g, self.verbose) {
|
if !self.check_point(g, false) {
|
||||||
return Err(String::from("invalid point"));
|
return Err(String::from("invalid point"));
|
||||||
}
|
}
|
||||||
let t: usize = num::cast(t).unwrap();
|
let t: usize = num::cast(t).unwrap();
|
||||||
|
@ -362,7 +359,6 @@ impl ElipticCurve {
|
||||||
return Ok(h);
|
return Ok(h);
|
||||||
}
|
}
|
||||||
for bit in t_bits {
|
for bit in t_bits {
|
||||||
dbg!(&index);
|
|
||||||
if index == l {
|
if index == l {
|
||||||
if self.verbose {
|
if self.verbose {
|
||||||
println!("h_{index} = {h}")
|
println!("h_{index} = {h}")
|
||||||
|
@ -390,12 +386,85 @@ impl ElipticCurve {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pymethods]
|
||||||
|
impl ElipticCurve {
|
||||||
|
#[new]
|
||||||
|
pub fn py_new(field: GalloisField, a: i128, b: i128, verbose: bool) -> PyResult<Self> {
|
||||||
|
match Self::new(field, a, b, verbose) {
|
||||||
|
Ok(v) => {return Ok(v)},
|
||||||
|
Err(e) => {
|
||||||
|
let py_e = PyValueError::new_err(e.to_string());
|
||||||
|
return Err(py_e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pyo3(name="new_point")]
|
||||||
|
pub fn py_new_point(&self, r: u128, s: u128) -> PyResult<ElipticCurvePoint> {
|
||||||
|
match self.new_point(r, s) {
|
||||||
|
Ok(v) => {return Ok(v)},
|
||||||
|
Err(e) => {
|
||||||
|
let py_e = PyValueError::new_err(e.to_string());
|
||||||
|
return Err(py_e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pyo3(name="poly")]
|
||||||
|
pub fn py_poly(&self, x: i128, y: i128) -> i128 {
|
||||||
|
self.poly(x, y)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pyo3(name="check_point", signature=(p, verbose = true))]
|
||||||
|
pub fn py_check_point(&self, p: ElipticCurvePoint, verbose: bool) -> bool {
|
||||||
|
self.check_point(p, verbose)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pyo3(name="add")]
|
||||||
|
pub fn py_add(&self, p1: ElipticCurvePoint, p2: ElipticCurvePoint)
|
||||||
|
-> PyResult<ElipticCurvePoint> {
|
||||||
|
match self.add(p1, p2) {
|
||||||
|
Ok(v) => {return Ok(v)},
|
||||||
|
Err(e) => {
|
||||||
|
let py_e = PyValueError::new_err(e.to_string());
|
||||||
|
return Err(py_e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pyo3(name="neg")]
|
||||||
|
pub fn py_neg(&self, p: ElipticCurvePoint) -> ElipticCurvePoint {
|
||||||
|
self.neg(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pyo3(name="mul")]
|
||||||
|
pub fn py_mul(&self, p1: ElipticCurvePoint, t: u128)
|
||||||
|
-> PyResult<ElipticCurvePoint> {
|
||||||
|
match self.mul(p1, t) {
|
||||||
|
Ok(v) => {return Ok(v)},
|
||||||
|
Err(e) => {
|
||||||
|
let py_e = PyValueError::new_err(e.to_string());
|
||||||
|
return Err(py_e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __str__(&self) -> PyResult<String> {
|
||||||
|
Ok(format!("{}", self))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __repr__(&self) -> PyResult<String> {
|
||||||
|
Ok(format!("{}", self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for ElipticCurve{
|
impl std::fmt::Display for ElipticCurve{
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
write!(f, "F(X, Y) = Y² - X³ -{}X - {}", self.a, self.b)
|
write!(f, "F(X, Y) = Y² - X³ -{}X - {}", self.a, self.b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pyclass]
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||||
/// represent a specific eliptic curves point
|
/// represent a specific eliptic curves point
|
||||||
///
|
///
|
||||||
|
@ -404,21 +473,27 @@ pub struct ElipticCurvePoint {
|
||||||
r: u128,
|
r: u128,
|
||||||
s: u128,
|
s: u128,
|
||||||
is_infinity_point: bool,
|
is_infinity_point: bool,
|
||||||
field: GalloisField,
|
|
||||||
verbose: bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pymethods]
|
||||||
impl ElipticCurvePoint {
|
impl ElipticCurvePoint {
|
||||||
|
#[new]
|
||||||
/// create a new point
|
/// create a new point
|
||||||
pub fn new(r: u128, s: u128, field: GalloisField, verbose: bool) -> ElipticCurvePoint {
|
pub fn new(r: u128, s: u128) -> ElipticCurvePoint {
|
||||||
ElipticCurvePoint {
|
ElipticCurvePoint {
|
||||||
r,
|
r,
|
||||||
s,
|
s,
|
||||||
is_infinity_point: false,
|
is_infinity_point: false,
|
||||||
field,
|
|
||||||
verbose
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn __str__(&self) -> PyResult<String> {
|
||||||
|
Ok(format!("{}", self))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __repr__(&self) -> PyResult<String> {
|
||||||
|
Ok(format!("{}", self))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for ElipticCurvePoint {
|
impl std::fmt::Display for ElipticCurvePoint {
|
||||||
|
@ -450,33 +525,27 @@ pub mod test {
|
||||||
let ec = ElipticCurve::new(f, -3, 3, true).expect("ec cant be created");
|
let ec = ElipticCurve::new(f, -3, 3, true).expect("ec cant be created");
|
||||||
// real points
|
// real points
|
||||||
let p = vec![
|
let p = vec![
|
||||||
ElipticCurvePoint::new(0, 4, f, false),
|
ec.new_point(0, 4 ).unwrap(),
|
||||||
ElipticCurvePoint::new(0, 9, f, false),
|
ec.new_point(0, 9 ).unwrap(),
|
||||||
ElipticCurvePoint::new(1, 1, f, false),
|
ec.new_point(1, 1 ).unwrap(),
|
||||||
ElipticCurvePoint::new(1, 12, f, false),
|
ec.new_point(1, 1 ).unwrap(),
|
||||||
ElipticCurvePoint::new(4, 4, f, false),
|
ec.new_point(4, 4 ).unwrap(),
|
||||||
ElipticCurvePoint::new(4, 9, f, false),
|
ec.new_point(4, 9 ).unwrap(),
|
||||||
ElipticCurvePoint::new(5, 3, f, false),
|
ec.new_point(5, 3 ).unwrap(),
|
||||||
ElipticCurvePoint::new(5, 10, f, false),
|
ec.new_point(5, 10 ).unwrap(),
|
||||||
ElipticCurvePoint::new(7, 0, f, false),
|
ec.new_point(7, 0 ).unwrap(),
|
||||||
ElipticCurvePoint::new(8, 6, f, false),
|
ec.new_point(8, 6 ).unwrap(),
|
||||||
ElipticCurvePoint::new(9, 4, f, false),
|
ec.new_point(9, 4 ).unwrap(),
|
||||||
ElipticCurvePoint::new(9, 9, f, false),
|
ec.new_point(9, 9 ).unwrap(),
|
||||||
ElipticCurvePoint::new(11, 1, f, false),
|
ec.new_point(11, 1 ).unwrap(),
|
||||||
ElipticCurvePoint::new(11, 12, f, false),
|
ec.new_point(11, 12 ).unwrap(),
|
||||||
];
|
];
|
||||||
// random values, not part of the e, fc.
|
// random values, not part of the e, fc.
|
||||||
let np = vec![
|
let np = vec![
|
||||||
ElipticCurvePoint::new(0, 5, f, false),
|
ec.new_point(0, 5).unwrap_err(),
|
||||||
ElipticCurvePoint::new(1, 9, f, false),
|
ec.new_point(1, 9).unwrap_err(),
|
||||||
ElipticCurvePoint::new(1, 4, f, false),
|
ec.new_point(1, 4).unwrap_err(),
|
||||||
];
|
];
|
||||||
for i in p {
|
|
||||||
assert!(ec.clone().check_point(i, true));
|
|
||||||
}
|
|
||||||
for i in np {
|
|
||||||
assert!(!ec.clone().check_point(i, true));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -15,12 +15,12 @@
|
||||||
/// License: MIT
|
/// License: MIT
|
||||||
/// Source: <https://git.cscherr.de/PlexSheep/plexcryptool/>
|
/// Source: <https://git.cscherr.de/PlexSheep/plexcryptool/>
|
||||||
|
|
||||||
use crate::{math::modexp::{self, modular_exponentiation_wrapper}, cplex::printing::seperator, math::modred::modred};
|
use crate::{math::modexp, cplex::printing::seperator, math::modred::modred};
|
||||||
|
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
use num::{Integer, NumCast, Signed, Unsigned};
|
use num::{Integer, NumCast};
|
||||||
|
|
||||||
use pyo3::{prelude::*, exceptions::PyValueError};
|
use pyo3::{prelude::*, exceptions::PyValueError};
|
||||||
|
|
||||||
|
@ -391,6 +391,7 @@ impl GalloisField {
|
||||||
self.cha = i;
|
self.cha = i;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
|
@ -458,6 +459,20 @@ impl GalloisField {
|
||||||
}
|
}
|
||||||
panic!("No order was found, but n is not 0 and all possibilities have been tried");
|
panic!("No order was found, but n is not 0 and all possibilities have been tried");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn __str__(&self) -> PyResult<String> {
|
||||||
|
Ok(format!("{}", self))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __repr__(&self) -> PyResult<String> {
|
||||||
|
Ok(format!("{}", self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for GalloisField {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
write!(f, "F_{}", self.base)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -482,7 +497,7 @@ pub mod test {
|
||||||
assert_eq!(field.reduce::<_, u128>(i as u128), i);
|
assert_eq!(field.reduce::<_, u128>(i as u128), i);
|
||||||
}
|
}
|
||||||
|
|
||||||
let field = GalloisField::new(16, true, None);
|
let _ = GalloisField::new(16, true, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in New Issue