diff --git a/generation/src/Add.hs b/generation/src/Add.hs index 7cc9969..dc3ffe0 100644 --- a/generation/src/Add.hs +++ b/generation/src/Add.hs @@ -202,6 +202,7 @@ declareSafeSignedAddOperators bitsize _ = testFileLit = Lit [] (Str (testFile False bitsize) Cooked Unsuffixed mempty) mempty in [sourceFile| use core::ops::Add; + #[cfg(test)] use crate::CryptoNum; #[cfg(test)] use crate::testing::{build_test_path,run_test}; diff --git a/generation/src/ModInv.hs b/generation/src/ModInv.hs index b0fdf96..2fffd76 100644 --- a/generation/src/ModInv.hs +++ b/generation/src/ModInv.hs @@ -36,13 +36,15 @@ declareModInv bitsize _ = testFileLit = Lit [] (Str (testFile True bitsize) Cooked Unsuffixed mempty) mempty in [sourceFile| use core::convert::TryFrom; - use crate::CryptoNum; + use crate::{CryptoNum,ModularInversion}; use crate::signed::$$sname; #[cfg(test)] use crate::testing::{build_test_path,run_test}; use crate::unsigned::$$uname; - impl $$uname { + impl ModularInversion for $$uname { + type Signed = $$sname; + fn modinv(&self, phi: &$$uname) -> Option<$$uname> { let (_, mut b, g) = phi.egcd(&self); diff --git a/generation/src/Subtract.hs b/generation/src/Subtract.hs index 81229fc..55f2531 100644 --- a/generation/src/Subtract.hs +++ b/generation/src/Subtract.hs @@ -133,6 +133,7 @@ declareSafeSignedSubtractOperators bitsize _ = testFileLit = Lit [] (Str (testFile True bitsize) Cooked Unsuffixed mempty) mempty in [sourceFile| use core::ops::Sub; + #[cfg(test)] use crate::CryptoNum; #[cfg(test)] use crate::testing::{build_test_path,run_test}; diff --git a/src/lib.rs b/src/lib.rs index e535b48..a1254e5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -52,8 +52,10 @@ pub trait DivMod: Sized { fn divmod(&self, rhs: &Self) -> (Self, Self); } -// Provides support for a variety of modular mathematical operations, as beloved -// by cryptographers. +/// Provides support for a variety of modular mathematical operations, as beloved +/// by cryptographers. Note that modular inversion and GCD calculations are shoved +/// off into another trait, because they operate on slightly different number +/// types. pub trait ModularOperations { // reduce the current value by the provided modulus fn reduce(&self, m: &Modulus) -> Self; @@ -66,6 +68,18 @@ pub trait ModularOperations { } +/// Provide support for modular inversion and GCD operations, which are useful +/// here and there. We provide default implementations for `modinv` and +/// `gcd_is_one`, based on the implementation of `egcd`. The built-in versions +/// explicitly define the latter, though, to improve performance. +pub trait ModularInversion: Sized { + type Signed; + + fn modinv(&self, phi: &Self) -> Option; + fn egcd(&self, rhs: &Self) -> (Self::Signed, Self::Signed, Self::Signed); + fn gcd_is_one(&self, b: &Self) -> bool; +} + /// An error in conversion of large numbers (either to primitives or to other numbers #[derive(Debug)] pub enum ConversionError {