Skip to content

Commit

Permalink
Cairo v2.6.3 (#200)
Browse files Browse the repository at this point in the history
cairo v2.6.3
  • Loading branch information
shramee authored Mar 18, 2024
1 parent 0299e4a commit 3875e43
Show file tree
Hide file tree
Showing 30 changed files with 1,332 additions and 775 deletions.
885 changes: 256 additions & 629 deletions Cargo.lock

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ glob = "0.3.0"
cairo-felt = "0.8.2"

# Cairo runner dependencies
cairo-lang-test-runner = "2.5.3"
cairo-lang-test-plugin = "2.5.3"
cairo-lang-runner = "2.5.3"
cairo-lang-sierra = "2.5.3"
scarb = { git = "https://github.com/software-mansion/scarb", version = "2.5.3" }
scarb-ui = { git = "https://github.com/software-mansion/scarb", version = "0.1.3" }
cairo-lang-test-runner = "2.6.3"
cairo-lang-test-plugin = "2.6.3"
cairo-lang-runner = "2.6.3"
cairo-lang-sierra = "2.6.3"
scarb = { git = "https://github.com/software-mansion/scarb", tag = "v2.6.3" }
scarb-ui = { git = "https://github.com/software-mansion/scarb", tag = "v2.6.3" }

anyhow = "1.0.66"
ark-ff = "0.4.0-alpha.7"
Expand Down
6 changes: 0 additions & 6 deletions corelib/Scarb.lock

This file was deleted.

3 changes: 2 additions & 1 deletion corelib/Scarb.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
[package]
name = "core"
version = "2.5.3"
version = "2.6.3"
edition = "2023_11"
experimental-features = ["coupons", "negative_impls"]

# NOTE: This is non-public, unstable Scarb's field, which instructs resolver that this package does not
# depend on `core`, which is only true for this particular package. Nobody else should use it.
Expand Down
1 change: 1 addition & 0 deletions corelib/cairo_project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ edition = "2023_11"

[config.global.experimental_features]
negative_impls = true
coupons = true
6 changes: 3 additions & 3 deletions corelib/src/array.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ extern fn array_new<T>() -> Array<T> nopanic;
extern fn array_append<T>(ref arr: Array<T>, value: T) nopanic;
extern fn array_pop_front<T>(ref arr: Array<T>) -> Option<Box<T>> nopanic;
extern fn array_pop_front_consume<T>(arr: Array<T>) -> Option<(Array<T>, Box<T>)> nopanic;
extern fn array_snapshot_pop_front<T>(ref arr: @Array<T>) -> Option<Box<@T>> nopanic;
pub(crate) extern fn array_snapshot_pop_front<T>(ref arr: @Array<T>) -> Option<Box<@T>> nopanic;
extern fn array_snapshot_pop_back<T>(ref arr: @Array<T>) -> Option<Box<@T>> nopanic;
#[panic_with('Index out of bounds', array_at)]
extern fn array_get<T>(
Expand All @@ -27,7 +27,7 @@ extern fn array_len<T>(arr: @Array<T>) -> usize nopanic;
#[generate_trait]
pub impl ArrayImpl<T> of ArrayTrait<T> {
#[inline(always)]
fn new() -> Array<T> {
fn new() -> Array<T> nopanic {
array_new()
}
#[inline(always)]
Expand Down Expand Up @@ -132,7 +132,7 @@ fn deserialize_array_helper<T, +Serde<T>, +Drop<T>>(

// Span.
pub struct Span<T> {
snapshot: @Array<T>
pub(crate) snapshot: @Array<T>
}

impl SpanCopy<T> of Copy<Span<T>>;
Expand Down
11 changes: 5 additions & 6 deletions corelib/src/byte_array.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ use core::zeroable::NonZeroIntoImpl;
pub(crate) const BYTE_ARRAY_MAGIC: felt252 =
0x46a6158a16a947e5916b2a2ca68501a45e93d7110e81aa2d6438b1c57c879a3;
const BYTES_IN_U128: usize = 16;
// TODO(yuval): change to `BYTES_IN_BYTES31 - 1` once consteval_int supports non-literals.
const BYTES_IN_BYTES31_MINUS_ONE: usize = consteval_int!(31 - 1);
const BYTES_IN_BYTES31_MINUS_ONE: usize = BYTES_IN_BYTES31 - 1;

// TODO(yuval): don't allow creation of invalid ByteArray?
#[derive(Drop, Clone, PartialEq, Serde, Default)]
Expand Down Expand Up @@ -224,7 +223,7 @@ pub impl ByteArrayImpl of ByteArrayTrait {
fn append_word_rev(ref self: ByteArray, word: felt252, len: usize) {
let mut index = 0;

let u256{low, high } = word.into();
let u256 { low, high } = word.into();
let low_part_limit = min(len, BYTES_IN_U128);
loop {
if index == low_part_limit {
Expand Down Expand Up @@ -280,7 +279,7 @@ pub impl ByteArrayImpl of ByteArrayTrait {
// responsibility.
#[inline]
fn append_split_index_lt_16(ref self: ByteArray, word: felt252, split_index: usize) {
let u256{low, high } = word.into();
let u256 { low, high } = word.into();

let (low_quotient, low_remainder) = u128_safe_divmod(
low, one_shift_left_bytes_u128(split_index).try_into().unwrap()
Expand All @@ -301,7 +300,7 @@ pub impl ByteArrayImpl of ByteArrayTrait {
// responsibility.
#[inline]
fn append_split_index_16(ref self: ByteArray, word: felt252) {
let u256{low, high } = word.into();
let u256 { low, high } = word.into();
self.append_split(high.into(), low.into());
}

Expand All @@ -314,7 +313,7 @@ pub impl ByteArrayImpl of ByteArrayTrait {
// responsibility.
#[inline]
fn append_split_index_gt_16(ref self: ByteArray, word: felt252, split_index: usize) {
let u256{low, high } = word.into();
let u256 { low, high } = word.into();

let (high_quotient, high_remainder) = u128_safe_divmod(
high, one_shift_left_bytes_u128(split_index - BYTES_IN_U128).try_into().unwrap()
Expand Down
57 changes: 20 additions & 37 deletions corelib/src/bytes_31.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub impl Bytes31Impl of Bytes31Trait {
// Gets the byte at the given index (LSB's index is 0), assuming that
// `index < BYTES_IN_BYTES31`. If the assumption is not met, the behavior is undefined.
fn at(self: @bytes31, index: usize) -> u8 {
let u256{low, high } = (*self).into();
let u256 { low, high } = (*self).into();
let res_u128 = if index < BYTES_IN_U128 {
(low / one_shift_left_bytes_u128(index)) % POW_2_8
} else {
Expand Down Expand Up @@ -104,7 +104,7 @@ pub(crate) fn split_bytes31(word: felt252, len: usize, index: usize) -> (felt252
return (word, 0);
}

let u256{low, high } = word.into();
let u256 { low, high } = word.into();

if index == BYTES_IN_U128 {
return (low.into(), high.into());
Expand Down Expand Up @@ -153,41 +153,24 @@ pub(crate) fn one_shift_left_bytes_felt252(n_bytes: usize) -> felt252 {
//
// Panics if `n_bytes >= BYTES_IN_U128`.
pub(crate) fn one_shift_left_bytes_u128(n_bytes: usize) -> u128 {
// TODO(yuval): change to match once it's supported for integers.
if n_bytes == 0 {
0x1_u128
} else if n_bytes == 1 {
0x100_u128
} else if n_bytes == 2 {
0x10000_u128
} else if n_bytes == 3 {
0x1000000_u128
} else if n_bytes == 4 {
0x100000000_u128
} else if n_bytes == 5 {
0x10000000000_u128
} else if n_bytes == 6 {
0x1000000000000_u128
} else if n_bytes == 7 {
0x100000000000000_u128
} else if n_bytes == 8 {
0x10000000000000000_u128
} else if n_bytes == 9 {
0x1000000000000000000_u128
} else if n_bytes == 10 {
0x100000000000000000000_u128
} else if n_bytes == 11 {
0x10000000000000000000000_u128
} else if n_bytes == 12 {
0x1000000000000000000000000_u128
} else if n_bytes == 13 {
0x100000000000000000000000000_u128
} else if n_bytes == 14 {
0x10000000000000000000000000000_u128
} else if n_bytes == 15 {
0x1000000000000000000000000000000_u128
} else {
core::panic_with_felt252('n_bytes too big')
match n_bytes {
0 => 0x1,
1 => 0x100,
2 => 0x10000,
3 => 0x1000000,
4 => 0x100000000,
5 => 0x10000000000,
6 => 0x1000000000000,
7 => 0x100000000000000,
8 => 0x10000000000000000,
9 => 0x1000000000000000000,
10 => 0x100000000000000000000,
11 => 0x10000000000000000000000,
12 => 0x1000000000000000000000000,
13 => 0x100000000000000000000000000,
14 => 0x10000000000000000000000000000,
15 => 0x1000000000000000000000000000000,
_ => core::panic_with_felt252('n_bytes too big'),
}
}

Expand Down
37 changes: 33 additions & 4 deletions corelib/src/cmp.cairo
Original file line number Diff line number Diff line change
@@ -1,15 +1,44 @@
/// Minimum of the two values.
/// # Arguments
/// * `a` - first comparable value
/// * `b` - Second comparable value
/// # Returns
/// * `result` - The smallest of the two values
#[must_use]
pub fn min<T, +PartialOrd<T>, +Drop<T>, +Copy<T>>(a: T, b: T) -> T {
if a > b {
return b;
b
} else {
a
}
a
}

/// Maximum of the two values.
/// # Arguments
/// * `a` - first comparable value
/// * `b` - Second comparable value
/// # Returns
/// * `result` - The greatest of the two values
#[must_use]
pub fn max<T, +PartialOrd<T>, +Drop<T>, +Copy<T>>(a: T, b: T) -> T {
if a > b {
return a;
a
} else {
b
}
}

/// Minimum and maximum of the two values.
/// # Arguments
/// * `a` - first comparable value
/// * `b` - Second comparable value
/// # Returns
/// * `result` - The two values sorted in ascending order
#[must_use]
pub fn minmax<T, +PartialOrd<T>, +Drop<T>, +Copy<T>>(a: T, b: T) -> (T, T) {
if a > b {
(b, a)
} else {
(a, b)
}
b
}
44 changes: 36 additions & 8 deletions corelib/src/ec.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,20 @@ impl EcPointTryIntoNonZero of TryInto<EcPoint, NonZeroEcPoint> {
}

// EC state.

// TODO(lior): Allow explicit clone() for EcState, since we don't allow implicit dup (Copy).
#[derive(Drop)]
pub extern type EcState;

mod internal {
impl EcStateCopy of Copy<super::EcState>;
pub impl EcStateClone of Clone<super::EcState> {
#[inline(always)]
fn clone(self: @super::EcState) -> super::EcState {
*self
}
}
}
impl EcStateClone = internal::EcStateClone;

/// Initializes an EC computation with the zero point.
extern fn ec_state_init() -> EcState nopanic;

Expand All @@ -72,23 +81,32 @@ extern fn ec_state_try_finalize_nz(s: EcState) -> Option<NonZeroEcPoint> nopanic
pub impl EcStateImpl of EcStateTrait {
/// Initializes an EC computation with the zero point.
#[must_use]
fn init() -> EcState {
fn init() -> EcState nopanic {
ec_state_init()
}
/// Adds a point to the computation.
#[inline(always)]
fn add(ref self: EcState, p: NonZeroEcPoint) {
fn add(ref self: EcState, p: NonZeroEcPoint) nopanic {
ec_state_add(ref self, :p);
}
/// Subs a point to the computation.
#[inline(always)]
fn sub(ref self: EcState, p: NonZeroEcPoint) {
// TODO(orizi): Have a `ec_neg` for NonZeroEcPoint as well, or a `ec_state_sub`.
let p: EcPoint = p.into();
let p_neg = ec_neg(p);
let p_neg_nz = p_neg.try_into().unwrap();
ec_state_add(ref self, p_neg_nz);
}
/// Adds the product p * scalar to the state.
#[inline(always)]
fn add_mul(ref self: EcState, scalar: felt252, p: NonZeroEcPoint) {
fn add_mul(ref self: EcState, scalar: felt252, p: NonZeroEcPoint) nopanic {
ec_state_add_mul(ref self, :scalar, :p);
}
/// Finalizes the EC computation and returns the result (returns `None` if the result is the
/// zero point).
#[inline(always)]
fn finalize_nz(self: EcState) -> Option<NonZeroEcPoint> {
fn finalize_nz(self: EcState) -> Option<NonZeroEcPoint> nopanic {
ec_state_try_finalize_nz(self)
}
/// Finalizes the EC computation and returns the result.
Expand All @@ -106,12 +124,22 @@ pub impl EcPointImpl of EcPointTrait {
/// Creates a new EC point from its (x, y) coordinates.
#[inline(always)]
fn new(x: felt252, y: felt252) -> Option<EcPoint> {
Option::Some(ec_point_try_new_nz(:x, :y)?.into())
Option::Some(EcPointTrait::new_nz(:x, :y)?.into())
}
/// Creates a new NonZero EC point from its (x, y) coordinates.
#[inline(always)]
fn new_nz(x: felt252, y: felt252) -> Option<NonZeroEcPoint> {
ec_point_try_new_nz(:x, :y)
}
/// Creates a new EC point from its x coordinate.
#[inline(always)]
fn new_from_x(x: felt252) -> Option<EcPoint> {
Option::Some(ec_point_from_x_nz(:x)?.into())
Option::Some(EcPointTrait::new_nz_from_x(:x)?.into())
}
/// Creates a new NonZero EC point from its x coordinate.
#[inline(always)]
fn new_nz_from_x(x: felt252) -> Option<NonZeroEcPoint> {
ec_point_from_x_nz(:x)
}
/// Returns the coordinates of the EC point.
#[inline(always)]
Expand Down
Loading

0 comments on commit 3875e43

Please sign in to comment.