First whack at modular inverses.

This commit is contained in:
2018-04-04 18:47:02 -04:00
parent 2f16a45784
commit 3cd37a881d
2 changed files with 67 additions and 0 deletions

View File

@@ -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 * &quotient);
s = old_s - (s * &quotient);
t = old_t - (t * &quotient);
old_r = prov_r;
old_s = prov_s;
old_t = prov_t;
}
(old_r, old_s, old_t)
}

View File

@@ -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