From 3b131c71cf07b6fc6edb2fbc9a0686fcdbfe77fd Mon Sep 17 00:00:00 2001 From: Ian Alexander Joiner <14581281+iajoiner@users.noreply.github.com> Date: Fri, 2 Aug 2024 18:40:08 -0400 Subject: [PATCH] feat: add `Into` to `Scalar` & improvement to `Scalar` in general (#78) # Rationale for this change This PR is a prerequisite of #77. # What changes are included in this PR? - add implementation as a part of `scalar_conversion_to_int` macro which is necessary since blanket implementation of `TryFrom` or `TryInto` is not allowed for traits by Rust - improve the macro so that `TryInto` is replaced with the more natural `TryFrom` - replace `std` with `core` # Are these changes tested? Yes --- .../database/scalar_and_i256_conversions.rs | 2 +- crates/proof-of-sql/src/base/scalar/mod.rs | 140 ++++++++++-------- .../src/base/scalar/mont_scalar_test.rs | 138 ++++++++--------- .../proof_primitive/dory/dory_commitment.rs | 1 + .../dory/dory_commitment_test.rs | 111 +++++++------- 5 files changed, 202 insertions(+), 190 deletions(-) diff --git a/crates/proof-of-sql/src/base/database/scalar_and_i256_conversions.rs b/crates/proof-of-sql/src/base/database/scalar_and_i256_conversions.rs index 3d0f6f268..832c3b05a 100644 --- a/crates/proof-of-sql/src/base/database/scalar_and_i256_conversions.rs +++ b/crates/proof-of-sql/src/base/database/scalar_and_i256_conversions.rs @@ -14,7 +14,7 @@ const MAX_SUPPORTED_I256: i256 = i256::from_parts( pub fn convert_scalar_to_i256(val: &S) -> i256 { let is_negative = val > &S::MAX_SIGNED; let abs_scalar = if is_negative { -*val } else { *val }; - let limbs = abs_scalar.into(); + let limbs: [u64; 4] = abs_scalar.into(); let low = (limbs[0] as u128) | ((limbs[1] as u128) << 64); let high = (limbs[2] as i128) | ((limbs[3] as i128) << 64); diff --git a/crates/proof-of-sql/src/base/scalar/mod.rs b/crates/proof-of-sql/src/base/scalar/mod.rs index 3216c730d..d0b686cde 100644 --- a/crates/proof-of-sql/src/base/scalar/mod.rs +++ b/crates/proof-of-sql/src/base/scalar/mod.rs @@ -30,43 +30,44 @@ pub trait Scalar: + Sync + Send + num_traits::One - + std::iter::Sum - + std::iter::Product + + core::iter::Sum + + core::iter::Product + Sub + Copy - + std::ops::MulAssign - + std::ops::AddAssign + + core::ops::MulAssign + + core::ops::AddAssign + num_traits::Zero - + for<'a> std::convert::From<&'a Self> // Required for `Column` to implement `MultilinearExtension` - + for<'a> std::convert::From<&'a bool> // Required for `Column` to implement `MultilinearExtension` - + for<'a> std::convert::From<&'a i16> // Required for `Column` to implement `MultilinearExtension` - + for<'a> std::convert::From<&'a i32> // Required for `Column` to implement `MultilinearExtension` - + for<'a> std::convert::From<&'a i64> // Required for `Column` to implement `MultilinearExtension` - + for<'a> std::convert::From<&'a i128> // Required for `Column` to implement `MultilinearExtension` - + std::convert::TryInto - + std::convert::TryInto - + std::convert::TryInto - + std::convert::TryInto - + std::convert::TryInto - + std::convert::Into<[u64; 4]> - + std::convert::From<[u64; 4]> + + for<'a> core::convert::From<&'a Self> // Required for `Column` to implement `MultilinearExtension` + + for<'a> core::convert::From<&'a bool> // Required for `Column` to implement `MultilinearExtension` + + for<'a> core::convert::From<&'a i16> // Required for `Column` to implement `MultilinearExtension` + + for<'a> core::convert::From<&'a i32> // Required for `Column` to implement `MultilinearExtension` + + for<'a> core::convert::From<&'a i64> // Required for `Column` to implement `MultilinearExtension` + + for<'a> core::convert::From<&'a i128> // Required for `Column` to implement `MultilinearExtension` + + core::convert::TryInto + + core::convert::TryInto + + core::convert::TryInto + + core::convert::TryInto + + core::convert::TryInto + + core::convert::Into<[u64; 4]> + + core::convert::From<[u64; 4]> + core::cmp::Ord - + std::ops::Neg + + core::ops::Neg + num_traits::Zero - + std::ops::AddAssign + + core::ops::AddAssign + ark_serialize::CanonicalSerialize //This enables us to put `Scalar`s on the transcript + ark_std::UniformRand //This enables us to get `Scalar`s as challenges from the transcript + num_traits::Inv> // Note: `inv` should return `None` exactly when the element is zero. - + std::ops::SubAssign + + core::ops::SubAssign + super::ref_into::RefInto<[u64; 4]> - + for<'a> std::convert::From<&'a String> + + for<'a> core::convert::From<&'a String> + super::encode::VarInt - + std::convert::From - + std::convert::From - + std::convert::From - + std::convert::From - + std::convert::From - + std::convert::From + + core::convert::From + + core::convert::From + + core::convert::From + + core::convert::From + + core::convert::From + + core::convert::From + + core::convert::Into + TryFrom { /// The value (p - 1) / 2. This is "mid-point" of the field - the "six" on the clock. @@ -90,114 +91,114 @@ pub trait Scalar: macro_rules! scalar_conversion_to_int { ($scalar:ty) => { - impl TryInto for $scalar { + impl TryFrom<$scalar> for i8 { type Error = ScalarConversionError; - fn try_into(self) -> Result { - let (sign, abs): (i128, [u64; 4]) = if self > Self::MAX_SIGNED { - (-1, (-self).into()) + fn try_from(value: $scalar) -> Result { + let (sign, abs): (i128, [u64; 4]) = if value > <$scalar>::MAX_SIGNED { + (-1, (-value).into()) } else { - (1, self.into()) + (1, value.into()) }; if abs[1] != 0 || abs[2] != 0 || abs[3] != 0 { return Err(ScalarConversionError::Overflow(format!( "{} is too large to fit in an i8", - self + value ))); } let val: i128 = sign * abs[0] as i128; val.try_into().map_err(|_| { ScalarConversionError::Overflow(format!( "{} is too large to fit in an i8", - self + value )) }) } } - impl TryInto for $scalar { + impl TryFrom<$scalar> for i16 { type Error = ScalarConversionError; - fn try_into(self) -> Result { - let (sign, abs): (i128, [u64; 4]) = if self > Self::MAX_SIGNED { - (-1, (-self).into()) + fn try_from(value: $scalar) -> Result { + let (sign, abs): (i128, [u64; 4]) = if value > <$scalar>::MAX_SIGNED { + (-1, (-value).into()) } else { - (1, self.into()) + (1, value.into()) }; if abs[1] != 0 || abs[2] != 0 || abs[3] != 0 { return Err(ScalarConversionError::Overflow(format!( "{} is too large to fit in an i16", - self + value ))); } let val: i128 = sign * abs[0] as i128; val.try_into().map_err(|_| { ScalarConversionError::Overflow(format!( "{} is too large to fit in an i16", - self + value )) }) } } - impl TryInto for $scalar { + impl TryFrom<$scalar> for i32 { type Error = ScalarConversionError; - fn try_into(self) -> Result { - let (sign, abs): (i128, [u64; 4]) = if self > Self::MAX_SIGNED { - (-1, (-self).into()) + fn try_from(value: $scalar) -> Result { + let (sign, abs): (i128, [u64; 4]) = if value > <$scalar>::MAX_SIGNED { + (-1, (-value).into()) } else { - (1, self.into()) + (1, value.into()) }; if abs[1] != 0 || abs[2] != 0 || abs[3] != 0 { return Err(ScalarConversionError::Overflow(format!( "{} is too large to fit in an i32", - self + value ))); } let val: i128 = sign * abs[0] as i128; val.try_into().map_err(|_| { ScalarConversionError::Overflow(format!( "{} is too large to fit in an i32", - self + value )) }) } } - impl TryInto for $scalar { + impl TryFrom<$scalar> for i64 { type Error = ScalarConversionError; - fn try_into(self) -> Result { - let (sign, abs): (i128, [u64; 4]) = if self > Self::MAX_SIGNED { - (-1, (-self).into()) + fn try_from(value: $scalar) -> Result { + let (sign, abs): (i128, [u64; 4]) = if value > <$scalar>::MAX_SIGNED { + (-1, (-value).into()) } else { - (1, self.into()) + (1, value.into()) }; if abs[1] != 0 || abs[2] != 0 || abs[3] != 0 { return Err(ScalarConversionError::Overflow(format!( "{} is too large to fit in an i64", - self + value ))); } let val: i128 = sign * abs[0] as i128; val.try_into().map_err(|_| { ScalarConversionError::Overflow(format!( "{} is too large to fit in an i64", - self + value )) }) } } - impl TryInto for $scalar { + impl TryFrom<$scalar> for i128 { type Error = ScalarConversionError; - fn try_into(self) -> Result { - let (sign, abs): (i128, [u64; 4]) = if self > Self::MAX_SIGNED { - (-1, (-self).into()) + fn try_from(value: $scalar) -> Result { + let (sign, abs): (i128, [u64; 4]) = if value > <$scalar>::MAX_SIGNED { + (-1, (-value).into()) } else { - (1, self.into()) + (1, value.into()) }; if abs[2] != 0 || abs[3] != 0 { return Err(ScalarConversionError::Overflow(format!( "{} is too large to fit in an i128", - self + value ))); } let val: u128 = (abs[1] as u128) << 64 | (abs[0] as u128); @@ -207,11 +208,26 @@ macro_rules! scalar_conversion_to_int { (-1, v) if v == i128::MAX as u128 + 1 => Ok(i128::MIN), _ => Err(ScalarConversionError::Overflow(format!( "{} is too large to fit in an i128", - self + value ))), } } } + + impl From<$scalar> for BigInt { + fn from(value: $scalar) -> Self { + // Since we wrap around in finite fields anything greater than the max signed value is negative + let is_negative = value > <$scalar>::MAX_SIGNED; + let sign = if is_negative { + num_bigint::Sign::Minus + } else { + num_bigint::Sign::Plus + }; + let value_abs: [u64; 4] = (if is_negative { -value } else { value }).into(); + let bits: &[u8] = bytemuck::cast_slice(&value_abs); + BigInt::from_bytes_le(sign, &bits) + } + } }; } diff --git a/crates/proof-of-sql/src/base/scalar/mont_scalar_test.rs b/crates/proof-of-sql/src/base/scalar/mont_scalar_test.rs index c039a7dad..e122000b2 100644 --- a/crates/proof-of-sql/src/base/scalar/mont_scalar_test.rs +++ b/crates/proof-of-sql/src/base/scalar/mont_scalar_test.rs @@ -1,5 +1,5 @@ use crate::base::scalar::{Curve25519Scalar, Scalar, ScalarConversionError}; -use ark_ff::BigInt; +use num_bigint::BigInt; use num_traits::{Inv, One}; #[test] @@ -30,8 +30,9 @@ fn test_add() { #[test] fn test_mod() { - let pm1: BigInt<4> = - BigInt!("7237005577332262213973186563042994240857116359379907606001950938285454250988"); + let pm1: ark_ff::BigInt<4> = ark_ff::BigInt!( + "7237005577332262213973186563042994240857116359379907606001950938285454250988" + ); let x = Curve25519Scalar::from(pm1.0); let one = Curve25519Scalar::from(1u64); let zero = Curve25519Scalar::from(0u64); @@ -104,21 +105,15 @@ fn test_curve25519_scalar_mid() { #[test] fn test_curve25519_scalar_to_i8() { + assert_eq!(i8::try_from(Curve25519Scalar::from(0)).unwrap(), 0); + assert_eq!(i8::try_from(Curve25519Scalar::ONE).unwrap(), 1); + assert_eq!(i8::try_from(Curve25519Scalar::from(-1)).unwrap(), -1); assert_eq!( - TryInto::::try_into(Curve25519Scalar::from(0)).unwrap(), - 0 - ); - assert_eq!(TryInto::::try_into(Curve25519Scalar::ONE).unwrap(), 1); - assert_eq!( - TryInto::::try_into(Curve25519Scalar::from(-1)).unwrap(), - -1 - ); - assert_eq!( - TryInto::::try_into(Curve25519Scalar::from(i8::MAX)).unwrap(), + i8::try_from(Curve25519Scalar::from(i8::MAX)).unwrap(), i8::MAX ); assert_eq!( - TryInto::::try_into(Curve25519Scalar::from(i8::MIN)).unwrap(), + i8::try_from(Curve25519Scalar::from(i8::MIN)).unwrap(), i8::MIN ); } @@ -126,32 +121,26 @@ fn test_curve25519_scalar_to_i8() { #[test] fn test_curve25519_scalar_to_i8_overflow() { matches!( - TryInto::::try_into(Curve25519Scalar::from(i8::MAX as i128 + 1)), + i8::try_from(Curve25519Scalar::from(i8::MAX as i128 + 1)), Err(ScalarConversionError::Overflow(_)) ); matches!( - TryInto::::try_into(Curve25519Scalar::from(i8::MIN as i128 - 1)), + i8::try_from(Curve25519Scalar::from(i8::MIN as i128 - 1)), Err(ScalarConversionError::Overflow(_)) ); } #[test] fn test_curve25519_scalar_to_i16() { + assert_eq!(i16::try_from(Curve25519Scalar::from(0)).unwrap(), 0); + assert_eq!(i16::try_from(Curve25519Scalar::ONE).unwrap(), 1); + assert_eq!(i16::try_from(Curve25519Scalar::from(-1)).unwrap(), -1); assert_eq!( - TryInto::::try_into(Curve25519Scalar::from(0)).unwrap(), - 0 - ); - assert_eq!(TryInto::::try_into(Curve25519Scalar::ONE).unwrap(), 1); - assert_eq!( - TryInto::::try_into(Curve25519Scalar::from(-1)).unwrap(), - -1 - ); - assert_eq!( - TryInto::::try_into(Curve25519Scalar::from(i16::MAX)).unwrap(), + i16::try_from(Curve25519Scalar::from(i16::MAX)).unwrap(), i16::MAX ); assert_eq!( - TryInto::::try_into(Curve25519Scalar::from(i16::MIN)).unwrap(), + i16::try_from(Curve25519Scalar::from(i16::MIN)).unwrap(), i16::MIN ); } @@ -159,32 +148,26 @@ fn test_curve25519_scalar_to_i16() { #[test] fn test_curve25519_scalar_to_i16_overflow() { matches!( - TryInto::::try_into(Curve25519Scalar::from(i16::MAX as i128 + 1)), + i16::try_from(Curve25519Scalar::from(i16::MAX as i128 + 1)), Err(ScalarConversionError::Overflow(_)) ); matches!( - TryInto::::try_into(Curve25519Scalar::from(i16::MIN as i128 - 1)), + i16::try_from(Curve25519Scalar::from(i16::MIN as i128 - 1)), Err(ScalarConversionError::Overflow(_)) ); } #[test] fn test_curve25519_scalar_to_i32() { + assert_eq!(i32::try_from(Curve25519Scalar::from(0)).unwrap(), 0); + assert_eq!(i32::try_from(Curve25519Scalar::ONE).unwrap(), 1); + assert_eq!(i32::try_from(Curve25519Scalar::from(-1)).unwrap(), -1); assert_eq!( - TryInto::::try_into(Curve25519Scalar::from(0)).unwrap(), - 0 - ); - assert_eq!(TryInto::::try_into(Curve25519Scalar::ONE).unwrap(), 1); - assert_eq!( - TryInto::::try_into(Curve25519Scalar::from(-1)).unwrap(), - -1 - ); - assert_eq!( - TryInto::::try_into(Curve25519Scalar::from(i32::MAX)).unwrap(), + i32::try_from(Curve25519Scalar::from(i32::MAX)).unwrap(), i32::MAX ); assert_eq!( - TryInto::::try_into(Curve25519Scalar::from(i32::MIN)).unwrap(), + i32::try_from(Curve25519Scalar::from(i32::MIN)).unwrap(), i32::MIN ); } @@ -192,32 +175,26 @@ fn test_curve25519_scalar_to_i32() { #[test] fn test_curve25519_scalar_to_i32_overflow() { matches!( - TryInto::::try_into(Curve25519Scalar::from(i32::MAX as i128 + 1)), + i32::try_from(Curve25519Scalar::from(i32::MAX as i128 + 1)), Err(ScalarConversionError::Overflow(_)) ); matches!( - TryInto::::try_into(Curve25519Scalar::from(i32::MIN as i128 - 1)), + i32::try_from(Curve25519Scalar::from(i32::MIN as i128 - 1)), Err(ScalarConversionError::Overflow(_)) ); } #[test] fn test_curve25519_scalar_to_i64() { + assert_eq!(i64::try_from(Curve25519Scalar::from(0)).unwrap(), 0); + assert_eq!(i64::try_from(Curve25519Scalar::ONE).unwrap(), 1); + assert_eq!(i64::try_from(Curve25519Scalar::from(-1)).unwrap(), -1); assert_eq!( - TryInto::::try_into(Curve25519Scalar::from(0)).unwrap(), - 0 - ); - assert_eq!(TryInto::::try_into(Curve25519Scalar::ONE).unwrap(), 1); - assert_eq!( - TryInto::::try_into(Curve25519Scalar::from(-1)).unwrap(), - -1 - ); - assert_eq!( - TryInto::::try_into(Curve25519Scalar::from(i64::MAX)).unwrap(), + i64::try_from(Curve25519Scalar::from(i64::MAX)).unwrap(), i64::MAX ); assert_eq!( - TryInto::::try_into(Curve25519Scalar::from(i64::MIN)).unwrap(), + i64::try_from(Curve25519Scalar::from(i64::MIN)).unwrap(), i64::MIN ); } @@ -225,32 +202,26 @@ fn test_curve25519_scalar_to_i64() { #[test] fn test_curve25519_scalar_to_i64_overflow() { matches!( - TryInto::::try_into(Curve25519Scalar::from(i64::MAX as i128 + 1)), + i64::try_from(Curve25519Scalar::from(i64::MAX as i128 + 1)), Err(ScalarConversionError::Overflow(_)) ); matches!( - TryInto::::try_into(Curve25519Scalar::from(i64::MIN as i128 - 1)), + i64::try_from(Curve25519Scalar::from(i64::MIN as i128 - 1)), Err(ScalarConversionError::Overflow(_)) ); } #[test] fn test_curve25519_scalar_to_i128() { + assert_eq!(i128::try_from(Curve25519Scalar::from(0)).unwrap(), 0); + assert_eq!(i128::try_from(Curve25519Scalar::ONE).unwrap(), 1); + assert_eq!(i128::try_from(Curve25519Scalar::from(-1)).unwrap(), -1); assert_eq!( - TryInto::::try_into(Curve25519Scalar::from(0)).unwrap(), - 0 - ); - assert_eq!(TryInto::::try_into(Curve25519Scalar::ONE).unwrap(), 1); - assert_eq!( - TryInto::::try_into(Curve25519Scalar::from(-1)).unwrap(), - -1 - ); - assert_eq!( - TryInto::::try_into(Curve25519Scalar::from(i128::MAX)).unwrap(), + i128::try_from(Curve25519Scalar::from(i128::MAX)).unwrap(), i128::MAX ); assert_eq!( - TryInto::::try_into(Curve25519Scalar::from(i128::MIN)).unwrap(), + i128::try_from(Curve25519Scalar::from(i128::MIN)).unwrap(), i128::MIN ); } @@ -258,11 +229,42 @@ fn test_curve25519_scalar_to_i128() { #[test] fn test_curve25519_scalar_to_i128_overflow() { matches!( - TryInto::::try_into(Curve25519Scalar::from(i128::MAX) + Curve25519Scalar::ONE), + i128::try_from(Curve25519Scalar::from(i128::MAX) + Curve25519Scalar::ONE), Err(ScalarConversionError::Overflow(_)) ); matches!( - TryInto::::try_into(Curve25519Scalar::from(i128::MIN) - Curve25519Scalar::ONE), + i128::try_from(Curve25519Scalar::from(i128::MIN) - Curve25519Scalar::ONE), Err(ScalarConversionError::Overflow(_)) ); } + +#[test] +fn test_curve25519_scalar_to_bigint() { + assert_eq!(BigInt::from(Curve25519Scalar::ZERO), BigInt::from(0_i8)); + assert_eq!(BigInt::from(Curve25519Scalar::ONE), BigInt::from(1_i8)); + assert_eq!(BigInt::from(-Curve25519Scalar::ONE), BigInt::from(-1_i8)); + assert_eq!( + BigInt::from(Curve25519Scalar::from(i128::MAX)), + BigInt::from(i128::MAX) + ); + assert_eq!( + BigInt::from(Curve25519Scalar::from(i128::MIN)), + BigInt::from(i128::MIN) + ); +} + +#[test] +fn test_curve25519_scalar_from_bigint() { + assert_eq!( + Curve25519Scalar::try_from(BigInt::from(0_i8)).unwrap(), + Curve25519Scalar::ZERO + ); + assert_eq!( + Curve25519Scalar::try_from(BigInt::from(1_i8)).unwrap(), + Curve25519Scalar::ONE + ); + assert_eq!( + Curve25519Scalar::try_from(BigInt::from(-1_i8)).unwrap(), + -Curve25519Scalar::ONE + ); +} diff --git a/crates/proof-of-sql/src/proof_primitive/dory/dory_commitment.rs b/crates/proof-of-sql/src/proof_primitive/dory/dory_commitment.rs index 66cb4ba51..b961a0280 100644 --- a/crates/proof-of-sql/src/proof_primitive/dory/dory_commitment.rs +++ b/crates/proof-of-sql/src/proof_primitive/dory/dory_commitment.rs @@ -32,6 +32,7 @@ use ark_ec::pairing::PairingOutput; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use core::ops::Mul; use derive_more::{AddAssign, Neg, Sub, SubAssign}; +use num_bigint::BigInt; use num_traits::One; /// The Dory scalar type. (alias for `MontScalar`) diff --git a/crates/proof-of-sql/src/proof_primitive/dory/dory_commitment_test.rs b/crates/proof-of-sql/src/proof_primitive/dory/dory_commitment_test.rs index c2f29b674..31fdf0f3a 100644 --- a/crates/proof-of-sql/src/proof_primitive/dory/dory_commitment_test.rs +++ b/crates/proof-of-sql/src/proof_primitive/dory/dory_commitment_test.rs @@ -1,125 +1,103 @@ use super::DoryScalar; use crate::base::scalar::{Scalar, ScalarConversionError}; use core::cmp::Ordering; +use num_bigint::BigInt; + #[test] fn test_dory_scalar_to_i8() { - assert_eq!(TryInto::::try_into(DoryScalar::from(0)).unwrap(), 0); - assert_eq!(TryInto::::try_into(DoryScalar::ONE).unwrap(), 1); - assert_eq!(TryInto::::try_into(DoryScalar::from(-1)).unwrap(), -1); - assert_eq!( - TryInto::::try_into(DoryScalar::from(i8::MAX)).unwrap(), - i8::MAX - ); - assert_eq!( - TryInto::::try_into(DoryScalar::from(i8::MIN)).unwrap(), - i8::MIN - ); + assert_eq!(i8::try_from(DoryScalar::from(0)).unwrap(), 0); + assert_eq!(i8::try_from(DoryScalar::ONE).unwrap(), 1); + assert_eq!(i8::try_from(DoryScalar::from(-1)).unwrap(), -1); + assert_eq!(i8::try_from(DoryScalar::from(i8::MAX)).unwrap(), i8::MAX); + assert_eq!(i8::try_from(DoryScalar::from(i8::MIN)).unwrap(), i8::MIN); } #[test] fn test_dory_scalar_to_i8_overflow() { matches!( - TryInto::::try_into(DoryScalar::from(i8::MAX as i128 + 1)), + i8::try_from(DoryScalar::from(i8::MAX as i128 + 1)), Err(ScalarConversionError::Overflow(_)) ); matches!( - TryInto::::try_into(DoryScalar::from(i8::MIN as i128 - 1)), + i8::try_from(DoryScalar::from(i8::MIN as i128 - 1)), Err(ScalarConversionError::Overflow(_)) ); } #[test] fn test_dory_scalar_to_i16() { - assert_eq!(TryInto::::try_into(DoryScalar::from(0)).unwrap(), 0); - assert_eq!(TryInto::::try_into(DoryScalar::ONE).unwrap(), 1); - assert_eq!(TryInto::::try_into(DoryScalar::from(-1)).unwrap(), -1); - assert_eq!( - TryInto::::try_into(DoryScalar::from(i16::MAX)).unwrap(), - i16::MAX - ); - assert_eq!( - TryInto::::try_into(DoryScalar::from(i16::MIN)).unwrap(), - i16::MIN - ); + assert_eq!(i16::try_from(DoryScalar::from(0)).unwrap(), 0); + assert_eq!(i16::try_from(DoryScalar::ONE).unwrap(), 1); + assert_eq!(i16::try_from(DoryScalar::from(-1)).unwrap(), -1); + assert_eq!(i16::try_from(DoryScalar::from(i16::MAX)).unwrap(), i16::MAX); + assert_eq!(i16::try_from(DoryScalar::from(i16::MIN)).unwrap(), i16::MIN); } #[test] fn test_dory_scalar_to_i16_overflow() { matches!( - TryInto::::try_into(DoryScalar::from(i16::MAX as i128 + 1)), + i16::try_from(DoryScalar::from(i16::MAX as i128 + 1)), Err(ScalarConversionError::Overflow(_)) ); matches!( - TryInto::::try_into(DoryScalar::from(i16::MIN as i128 - 1)), + i16::try_from(DoryScalar::from(i16::MIN as i128 - 1)), Err(ScalarConversionError::Overflow(_)) ); } #[test] fn test_dory_scalar_to_i32() { - assert_eq!(TryInto::::try_into(DoryScalar::from(0)).unwrap(), 0); - assert_eq!(TryInto::::try_into(DoryScalar::ONE).unwrap(), 1); - assert_eq!(TryInto::::try_into(DoryScalar::from(-1)).unwrap(), -1); - assert_eq!( - TryInto::::try_into(DoryScalar::from(i32::MAX)).unwrap(), - i32::MAX - ); - assert_eq!( - TryInto::::try_into(DoryScalar::from(i32::MIN)).unwrap(), - i32::MIN - ); + assert_eq!(i32::try_from(DoryScalar::from(0)).unwrap(), 0); + assert_eq!(i32::try_from(DoryScalar::ONE).unwrap(), 1); + assert_eq!(i32::try_from(DoryScalar::from(-1)).unwrap(), -1); + assert_eq!(i32::try_from(DoryScalar::from(i32::MAX)).unwrap(), i32::MAX); + assert_eq!(i32::try_from(DoryScalar::from(i32::MIN)).unwrap(), i32::MIN); } #[test] fn test_dory_scalar_to_i32_overflow() { matches!( - TryInto::::try_into(DoryScalar::from(i32::MAX as i128 + 1)), + i32::try_from(DoryScalar::from(i32::MAX as i128 + 1)), Err(ScalarConversionError::Overflow(_)) ); matches!( - TryInto::::try_into(DoryScalar::from(i32::MIN as i128 - 1)), + i32::try_from(DoryScalar::from(i32::MIN as i128 - 1)), Err(ScalarConversionError::Overflow(_)) ); } #[test] fn test_dory_scalar_to_i64() { - assert_eq!(TryInto::::try_into(DoryScalar::from(0)).unwrap(), 0); - assert_eq!(TryInto::::try_into(DoryScalar::ONE).unwrap(), 1); - assert_eq!(TryInto::::try_into(DoryScalar::from(-1)).unwrap(), -1); - assert_eq!( - TryInto::::try_into(DoryScalar::from(i64::MAX)).unwrap(), - i64::MAX - ); - assert_eq!( - TryInto::::try_into(DoryScalar::from(i64::MIN)).unwrap(), - i64::MIN - ); + assert_eq!(i64::try_from(DoryScalar::from(0)).unwrap(), 0); + assert_eq!(i64::try_from(DoryScalar::ONE).unwrap(), 1); + assert_eq!(i64::try_from(DoryScalar::from(-1)).unwrap(), -1); + assert_eq!(i64::try_from(DoryScalar::from(i64::MAX)).unwrap(), i64::MAX); + assert_eq!(i64::try_from(DoryScalar::from(i64::MIN)).unwrap(), i64::MIN); } #[test] fn test_dory_scalar_to_i64_overflow() { matches!( - TryInto::::try_into(DoryScalar::from(i64::MAX as i128 + 1)), + i64::try_from(DoryScalar::from(i64::MAX as i128 + 1)), Err(ScalarConversionError::Overflow(_)) ); matches!( - TryInto::::try_into(DoryScalar::from(i64::MIN as i128 - 1)), + i64::try_from(DoryScalar::from(i64::MIN as i128 - 1)), Err(ScalarConversionError::Overflow(_)) ); } #[test] fn test_dory_scalar_to_i128() { - assert_eq!(TryInto::::try_into(DoryScalar::from(0)).unwrap(), 0); - assert_eq!(TryInto::::try_into(DoryScalar::ONE).unwrap(), 1); - assert_eq!(TryInto::::try_into(DoryScalar::from(-1)).unwrap(), -1); + assert_eq!(i128::try_from(DoryScalar::from(0)).unwrap(), 0); + assert_eq!(i128::try_from(DoryScalar::ONE).unwrap(), 1); + assert_eq!(i128::try_from(DoryScalar::from(-1)).unwrap(), -1); assert_eq!( - TryInto::::try_into(DoryScalar::from(i128::MAX)).unwrap(), + i128::try_from(DoryScalar::from(i128::MAX)).unwrap(), i128::MAX ); assert_eq!( - TryInto::::try_into(DoryScalar::from(i128::MIN)).unwrap(), + i128::try_from(DoryScalar::from(i128::MIN)).unwrap(), i128::MIN ); } @@ -127,15 +105,30 @@ fn test_dory_scalar_to_i128() { #[test] fn test_dory_scalar_to_i128_overflow() { matches!( - TryInto::::try_into(DoryScalar::from(i128::MAX) + DoryScalar::ONE), + i128::try_from(DoryScalar::from(i128::MAX) + DoryScalar::ONE), Err(ScalarConversionError::Overflow(_)) ); matches!( - TryInto::::try_into(DoryScalar::from(i128::MIN) - DoryScalar::ONE), + i128::try_from(DoryScalar::from(i128::MIN) - DoryScalar::ONE), Err(ScalarConversionError::Overflow(_)) ); } +#[test] +fn test_dory_scalar_to_bigint() { + assert_eq!(BigInt::from(DoryScalar::ZERO), BigInt::from(0_i8)); + assert_eq!(BigInt::from(DoryScalar::ONE), BigInt::from(1_i8)); + assert_eq!(BigInt::from(-DoryScalar::ONE), BigInt::from(-1_i8)); + assert_eq!( + BigInt::from(DoryScalar::from(i128::MAX)), + BigInt::from(i128::MAX) + ); + assert_eq!( + BigInt::from(DoryScalar::from(i128::MIN)), + BigInt::from(i128::MIN) + ); +} + #[test] fn scalar_comparison_works() { let zero = DoryScalar::ZERO;