Skip to content

Commit

Permalink
Merge branch 'main' into feat/to_hex_string_helper
Browse files Browse the repository at this point in the history
  • Loading branch information
Oppen authored Dec 20, 2023
2 parents 30840e2 + 6686436 commit 955326a
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 2 deletions.
5 changes: 4 additions & 1 deletion crates/starknet-types-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,15 @@ arbitrary = { version = "1.3.0", optional = true, default-features = false }
num-traits = { version = "0.2.16", default-features = false }
num-bigint = {version = "0.4.4", default-features = false}
num-integer = {version = "0.1.45", default-features = false}
lazy_static = { version = "1.4.0", default-features = false, features = [
"spin_no_std",
] }

[features]
default = ["std", "serde", "curve"]
curve = []
hash = ["dep:lambdaworks-crypto"]
std = []
std = ["alloc"]
alloc = ["serde?/alloc"]
arbitrary = ["std", "dep:arbitrary"]

Expand Down
104 changes: 103 additions & 1 deletion crates/starknet-types-core/src/felt.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
use core::ops::{Add, Mul, Neg};

use bitvec::array::BitArray;
use num_bigint::BigInt;
use lazy_static::lazy_static;
use num_bigint::{BigInt, BigUint, Sign};
use num_integer::Integer;
use num_traits::Num;
use num_traits::{FromPrimitive, One, ToPrimitive, Zero};

lazy_static! {
pub static ref CAIRO_PRIME_BIGINT: BigInt = BigInt::from_str_radix(
"800000000000011000000000000000000000000000000000000000000000001",
16
)
.unwrap();
}

#[cfg(target_pointer_width = "64")]
pub type BitArrayStore = [u64; 4];

Expand Down Expand Up @@ -353,6 +363,19 @@ impl Felt {
pub fn bits(&self) -> usize {
self.0.representative().bits_le()
}

pub fn to_biguint(&self) -> BigUint {
let big_digits = self
.to_le_digits()
.into_iter()
.flat_map(|limb| [limb as u32, (limb >> 32) as u32])
.collect();
BigUint::new(big_digits)
}

pub fn to_bigint(&self) -> BigInt {
self.to_biguint().into()
}
}

#[cfg(feature = "arbitrary")]
Expand Down Expand Up @@ -441,6 +464,24 @@ impl From<i128> for Felt {
}
}

impl From<&BigInt> for Felt {
fn from(bigint: &BigInt) -> Felt {
let (sign, bytes) = bigint.mod_floor(&CAIRO_PRIME_BIGINT).to_bytes_le();
let felt = Felt::from_bytes_le_slice(&bytes);
if sign == Sign::Minus {
felt.neg()
} else {
felt
}
}
}

impl From<&BigUint> for Felt {
fn from(biguint: &BigUint) -> Felt {
Felt::from_bytes_le_slice(&biguint.to_bytes_le())
}
}

macro_rules! impl_from {
($from:ty, $with:ty) => {
impl From<$from> for Felt {
Expand Down Expand Up @@ -1613,4 +1654,65 @@ mod test {

assert_eq!(x.mul_mod(&y, &p), expected_result);
}

#[test]
fn bigints_to_felt() {
let one = &*CAIRO_PRIME_BIGINT + BigInt::from(1_u32);
assert_eq!(Felt::from(&one.to_biguint().unwrap()), Felt::from(1));
assert_eq!(Felt::from(&one), Felt::from(1));

let zero = &*CAIRO_PRIME_BIGINT * 99_u32;
assert_eq!(Felt::from(&zero.to_biguint().unwrap()), Felt::from(0));
assert_eq!(Felt::from(&zero), Felt::from(0));

assert_eq!(
Felt::from(&BigInt::from(-1)),
Felt::from_hex("0x800000000000011000000000000000000000000000000000000000000000000")
.unwrap()
);

let numbers_str = [
"0x0",
"0x1",
"0x10",
"0x8000000000000110000000000",
"0xffffffffffffff",
"0xffffffffefff12380777abcd",
];

for number_str in numbers_str {
assert_eq!(
Felt::from(&BigInt::from_str_radix(&number_str[2..], 16).unwrap()),
Felt::from_hex(number_str).unwrap()
);
assert_eq!(
Felt::from(&BigUint::from_str_radix(&number_str[2..], 16).unwrap()),
Felt::from_hex(number_str).unwrap()
)
}
}

#[test]
fn felt_to_bigints() {
let numbers_str = [
"0x0",
"0x1",
"0x10",
"0x8000000000000110000000000",
"0xffffffffffffff",
"0xffffffffefff12380777abcd",
];

for number_str in numbers_str {
assert_eq!(
Felt::from_hex(number_str).unwrap().to_bigint(),
BigInt::from_str_radix(&number_str[2..], 16).unwrap()
);

assert_eq!(
Felt::from_hex(number_str).unwrap().to_biguint(),
BigUint::from_str_radix(&number_str[2..], 16).unwrap()
);
}
}
}

0 comments on commit 955326a

Please sign in to comment.