First whack at modular inverses.
This commit is contained in:
@@ -7,3 +7,54 @@ mod unsigned;
|
||||
|
||||
pub use self::signed::SCN;
|
||||
pub use self::unsigned::UCN;
|
||||
|
||||
use std::ops::Neg;
|
||||
|
||||
pub fn modinv(e: &UCN, phi: &UCN) -> UCN {
|
||||
let (_, mut x, _) = extended_euclidean(&e, &phi);
|
||||
let int_phi = SCN::from(phi.clone());
|
||||
while x.is_negative() {
|
||||
x = x + &int_phi;
|
||||
}
|
||||
x.into()
|
||||
}
|
||||
|
||||
fn extended_euclidean(a: &UCN, b: &UCN) -> (SCN, SCN, SCN) {
|
||||
let posinta = SCN::from(a.clone());
|
||||
let posintb = SCN::from(b.clone());
|
||||
let (d, x, y) = egcd(posinta, posintb);
|
||||
|
||||
if d.is_negative() {
|
||||
(d.neg(), x.neg(), y.neg())
|
||||
} else {
|
||||
(d, x, y)
|
||||
}
|
||||
}
|
||||
|
||||
fn egcd(a: SCN, b: SCN) -> (SCN, SCN, SCN) {
|
||||
let mut s = SCN::zero();
|
||||
let mut old_s = SCN::from(1 as u8);
|
||||
let mut t = SCN::from(1 as u8);
|
||||
let mut old_t = SCN::zero();
|
||||
let mut r = b;
|
||||
let mut old_r = a;
|
||||
|
||||
while !r.is_zero() {
|
||||
let quotient = old_r.clone() / r.clone();
|
||||
|
||||
let prov_r = r.clone();
|
||||
let prov_s = s.clone();
|
||||
let prov_t = t.clone();
|
||||
|
||||
r = old_r - (r * "ient);
|
||||
s = old_s - (s * "ient);
|
||||
t = old_t - (t * "ient);
|
||||
|
||||
old_r = prov_r;
|
||||
old_s = prov_s;
|
||||
old_t = prov_t;
|
||||
}
|
||||
|
||||
(old_r, old_s, old_t)
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,10 @@ impl SCN {
|
||||
self.value.is_zero()
|
||||
}
|
||||
|
||||
pub fn is_negative(&self) -> bool {
|
||||
self.negative
|
||||
}
|
||||
|
||||
pub fn from_str(x: &str) -> SCN {
|
||||
if x.get(0..1) == Some("-") {
|
||||
SCN{ negative: true, value: UCN::from_str(&x[1..]) }
|
||||
@@ -59,6 +63,18 @@ define_signed_into!(SCN, i16, u16);
|
||||
define_signed_into!(SCN, i32, u32);
|
||||
define_signed_into!(SCN, i64, u64);
|
||||
|
||||
impl From<UCN> for SCN {
|
||||
fn from(x: UCN) -> SCN {
|
||||
SCN{ negative: false, value: x }
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<UCN> for SCN {
|
||||
fn into(self) -> UCN {
|
||||
self.value
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Comparisons
|
||||
|
||||
Reference in New Issue
Block a user