From 29a14b39e6839ef3601fc8c7a9b0aca674b6b757 Mon Sep 17 00:00:00 2001 From: Adam Wick Date: Sat, 5 May 2018 19:42:21 -0700 Subject: [PATCH] Fix the bits() implementation, and add is_multiple_of() and gcd(). --- src/cryptonum/unsigned.rs | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/cryptonum/unsigned.rs b/src/cryptonum/unsigned.rs index 34f34ca..6f70a08 100644 --- a/src/cryptonum/unsigned.rs +++ b/src/cryptonum/unsigned.rs @@ -1,5 +1,5 @@ use cryptonum::signed::SCN; -use num::{BigUint,ToPrimitive,Zero}; +use num::{BigInt,BigUint,ToPrimitive,Zero}; use std::fmt; use std::fmt::Write; use std::cmp::Ordering; @@ -24,7 +24,15 @@ impl UCN { } pub fn bits(&self) -> usize { - self.contents.len() * 64 + let num_elems = self.contents.len(); + let mut res = num_elems * 64; + + if self.contents.len() > 0 { + assert!(self.contents[num_elems - 1] != 0); + res -= self.contents[num_elems - 1].leading_zeros() as usize; + } + + res } pub fn is_zero(&self) -> bool { @@ -47,6 +55,18 @@ impl UCN { } } + pub fn is_multiple_of(&self, other: &UCN) -> bool { + self % other == UCN::from(1u64) + } + + pub fn gcd(&self, other: &UCN) -> UCN { + let a = SCN{ negative: false, value: self.clone() }; + let b = SCN{ negative: false, value: other.clone() }; + let (d,_,_) = a.egcd(b); + assert!(!d.negative); + d.value + } + fn clean(&mut self) { loop { match self.contents.pop() {