Skip to content

Commit

Permalink
Merge branch 'main' into fix-crun-parsed-program
Browse files Browse the repository at this point in the history
  • Loading branch information
MegaRedHand authored Jul 12, 2023
2 parents 8f71f3f + 013c8ba commit 82ffa9a
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 8 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

* perf: remove pointless iterator from rc limits tracking [#1316](https://github.com/lambdaclass/cairo-vm/pull/1316)

* feat(felt): add `from_bytes_le` and `from_bytes_ne` methods to `Felt252` [#1326](https://github.com/lambdaclass/cairo-vm/pull/1326)

#### [0.8.2] - 2023-7-10

* chore: update dependencies, particularly lamdaworks 0.1.2 -> 0.1.3 [#1323](https://github.com/lambdaclass/cairo-vm/pull/1323)
Expand Down
10 changes: 5 additions & 5 deletions felt/src/bigint_felt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,11 @@ impl FeltOps for FeltBigInt<FIELD_HIGH, FIELD_LOW> {
}

fn from_bytes_be(bytes: &[u8]) -> FeltBigInt<FIELD_HIGH, FIELD_LOW> {
let mut value = BigUint::from_bytes_be(bytes);
if value >= *CAIRO_PRIME_BIGUINT {
value = value.mod_floor(&CAIRO_PRIME_BIGUINT);
}
Self::from(value)
Self::from(BigUint::from_bytes_be(bytes))
}

fn from_bytes_le(bytes: &[u8]) -> FeltBigInt<FIELD_HIGH, FIELD_LOW> {
Self::from(BigUint::from_bytes_le(bytes))
}

#[cfg(any(feature = "std", feature = "alloc"))]
Expand Down
48 changes: 48 additions & 0 deletions felt/src/lib_bigint_felt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ pub(crate) trait FeltOps {

fn from_bytes_be(bytes: &[u8]) -> Self;

fn from_bytes_le(bytes: &[u8]) -> Self;

#[cfg(any(feature = "std", feature = "alloc"))]
fn to_str_radix(&self, radix: u32) -> String;

Expand Down Expand Up @@ -181,6 +183,19 @@ impl Felt252 {
value: FeltBigInt::from_bytes_be(bytes),
}
}
pub fn from_bytes_le(bytes: &[u8]) -> Self {
Self {
value: FeltBigInt::from_bytes_le(bytes),
}
}
pub fn from_bytes_ne(bytes: &[u8]) -> Self {
// Call either version depending on target endianness
#[cfg(target_endian = "little")]
let res = Self::from_bytes_le(bytes);
#[cfg(target_endian = "big")]
let res = Self::from_bytes_be(bytes);
res
}
#[cfg(any(feature = "std", feature = "alloc"))]
pub fn to_str_radix(&self, radix: u32) -> String {
self.value.to_str_radix(radix)
Expand Down Expand Up @@ -1019,6 +1034,31 @@ mod test {
prop_assert!(&x.to_biguint() < p);
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn from_bytes_be(high: u128, low: u128) {
let expected = (Felt252::from(high) << 128_usize) + Felt252::from(low);
let mut bytes = [0; 32];
// big-endian order: [ high, low ]
bytes[..16].copy_from_slice(&high.to_be_bytes());
bytes[16..].copy_from_slice(&low.to_be_bytes());
let got = Felt252::from_bytes_be(&bytes);
prop_assert_eq!(got, expected);
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn from_bytes_le(high: u128, low: u128) {
let expected = (Felt252::from(high) << 128_usize) + Felt252::from(low);
let mut bytes = [0; 32];
// little-endian order: [ low, high ]
bytes[..16].copy_from_slice(&low.to_le_bytes());
bytes[16..].copy_from_slice(&high.to_le_bytes());
let got = Felt252::from_bytes_le(&bytes);
prop_assert_eq!(got, expected);
}


#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn to_be_bytes(ref x in any::<Felt252>()) {
Expand Down Expand Up @@ -1668,4 +1708,12 @@ mod test {
let zero = Felt252::zero();
assert_eq!(&zero.signum(), &zero)
}

#[test]
fn from_bytes_ne() {
let expected = Felt252::zero();
let bytes = [0; 32];
let got = Felt252::from_bytes_ne(&bytes);
assert_eq!(got, expected);
}
}
57 changes: 56 additions & 1 deletion felt/src/lib_lambdaworks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,24 @@ impl Felt252 {
}

pub fn from_bytes_be(bytes: &[u8]) -> Self {
// TODO: use upstream's version when it's more lenient
Self::from(BigUint::from_bytes_be(bytes))
}

pub fn from_bytes_le(bytes: &[u8]) -> Self {
// TODO: use upstream's version when it's more lenient
Self::from(BigUint::from_bytes_le(bytes))
}

pub fn from_bytes_ne(bytes: &[u8]) -> Self {
// Call either version depending on target endianness
#[cfg(target_endian = "little")]
let res = Self::from_bytes_le(bytes);
#[cfg(target_endian = "big")]
let res = Self::from_bytes_be(bytes);
res
}

#[cfg(any(feature = "std", feature = "alloc"))]
pub fn to_str_radix(&self, radix: u32) -> String {
if radix == 16 {
Expand Down Expand Up @@ -995,12 +1010,44 @@ mod test {
// In this and some of the following tests, The value of {x} can be either [0] or a
// very large number, in order to try to overflow the value of {p} and thus ensure the
// modular arithmetic is working correctly.
fn new_in_range(ref x in any::<[u8; 40]>()) {
fn new_in_range_be(ref x in any::<[u8; 40]>()) {
let x = Felt252::from_bytes_be(x);
let p = &BigUint::parse_bytes(PRIME_STR[2..].as_bytes(), 16).unwrap();
prop_assert!(&x.to_biguint() < p);
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn new_in_range_le(ref x in any::<[u8; 40]>()) {
let x = Felt252::from_bytes_le(x);
let p = &BigUint::parse_bytes(PRIME_STR[2..].as_bytes(), 16).unwrap();
prop_assert!(&x.to_biguint() < p);
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn from_bytes_be(high: u128, low: u128) {
let expected = (Felt252::from(high) << 128_usize) + Felt252::from(low);
let mut bytes = [0; 32];
// big-endian order: [ high, low ]
bytes[..16].copy_from_slice(&high.to_be_bytes());
bytes[16..].copy_from_slice(&low.to_be_bytes());
let got = Felt252::from_bytes_be(&bytes);
prop_assert_eq!(got, expected);
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn from_bytes_le(high: u128, low: u128) {
let expected = (Felt252::from(high) << 128_usize) + Felt252::from(low);
let mut bytes = [0; 32];
// little-endian order: [ low, high ]
bytes[..16].copy_from_slice(&low.to_le_bytes());
bytes[16..].copy_from_slice(&high.to_le_bytes());
let got = Felt252::from_bytes_le(&bytes);
prop_assert_eq!(got, expected);
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn to_be_bytes(ref x in any::<Felt252>()) {
Expand Down Expand Up @@ -1702,4 +1749,12 @@ mod test {
fn default_is_zero() {
assert_eq!(Felt252::default(), Felt252::zero())
}

#[test]
fn from_bytes_ne() {
let expected = Felt252::zero();
let bytes = [0; 32];
let got = Felt252::from_bytes_ne(&bytes);
assert_eq!(got, expected);
}
}
4 changes: 2 additions & 2 deletions fuzzer/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 82ffa9a

Please sign in to comment.