| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- /* This file is part of DarkFi (https://dark.fi)
- *
- * Copyright (C) 2020-2023 Dyne.org foundation
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
- use darkfi_sdk::pasta::{group::ff::PrimeField, pallas};
- use dashu::integer::{IBig, Sign, UBig};
- use log::debug;
- use super::Float10;
- 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.unsigned_abs())
- } else {
- sig.clone() / rad.pow(exp.unsigned_abs())
- };
- val
- }
- /// 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);
- let (sign, word) = val.as_sign_words();
- let mut words: [u64; 4] = [0, 0, 0, 0];
- words[..word.len()].copy_from_slice(word);
- match sign {
- Sign::Positive => pallas::Base::from_raw(words),
- Sign::Negative => pallas::Base::from_raw(words).neg(),
- }
- }
- /// 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);
- IBig::from_parts(Sign::Positive, uparts)
- }
- #[cfg(test)]
- mod tests {
- use dashu::integer::IBig;
- use crate::consensus::{
- types::Float10,
- utils::{base2ibig, fbig2base, fbig2ibig},
- };
- use darkfi_sdk::pasta::pallas;
- #[test]
- fn dashu_fbig2ibig() {
- let f = Float10::try_from("234234223.000").unwrap();
- let i: IBig = fbig2ibig(f);
- let sig = IBig::from(234234223);
- assert_eq!(i, sig);
- }
- #[test]
- fn dashu_test_base2ibig() {
- //
- let fbig: Float10 = Float10::try_from(
- "289480223093290488558927462521719769633630564819415607159546767643499676303",
- )
- .unwrap();
- 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::try_from(
- "-20065240046497827215558476051577517633529246907153511707181011345840062564.87",
- )
- .unwrap();
- 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);
- }
- }
|