From 36f61bb3f2542125bacd2a5434fea3f88f149193 Mon Sep 17 00:00:00 2001 From: mohab metwally Date: Thu, 12 Jan 2023 01:07:34 +0200 Subject: [PATCH] [consensus/utils] fixed bug in fbig2ibig, added extra test case --- src/consensus/utils.rs | 70 +++++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/src/consensus/utils.rs b/src/consensus/utils.rs index cf868e25b..cfdc2ee00 100644 --- a/src/consensus/utils.rs +++ b/src/consensus/utils.rs @@ -19,6 +19,9 @@ use darkfi_sdk::pasta::pallas; use dashu::integer::{IBig, Sign}; use log::debug; +use dashu::integer::UBig; +use darkfi_sdk::pasta::group::ff::PrimeField; +use crate::consensus::{constants::RADIX_BITS}; use super::Float10; @@ -26,27 +29,18 @@ pub fn fbig2ibig(f: Float10) -> IBig { let rad = IBig::try_from(10).unwrap(); let sig = f.repr().significand(); let exp = f.repr().exponent(); - let val: IBig = if exp >= 0 { sig.clone() * rad.pow(exp as usize) } else { sig.clone() }; - debug!(target: "consensus::utils", "fbig2ibig (f): {}", f); - debug!(target: "consensus::utils", "fbig2ibig (i): {}", val); + + let val: IBig = if exp >= 0 { + sig.clone() * rad.pow(exp as usize) + } else { + sig.clone() / rad.pow(exp.abs() as usize) + }; + val } -/* -pub fn base2ibig(base: pallas::Base) -> IBig { - // - let byts: [u8; 32] = base.to_repr(); - let words: [u64; 4] = [ - u64::from_le_bytes(byts[0..8].try_into().expect("")), - u64::from_le_bytes(byts[8..16].try_into().expect("")), - u64::from_le_bytes(byts[16..24].try_into().expect("")), - u64::from_le_bytes(byts[24..32].try_into().expect("")), - ]; - let uparts = UBig::from_words(&words); - //TODO both y, and t are positive, but workout the sign for general use - let ibig = IBig::from_parts(Sign::Positive, uparts); - ibig -} -*/ + +/// note! nagative values in pallas field won't wraps, and won't +/// convert back to same value. pub fn fbig2base(f: Float10) -> pallas::Base { debug!(target: "consensus::utils", "fbig -> base (f): {}", f); let val: IBig = fbig2ibig(f); @@ -59,11 +53,28 @@ pub fn fbig2base(f: Float10) -> pallas::Base { } } +/// note! only support positive conversion, and zero. +/// used for testing purpose on non-negative values at the moment. +pub fn base2ibig(base: pallas::Base) -> IBig { + // + let byts: [u8; 32] = base.to_repr(); + let words: [u64; 4] = [ + u64::from_le_bytes(byts[0..8].try_into().expect("")), + u64::from_le_bytes(byts[8..16].try_into().expect("")), + u64::from_le_bytes(byts[16..24].try_into().expect("")), + u64::from_le_bytes(byts[24..32].try_into().expect("")), + ]; + let uparts = UBig::from_words(&words); + let ibig = IBig::from_parts(Sign::Positive, uparts); + ibig +} #[cfg(test)] mod tests { use dashu::integer::IBig; - use crate::consensus::{types::Float10, utils::fbig2ibig}; + use darkfi_sdk::pasta::{pallas, group::ff::PrimeField}; + use crate::consensus::{constants::RADIX_BITS, types::Float10, utils::{fbig2ibig, fbig2base, base2ibig}}; + #[test] fn dashu_fbig2ibig() { @@ -73,20 +84,23 @@ mod tests { assert_eq!(i, sig); } - /* #[test] fn dashu_test_base2ibig() { // - let fbig: Float10 = Float10::from_str_native( - "28948022309329048855892746252171976963363056481941560715954676764349967630337", - ) - .unwrap() - .with_precision(RADIX_BITS) - .value(); + let fbig: Float10 = Float10::from_str_native("289480223093290488558927462521719769633630564819415607159546767643499676303").unwrap().with_precision(RADIX_BITS).value(); let ibig = fbig2ibig(fbig.clone()); let res_base: pallas::Base = fbig2base(fbig.clone()); let res_ibig: IBig = base2ibig(res_base); assert_eq!(res_ibig, ibig); } - */ + + #[test] + fn dashu_test2_base2ibig() { + //assert that field wrapping for negative values won't hold during conversions. + let fbig: Float10 = Float10::from_str_native("-20065240046497827215558476051577517633529246907153511707181011345840062564.87").unwrap().with_precision(RADIX_BITS).value(); + let ibig = fbig2ibig(fbig.clone()); + let res_base: pallas::Base = fbig2base(fbig.clone()); + let res_ibig: IBig = base2ibig(res_base); + assert_ne!(res_ibig, ibig); + } }