From 6788e11a7edd68c2d01489ab8615b9ea6b5c94a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1?= <47506558+MegaRedHand@users.noreply.github.com> Date: Tue, 27 Jun 2023 17:22:28 -0300 Subject: [PATCH 1/5] Add missing methods to lambdaworks impl --- felt/Cargo.toml | 2 +- felt/src/lib_bigint_felt.rs | 6 ++++++ felt/src/lib_lambdaworks.rs | 21 +++++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/felt/Cargo.toml b/felt/Cargo.toml index 3ec81bc973..1229aad703 100644 --- a/felt/Cargo.toml +++ b/felt/Cargo.toml @@ -19,7 +19,7 @@ lazy_static = { version = "1.4.0", default-features = false, features = [ "spin_no_std", ] } serde = { version = "1.0", features = ["derive"], default-features = false } -lambdaworks-math = { version = "0.1.1", default-features = false, optional=true } +lambdaworks-math = { version = "0.1.1", default-features = false, optional = true } [dev-dependencies] proptest = "1.1.0" diff --git a/felt/src/lib_bigint_felt.rs b/felt/src/lib_bigint_felt.rs index 18df387924..4cc886d18d 100644 --- a/felt/src/lib_bigint_felt.rs +++ b/felt/src/lib_bigint_felt.rs @@ -142,11 +142,14 @@ impl Felt252 { pub fn new>(value: T) -> Self { value.into() } + + #[deprecated] pub fn modpow(&self, exponent: &Felt252, modulus: &Felt252) -> Self { Self { value: self.value.modpow(&exponent.value, &modulus.value), } } + pub fn iter_u64_digits(&self) -> U64Digits { self.value.iter_u64_digits() } @@ -184,10 +187,13 @@ impl Felt252 { } #[cfg(any(feature = "std", feature = "alloc"))] + #[deprecated] pub fn to_signed_bytes_le(&self) -> Vec { + // NOTE: this is unsigned self.value.to_signed_bytes_le() } #[cfg(any(feature = "std", feature = "alloc"))] + #[deprecated] pub fn to_bytes_be(&self) -> Vec { self.value.to_bytes_be() } diff --git a/felt/src/lib_lambdaworks.rs b/felt/src/lib_lambdaworks.rs index 635fb13abd..4342fd6649 100644 --- a/felt/src/lib_lambdaworks.rs +++ b/felt/src/lib_lambdaworks.rs @@ -189,10 +189,31 @@ impl Felt252 { value.into() } + #[deprecated] + pub fn modpow(&self, exponent: &Felt252, modulus: &Felt252) -> Self { + Self::from( + self.to_biguint() + .modpow(&exponent.to_biguint(), &modulus.to_biguint()), + ) + } + pub fn iter_u64_digits(&self) -> impl Iterator { self.value.representative().limbs.into_iter().rev() } + #[cfg(any(feature = "std", feature = "alloc"))] + #[deprecated] + pub fn to_signed_bytes_le(&self) -> Vec { + // NOTE: this is unsigned + self.to_biguint().to_bytes_le() + } + + #[cfg(any(feature = "std", feature = "alloc"))] + #[deprecated] + pub fn to_bytes_be(&self) -> Vec { + self.to_be_bytes().to_vec() + } + pub fn to_le_bytes(&self) -> [u8; 32] { // TODO: upstream should return array let mut bytes = [0; 32]; From 69b46b2b6f8d29461f51d23f4a00d6092fe970ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1?= <47506558+MegaRedHand@users.noreply.github.com> Date: Wed, 28 Jun 2023 16:58:20 -0300 Subject: [PATCH 2/5] Remove `modpow` and `to_signed_bytes_le` from lw-felt * Add `From<&Big(U)Int>` to lw-felt * Move comments out of `FeltOps` and remove trait --- felt/src/lib_bigint_felt.rs | 96 ++++++++++++------------------------- felt/src/lib_lambdaworks.rs | 33 ++++++------- 2 files changed, 45 insertions(+), 84 deletions(-) diff --git a/felt/src/lib_bigint_felt.rs b/felt/src/lib_bigint_felt.rs index 4cc886d18d..f9ab2aa126 100644 --- a/felt/src/lib_bigint_felt.rs +++ b/felt/src/lib_bigint_felt.rs @@ -19,71 +19,6 @@ use core::{ #[cfg(all(not(feature = "std"), feature = "alloc"))] use alloc::{string::String, vec::Vec}; -pub(crate) trait FeltOps { - fn new>>(value: T) -> Self; - - fn modpow( - &self, - exponent: &FeltBigInt, - modulus: &FeltBigInt, - ) -> Self; - - fn iter_u64_digits(&self) -> U64Digits; - - #[cfg(any(feature = "std", feature = "alloc"))] - fn to_signed_bytes_le(&self) -> Vec; - - #[cfg(any(feature = "std", feature = "alloc"))] - fn to_bytes_be(&self) -> Vec; - - fn parse_bytes(buf: &[u8], radix: u32) -> Option>; - - fn from_bytes_be(bytes: &[u8]) -> Self; - - #[cfg(any(feature = "std", feature = "alloc"))] - fn to_str_radix(&self, radix: u32) -> String; - - /// Converts [`Felt252`] into a [`BigInt`] number in the range: `(- FIELD / 2, FIELD / 2)`. - /// - /// # Examples - /// - /// ``` - /// # use crate::cairo_felt::Felt252; - /// # use num_bigint::BigInt; - /// # use num_traits::Bounded; - /// let positive = Felt252::new(5); - /// assert_eq!(positive.to_signed_felt(), Into::::into(5)); - /// - /// let negative = Felt252::max_value(); - /// assert_eq!(negative.to_signed_felt(), Into::::into(-1)); - /// ``` - fn to_signed_felt(&self) -> BigInt; - - // Converts [`Felt252`]'s representation directly into a [`BigInt`]. - // Equivalent to doing felt.to_biguint().to_bigint(). - fn to_bigint(&self) -> BigInt; - - /// Converts [`Felt252`] into a [`BigUint`] number. - /// - /// # Examples - /// - /// ``` - /// # use crate::cairo_felt::Felt252; - /// # use num_bigint::BigUint; - /// # use num_traits::{Num, Bounded}; - /// let positive = Felt252::new(5); - /// assert_eq!(positive.to_biguint(), Into::::into(5_u32)); - /// - /// let negative = Felt252::max_value(); - /// assert_eq!(negative.to_biguint(), BigUint::from_str_radix("800000000000011000000000000000000000000000000000000000000000000", 16).unwrap()); - /// ``` - fn to_biguint(&self) -> BigUint; - - fn bits(&self) -> u64; - - fn prime() -> BigUint; -} - #[macro_export] macro_rules! felt_str { ($val: expr) => { @@ -193,7 +128,6 @@ impl Felt252 { self.value.to_signed_bytes_le() } #[cfg(any(feature = "std", feature = "alloc"))] - #[deprecated] pub fn to_bytes_be(&self) -> Vec { self.value.to_bytes_be() } @@ -213,16 +147,46 @@ impl Felt252 { self.value.to_str_radix(radix) } + /// Converts [`Felt252`] into a [`BigInt`] number in the range: `(- FIELD / 2, FIELD / 2)`. + /// + /// # Examples + /// + /// ``` + /// # use crate::cairo_felt::Felt252; + /// # use num_bigint::BigInt; + /// # use num_traits::Bounded; + /// let positive = Felt252::new(5); + /// assert_eq!(positive.to_signed_felt(), Into::::into(5)); + /// + /// let negative = Felt252::max_value(); + /// assert_eq!(negative.to_signed_felt(), Into::::into(-1)); + /// ``` pub fn to_signed_felt(&self) -> BigInt { #[allow(deprecated)] self.value.to_signed_felt() } + // Converts [`Felt252`]'s representation directly into a [`BigInt`]. + // Equivalent to doing felt.to_biguint().to_bigint(). pub fn to_bigint(&self) -> BigInt { #[allow(deprecated)] self.value.to_bigint() } + /// Converts [`Felt252`] into a [`BigUint`] number. + /// + /// # Examples + /// + /// ``` + /// # use crate::cairo_felt::Felt252; + /// # use num_bigint::BigUint; + /// # use num_traits::{Num, Bounded}; + /// let positive = Felt252::new(5); + /// assert_eq!(positive.to_biguint(), Into::::into(5_u32)); + /// + /// let negative = Felt252::max_value(); + /// assert_eq!(negative.to_biguint(), BigUint::from_str_radix("800000000000011000000000000000000000000000000000000000000000000", 16).unwrap()); + /// ``` pub fn to_biguint(&self) -> BigUint { #[allow(deprecated)] self.value.to_biguint() diff --git a/felt/src/lib_lambdaworks.rs b/felt/src/lib_lambdaworks.rs index 4342fd6649..b9084167c6 100644 --- a/felt/src/lib_lambdaworks.rs +++ b/felt/src/lib_lambdaworks.rs @@ -148,7 +148,6 @@ impl From for Felt252 { } } -// TODO: bury BigUint? impl From for Felt252 { fn from(mut value: BigUint) -> Self { if value >= *CAIRO_PRIME_BIGUINT { @@ -163,7 +162,21 @@ impl From for Felt252 { } } -// TODO: bury BigInt? +impl From<&BigUint> for Felt252 { + fn from(value: &BigUint) -> Self { + if value >= &CAIRO_PRIME_BIGUINT { + Self::from(value.clone()) + } else { + let mut limbs = [0; 4]; + for (i, l) in (0..4).rev().zip(value.iter_u64_digits()) { + limbs[i] = l; + } + let value = FieldElement::new(UnsignedInteger::from_limbs(limbs)); + Self { value } + } + } +} + // NOTE: used for deserialization impl From for Felt252 { fn from(value: BigInt) -> Self { @@ -189,27 +202,11 @@ impl Felt252 { value.into() } - #[deprecated] - pub fn modpow(&self, exponent: &Felt252, modulus: &Felt252) -> Self { - Self::from( - self.to_biguint() - .modpow(&exponent.to_biguint(), &modulus.to_biguint()), - ) - } - pub fn iter_u64_digits(&self) -> impl Iterator { self.value.representative().limbs.into_iter().rev() } #[cfg(any(feature = "std", feature = "alloc"))] - #[deprecated] - pub fn to_signed_bytes_le(&self) -> Vec { - // NOTE: this is unsigned - self.to_biguint().to_bytes_le() - } - - #[cfg(any(feature = "std", feature = "alloc"))] - #[deprecated] pub fn to_bytes_be(&self) -> Vec { self.to_be_bytes().to_vec() } From d7d4f19ced257709219a5aa2a8583b68830bceb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1?= <47506558+MegaRedHand@users.noreply.github.com> Date: Wed, 28 Jun 2023 17:09:25 -0300 Subject: [PATCH 3/5] Fix build --- felt/src/lib_bigint_felt.rs | 40 +++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/felt/src/lib_bigint_felt.rs b/felt/src/lib_bigint_felt.rs index f9ab2aa126..becde80729 100644 --- a/felt/src/lib_bigint_felt.rs +++ b/felt/src/lib_bigint_felt.rs @@ -19,6 +19,41 @@ use core::{ #[cfg(all(not(feature = "std"), feature = "alloc"))] use alloc::{string::String, vec::Vec}; +pub(crate) trait FeltOps { + fn new>>(value: T) -> Self; + + fn modpow( + &self, + exponent: &FeltBigInt, + modulus: &FeltBigInt, + ) -> Self; + + fn iter_u64_digits(&self) -> U64Digits; + + #[cfg(any(feature = "std", feature = "alloc"))] + fn to_signed_bytes_le(&self) -> Vec; + + #[cfg(any(feature = "std", feature = "alloc"))] + fn to_bytes_be(&self) -> Vec; + + fn parse_bytes(buf: &[u8], radix: u32) -> Option>; + + fn from_bytes_be(bytes: &[u8]) -> Self; + + #[cfg(any(feature = "std", feature = "alloc"))] + fn to_str_radix(&self, radix: u32) -> String; + + fn to_signed_felt(&self) -> BigInt; + + fn to_bigint(&self) -> BigInt; + + fn to_biguint(&self) -> BigUint; + + fn bits(&self) -> u64; + + fn prime() -> BigUint; +} + #[macro_export] macro_rules! felt_str { ($val: expr) => { @@ -78,7 +113,7 @@ impl Felt252 { value.into() } - #[deprecated] + // #[deprecated] pub fn modpow(&self, exponent: &Felt252, modulus: &Felt252) -> Self { Self { value: self.value.modpow(&exponent.value, &modulus.value), @@ -122,12 +157,13 @@ impl Felt252 { } #[cfg(any(feature = "std", feature = "alloc"))] - #[deprecated] + // #[deprecated] pub fn to_signed_bytes_le(&self) -> Vec { // NOTE: this is unsigned self.value.to_signed_bytes_le() } #[cfg(any(feature = "std", feature = "alloc"))] + // #[deprecated] pub fn to_bytes_be(&self) -> Vec { self.value.to_bytes_be() } From 4b12090af3e981f2e71f6c953dfd473b6f0366c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1?= <47506558+MegaRedHand@users.noreply.github.com> Date: Wed, 28 Jun 2023 17:13:32 -0300 Subject: [PATCH 4/5] Update changelog --- CHANGELOG.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f75ea196f7..b2629c92fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ #### Upcoming Changes +* fix: add `to_bytes_be` to the felt when `lambdaworks-felt` feature is active [#1290](https://github.com/lambdaclass/cairo-vm/pull/1290) + +* chore: mark `modpow` and `to_signed_bytes_le` as *deprecated* [#1290](https://github.com/lambdaclass/cairo-vm/pull/1290) + * fix: bump *lambdaworks-math* to latest version, that fixes no-std support [#1293](https://github.com/lambdaclass/cairo-vm/pull/1293) * build: remove dependecy to `thiserror` (use `thiserror-no-std/std` instead) @@ -13,8 +17,8 @@ * feat: Add feature `lambdaworks-felt` to `felt` & `cairo-vm` crates [#1281](https://github.com/lambdaclass/cairo-rs/pull/1281) Changes under this feature: - * `Felt252` now uses _lambdaworks_' `FieldElement` internally - * BREAKING: some methods of `Felt252` were removed, namely: `modpow` and `to_bytes_be` + * `Felt252` now uses *LambdaWorks*' `FieldElement` internally + * BREAKING: some methods of `Felt252` were removed, namely: `modpow` and `to_signed_bytes_le` #### [0.7.0] - 2023-6-26 From bdfa0a046be2bcd884dd6b51bd0e2f43160df016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1?= <47506558+MegaRedHand@users.noreply.github.com> Date: Wed, 28 Jun 2023 17:15:36 -0300 Subject: [PATCH 5/5] Uncomment deprecated tags --- felt/src/lib_bigint_felt.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/felt/src/lib_bigint_felt.rs b/felt/src/lib_bigint_felt.rs index becde80729..f505cb4e04 100644 --- a/felt/src/lib_bigint_felt.rs +++ b/felt/src/lib_bigint_felt.rs @@ -113,7 +113,7 @@ impl Felt252 { value.into() } - // #[deprecated] + #[deprecated] pub fn modpow(&self, exponent: &Felt252, modulus: &Felt252) -> Self { Self { value: self.value.modpow(&exponent.value, &modulus.value), @@ -157,13 +157,12 @@ impl Felt252 { } #[cfg(any(feature = "std", feature = "alloc"))] - // #[deprecated] + #[deprecated] pub fn to_signed_bytes_le(&self) -> Vec { // NOTE: this is unsigned self.value.to_signed_bytes_le() } #[cfg(any(feature = "std", feature = "alloc"))] - // #[deprecated] pub fn to_bytes_be(&self) -> Vec { self.value.to_bytes_be() }