Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ repository.workspace = true
resolver = "2"

[features]
default = ["with-debug-utils"]
with-cheatcode = []
with-debug-utils = []
with-mem-tracing = []
Expand All @@ -130,6 +131,7 @@ cairo-lang-sierra.workspace = true
cairo-lang-utils.workspace = true
educe.workspace = true
itertools.workspace = true
lambdaworks-math.workspace = true
lazy_static.workspace = true
libc.workspace = true
libloading.workspace = true
Expand Down
15 changes: 15 additions & 0 deletions programs/benches/factorial_2M_inv.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
fn factorial_inv(value: felt252, n: felt252) -> felt252 {
if (n == 1) {
value
} else {
factorial_inv(felt252_div(value, n.try_into().unwrap()), n - 1)
}
}

fn main() {
let result = factorial_inv(0x4d6e41de886ac83938da3456ccf1481182687989ead34d9d35236f0864575a0, 2_000_000);
assert(
result == 1,
'invalid result'
);
}
9 changes: 7 additions & 2 deletions src/arch/aarch64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
#![cfg(target_arch = "aarch64")]

use super::AbiArgument;
use crate::{error::Error, starknet::U256, utils::get_integer_layout};
use crate::{
error::Error,
starknet::U256,
utils::{get_integer_layout, montgomery::MontyBytes},
};
use cairo_lang_sierra::ids::ConcreteTypeId;
use num_traits::ToBytes;
use starknet_types_core::felt::Felt;
Expand Down Expand Up @@ -197,7 +201,8 @@ impl AbiArgument for Felt {
if buffer.len() >= 56 {
align_to(buffer, get_integer_layout(252).align());
}
buffer.extend_from_slice(&self.to_bytes_le());

buffer.extend_from_slice(&self.to_bytes_le_raw());
Ok(())
}
}
Expand Down
8 changes: 6 additions & 2 deletions src/arch/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
#![cfg(target_arch = "x86_64")]

use super::AbiArgument;
use crate::{error::Error, starknet::U256, utils::get_integer_layout};
use crate::{
error::Error,
starknet::U256,
utils::{get_integer_layout, montgomery::MontyBytes},
};
use cairo_lang_sierra::ids::ConcreteTypeId;
use num_traits::ToBytes;
use starknet_types_core::felt::Felt;
Expand Down Expand Up @@ -159,7 +163,7 @@ impl AbiArgument for Felt {
align_to(buffer, get_integer_layout(252).align());
}

buffer.extend_from_slice(&self.to_bytes_le());
buffer.extend_from_slice(&self.to_bytes_le_raw());
Ok(())
}
}
Expand Down
9 changes: 8 additions & 1 deletion src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ use cairo_lang_sierra::{
use libc::c_void;
use num_bigint::BigInt;
use num_traits::One;
use starknet_types_core::felt::Felt;
use std::{alloc::Layout, arch::global_asm, ptr::NonNull};

mod aot;
Expand Down Expand Up @@ -450,11 +451,17 @@ fn parse_result(

#[cfg(target_arch = "aarch64")]
Ok(Value::Felt252({
use lambdaworks_math::{
traits::ByteConversion, unsigned_integer::element::U256,
};

let data = unsafe {
std::mem::transmute::<&mut [u64; 4], &mut [u8; 32]>(&mut ret_registers)
};
data[31] &= 0x0F; // Filter out first 4 bits (they're outside an i252).
starknet_types_core::felt::Felt::from_bytes_le(data)
let value = U256::from_bytes_le(data).unwrap();

Felt::from_raw(value.limbs)
}))
}
},
Expand Down
14 changes: 11 additions & 3 deletions src/executor/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ use crate::{
types::TypeBuilder,
utils::{
decode_error_message, generate_function_name, get_integer_layout, get_types_total_size,
libc_free, libc_malloc, BuiltinCosts,
libc_free, libc_malloc, montgomery::MontyBytes, BuiltinCosts,
},
OptLevel,
};
Expand All @@ -75,6 +75,7 @@ use cairo_lang_starknet_classes::{
};
use educe::Educe;
use itertools::{chain, Itertools};
use lambdaworks_math::{traits::ByteConversion, unsigned_integer::element::UnsignedInteger};
use libloading::Library;
use serde::{Deserialize, Serialize};
use starknet_types_core::felt::Felt;
Expand Down Expand Up @@ -500,7 +501,8 @@ impl AotContractExecutor {
};

