From c07b47ee1a7aa3469753fa2ec49f3b499defac55 Mon Sep 17 00:00:00 2001 From: Sebastiano Tronto Date: Mon, 23 Jun 2025 11:21:11 +0200 Subject: Finalized --- README.md | 3 +++ src/lib.rs | 83 +++++++++++++++++++++++++++++++------------------------------- 2 files changed, 44 insertions(+), 42 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..6ea48d6 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +A small library for integers modulo n, similar to +[zmodn](https://git.tronto.net/zmodn/file/README.md.html) +but in Rust. diff --git a/src/lib.rs b/src/lib.rs index 6369b9f..2b0573a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,20 +1,19 @@ -// TODO: make Zmod argument type generic -// TODO: re-implement ECM? - use std::fmt; use std::ops; +pub type BaseInt = i64; + // We assume canonical representative, can compare value for PartialEq #[derive(Copy, Clone, Debug, PartialEq)] -pub struct Zmod { - value: i64 +pub struct Zmod { + value: BaseInt } -fn canonical_rep(x: i64) -> i64 { +fn canonical_rep(x: BaseInt) -> BaseInt { return (x % N + N) % N; } -fn extended_gcd(a: i64, b: i64) -> (i64, i64, i64) { +fn extended_gcd(a: BaseInt, b: BaseInt) -> (BaseInt, BaseInt, BaseInt) { if b == 0 { return (a, 1, 0); } @@ -22,15 +21,15 @@ fn extended_gcd(a: i64, b: i64) -> (i64, i64, i64) { (g, y, x - y*(a/b)) } -impl Zmod { - pub fn from(x: i64) -> Zmod { +impl Zmod { + pub fn from(x: BaseInt) -> Zmod { #[cfg(debug_assertions)] assert!(N > 1, "modulus must be greater than 1"); Zmod:: { value: canonical_rep::(x) } } - fn inverse(self) -> Result, i64> { + fn inverse(self) -> Result, BaseInt> { let (g, a, _) = extended_gcd(self.value, N); if g == 1 { Ok(Zmod::::from(a)) @@ -40,13 +39,13 @@ impl Zmod { } } -impl fmt::Display for Zmod { +impl fmt::Display for Zmod { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "({} mod {})", self.value, N) } } -impl ops::Add for Zmod { +impl ops::Add for Zmod { type Output = Zmod; fn add(self, z: Zmod) -> Zmod { @@ -54,15 +53,15 @@ impl ops::Add for Zmod { } } -impl ops::Add for Zmod { +impl ops::Add for Zmod { type Output = Zmod; - fn add(self, z: i64) -> Zmod { + fn add(self, z: BaseInt) -> Zmod { Zmod::::from(self.value + z) } } -impl ops::Add> for i64 { +impl ops::Add> for BaseInt { type Output = Zmod::; fn add(self, z: Zmod::) -> Zmod { @@ -70,19 +69,19 @@ impl ops::Add> for i64 { } } -impl ops::AddAssign for Zmod { +impl ops::AddAssign for Zmod { fn add_assign(&mut self, z: Zmod) { self.value = canonical_rep::(self.value + z.value); } } -impl ops::AddAssign for Zmod { - fn add_assign(&mut self, z: i64) { +impl ops::AddAssign for Zmod { + fn add_assign(&mut self, z: BaseInt) { self.value = canonical_rep::(self.value + z); } } -impl ops::Sub for Zmod { +impl ops::Sub for Zmod { type Output = Zmod; fn sub(self, z: Zmod) -> Zmod { @@ -90,15 +89,15 @@ impl ops::Sub for Zmod { } } -impl ops::Sub for Zmod { +impl ops::Sub for Zmod { type Output = Zmod; - fn sub(self, z: i64) -> Zmod { + fn sub(self, z: BaseInt) -> Zmod { Zmod::::from(self.value - z) } } -impl ops::Sub> for i64 { +impl ops::Sub> for BaseInt { type Output = Zmod; fn sub(self, z: Zmod) -> Zmod { @@ -106,19 +105,19 @@ impl ops::Sub> for i64 { } } -impl ops::SubAssign for Zmod { +impl ops::SubAssign for Zmod { fn sub_assign(&mut self, z: Zmod) { self.value = canonical_rep::(self.value - z.value); } } -impl ops::SubAssign for Zmod { - fn sub_assign(&mut self, z: i64) { +impl ops::SubAssign for Zmod { + fn sub_assign(&mut self, z: BaseInt) { self.value = canonical_rep::(self.value - z); } } -impl ops::Neg for Zmod { +impl ops::Neg for Zmod { type Output = Zmod; fn neg(self) -> Zmod { @@ -126,7 +125,7 @@ impl ops::Neg for Zmod { } } -impl ops::Mul for Zmod { +impl ops::Mul for Zmod { type Output = Zmod; fn mul(self, z: Zmod) -> Zmod { @@ -134,15 +133,15 @@ impl ops::Mul for Zmod { } } -impl ops::Mul for Zmod { +impl ops::Mul for Zmod { type Output = Zmod; - fn mul(self, z: i64) -> Zmod { + fn mul(self, z: BaseInt) -> Zmod { Zmod::::from(self.value * z) } } -impl ops::Mul> for i64 { +impl ops::Mul> for BaseInt { type Output = Zmod; fn mul(self, z: Zmod) -> Zmod { @@ -150,38 +149,38 @@ impl ops::Mul> for i64 { } } -impl ops::MulAssign for Zmod { +impl ops::MulAssign for Zmod { fn mul_assign(&mut self, z: Zmod) { self.value = canonical_rep::(self.value * z.value); } } -impl ops::MulAssign for Zmod { - fn mul_assign(&mut self, z: i64) { +impl ops::MulAssign for Zmod { + fn mul_assign(&mut self, z: BaseInt) { self.value = canonical_rep::(self.value * z); } } -impl ops::Div for Zmod { - type Output = Result, i64>; +impl ops::Div for Zmod { + type Output = Result, BaseInt>; - fn div(self, z: Zmod) -> Result, i64> { + fn div(self, z: Zmod) -> Result, BaseInt> { Ok(self * z.inverse()?) } } -impl ops::Div for Zmod { - type Output = Result, i64>; +impl ops::Div for Zmod { + type Output = Result, BaseInt>; - fn div(self, z: i64) -> Result, i64> { + fn div(self, z: BaseInt) -> Result, BaseInt> { self / Zmod::::from(z) } } -impl ops::Div> for i64 { - type Output = Result, i64>; +impl ops::Div> for BaseInt { + type Output = Result, BaseInt>; - fn div(self, z: Zmod) -> Result, i64> { + fn div(self, z: Zmod) -> Result, BaseInt> { Zmod::::from(self) / z } } -- cgit v1.3