From c34629aa47f9e8851520099bac4f5e02f59934e0 Mon Sep 17 00:00:00 2001 From: Adam Wick Date: Sat, 5 May 2018 19:41:30 -0700 Subject: [PATCH] Add conversions for BigInt/BigUint. --- src/cryptonum/signed.rs | 11 +++++++++++ src/cryptonum/unsigned.rs | 39 +++++++++++++++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/cryptonum/signed.rs b/src/cryptonum/signed.rs index 4079f29..1ff5d37 100644 --- a/src/cryptonum/signed.rs +++ b/src/cryptonum/signed.rs @@ -1,4 +1,6 @@ use cryptonum::unsigned::{UCN,divmod}; +use num::BigInt; +use num::bigint::Sign; use std::fmt; use std::cmp::Ordering; use std::fmt::Write; @@ -102,6 +104,15 @@ impl Into for SCN { } } +impl From for BigInt { + fn from(x: SCN) -> BigInt { + let sign = if x.is_negative() { Sign::Minus } else { Sign::Plus }; + let numbytes = x.value.contents.len() * 8; + let bytes = x.value.to_bytes(numbytes); + BigInt::from_bytes_be(sign, &bytes) + } +} + //------------------------------------------------------------------------------ // // Comparisons diff --git a/src/cryptonum/unsigned.rs b/src/cryptonum/unsigned.rs index 83b5c36..34f34ca 100644 --- a/src/cryptonum/unsigned.rs +++ b/src/cryptonum/unsigned.rs @@ -350,7 +350,14 @@ define_into!(UCN, u64); define_into!(UCN, usize); impl From for UCN { - fn from(mut x: BigUint) -> UCN { + fn from(x: BigUint) -> UCN { + UCN::from(&x) + } +} + +impl<'a> From<&'a BigUint> for UCN { + fn from(inval: &BigUint) -> UCN { + let mut x = inval.clone(); let mut dest = Vec::new(); let mask = BigUint::from(0xFFFFFFFFFFFFFFFF as u64); @@ -368,11 +375,28 @@ impl From for UCN { } } -impl Into for UCN { - fn into(self) -> BigUint { +impl From for UCN { + fn from(x: BigInt) -> UCN { + UCN::from(&x) + } +} + +impl<'a> From<&'a BigInt> for UCN { + fn from(x: &BigInt) -> UCN { + match x.to_biguint() { + None => + panic!("Attempt to coerce negative BigInt into UCN"), + Some(x) => + UCN::from(x) + } + } +} + +impl From for BigUint { + fn from(x: UCN) -> BigUint { let mut result = BigUint::zero(); - for part in self.contents.iter().rev() { + for part in x.contents.iter().rev() { result <<= 64; result += BigUint::from(*part); } @@ -381,6 +405,13 @@ impl Into for UCN { } } +impl From for BigInt { + fn from(x: UCN) -> BigInt { + let uint = BigUint::from(x); + BigInt::from(uint) + } +} + //------------------------------------------------------------------------------ // // Comparisons