for (idx, elem) in args.iter().enumerate() {
let f = elem.to_bytes_le();
let f = elem.to_bytes_le_raw();

unsafe {
std::ptr::copy_nonoverlapping(
f.as_ptr().cast::<u8>(),
Expand Down Expand Up @@ -666,9 +668,15 @@ impl AotContractExecutor {
let cur_elem_ptr = unsafe { array_ptr.byte_add(elem_stride * i as usize) };

let mut data = unsafe { cur_elem_ptr.cast::<[u8; 32]>().read() };

data[31] &= 0x0F; // Filter out first 4 bits (they're outside an i252).

array_value.push(Felt::from_bytes_le(&data));
let felt = {
let data = UnsignedInteger::from_bytes_le(&data).unwrap();
Felt::from_raw(data.limbs)
};

array_value.push(felt);
}

unsafe {
Expand Down
11 changes: 8 additions & 3 deletions src/libfuncs/bool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ use crate::{
error::{panic::ToNativeAssertError, Result},
metadata::MetadataStorage,
types::TypeBuilder,
utils::ProgramRegistryExt,
utils::{
montgomery::{self, MONTY_R2},
ProgramRegistryExt,
},
};
use cairo_lang_sierra::{
extensions::{
Expand Down Expand Up @@ -200,9 +203,11 @@ pub fn build_bool_to_felt252<'ctx, 'this>(
let value = entry.arg(0)?;
let tag_value = entry.extract_value(context, location, value, tag_ty, 0)?;

let result = entry.extui(tag_value, felt252_ty, location)?;
// Convert into Montgomery representation.
let r2 = entry.const_int(context, location, *MONTY_R2, 257)?;
let felt = montgomery::mlir::monty_mul(context, entry, tag_value, r2, felt252_ty, location)?;

helper.br(entry, 0, &[result], location)
helper.br(entry, 0, &[felt], location)
}

#[cfg(test)]
Expand Down
16 changes: 10 additions & 6 deletions src/libfuncs/const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

use super::LibfuncHelper;
use crate::{
error::{Error, Result},
error::{panic::ToNativeAssertError, Error, Result},
libfuncs::{r#enum::build_enum_value, r#struct::build_struct_value},
metadata::{realloc_bindings::ReallocBindingsMeta, MetadataStorage},
native_panic,
types::TypeBuilder,
utils::{ProgramRegistryExt, RangeExt, PRIME},
utils::{montgomery::monty_transform, ProgramRegistryExt, RangeExt, PRIME},
};
use cairo_lang_sierra::{
extensions::{
Expand Down Expand Up @@ -265,8 +265,10 @@ pub fn build_const_type_value<'ctx, 'this>(
Sign::Minus => PRIME.clone() - value,
_ => value,
};

Ok(entry.const_int_from_type(context, location, value, inner_ty)?)
let monty_value = monty_transform(&value, &PRIME).to_native_assert_error(&format!(
"could not transform felt252: {value} to Montgomery form"
))?;
Ok(entry.const_int_from_type(context, location, monty_value, inner_ty)?)
}
CoreTypeConcrete::Starknet(
StarknetTypeConcrete::ClassHash(_) | StarknetTypeConcrete::ContractAddress(_),
Expand All @@ -281,8 +283,10 @@ pub fn build_const_type_value<'ctx, 'this>(
Sign::Minus => PRIME.clone() - value,
_ => value,
};

Ok(entry.const_int_from_type(context, location, value, inner_ty)?)
let monty_value = monty_transform(&value, &PRIME).to_native_assert_error(&format!(
"could not transform felt252: {value} to Montgomery form"
))?;
Ok(entry.const_int_from_type(context, location, monty_value, inner_ty)?)
}
CoreTypeConcrete::Uint8(_)
| CoreTypeConcrete::Uint16(_)
Expand Down
Loading
Loading