diff --git a/src/ascii/Scarb.toml b/src/ascii/Scarb.toml index 59b8dcc2..7fabc523 100644 --- a/src/ascii/Scarb.toml +++ b/src/ascii/Scarb.toml @@ -3,6 +3,7 @@ name = "alexandria_ascii" version = "0.1.0" description = "utilities for working with ascii values" homepage = "https://github.com/keep-starknet-strange/alexandria/tree/main/src/ascii" +edition = "2023_11" [tool] fmt.workspace = true diff --git a/src/ascii/src/integer.cairo b/src/ascii/src/integer.cairo index da0ff88d..c7016094 100644 --- a/src/ascii/src/integer.cairo +++ b/src/ascii/src/integer.cairo @@ -1,11 +1,12 @@ use alexandria_data_structures::array_ext::ArrayTraitExt; +use core::num::traits::Zero; -trait ToAsciiTrait { +pub trait ToAsciiTrait { fn to_ascii(self: T) -> U; } // converts integers into an array of its individual ascii values -trait ToAsciiArrayTrait { +pub trait ToAsciiArrayTrait { fn to_ascii_array(self: T) -> Array; fn to_inverse_ascii_array(self: T) -> Array; } @@ -19,7 +20,7 @@ impl ToAsciiArrayTraitImpl< +Into, +TryInto, +TryInto>, - +Zeroable, + +Zero, +Drop, +Copy, > of ToAsciiArrayTrait { @@ -59,7 +60,7 @@ impl SmallIntegerToAsciiTraitImpl< +Into, +TryInto, +TryInto>, - +Zeroable, + +Zero, +Drop, +Copy, > of ToAsciiTrait { @@ -91,7 +92,7 @@ impl BigIntegerToAsciiTraitImpl< +Into, +TryInto, +TryInto>, - +Zeroable, + +Zero, +Drop, +Copy, > of ToAsciiTrait> { @@ -174,33 +175,26 @@ impl U256ToAsciiTraitImpl of ToAsciiTrait> { let mut inverse_ascii_arr = self.to_inverse_ascii_array().span(); let mut index = 0; let mut ascii: felt252 = 0; - loop { - match inverse_ascii_arr.pop_back() { - Option::Some(val) => { - let new_ascii = ascii * 256 + *val; - // if index is currently at 30 it means we have processed the number for index 31 - // this means we have reached the max size of felt252 at 31 characters - // so we append the current ascii and reset the ascii to 0 - // do the same at index 61 as well because max u256 is 78 characters - ascii = - if index == 30 || index == 61 { - data.append(new_ascii); - 0 - } else { - new_ascii - }; - }, - Option::None(_) => { - // if ascii is 0 it means we have already appended the first ascii - // and there's no need to append it again - if ascii.is_non_zero() { - data.append(ascii); - } - break; - }, + while let Option::Some(val) = inverse_ascii_arr + .pop_back() { + let new_ascii = ascii * 256 + *val; + // if index is currently at 30 it means we have processed the number for index 31 + // this means we have reached the max size of felt252 at 31 characters + // so we append the current ascii and reset the ascii to 0 + // do the same at index 61 as well because max u256 is 78 characters + ascii = + if index == 30 || index == 61 { + data.append(new_ascii); + 0 + } else { + new_ascii + }; + index += 1; }; - index += 1; - }; + + if ascii.is_non_zero() { + data.append(ascii); + } data } } diff --git a/src/ascii/src/lib.cairo b/src/ascii/src/lib.cairo index c7547a90..c1272d53 100644 --- a/src/ascii/src/lib.cairo +++ b/src/ascii/src/lib.cairo @@ -1,4 +1,4 @@ -mod integer; +pub mod integer; #[cfg(test)] mod tests; diff --git a/src/ascii/src/tests/test_ascii_integer.cairo b/src/ascii/src/tests/test_ascii_integer.cairo index 81928fa1..a67f0db7 100644 --- a/src/ascii/src/tests/test_ascii_integer.cairo +++ b/src/ascii/src/tests/test_ascii_integer.cairo @@ -1,5 +1,5 @@ use alexandria_ascii::ToAsciiTrait; -use integer::BoundedInt; +use core::integer::BoundedInt; #[test] #[available_gas(2000000000)] @@ -23,7 +23,7 @@ fn u256_to_ascii() { let ascii: Array = 1157920892373161954235709850086_u256.to_ascii(); assert_eq!(ascii.len(), 1, "u256 31 char wrong len"); assert_eq!(*ascii.at(0), '1157920892373161954235709850086', "31 char u256 wrong felt"); - // ---------------------------- 62 cahr u256 test --------------------------- // + // ---------------------------- 62 char u256 test --------------------------- // let ascii: Array = 11579208923731619542357098500868790785326998466564056403945758_u256 .to_ascii(); assert_eq!(ascii.len(), 2, "u256 31 char wrong len"); @@ -59,10 +59,10 @@ fn u128_to_ascii() { fn u64_to_ascii() { // ------------------------------ max u64 test ------------------------------ // let num: u64 = BoundedInt::max(); - assert_eq!(num.to_ascii(), '18446744073709551615', "incorect u64 max felt"); + assert_eq!(num.to_ascii(), '18446744073709551615', "incorrect u64 max felt"); // ------------------------------ min u64 test ------------------------------ // let num: u64 = BoundedInt::min(); - assert_eq!(num.to_ascii(), '0', "incorect u64 min felt"); + assert_eq!(num.to_ascii(), '0', "incorrect u64 min felt"); } #[test] @@ -70,10 +70,10 @@ fn u64_to_ascii() { fn u32_to_ascii() { // ------------------------------ max u32 test ------------------------------ // let num: u32 = BoundedInt::max(); - assert_eq!(num.to_ascii(), '4294967295', "incorect u32 max felt"); + assert_eq!(num.to_ascii(), '4294967295', "incorrect u32 max felt"); // ------------------------------ min u32 test ------------------------------ // let num: u32 = BoundedInt::min(); - assert_eq!(num.to_ascii(), '0', "incorect u32 min felt"); + assert_eq!(num.to_ascii(), '0', "incorrect u32 min felt"); } #[test] @@ -81,10 +81,10 @@ fn u32_to_ascii() { fn u16_to_ascii() { // ------------------------------ max u16 test ------------------------------ // let num: u16 = BoundedInt::max(); - assert_eq!(num.to_ascii(), '65535', "incorect u16 max felt"); + assert_eq!(num.to_ascii(), '65535', "incorrect u16 max felt"); // ------------------------------ min u16 test ------------------------------ // let num: u16 = BoundedInt::min(); - assert_eq!(num.to_ascii(), '0', "incorect u16 min felt"); + assert_eq!(num.to_ascii(), '0', "incorrect u16 min felt"); } #[test] @@ -92,8 +92,8 @@ fn u16_to_ascii() { fn u8_to_ascii() { // ------------------------------- max u8 test ------------------------------ // let num: u8 = BoundedInt::max(); - assert_eq!(num.to_ascii(), '255', "incorect u8 max felt"); + assert_eq!(num.to_ascii(), '255', "incorrect u8 max felt"); // ------------------------------- min u8 test ------------------------------ // let num: u8 = BoundedInt::min(); - assert_eq!(num.to_ascii(), '0', "incorect u8 min felt"); + assert_eq!(num.to_ascii(), '0', "incorrect u8 min felt"); } diff --git a/src/bytes/Scarb.toml b/src/bytes/Scarb.toml index 3059a36e..64ea34a7 100644 --- a/src/bytes/Scarb.toml +++ b/src/bytes/Scarb.toml @@ -3,6 +3,7 @@ name = "alexandria_bytes" version = "0.1.0" description = "An implementation similar to Solidity bytes written in Cairo 1" homepage = "https://github.com/keep-starknet-strange/alexandria/tree/main/src/bytes" +edition = "2023_11" [tool] fmt.workspace = true diff --git a/src/bytes/src/bytes.cairo b/src/bytes/src/bytes.cairo index 8f8055be..271b8aaf 100644 --- a/src/bytes/src/bytes.cairo +++ b/src/bytes/src/bytes.cairo @@ -3,6 +3,7 @@ use alexandria_bytes::utils::{ }; use alexandria_math::sha256::sha256; use alexandria_math::{U128BitShift, U256BitShift}; +use core::byte_array::ByteArrayTrait; use starknet::ContractAddress; /// Bytes is a dynamic array of u128, where each element contains 16 bytes. @@ -31,26 +32,31 @@ const BYTES_PER_ELEMENT: usize = 16; /// - size: the number of bytes in the Bytes /// - data: the data of the Bytes #[derive(Drop, Clone, PartialEq, Serde)] -struct Bytes { +pub struct Bytes { size: usize, data: Array } -trait BytesTrait { +pub impl BytesIndex of IndexView { + fn index(self: @Bytes, index: usize) -> @u128 { + self.data[index] + } +} + + +pub trait BytesTrait { /// Create a Bytes from an array of u128 fn new(size: usize, data: Array) -> Bytes; /// Create an empty Bytes fn new_empty() -> Bytes; /// Create a Bytes with size bytes 0 fn zero(size: usize) -> Bytes; - /// Create a Bytes from ByteArray ( Array ) - fn from_byte_array(bytes: ByteArray) -> Bytes; - /// Create a ByteArray from Bytes - fn to_byte_array(self: Bytes) -> ByteArray; /// Locate offset in Bytes fn locate(offset: usize) -> (usize, usize); /// Get Bytes size fn size(self: @Bytes) -> usize; + /// Get data + fn data(self: Bytes) -> Array; /// update specific value (1 bytes) at specific offset fn update_at(ref self: Bytes, offset: usize, value: u8); /// Read value with size bytes from Bytes, and packed into u128 @@ -144,42 +150,6 @@ impl BytesImpl of BytesTrait { Bytes { size, data } } - fn from_byte_array(mut bytes: ByteArray) -> Bytes { - let mut res = BytesTrait::new_empty(); - loop { - match bytes.data.pop_front() { - Option::Some(val) => res.append_bytes31(val), - Option::None => { break; } - } - }; - // Last elem - if bytes.pending_word_len != 0 { - let mut val: u256 = bytes.pending_word.into(); - // Only append the right-aligned bytes of the last word ( using specified length ) - val = U256BitShift::shl(val, 8 * (32 - bytes.pending_word_len.into())); - res.concat(@BytesTrait::new(bytes.pending_word_len, array![val.high, val.low])); - } - res - } - - fn to_byte_array(self: Bytes) -> ByteArray { - let mut res: ByteArray = Default::default(); - let mut offset = 0; - while offset < self - .size() { - if offset + 31 <= self.size() { - let (new_offset, value) = self.read_bytes31(offset); - res.append_word(value.into(), 31); - offset = new_offset; - } else { - let (new_offset, value) = self.read_u8(offset); - res.append_byte(value); - offset = new_offset; - } - }; - res - } - /// Locate offset in Bytes /// Arguments: /// - offset: the offset in Bytes @@ -197,6 +167,11 @@ impl BytesImpl of BytesTrait { *self.size } + + fn data(self: Bytes) -> Array { + self.data + } + /// update specific value (1 bytes) at specific offset fn update_at(ref self: Bytes, offset: usize, value: u8) { assert(offset < self.size(), 'update out of bound'); @@ -581,3 +556,35 @@ impl BytesImpl of BytesTrait { u8_array_to_u256(output.span()) } } + +pub impl ByteArrayIntoBytes of Into { + fn into(self: ByteArray) -> Bytes { + let mut res = BytesTrait::new_empty(); + let mut len = 0; + while len < self.len() { + res.append_u8(self[len]); + len += 1; + }; + res + } +} + +pub impl BytesIntoByteArray of Into { + fn into(self: Bytes) -> ByteArray { + let mut res: ByteArray = Default::default(); + let mut offset = 0; + while offset < self + .size() { + if offset + 31 <= self.size() { + let (new_offset, value) = self.read_bytes31(offset); + res.append_word(value.into(), 31); + offset = new_offset; + } else { + let (new_offset, value) = self.read_u8(offset); + res.append_byte(value); + offset = new_offset; + } + }; + res + } +} diff --git a/src/bytes/src/lib.cairo b/src/bytes/src/lib.cairo index be3854a4..2e163f48 100644 --- a/src/bytes/src/lib.cairo +++ b/src/bytes/src/lib.cairo @@ -1,7 +1,7 @@ -mod bytes; +pub mod bytes; #[cfg(test)] mod tests; -mod utils; +pub mod utils; -use bytes::{Bytes, BytesTrait}; +pub use bytes::{Bytes, BytesTrait, BytesIndex}; diff --git a/src/bytes/src/tests/test_bytes.cairo b/src/bytes/src/tests/test_bytes.cairo index 4be7f1c6..aca7edf9 100644 --- a/src/bytes/src/tests/test_bytes.cairo +++ b/src/bytes/src/tests/test_bytes.cairo @@ -1,18 +1,18 @@ use alexandria_bytes::utils::{BytesDebug, BytesDisplay}; -use alexandria_bytes::{Bytes, BytesTrait}; +use alexandria_bytes::{Bytes, BytesTrait, BytesIndex}; use starknet::ContractAddress; #[test] #[available_gas(20000000)] fn test_bytes_zero() { let bytes = BytesTrait::zero(1); - assert_eq!(bytes.size, 1, "invalid size"); - assert_eq!(*bytes.data[0], 0, "invalid value"); + assert_eq!(bytes.size(), 1, "invalid size"); + assert_eq!(*bytes[0], 0, "invalid value"); let bytes = BytesTrait::zero(17); - assert_eq!(bytes.size, 17, "invalid size"); - assert_eq!(*bytes.data[0], 0, "invalid value"); - assert_eq!(*bytes.data[1], 0, "invalid value"); + assert_eq!(bytes.size(), 17, "invalid size"); + assert_eq!(*bytes[0], 0, "invalid value"); + assert_eq!(*bytes[1], 0, "invalid value"); let (_, value) = bytes.read_u8(15); assert_eq!(value, 0, "invalid value"); let (_, value) = bytes.read_u8(0); @@ -35,24 +35,24 @@ fn test_bytes_update() { let mut bytes = BytesTrait::new(5, array![0x01020304050000000000000000000000]); bytes.update_at(0, 0x05); - assert_eq!(bytes.size, 5, "update_size1"); - assert_eq!(*bytes.data[0], 0x05020304050000000000000000000000, "update_value_1"); + assert_eq!(bytes.size(), 5, "update_size1"); + assert_eq!(*bytes[0], 0x05020304050000000000000000000000, "update_value_1"); bytes.update_at(1, 0x06); - assert_eq!(bytes.size, 5, "update_size2"); - assert_eq!(*bytes.data[0], 0x05060304050000000000000000000000, "update_value_2"); + assert_eq!(bytes.size(), 5, "update_size2"); + assert_eq!(*bytes[0], 0x05060304050000000000000000000000, "update_value_2"); bytes.update_at(2, 0x07); - assert_eq!(bytes.size, 5, "update_size3"); - assert_eq!(*bytes.data[0], 0x05060704050000000000000000000000, "update_value_3"); + assert_eq!(bytes.size(), 5, "update_size3"); + assert_eq!(*bytes[0], 0x05060704050000000000000000000000, "update_value_3"); bytes.update_at(3, 0x08); - assert_eq!(bytes.size, 5, "update_size4"); - assert_eq!(*bytes.data[0], 0x05060708050000000000000000000000, "update_value_4"); + assert_eq!(bytes.size(), 5, "update_size4"); + assert_eq!(*bytes[0], 0x05060708050000000000000000000000, "update_value_4"); bytes.update_at(4, 0x09); - assert_eq!(bytes.size, 5, "update_size5"); - assert_eq!(*bytes.data[0], 0x05060708090000000000000000000000, "update_value_5"); + assert_eq!(bytes.size(), 5, "update_size5"); + assert_eq!(*bytes[0], 0x05060708090000000000000000000000, "update_value_5"); let mut bytes = BytesTrait::new( 42, @@ -64,16 +64,16 @@ fn test_bytes_update() { ); bytes.update_at(16, 0x16); - assert_eq!(bytes.size, 42, "update_size6"); - assert_eq!(*bytes.data[0], 0x01020304050607080910111213141516, "update_value_6"); - assert_eq!(*bytes.data[1], 0x16020304050607080910111213141516, "update_value_7"); - assert_eq!(*bytes.data[2], 0x01020304050607080910000000000000, "update_value_8"); + assert_eq!(bytes.size(), 42, "update_size6"); + assert_eq!(*bytes[0], 0x01020304050607080910111213141516, "update_value_6"); + assert_eq!(*bytes[1], 0x16020304050607080910111213141516, "update_value_7"); + assert_eq!(*bytes[2], 0x01020304050607080910000000000000, "update_value_8"); bytes.update_at(15, 0x01); - assert_eq!(bytes.size, 42, "update_size7"); - assert_eq!(*bytes.data[0], 0x01020304050607080910111213141501, "update_value_9"); - assert_eq!(*bytes.data[1], 0x16020304050607080910111213141516, "update_value_10"); - assert_eq!(*bytes.data[2], 0x01020304050607080910000000000000, "update_value_11"); + assert_eq!(bytes.size(), 42, "update_size7"); + assert_eq!(*bytes[0], 0x01020304050607080910111213141501, "update_value_9"); + assert_eq!(*bytes[1], 0x16020304050607080910111213141516, "update_value_10"); + assert_eq!(*bytes[2], 0x01020304050607080910000000000000, "update_value_11"); } #[test] @@ -360,10 +360,10 @@ fn test_bytes_read_bytes31() { ); let (offset, val) = bytes.read_bytes31(0); assert_eq!(offset, 31, "Offset after read_bytes31 failed"); - assert!( - val == bytes31_const::<0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f>(), - "read_bytes31 test failed" - ) + let byte31: bytes31 = 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + .try_into() + .unwrap(); + assert!(val == byte31, "read_bytes31 test failed") } #[test] @@ -419,7 +419,7 @@ fn test_bytes_read_bytes() { let bytes = BytesTrait::new(46, array); let (new_offset, sub_bytes) = bytes.read_bytes(4, 37); - let sub_bytes_data = @sub_bytes.data; + let sub_bytes_data = @sub_bytes; assert_eq!(new_offset, 41, "read_bytes_offset"); assert_eq!(sub_bytes.size(), 37, "read_bytes_size"); assert_eq!(*sub_bytes_data[0], 0x05060708091011121314015401855d77, "read_bytes_value_1"); @@ -427,21 +427,21 @@ fn test_bytes_read_bytes() { assert_eq!(*sub_bytes_data[2], 0x6c2e0e04e10000000000000000000000, "read_bytes_value_3"); let (new_offset, sub_bytes) = bytes.read_bytes(0, 14); - let sub_bytes_data = @sub_bytes.data; + let sub_bytes_data = @sub_bytes; assert_eq!(new_offset, 14, "read_bytes_offset"); assert_eq!(sub_bytes.size(), 14, "read_bytes_size"); assert_eq!(*sub_bytes_data[0], 0x01020304050607080910111213140000, "read_bytes_value_4"); // read first byte let (new_offset, sub_bytes) = bytes.read_bytes(0, 1); - let sub_bytes_data = @sub_bytes.data; + let sub_bytes_data = @sub_bytes; assert_eq!(new_offset, 1, "read_bytes_offset"); assert_eq!(sub_bytes.size(), 1, "read_bytes_size"); assert_eq!(*sub_bytes_data[0], 0x01000000000000000000000000000000, "read_bytes_value_5"); // read last byte let (new_offset, sub_bytes) = bytes.read_bytes(45, 1); - let sub_bytes_data = @sub_bytes.data; + let sub_bytes_data = @sub_bytes; assert_eq!(new_offset, 46, "read_bytes_offset"); assert_eq!(sub_bytes.size(), 1, "read_bytes_size"); assert_eq!(*sub_bytes_data[0], 0x4f000000000000000000000000000000, "read_bytes_value_6"); @@ -454,96 +454,86 @@ fn test_bytes_append() { // append_u128_packed bytes.append_u128_packed(0x101112131415161718, 9); - let Bytes { size, mut data } = bytes; - assert_eq!(size, 9, "append_u128_packed_1_size"); - assert_eq!(*data[0], 0x10111213141516171800000000000000, "append_u128_packed_1_value_1"); - bytes = Bytes { size: size, data: data }; + assert_eq!(bytes.size(), 9, "append_u128_packed_1_size"); + assert_eq!(*bytes[0], 0x10111213141516171800000000000000, "append_u128_packed_1_value_1"); + bytes = BytesTrait::new(bytes.size(), bytes.data()); bytes.append_u128_packed(0x101112131415161718, 9); - let Bytes { size, mut data } = bytes; - assert_eq!(size, 18, "append_u128_packed_2_size"); - assert_eq!(*data[0], 0x10111213141516171810111213141516, "append_u128_packed_2_value_1"); - assert_eq!(*data[1], 0x17180000000000000000000000000000, "append_u128_packed_2_value_2"); - bytes = Bytes { size: size, data: data }; + assert_eq!(bytes.size(), 18, "append_u128_packed_2_size"); + assert_eq!(*bytes[0], 0x10111213141516171810111213141516, "append_u128_packed_2_value_1"); + assert_eq!(*bytes[1], 0x17180000000000000000000000000000, "append_u128_packed_2_value_2"); + bytes = BytesTrait::new(bytes.size(), bytes.data()); // append_u8 bytes.append_u8(0x01); - let Bytes { size, mut data } = bytes; - assert_eq!(size, 19, "append_u8_size"); - assert_eq!(*data[0], 0x10111213141516171810111213141516, "append_u8_value_1"); - assert_eq!(*data[1], 0x17180100000000000000000000000000, "append_u8_value_2"); - bytes = Bytes { size: size, data: data }; + assert_eq!(bytes.size(), 19, "append_u8_size"); + assert_eq!(*bytes[0], 0x10111213141516171810111213141516, "append_u8_value_1"); + assert_eq!(*bytes[1], 0x17180100000000000000000000000000, "append_u8_value_2"); + bytes = BytesTrait::new(bytes.size(), bytes.data()); // append_u16 bytes.append_u16(0x0102); - let Bytes { size, mut data } = bytes; - assert_eq!(size, 21, "append_u16_size"); - assert_eq!(*data[0], 0x10111213141516171810111213141516, "append_u16_value_1"); - assert_eq!(*data[1], 0x17180101020000000000000000000000, "append_u16_value_2"); - bytes = Bytes { size: size, data: data }; + assert_eq!(bytes.size(), 21, "append_u16_size"); + assert_eq!(*bytes[0], 0x10111213141516171810111213141516, "append_u16_value_1"); + assert_eq!(*bytes[1], 0x17180101020000000000000000000000, "append_u16_value_2"); + bytes = BytesTrait::new(bytes.size(), bytes.data()); // append_u32 bytes.append_u32(0x01020304); - let Bytes { size, mut data } = bytes; - assert_eq!(size, 25, "append_u32_size"); - assert_eq!(*data[0], 0x10111213141516171810111213141516, "append_u32_value_1"); - assert_eq!(*data[1], 0x17180101020102030400000000000000, "append_u32_value_2"); - bytes = Bytes { size: size, data: data }; + assert_eq!(bytes.size(), 25, "append_u32_size"); + assert_eq!(*bytes[0], 0x10111213141516171810111213141516, "append_u32_value_1"); + assert_eq!(*bytes[1], 0x17180101020102030400000000000000, "append_u32_value_2"); + bytes = BytesTrait::new(bytes.size(), bytes.data()); // append_usize bytes.append_usize(0x01); - let Bytes { size, mut data } = bytes; - assert_eq!(size, 29, "append_usize_size"); - assert_eq!(*data[0], 0x10111213141516171810111213141516, "append_usize_value_1"); - assert_eq!(*data[1], 0x17180101020102030400000001000000, "append_usize_value_2"); - bytes = Bytes { size: size, data: data }; + assert_eq!(bytes.size(), 29, "append_usize_size"); + assert_eq!(*bytes[0], 0x10111213141516171810111213141516, "append_usize_value_1"); + assert_eq!(*bytes[1], 0x17180101020102030400000001000000, "append_usize_value_2"); + bytes = BytesTrait::new(bytes.size(), bytes.data()); // append_u64 bytes.append_u64(0x030405060708); - let Bytes { size, mut data } = bytes; - assert_eq!(size, 37, "append_u64_size"); - assert_eq!(*data[0], 0x10111213141516171810111213141516, "append_u64_value_1"); - assert_eq!(*data[1], 0x17180101020102030400000001000003, "append_u64_value_2"); - assert_eq!(*data[2], 0x04050607080000000000000000000000, "append_u64_value_3"); - bytes = Bytes { size: size, data: data }; + assert_eq!(bytes.size(), 37, "append_u64_size"); + assert_eq!(*bytes[0], 0x10111213141516171810111213141516, "append_u64_value_1"); + assert_eq!(*bytes[1], 0x17180101020102030400000001000003, "append_u64_value_2"); + assert_eq!(*bytes[2], 0x04050607080000000000000000000000, "append_u64_value_3"); + bytes = BytesTrait::new(bytes.size(), bytes.data()); // append_u128 bytes.append_u128(0x101112131415161718); - let Bytes { size, mut data } = bytes; - assert_eq!(size, 53, "append_u128_size"); - assert_eq!(*data[0], 0x10111213141516171810111213141516, "append_u128_value_1"); - assert_eq!(*data[1], 0x17180101020102030400000001000003, "append_u128_value_2"); - assert_eq!(*data[2], 0x04050607080000000000000010111213, "append_u128_value_3"); - assert_eq!(*data[3], 0x14151617180000000000000000000000, "append_u128_value_4"); - bytes = Bytes { size: size, data: data }; + assert_eq!(bytes.size(), 53, "append_u128_size"); + assert_eq!(*bytes[0], 0x10111213141516171810111213141516, "append_u128_value_1"); + assert_eq!(*bytes[1], 0x17180101020102030400000001000003, "append_u128_value_2"); + assert_eq!(*bytes[2], 0x04050607080000000000000010111213, "append_u128_value_3"); + assert_eq!(*bytes[3], 0x14151617180000000000000000000000, "append_u128_value_4"); + bytes = BytesTrait::new(bytes.size(), bytes.data()); // append_u256 bytes.append_u256(u256 { low: 0x01020304050607, high: 0x010203040506070809 }); - let Bytes { size, mut data } = bytes; - assert_eq!(size, 85, "append_u256_size"); - assert_eq!(*data[0], 0x10111213141516171810111213141516, "append_u256_value_1"); - assert_eq!(*data[1], 0x17180101020102030400000001000003, "append_u256_value_2"); - assert_eq!(*data[2], 0x04050607080000000000000010111213, "append_u256_value_3"); - assert_eq!(*data[3], 0x14151617180000000000000001020304, "append_u256_value_4"); - assert_eq!(*data[4], 0x05060708090000000000000000000102, "append_u256_value_5"); - assert_eq!(*data[5], 0x03040506070000000000000000000000, "append_u256_value_6"); - bytes = Bytes { size: size, data: data }; + assert_eq!(bytes.size(), 85, "append_u256_size"); + assert_eq!(*bytes[0], 0x10111213141516171810111213141516, "append_u256_value_1"); + assert_eq!(*bytes[1], 0x17180101020102030400000001000003, "append_u256_value_2"); + assert_eq!(*bytes[2], 0x04050607080000000000000010111213, "append_u256_value_3"); + assert_eq!(*bytes[3], 0x14151617180000000000000001020304, "append_u256_value_4"); + assert_eq!(*bytes[4], 0x05060708090000000000000000000102, "append_u256_value_5"); + assert_eq!(*bytes[5], 0x03040506070000000000000000000000, "append_u256_value_6"); + bytes = BytesTrait::new(bytes.size(), bytes.data()); // append_address let address = 0x015401855d7796176b05d160196ff92381eb7910f5446c2e0e04e13db2194a4f .try_into() .unwrap(); bytes.append_address(address); - let Bytes { size, mut data } = bytes; - assert_eq!(size, 117, "append_address_size"); - assert_eq!(*data[0], 0x10111213141516171810111213141516, "append_address_value_1"); - assert_eq!(*data[1], 0x17180101020102030400000001000003, "append_address_value_2"); - assert_eq!(*data[2], 0x04050607080000000000000010111213, "append_address_value_3"); - assert_eq!(*data[3], 0x14151617180000000000000001020304, "append_address_value_4"); - assert_eq!(*data[4], 0x05060708090000000000000000000102, "append_address_value_5"); - assert_eq!(*data[5], 0x0304050607015401855d7796176b05d1, "append_address_value_6"); - assert_eq!(*data[6], 0x60196ff92381eb7910f5446c2e0e04e1, "append_address_value_7"); - assert_eq!(*data[7], 0x3db2194a4f0000000000000000000000, "append_address_value_8"); + assert_eq!(bytes.size(), 117, "append_address_size"); + assert_eq!(*bytes[0], 0x10111213141516171810111213141516, "append_address_value_1"); + assert_eq!(*bytes[1], 0x17180101020102030400000001000003, "append_address_value_2"); + assert_eq!(*bytes[2], 0x04050607080000000000000010111213, "append_address_value_3"); + assert_eq!(*bytes[3], 0x14151617180000000000000001020304, "append_address_value_4"); + assert_eq!(*bytes[4], 0x05060708090000000000000000000102, "append_address_value_5"); + assert_eq!(*bytes[5], 0x0304050607015401855d7796176b05d1, "append_address_value_6"); + assert_eq!(*bytes[6], 0x60196ff92381eb7910f5446c2e0e04e1, "append_address_value_7"); + assert_eq!(*bytes[7], 0x3db2194a4f0000000000000000000000, "append_address_value_8"); } #[test] @@ -569,55 +559,53 @@ fn test_bytes_concat() { let other = BytesTrait::new(46, array); bytes.concat(@other); - let Bytes { size, mut data } = bytes; - assert_eq!(size, 163, "concat_size"); - assert_eq!(*data[0], 0x10111213141516171810111213141516, "concat_value_1"); - assert_eq!(*data[1], 0x17180101020102030400000001000003, "concat_value_2"); - assert_eq!(*data[2], 0x04050607080000000000000010111213, "concat_value_3"); - assert_eq!(*data[3], 0x14151617180000000000000001020304, "concat_value_4"); - assert_eq!(*data[4], 0x05060708090000000000000000000102, "concat_value_5"); - assert_eq!(*data[5], 0x0304050607015401855d7796176b05d1, "concat_value_6"); - assert_eq!(*data[6], 0x60196ff92381eb7910f5446c2e0e04e1, "concat_value_7"); - assert_eq!(*data[7], 0x3db2194a4f0102030405060708091011, "concat_value_8"); - assert_eq!(*data[8], 0x121314015401855d7796176b05d16019, "concat_value_9"); - assert_eq!(*data[9], 0x6ff92381eb7910f5446c2e0e04e13db2, "concat_value_10"); - assert_eq!(*data[10], 0x194a4f00000000000000000000000000, "concat_value_11"); - bytes = Bytes { size: size, data: data }; + assert_eq!(bytes.size(), 163, "concat_size"); + assert_eq!(*bytes[0], 0x10111213141516171810111213141516, "concat_value_1"); + assert_eq!(*bytes[1], 0x17180101020102030400000001000003, "concat_value_2"); + assert_eq!(*bytes[2], 0x04050607080000000000000010111213, "concat_value_3"); + assert_eq!(*bytes[3], 0x14151617180000000000000001020304, "concat_value_4"); + assert_eq!(*bytes[4], 0x05060708090000000000000000000102, "concat_value_5"); + assert_eq!(*bytes[5], 0x0304050607015401855d7796176b05d1, "concat_value_6"); + assert_eq!(*bytes[6], 0x60196ff92381eb7910f5446c2e0e04e1, "concat_value_7"); + assert_eq!(*bytes[7], 0x3db2194a4f0102030405060708091011, "concat_value_8"); + assert_eq!(*bytes[8], 0x121314015401855d7796176b05d16019, "concat_value_9"); + assert_eq!(*bytes[9], 0x6ff92381eb7910f5446c2e0e04e13db2, "concat_value_10"); + assert_eq!(*bytes[10], 0x194a4f00000000000000000000000000, "concat_value_11"); + bytes = BytesTrait::new(bytes.size(), bytes.data()); // empty bytes concat let mut empty_bytes = BytesTrait::new_empty(); empty_bytes.concat(@bytes); - let Bytes { size, data } = empty_bytes; - - assert_eq!(size, 163, "concat_size"); - assert_eq!(*data[0], 0x10111213141516171810111213141516, "concat_value_1"); - assert_eq!(*data[1], 0x17180101020102030400000001000003, "concat_value_2"); - assert_eq!(*data[2], 0x04050607080000000000000010111213, "concat_value_3"); - assert_eq!(*data[3], 0x14151617180000000000000001020304, "concat_value_4"); - assert_eq!(*data[4], 0x05060708090000000000000000000102, "concat_value_5"); - assert_eq!(*data[5], 0x0304050607015401855d7796176b05d1, "concat_value_6"); - assert_eq!(*data[6], 0x60196ff92381eb7910f5446c2e0e04e1, "concat_value_7"); - assert_eq!(*data[7], 0x3db2194a4f0102030405060708091011, "concat_value_8"); - assert_eq!(*data[8], 0x121314015401855d7796176b05d16019, "concat_value_9"); - assert_eq!(*data[9], 0x6ff92381eb7910f5446c2e0e04e13db2, "concat_value_10"); - assert_eq!(*data[10], 0x194a4f00000000000000000000000000, "concat_value_11"); + + assert_eq!(bytes.size(), 163, "concat_size"); + assert_eq!(*bytes[0], 0x10111213141516171810111213141516, "concat_value_1"); + assert_eq!(*bytes[1], 0x17180101020102030400000001000003, "concat_value_2"); + assert_eq!(*bytes[2], 0x04050607080000000000000010111213, "concat_value_3"); + assert_eq!(*bytes[3], 0x14151617180000000000000001020304, "concat_value_4"); + assert_eq!(*bytes[4], 0x05060708090000000000000000000102, "concat_value_5"); + assert_eq!(*bytes[5], 0x0304050607015401855d7796176b05d1, "concat_value_6"); + assert_eq!(*bytes[6], 0x60196ff92381eb7910f5446c2e0e04e1, "concat_value_7"); + assert_eq!(*bytes[7], 0x3db2194a4f0102030405060708091011, "concat_value_8"); + assert_eq!(*bytes[8], 0x121314015401855d7796176b05d16019, "concat_value_9"); + assert_eq!(*bytes[9], 0x6ff92381eb7910f5446c2e0e04e13db2, "concat_value_10"); + assert_eq!(*bytes[10], 0x194a4f00000000000000000000000000, "concat_value_11"); // concat empty_bytes let empty_bytes = BytesTrait::new_empty(); bytes.concat(@empty_bytes); - assert_eq!(size, 163, "concat_size"); - assert_eq!(*data[0], 0x10111213141516171810111213141516, "concat_value_1"); - assert_eq!(*data[1], 0x17180101020102030400000001000003, "concat_value_2"); - assert_eq!(*data[2], 0x04050607080000000000000010111213, "concat_value_3"); - assert_eq!(*data[3], 0x14151617180000000000000001020304, "concat_value_4"); - assert_eq!(*data[4], 0x05060708090000000000000000000102, "concat_value_5"); - assert_eq!(*data[5], 0x0304050607015401855d7796176b05d1, "concat_value_6"); - assert_eq!(*data[6], 0x60196ff92381eb7910f5446c2e0e04e1, "concat_value_7"); - assert_eq!(*data[7], 0x3db2194a4f0102030405060708091011, "concat_value_8"); - assert_eq!(*data[8], 0x121314015401855d7796176b05d16019, "concat_value_9"); - assert_eq!(*data[9], 0x6ff92381eb7910f5446c2e0e04e13db2, "concat_value_10"); - assert_eq!(*data[10], 0x194a4f00000000000000000000000000, "concat_value_11"); + assert_eq!(bytes.size(), 163, "concat_size"); + assert_eq!(*bytes[0], 0x10111213141516171810111213141516, "concat_value_1"); + assert_eq!(*bytes[1], 0x17180101020102030400000001000003, "concat_value_2"); + assert_eq!(*bytes[2], 0x04050607080000000000000010111213, "concat_value_3"); + assert_eq!(*bytes[3], 0x14151617180000000000000001020304, "concat_value_4"); + assert_eq!(*bytes[4], 0x05060708090000000000000000000102, "concat_value_5"); + assert_eq!(*bytes[5], 0x0304050607015401855d7796176b05d1, "concat_value_6"); + assert_eq!(*bytes[6], 0x60196ff92381eb7910f5446c2e0e04e1, "concat_value_7"); + assert_eq!(*bytes[7], 0x3db2194a4f0102030405060708091011, "concat_value_8"); + assert_eq!(*bytes[8], 0x121314015401855d7796176b05d16019, "concat_value_9"); + assert_eq!(*bytes[9], 0x6ff92381eb7910f5446c2e0e04e13db2, "concat_value_10"); + assert_eq!(*bytes[10], 0x194a4f00000000000000000000000000, "concat_value_11"); } #[test] @@ -709,7 +697,7 @@ fn test_byte_array_conversions() { 0x3db2194a000000000000000000000000 ] ); - let byte_array = bytes.clone().to_byte_array(); - let new_bytes = BytesTrait::from_byte_array(byte_array); + let byte_array: ByteArray = bytes.clone().into(); + let new_bytes: Bytes = byte_array.into(); assert_eq!(bytes, new_bytes, "byte <-> byte_array conversion failed"); } diff --git a/src/bytes/src/utils.cairo b/src/bytes/src/utils.cairo index de145e0a..cc77502b 100644 --- a/src/bytes/src/utils.cairo +++ b/src/bytes/src/utils.cairo @@ -1,9 +1,9 @@ use alexandria_bytes::{Bytes, BytesTrait}; use alexandria_data_structures::array_ext::ArrayTraitExt; use core::fmt::{Debug, Display, Formatter, Error}; +use core::integer::u128_byte_reverse; +use core::keccak::cairo_keccak; use core::to_byte_array::{AppendFormattedToByteArray, FormatAsByteArray}; -use integer::u128_byte_reverse; -use keccak::{u128_to_u64, u128_split as u128_split_to_u64, cairo_keccak}; fn format_byte_hex(byte: u8, ref f: Formatter) -> Result<(), Error> { let base: NonZero = 16_u8.try_into().unwrap(); @@ -15,7 +15,7 @@ fn format_byte_hex(byte: u8, ref f: Formatter) -> Result<(), Error> { Display::fmt(@byte.format_as_byte_array(base), ref f) } -impl BytesDebug of Debug { +pub impl BytesDebug of Debug { fn fmt(self: @Bytes, ref f: Formatter) -> Result<(), Error> { let mut i: usize = 0; let prefix: ByteArray = "0x"; @@ -34,7 +34,7 @@ impl BytesDebug of Debug { } } -impl BytesDisplay of Display { +pub impl BytesDisplay of Display { fn fmt(self: @Bytes, ref f: Formatter) -> Result<(), Error> { let mut i: usize = 0; let prefix: ByteArray = "0x"; @@ -56,7 +56,7 @@ impl BytesDisplay of Display { /// Computes the keccak256 of multiple uint128 values. /// The values are interpreted as big-endian. /// https://github.com/starkware-libs/cairo/blob/main/corelib/src/keccak.cairo -fn keccak_u128s_be(mut input: Span, n_bytes: usize) -> u256 { +pub fn keccak_u128s_be(mut input: Span, n_bytes: usize) -> u256 { let mut keccak_input = array![]; let mut size = n_bytes; while let Option::Some(v) = input @@ -95,20 +95,22 @@ fn u256_reverse_endian(input: u256) -> u256 { fn keccak_add_uint128_be(ref keccak_input: Array::, value: u128, value_size: usize) { if value_size == 16 { - let (high, low) = u128_split_to_u64(u128_byte_reverse(value)); - keccak_input.append(low); - keccak_input.append(high); + let (high, low) = core::integer::u128_safe_divmod( + u128_byte_reverse(value), 0x10000000000000000_u128.try_into().unwrap() + ); + keccak_input.append(low.try_into().unwrap()); + keccak_input.append(high.try_into().unwrap()); } else { let reversed_value = u128_byte_reverse(value); let (reversed_value, _) = u128_split(reversed_value, 16, value_size); if value_size <= 8 { - keccak_input.append(u128_to_u64(reversed_value)); + keccak_input.append(reversed_value.try_into().unwrap()); } else { let (high, low) = DivRem::div_rem( reversed_value, u128_fast_pow2(64).try_into().expect('Division by 0') ); - keccak_input.append(u128_to_u64(low)); - keccak_input.append(u128_to_u64(high)); + keccak_input.append(low.try_into().unwrap()); + keccak_input.append(high.try_into().unwrap()); } } } @@ -132,7 +134,7 @@ fn update_u256_array_at(arr: @Array, index: usize, value: u256) -> Array) to u256 /// result length MUST be 32 -fn u8_array_to_u256(arr: Span) -> u256 { +pub fn u8_array_to_u256(arr: Span) -> u256 { assert(arr.len() == 32, 'too large'); let mut i = 0; let mut high = 0; @@ -167,7 +169,7 @@ fn u64_array_slice(src: @Array, mut begin: usize, len: usize) -> Array /// * `len` - The length of the slice. /// # Returns /// * `Array` - The slice of the array. -fn u128_array_slice(src: @Array, mut begin: usize, len: usize) -> Array { +pub fn u128_array_slice(src: @Array, mut begin: usize, len: usize) -> Array { let mut slice = array![]; let end = begin + len; while begin < end && begin < src.len() { @@ -201,7 +203,7 @@ fn array_slice, impl TCopy: Copy>( /// u128_split(0x01020304, 4, 0) -> (0, 0x01020304) /// u128_split(0x01020304, 4, 1) -> (0x01, 0x020304) /// u128_split(0x0001020304, 5, 1) -> (0x00, 0x01020304) -fn u128_split(value: u128, value_size: usize, left_size: usize) -> (u128, u128) { +pub fn u128_split(value: u128, value_size: usize, left_size: usize) -> (u128, u128) { assert(value_size <= 16, 'value_size can not be gt 16'); assert(left_size <= value_size, 'size can not be gt value_size'); @@ -223,7 +225,7 @@ fn u128_split(value: u128, value_size: usize, left_size: usize) -> (u128, u128) /// - sub_value: the sub value of origin u128 /// Examples: /// u128_sub_value(0x000001020304, 6, 1, 3) -> 0x000102 -fn read_sub_u128(value: u128, value_size: usize, offset: usize, size: usize) -> u128 { +pub fn read_sub_u128(value: u128, value_size: usize, offset: usize, size: usize) -> u128 { assert(offset + size <= value_size, 'too long'); if (value_size == 0) || (size == 0) { @@ -249,7 +251,7 @@ fn read_sub_u128(value: u128, value_size: usize, offset: usize, size: usize) -> /// Examples: /// u128_join(0x010203, 0xaabb, 2) -> 0x010203aabb /// u128_join(0x010203, 0, 2) -> 0x0102030000 -fn u128_join(left: u128, right: u128, right_size: usize) -> u128 { +pub fn u128_join(left: u128, right: u128, right_size: usize) -> u128 { let left_size = u128_bytes_len(left); assert(left_size + right_size <= 16, 'left shift overflow'); let shift = u128_fast_pow2(right_size * 8); diff --git a/src/data_structures/Scarb.toml b/src/data_structures/Scarb.toml index 36ee1b1b..835ba1c9 100644 --- a/src/data_structures/Scarb.toml +++ b/src/data_structures/Scarb.toml @@ -3,6 +3,7 @@ name = "alexandria_data_structures" version = "0.2.0" description = "A set of Cairo data structure libraries and algorithms" homepage = "https://github.com/keep-starknet-strange/alexandria/tree/main/src/data_structures" +edition = "2023_11" [tool] fmt.workspace = true diff --git a/src/data_structures/src/array_ext.cairo b/src/data_structures/src/array_ext.cairo index 8a83d1b0..87ca7e3d 100644 --- a/src/data_structures/src/array_ext.cairo +++ b/src/data_structures/src/array_ext.cairo @@ -1,4 +1,4 @@ -trait ArrayTraitExt { +pub trait ArrayTraitExt { fn append_all(ref self: Array, ref arr: Array); fn pop_front_n(ref self: Array, n: usize); fn reverse(self: @Array) -> Array; @@ -15,12 +15,12 @@ trait ArrayTraitExt { fn unique<+PartialEq>(self: @Array) -> Array; } -trait SpanTraitExt { +pub trait SpanTraitExt { fn pop_front_n(ref self: Span, n: usize); fn pop_back_n(ref self: Span, n: usize); fn reverse(self: Span) -> Array; fn contains<+PartialEq>(self: Span, item: T) -> bool; - fn concat(self: Span, a: Span) -> Span; + fn concat(self: Span, a: Span) -> Array; fn index_of<+PartialEq>(self: Span, item: T) -> Option; fn occurrences_of<+PartialEq>(self: Span, item: T) -> usize; fn min<+PartialEq, +PartialOrd>(self: Span) -> Option; @@ -159,7 +159,7 @@ impl SpanImpl, +Drop> of SpanTraitExt { } } - fn concat(self: Span, a: Span) -> Span { + fn concat(self: Span, a: Span) -> Array { let mut ret = array![]; let mut i = 0; @@ -172,7 +172,7 @@ impl SpanImpl, +Drop> of SpanTraitExt { ret.append(*a[i]); i += 1; }; - ret.span() + ret } fn index_of<+PartialEq>(mut self: Span, item: T) -> Option { diff --git a/src/data_structures/src/bit_array.cairo b/src/data_structures/src/bit_array.cairo index b9e488c0..456d72a7 100644 --- a/src/data_structures/src/bit_array.cairo +++ b/src/data_structures/src/bit_array.cairo @@ -1,16 +1,16 @@ -use array::{serialize_array_helper, deserialize_array_helper}; -use byte_array::BYTES_IN_BYTES31_MINUS_ONE; -use bytes_31::{ - one_shift_left_bytes_u128, one_shift_left_bytes_felt252, bytes31, BYTES_IN_U128, - BYTES_IN_BYTES31, -}; -use integer::u512; -use serde::into_felt252_based::SerdeImpl; +use core::bytes_31::bytes31; +use core::integer::u512; +use core::serde::Serde; +use core::serde::into_felt252_based::SerdeImpl; const SELECT_BIT: u128 = 0b10; +const POW_2_128: felt252 = 0x100000000000000000000000000000000; +const BYTES_IN_U128: usize = 16; +const BYTES_IN_BYTES31: usize = 31; +const BYTES_IN_BYTES31_MINUS_ONE: usize = BYTES_IN_BYTES31 - 1; #[derive(Clone, Drop)] -struct BitArray { +pub struct BitArray { data: Array, current: felt252, read_pos: usize, @@ -23,7 +23,10 @@ impl BitArrayDefaultImpl of Default { } } -trait BitArrayTrait { +pub trait BitArrayTrait { + fn new(data: Array, current: felt252, read_pos: usize, write_pos: usize,) -> BitArray; + fn current(self: @BitArray) -> felt252; + fn data(self: BitArray) -> Array; /// Appends a single bit to the BitArray /// # Arguments /// `bit` - either true or false, representing a single bit to be appended @@ -121,6 +124,18 @@ trait BitArrayTrait { } impl BitArrayImpl of BitArrayTrait { + fn new(data: Array, current: felt252, read_pos: usize, write_pos: usize,) -> BitArray { + BitArray { data, current, read_pos, write_pos, } + } + + fn current(self: @BitArray) -> felt252 { + *self.current + } + + fn data(self: BitArray) -> Array { + self.data + } + fn append_bit(ref self: BitArray, bit: bool) { let (byte_number, bit_offset) = DivRem::div_rem( self.write_pos, 8_usize.try_into().unwrap() @@ -452,26 +467,21 @@ impl BitArrayIndexView of IndexView { impl BitArraySerde of Serde { fn serialize(self: @BitArray, ref output: Array) { self.len().serialize(ref output); - let bytes31_arr = self.data.span(); - serialize_array_helper(bytes31_arr, ref output); + self.data.serialize(ref output); output.append(*self.current); } fn deserialize(ref serialized: Span) -> Option { - let length = *serialized.pop_front()?; - let length: usize = length.try_into().unwrap(); - let length_in_felts = length / 8 / BYTES_IN_BYTES31; - let bytes31_arr = deserialize_array_helper( - ref serialized, array![], length_in_felts.into() - )?; + let write_pos = Serde::::deserialize(ref serialized)?; + let bytes31_arr = Serde::>::deserialize(ref serialized)?; let current = *serialized.pop_front()?; - Option::Some(BitArray { data: bytes31_arr, current, read_pos: 0, write_pos: length }) + Option::Some(BitArray { data: bytes31_arr, current, read_pos: 0, write_pos }) } } // helper #[inline(always)] -fn shift_bit(number: usize) -> u8 { +pub fn shift_bit(number: usize) -> u8 { if number == 0 { 1_u8 } else if number == 1 { @@ -489,7 +499,7 @@ fn shift_bit(number: usize) -> u8 { } else if number == 7 { 0b10000000_u8 } else { - panic_with_felt252('invalid shift') + panic!("invalid shift") } } @@ -503,3 +513,36 @@ fn select(word: felt252, byte_index: usize, bit_index: usize) -> bool { }; (shifted_bytes / shift_bit(bit_index).into()) % SELECT_BIT == 1 } + +// TODO Copied from standard library as those aren't visible anymore +pub fn one_shift_left_bytes_felt252(n_bytes: usize) -> felt252 { + if n_bytes < BYTES_IN_U128 { + one_shift_left_bytes_u128(n_bytes).into() + } else { + one_shift_left_bytes_u128(n_bytes - BYTES_IN_U128).into() * POW_2_128 + } +} + +pub fn one_shift_left_bytes_u128(n_bytes: usize) -> u128 { + 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' + ), // For some reason we can't use panic!("") macro here... (running out of gas) + } +} diff --git a/src/data_structures/src/byte_appender.cairo b/src/data_structures/src/byte_appender.cairo index 079ea583..d6aef1e7 100644 --- a/src/data_structures/src/byte_appender.cairo +++ b/src/data_structures/src/byte_appender.cairo @@ -1,13 +1,13 @@ use alexandria_encoding::reversible::reversing; -use byte_array::ByteArrayTrait; -use bytes_31::{one_shift_left_bytes_felt252, one_shift_left_bytes_u128}; -use integer::u512; +use core::byte_array::ByteArrayTrait; +use core::integer::u512; +use super::bit_array::{one_shift_left_bytes_felt252, one_shift_left_bytes_u128}; /// Generic support trait for appending signed and unsigned integers onto byte storage. /// There are two functions, one for each of big and little endian byte order due to /// performance considerations. The byte reversal could be used in the naïve case when /// only one implementation is worthwhile. -trait ByteAppenderSupportTrait { +pub trait ByteAppenderSupportTrait { /// Appends `bytes` data of size `count` ordered in big endian /// # Arguments /// * `bytes` - big endian ordered bytes to append @@ -61,7 +61,7 @@ impl ByteAppenderSupportByteArrayImpl of ByteAppenderSupportTrait { } } -trait ByteAppender { +pub trait ByteAppender { /// Appends an unsigned 16 bit integer encoded in big endian /// # Arguments /// * `word` - a 16 bit unsigned integer typed as u16 diff --git a/src/data_structures/src/byte_array_ext.cairo b/src/data_structures/src/byte_array_ext.cairo index 0f0d9f26..e48bfb44 100644 --- a/src/data_structures/src/byte_array_ext.cairo +++ b/src/data_structures/src/byte_array_ext.cairo @@ -1,6 +1,6 @@ use alexandria_data_structures::byte_reader::ByteReader; -impl SpanU8IntoBytearray of Into, ByteArray> { +pub impl SpanU8IntoBytearray of Into, ByteArray> { #[inline] fn into(self: Span) -> ByteArray { let mut reader = self.reader(); @@ -21,7 +21,7 @@ impl ArrayU8IntoByteArray of Into, ByteArray> { } } -impl ByteArrayIntoArrayU8 of Into> { +pub impl ByteArrayIntoArrayU8 of Into> { fn into(self: ByteArray) -> Array { let mut reader = self.reader(); let mut result = array![]; diff --git a/src/data_structures/src/byte_reader.cairo b/src/data_structures/src/byte_reader.cairo index daed23d6..c84a5af1 100644 --- a/src/data_structures/src/byte_reader.cairo +++ b/src/data_structures/src/byte_reader.cairo @@ -1,13 +1,13 @@ -use bytes_31::{one_shift_left_bytes_u128, one_shift_left_bytes_felt252}; -use integer::u512; +use core::integer::u512; +use super::bit_array::{one_shift_left_bytes_felt252, one_shift_left_bytes_u128}; #[derive(Copy, Clone, Drop)] -struct ByteReaderState { - data: @T, +pub struct ByteReaderState { + pub(crate) data: @T, index: usize, } -trait ByteReader { +pub trait ByteReader { /// Wraps the array of bytes in a ByteReader for sequential consumption of integers and/or bytes /// # Returns /// * `ByteReader` - The reader struct wrapping a read-only snapshot of this ByteArray @@ -531,7 +531,7 @@ trait Len { impl ArrayU8LenImpl of Len> { #[inline] fn len(self: @Array) -> usize { - core::array::array_len::(self) + core::array::ArrayImpl::len(self) } } diff --git a/src/data_structures/src/lib.cairo b/src/data_structures/src/lib.cairo index 89d1aaa0..992d08a6 100644 --- a/src/data_structures/src/lib.cairo +++ b/src/data_structures/src/lib.cairo @@ -1,11 +1,11 @@ -mod array_ext; -mod bit_array; -mod byte_appender; -mod byte_array_ext; -mod byte_reader; -mod queue; -mod stack; +pub mod array_ext; +pub mod bit_array; +pub mod byte_appender; +pub mod byte_array_ext; +pub mod byte_reader; +pub mod queue; +pub mod stack; #[cfg(test)] mod tests; -mod vec; +pub mod vec; diff --git a/src/data_structures/src/queue.cairo b/src/data_structures/src/queue.cairo index 0c432c40..cff33e62 100644 --- a/src/data_structures/src/queue.cairo +++ b/src/data_structures/src/queue.cairo @@ -1,10 +1,10 @@ const ZERO_USIZE: usize = 0; -struct Queue { +pub struct Queue { elements: Array, } -trait QueueTrait { +pub trait QueueTrait { fn new() -> Queue; fn enqueue(ref self: Queue, value: T); fn dequeue(ref self: Queue) -> Option; diff --git a/src/data_structures/src/stack.cairo b/src/data_structures/src/stack.cairo index 13502cee..b7e0190e 100644 --- a/src/data_structures/src/stack.cairo +++ b/src/data_structures/src/stack.cairo @@ -12,8 +12,9 @@ //! Remove the item from the stack; //! let item = stack.pop(); //! ``` +use core::nullable::NullableImpl; -trait StackTrait { +pub trait StackTrait { /// Creates a new Stack instance. fn new() -> S; /// Pushes a new value onto the stack. @@ -28,7 +29,7 @@ trait StackTrait { fn is_empty(self: @S) -> bool; } -struct Felt252Stack { +pub struct Felt252Stack { elements: Felt252Dict, len: usize, } @@ -103,7 +104,7 @@ impl Felt252StackImpl< } -struct NullableStack { +pub struct NullableStack { elements: Felt252Dict>, len: usize, } @@ -122,7 +123,7 @@ impl NullableStackImpl, +Drop,> of StackTrait, T } fn push(ref self: NullableStack, value: T) { - self.elements.insert(self.len.into(), nullable_from_box(BoxTrait::new(value))); + self.elements.insert(self.len.into(), NullableImpl::new(value)); self.len += 1; } diff --git a/src/data_structures/src/tests/bit_array_test.cairo b/src/data_structures/src/tests/bit_array_test.cairo index 9cbe6f67..df0bc09d 100644 --- a/src/data_structures/src/tests/bit_array_test.cairo +++ b/src/data_structures/src/tests/bit_array_test.cairo @@ -1,7 +1,8 @@ -use alexandria_data_structures::bit_array::{BitArray, BitArrayTrait, shift_bit}; -use bytes_31::one_shift_left_bytes_felt252; -use integer::BoundedInt; -use integer::u512; +use alexandria_data_structures::bit_array::{ + BitArray, BitArrayTrait, one_shift_left_bytes_felt252, shift_bit +}; +use core::integer::BoundedInt; +use core::integer::u512; #[test] #[available_gas(30000000)] @@ -17,11 +18,11 @@ fn test_append_bit() { .try_into() .unwrap(); let expected: Array = array![val, val,]; - assert!(ba.data == expected, "illegal array"); assert( - ba.current == 0xa * one_shift_left_bytes_felt252(30) * shift_bit(4).into(), + ba.current() == 0xa * one_shift_left_bytes_felt252(30) * shift_bit(4).into(), 'expected current 0xa' ); + assert!(ba.data() == expected, "illegal array"); } #[test] @@ -294,6 +295,8 @@ fn test_serde_serialize() { let length = out.pop_front().unwrap(); let length: usize = length.try_into().unwrap(); assert!(length == ba.len(), "len not equal"); + // We gotta skip one now + out.pop_front().unwrap(); let data: felt252 = out.pop_front().unwrap(); let expected: felt252 = BoundedInt::::max().into() - 1; let expected = expected * one_shift_left_bytes_felt252(15); @@ -327,12 +330,5 @@ fn test_serde_ser_deser() { // helpers fn sample_bit_array() -> BitArray { let sample: felt252 = BoundedInt::::max().into() - 1; - let u256 { low, high: _ } = sample.into(); - let ba = BitArray { - data: array![], - current: low.into() * one_shift_left_bytes_felt252(15), - read_pos: 0, - write_pos: 8 * 16, - }; - ba + BitArrayTrait::new(array![], sample * one_shift_left_bytes_felt252(15), 0, 8 * 16) } diff --git a/src/data_structures/src/tests/byte_appender_test.cairo b/src/data_structures/src/tests/byte_appender_test.cairo index 835ee6d5..9e44d275 100644 --- a/src/data_structures/src/tests/byte_appender_test.cairo +++ b/src/data_structures/src/tests/byte_appender_test.cairo @@ -3,7 +3,7 @@ use alexandria_data_structures::tests::byte_reader_test::{ test_array_8, test_array_16, test_array_16_neg, test_array_32, test_array_64, test_byte_array_8, test_byte_array_16, test_byte_array_16_neg, test_byte_array_32, test_byte_array_64 }; -use integer::u512; +use core::integer::u512; #[test] #[available_gas(1000000)] @@ -13,7 +13,7 @@ fn test_append_u16() { ba.append_u16(0x0304_u16); ba.append_u16(0x0506_u16); ba.append_u16(0x0708_u16); - assert!(ba == test_byte_array_8(), "u16 differs"); + assert_eq!(ba, test_byte_array_8(), "u16 differs"); } #[test] @@ -24,7 +24,7 @@ fn test_append_u16_arr() { ba.append_u16(0x0304_u16); ba.append_u16(0x0506_u16); ba.append_u16(0x0708_u16); - assert!(ba == test_array_8(), "u16 differs"); + assert_eq!(ba, test_array_8(), "u16 differs"); } #[test] @@ -35,7 +35,7 @@ fn test_append_u16_le() { ba.append_u16_le(0x0403_u16); ba.append_u16_le(0x0605_u16); ba.append_u16_le(0x0807_u16); - assert!(ba == test_byte_array_8(), "u16 differs"); + assert_eq!(ba, test_byte_array_8(), "u16 differs"); } #[test] @@ -46,7 +46,7 @@ fn test_append_u16_le_arr() { ba.append_u16_le(0x0403_u16); ba.append_u16_le(0x0605_u16); ba.append_u16_le(0x0807_u16); - assert!(ba == test_array_8(), "u16 differs"); + assert_eq!(ba, test_array_8(), "u16 differs"); } #[test] @@ -55,7 +55,7 @@ fn test_append_u32() { let mut ba: ByteArray = Default::default(); ba.append_u32(0x01020304_u32); ba.append_u32(0x05060708_u32); - assert!(ba == test_byte_array_8(), "u32 differs"); + assert_eq!(ba, test_byte_array_8(), "u32 differs"); } #[test] @@ -64,7 +64,7 @@ fn test_append_u32_arr() { let mut ba: Array = array![]; ba.append_u32(0x01020304_u32); ba.append_u32(0x05060708_u32); - assert!(ba == test_array_8(), "u32 differs"); + assert_eq!(ba, test_array_8(), "u32 differs"); } #[test] @@ -73,7 +73,7 @@ fn test_append_u32_le() { let mut ba: ByteArray = Default::default(); ba.append_u32_le(0x04030201_u32); ba.append_u32_le(0x08070605_u32); - assert!(ba == test_byte_array_8(), "u32 differs"); + assert_eq!(ba, test_byte_array_8(), "u32 differs"); } #[test] @@ -82,7 +82,7 @@ fn test_append_u32_le_arr() { let mut ba: Array = array![]; ba.append_u32_le(0x04030201_u32); ba.append_u32_le(0x08070605_u32); - assert!(ba == test_array_8(), "u32 differs"); + assert_eq!(ba, test_array_8(), "u32 differs"); } #[test] @@ -91,7 +91,7 @@ fn test_append_u64() { let mut ba: ByteArray = Default::default(); ba.append_u64(0x0102030405060708_u64); ba.append_u64(0x090a0b0c0d0e0f10_u64); - assert!(ba == test_byte_array_16(), "u64 differs"); + assert_eq!(ba, test_byte_array_16(), "u64 differs"); } #[test] @@ -100,7 +100,7 @@ fn test_append_u64_arr() { let mut ba: Array = array![]; ba.append_u64(0x0102030405060708_u64); ba.append_u64(0x090a0b0c0d0e0f10_u64); - assert!(ba == test_array_16(), "u64 differs"); + assert_eq!(ba, test_array_16(), "u64 differs"); } #[test] @@ -109,7 +109,7 @@ fn test_append_u64_le() { let mut ba: ByteArray = Default::default(); ba.append_u64_le(0x0807060504030201_u64); ba.append_u64_le(0x100f0e0d0c0b0a09_u64); - assert!(ba == test_byte_array_16(), "u64 differs"); + assert_eq!(ba, test_byte_array_16(), "u64 differs"); } #[test] @@ -118,7 +118,7 @@ fn test_append_u64_le_arr() { let mut ba: Array = array![]; ba.append_u64_le(0x0807060504030201_u64); ba.append_u64_le(0x100f0e0d0c0b0a09_u64); - assert!(ba == test_array_16(), "u64 differs"); + assert_eq!(ba, test_array_16(), "u64 differs"); } #[test] @@ -127,7 +127,7 @@ fn test_append_u128() { let mut ba: ByteArray = Default::default(); ba.append_u128(0x0102030405060708090a0b0c0d0e0f10_u128); ba.append_u128(0x1112131415161718191a1b1c1d1e1f20_u128); - assert!(ba == test_byte_array_32(), "u128 differs"); + assert_eq!(ba, test_byte_array_32(), "u128 differs"); } #[test] @@ -136,7 +136,7 @@ fn test_append_u128_arr() { let mut ba: Array = array![]; ba.append_u128(0x0102030405060708090a0b0c0d0e0f10_u128); ba.append_u128(0x1112131415161718191a1b1c1d1e1f20_u128); - assert!(ba == test_array_32(), "u128 differs"); + assert_eq!(ba, test_array_32(), "u128 differs"); } #[test] @@ -145,7 +145,7 @@ fn test_append_u128_le() { let mut ba: ByteArray = Default::default(); ba.append_u128_le(0x100f0e0d0c0b0a090807060504030201_u128); ba.append_u128_le(0x201f1e1d1c1b1a191817161514131211_u128); - assert!(ba == test_byte_array_32(), "u128 differs"); + assert_eq!(ba, test_byte_array_32(), "u128 differs"); } #[test] @@ -154,7 +154,7 @@ fn test_append_u128_le_arr() { let mut ba: Array = array![]; ba.append_u128_le(0x100f0e0d0c0b0a090807060504030201_u128); ba.append_u128_le(0x201f1e1d1c1b1a191817161514131211_u128); - assert!(ba == test_array_32(), "u128 differs"); + assert_eq!(ba, test_array_32(), "u128 differs"); } #[test] @@ -165,7 +165,7 @@ fn test_append_u256() { high: 0x0102030405060708090a0b0c0d0e0f10_u128, low: 0x1112131415161718191a1b1c1d1e1f20_u128, }; ba.append_u256(word); - assert!(ba == test_byte_array_32(), "u256 differs"); + assert_eq!(ba, test_byte_array_32(), "u256 differs"); } #[test] @@ -176,7 +176,7 @@ fn test_append_u256_arr() { high: 0x0102030405060708090a0b0c0d0e0f10_u128, low: 0x1112131415161718191a1b1c1d1e1f20_u128, }; ba.append_u256(word); - assert!(ba == test_array_32(), "u256 differs"); + assert_eq!(ba, test_array_32(), "u256 differs"); } #[test] @@ -187,7 +187,7 @@ fn test_append_u256_le() { low: 0x100f0e0d0c0b0a090807060504030201_u128, high: 0x201f1e1d1c1b1a191817161514131211_u128, }; ba.append_u256_le(word); - assert!(ba == test_byte_array_32(), "u256 differs"); + assert_eq!(ba, test_byte_array_32(), "u256 differs"); } #[test] @@ -198,7 +198,7 @@ fn test_append_u256_le_arr() { low: 0x100f0e0d0c0b0a090807060504030201_u128, high: 0x201f1e1d1c1b1a191817161514131211_u128, }; ba.append_u256_le(word); - assert!(ba == test_array_32(), "u256 differs"); + assert_eq!(ba, test_array_32(), "u256 differs"); } #[test] @@ -213,7 +213,7 @@ fn test_append_u512() { let mut ba: ByteArray = Default::default(); ba.append_u512(test64); - assert!(ba == test_byte_array_64(), "test64 differs"); + assert_eq!(ba, test_byte_array_64(), "test64 differs"); } #[test] @@ -228,7 +228,7 @@ fn test_append_u512_arr() { let mut ba: Array = array![]; ba.append_u512(test64); - assert!(ba == test_array_64(), "test64 differs"); + assert_eq!(ba, test_array_64(), "test64 differs"); } #[test] @@ -243,7 +243,7 @@ fn test_append_u512_le() { let mut ba: ByteArray = Default::default(); ba.append_u512_le(test64); - assert!(ba == test_byte_array_64(), "test64 differs"); + assert_eq!(ba, test_byte_array_64(), "test64 differs"); } #[test] @@ -258,7 +258,7 @@ fn test_append_u512_le_arr() { let mut ba: Array = array![]; ba.append_u512_le(test64); - assert!(ba == test_array_64(), "test64 differs"); + assert_eq!(ba, test_array_64(), "test64 differs"); } #[test] @@ -268,7 +268,7 @@ fn test_append_i8() { ba1.append_i8(127_i8); let mut ba2: ByteArray = Default::default(); ba2.append_byte(0x7f_u8); - assert!(ba1 == ba2, "i8 differs"); + assert_eq!(ba1, ba2, "i8 differs"); } #[test] @@ -278,7 +278,7 @@ fn test_append_i8_arr() { ba1.append_i8(127_i8); let mut ba2: Array = array![]; ba2.append(0x7f_u8); - assert!(ba1 == ba2, "i8 differs"); + assert_eq!(ba1, ba2, "i8 differs"); } #[test] @@ -288,7 +288,7 @@ fn test_append_i8_neg() { ba1.append_i8(-128_i8); let mut ba2: ByteArray = Default::default(); ba2.append_byte(0x80_u8); - assert!(ba1 == ba2, "negative i8 differs"); + assert_eq!(ba1, ba2, "negative i8 differs"); } #[test] @@ -298,7 +298,7 @@ fn test_append_i8_neg_arr() { ba1.append_i8(-128_i8); let mut ba2: Array = array![]; ba2.append(0x80_u8); - assert!(ba1 == ba2, "negative i8 differs"); + assert_eq!(ba1, ba2, "negative i8 differs"); } #[test] @@ -309,7 +309,7 @@ fn test_append_i16() { ba1.append_i16(0x0304_i16); ba1.append_i16(0x0506_i16); ba1.append_i16(0x0708_i16); - assert!(ba1 == test_byte_array_8(), "i16 differs"); + assert_eq!(ba1, test_byte_array_8(), "i16 differs"); } #[test] @@ -320,7 +320,7 @@ fn test_append_i16_arr() { ba1.append_i16(0x0304_i16); ba1.append_i16(0x0506_i16); ba1.append_i16(0x0708_i16); - assert!(ba1 == test_array_8(), "i16 differs"); + assert_eq!(ba1, test_array_8(), "i16 differs"); } #[test] @@ -331,7 +331,7 @@ fn test_append_i16_le() { ba1.append_i16_le(0x0403_i16); ba1.append_i16_le(0x0605_i16); ba1.append_i16_le(0x0807_i16); - assert!(ba1 == test_byte_array_8(), "i16 differs"); + assert_eq!(ba1, test_byte_array_8(), "i16 differs"); } #[test] @@ -342,7 +342,7 @@ fn test_append_i16_le_arr() { ba1.append_i16_le(0x0403_i16); ba1.append_i16_le(0x0605_i16); ba1.append_i16_le(0x0807_i16); - assert!(ba1 == test_array_8(), "i16 differs"); + assert_eq!(ba1, test_array_8(), "i16 differs"); } #[test] @@ -357,7 +357,7 @@ fn test_append_i16_neg() { ba1.append_i16(-1_i16); ba1.append_i16(-1_i16); ba1.append_i16(-2_i16); - assert!(ba1 == test_byte_array_16_neg(), "negative i16 differs"); + assert_eq!(ba1, test_byte_array_16_neg(), "negative i16 differs"); } #[test] @@ -372,7 +372,7 @@ fn test_append_i16_neg_arr() { ba1.append_i16(-1_i16); ba1.append_i16(-1_i16); ba1.append_i16(-2_i16); - assert!(ba1 == test_array_16_neg(), "negative i16 differs"); + assert_eq!(ba1, test_array_16_neg(), "negative i16 differs"); } #[test] @@ -387,7 +387,7 @@ fn test_append_i16_le_neg() { ba1.append_i16_le(-1_i16); ba1.append_i16_le(-1_i16); ba1.append_i16_le(-257_i16); - assert!(ba1 == test_byte_array_16_neg(), "negative i16 differs"); + assert_eq!(ba1, test_byte_array_16_neg(), "negative i16 differs"); } #[test] @@ -402,7 +402,7 @@ fn test_append_i16_le_neg_arr() { ba1.append_i16_le(-1_i16); ba1.append_i16_le(-1_i16); ba1.append_i16_le(-257_i16); - assert!(ba1 == test_array_16_neg(), "negative i16 differs"); + assert_eq!(ba1, test_array_16_neg(), "negative i16 differs"); } #[test] @@ -411,7 +411,7 @@ fn test_append_i32() { let mut ba: ByteArray = Default::default(); ba.append_i32(0x01020304_i32); ba.append_i32(0x05060708_i32); - assert!(ba == test_byte_array_8(), "i32 differs"); + assert_eq!(ba, test_byte_array_8(), "i32 differs"); } #[test] @@ -420,7 +420,7 @@ fn test_append_i32_arr() { let mut ba: Array = array![]; ba.append_i32(0x01020304_i32); ba.append_i32(0x05060708_i32); - assert!(ba == test_array_8(), "i32 differs"); + assert_eq!(ba, test_array_8(), "i32 differs"); } #[test] @@ -429,7 +429,7 @@ fn test_append_i32_le() { let mut ba: ByteArray = Default::default(); ba.append_i32_le(0x04030201_i32); ba.append_i32_le(0x08070605_i32); - assert!(ba == test_byte_array_8(), "i32 differs"); + assert_eq!(ba, test_byte_array_8(), "i32 differs"); } #[test] @@ -438,7 +438,7 @@ fn test_append_i32_le_arr() { let mut ba: Array = array![]; ba.append_i32_le(0x04030201_i32); ba.append_i32_le(0x08070605_i32); - assert!(ba == test_array_8(), "i32 differs"); + assert_eq!(ba, test_array_8(), "i32 differs"); } #[test] @@ -449,7 +449,7 @@ fn test_append_i32_neg() { ba.append_i32(-1_i32); ba.append_i32(-1_i32); ba.append_i32(-2_i32); - assert!(ba == test_byte_array_16_neg(), "negative i32 differs"); + assert_eq!(ba, test_byte_array_16_neg(), "negative i32 differs"); } #[test] #[available_gas(1000000)] @@ -459,7 +459,7 @@ fn test_append_i32_neg_arr() { ba.append_i32(-1_i32); ba.append_i32(-1_i32); ba.append_i32(-2_i32); - assert!(ba == test_array_16_neg(), "negative i32 differs"); + assert_eq!(ba, test_array_16_neg(), "negative i32 differs"); } #[test] @@ -470,7 +470,7 @@ fn test_append_i32_le_neg() { ba.append_i32_le(-1_i32); ba.append_i32_le(-1_i32); ba.append_i32_le(-16777217_i32); - assert!(ba == test_byte_array_16_neg(), "negative i32 differs"); + assert_eq!(ba, test_byte_array_16_neg(), "negative i32 differs"); } #[test] @@ -481,7 +481,7 @@ fn test_append_i32_le_neg_arr() { ba.append_i32_le(-1_i32); ba.append_i32_le(-1_i32); ba.append_i32_le(-16777217_i32); - assert!(ba == test_array_16_neg(), "negative i32 differs"); + assert_eq!(ba, test_array_16_neg(), "negative i32 differs"); } #[test] @@ -490,7 +490,7 @@ fn test_append_i64() { let mut ba: ByteArray = Default::default(); ba.append_i64(0x0102030405060708_i64); ba.append_i64(0x090a0b0c0d0e0f10_i64); - assert!(ba == test_byte_array_16(), "i64 differs"); + assert_eq!(ba, test_byte_array_16(), "i64 differs"); } #[test] @@ -499,7 +499,7 @@ fn test_append_i64_arr() { let mut ba: Array = array![]; ba.append_i64(0x0102030405060708_i64); ba.append_i64(0x090a0b0c0d0e0f10_i64); - assert!(ba == test_array_16(), "i64 differs"); + assert_eq!(ba, test_array_16(), "i64 differs"); } #[test] @@ -508,7 +508,7 @@ fn test_append_i64_le() { let mut ba: ByteArray = Default::default(); ba.append_i64_le(0x0807060504030201_i64); ba.append_i64_le(0x100f0e0d0c0b0a09_i64); - assert!(ba == test_byte_array_16(), "i64 differs"); + assert_eq!(ba, test_byte_array_16(), "i64 differs"); } #[test] @@ -517,7 +517,7 @@ fn test_append_i64_le_arr() { let mut ba: Array = array![]; ba.append_i64_le(0x0807060504030201_i64); ba.append_i64_le(0x100f0e0d0c0b0a09_i64); - assert!(ba == test_array_16(), "i64 differs"); + assert_eq!(ba, test_array_16(), "i64 differs"); } #[test] @@ -526,7 +526,7 @@ fn test_append_i64_neg() { let mut ba: ByteArray = Default::default(); ba.append_i64(-1_i64); ba.append_i64(-2_i64); - assert!(ba == test_byte_array_16_neg(), "negative i64 differs"); + assert_eq!(ba, test_byte_array_16_neg(), "negative i64 differs"); } #[test] @@ -535,7 +535,7 @@ fn test_append_i64_neg_arr() { let mut ba: Array = array![]; ba.append_i64(-1_i64); ba.append_i64(-2_i64); - assert!(ba == test_array_16_neg(), "negative i64 differs"); + assert_eq!(ba, test_array_16_neg(), "negative i64 differs"); } #[test] @@ -544,7 +544,7 @@ fn test_append_i64_le_neg() { let mut ba: ByteArray = Default::default(); ba.append_i64_le(-1_i64); ba.append_i64_le(-72057594037927937_i64); - assert!(ba == test_byte_array_16_neg(), "negative i64 differs"); + assert_eq!(ba, test_byte_array_16_neg(), "negative i64 differs"); } #[test] @@ -553,7 +553,7 @@ fn test_append_i64_le_neg_arr() { let mut ba: Array = array![]; ba.append_i64_le(-1_i64); ba.append_i64_le(-72057594037927937_i64); - assert!(ba == test_array_16_neg(), "negative i64 differs"); + assert_eq!(ba, test_array_16_neg(), "negative i64 differs"); } #[test] @@ -562,7 +562,7 @@ fn test_append_i128() { let mut ba: ByteArray = Default::default(); ba.append_i128(0x0102030405060708090a0b0c0d0e0f10_i128); ba.append_i128(0x1112131415161718191a1b1c1d1e1f20_i128); - assert!(ba == test_byte_array_32(), "i128 differs"); + assert_eq!(ba, test_byte_array_32(), "i128 differs"); } #[test] @@ -571,7 +571,7 @@ fn test_append_i128_arr() { let mut ba: Array = array![]; ba.append_i128(0x0102030405060708090a0b0c0d0e0f10_i128); ba.append_i128(0x1112131415161718191a1b1c1d1e1f20_i128); - assert!(ba == test_array_32(), "i128 differs"); + assert_eq!(ba, test_array_32(), "i128 differs"); } #[test] @@ -580,7 +580,7 @@ fn test_append_i128_le() { let mut ba: ByteArray = Default::default(); ba.append_i128_le(0x100f0e0d0c0b0a090807060504030201_i128); ba.append_i128_le(0x201f1e1d1c1b1a191817161514131211_i128); - assert!(ba == test_byte_array_32(), "i128 differs"); + assert_eq!(ba, test_byte_array_32(), "i128 differs"); } #[test] @@ -589,7 +589,7 @@ fn test_append_i128_le_arr() { let mut ba: Array = array![]; ba.append_i128_le(0x100f0e0d0c0b0a090807060504030201_i128); ba.append_i128_le(0x201f1e1d1c1b1a191817161514131211_i128); - assert!(ba == test_array_32(), "i128 differs"); + assert_eq!(ba, test_array_32(), "i128 differs"); } #[test] @@ -597,7 +597,7 @@ fn test_append_i128_le_arr() { fn test_append_i128_neg() { let mut ba: ByteArray = Default::default(); ba.append_i128(-2_i128); - assert!(ba == test_byte_array_16_neg(), "negative i128 differs"); + assert_eq!(ba, test_byte_array_16_neg(), "negative i128 differs"); } #[test] @@ -605,7 +605,7 @@ fn test_append_i128_neg() { fn test_append_i128_neg_arr() { let mut ba: Array = array![]; ba.append_i128(-2_i128); - assert!(ba == test_array_16_neg(), "negative i128 differs"); + assert_eq!(ba, test_array_16_neg(), "negative i128 differs"); } #[test] @@ -613,7 +613,7 @@ fn test_append_i128_neg_arr() { fn test_append_i128_le_neg() { let mut ba: ByteArray = Default::default(); ba.append_i128_le(-1329227995784915872903807060280344577_i128); - assert!(ba == test_byte_array_16_neg(), "negative i128 differs"); + assert_eq!(ba, test_byte_array_16_neg(), "negative i128 differs"); } #[test] @@ -621,5 +621,5 @@ fn test_append_i128_le_neg() { fn test_append_i128_le_neg_arr() { let mut ba: Array = array![]; ba.append_i128_le(-1329227995784915872903807060280344577_i128); - assert!(ba == test_array_16_neg(), "negative i128 differs"); + assert_eq!(ba, test_array_16_neg(), "negative i128 differs"); } diff --git a/src/data_structures/src/tests/byte_reader_test.cairo b/src/data_structures/src/tests/byte_reader_test.cairo index 1c203985..a35305b3 100644 --- a/src/data_structures/src/tests/byte_reader_test.cairo +++ b/src/data_structures/src/tests/byte_reader_test.cairo @@ -1,5 +1,5 @@ use alexandria_data_structures::byte_reader::ByteReader; -use integer::u512; +use core::integer::u512; #[test] #[available_gas(1000000)] @@ -468,9 +468,9 @@ fn test_clone_byte_array_reader() { let mut rd1 = ba.reader(); let mut rd2 = rd1.clone(); let a = rd1.read_u128().unwrap(); - assert!(rd1.index != rd2.index, "indicies equal"); + assert!(rd1.len() != rd2.len(), "indices equal"); let b = rd2.read_u128().unwrap(); - assert!(rd1.index == rd2.index, "indicies not equal"); + assert!(rd1.len() == rd2.len(), "indices not equal"); assert!(a == b, "copy ByteArrayReader failed"); } @@ -481,9 +481,9 @@ fn test_clone_array_of_bytes_reader() { let mut rd1 = ba.reader(); let mut rd2 = rd1.clone(); let a = rd1.read_u128().unwrap(); - assert!(rd1.index != rd2.index, "indicies equal"); + assert!(rd1.len() != rd2.len(), "indices equal"); let b = rd2.read_u128().unwrap(); - assert!(rd1.index == rd2.index, "indicies not equal"); + assert!(rd1.len() == rd2.len(), "indices not equal"); assert!(a == b, "copy ByteArrayReader failed"); } @@ -500,39 +500,39 @@ fn test_byte_array_reader_equals_array_of_bytes_reader() { } // helpers -fn test_byte_array_8() -> ByteArray { +pub fn test_byte_array_8() -> ByteArray { let mut ba1 = Default::default(); ba1.append_word(0x0102030405060708, 8); ba1 } -fn test_byte_array_16() -> ByteArray { +pub fn test_byte_array_16() -> ByteArray { let mut ba1 = Default::default(); ba1.append_word(0x0102030405060708090a0b0c0d0e0f10, 16); ba1 } -fn test_byte_array_32() -> ByteArray { +pub fn test_byte_array_32() -> ByteArray { let mut ba1 = Default::default(); ba1.append_word(0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f, 31); ba1.append_word(0x20, 1); ba1 } -fn test_byte_array_32_neg() -> ByteArray { +pub fn test_byte_array_32_neg() -> ByteArray { let mut ba1 = Default::default(); ba1.append_word(0xfffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1, 31); ba1.append_word(0xe0, 1); ba1 } -fn test_byte_array_16_neg() -> ByteArray { +pub fn test_byte_array_16_neg() -> ByteArray { let mut ba1 = Default::default(); ba1.append_word(0xfffffffffffffffffffffffffffffffe, 16); ba1 } -fn test_byte_array_64() -> ByteArray { +pub fn test_byte_array_64() -> ByteArray { let mut ba1 = Default::default(); ba1.append_word(0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f, 31); ba1.append_word(0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e, 31); @@ -540,15 +540,15 @@ fn test_byte_array_64() -> ByteArray { ba1 } -fn test_array_8() -> Array { +pub fn test_array_8() -> Array { array![1, 2, 3, 4, 5, 6, 7, 8] } -fn test_array_16() -> Array { +pub fn test_array_16() -> Array { array![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] } -fn test_array_32() -> Array { +pub fn test_array_32() -> Array { array![ 1, 2, @@ -585,7 +585,7 @@ fn test_array_32() -> Array { ] } -fn test_array_32_neg() -> Array { +pub fn test_array_32_neg() -> Array { array![ 0xff, 0xfe, @@ -622,7 +622,7 @@ fn test_array_32_neg() -> Array { ] } -fn test_array_16_neg() -> Array { +pub fn test_array_16_neg() -> Array { array![ 0xff, 0xff, @@ -643,7 +643,7 @@ fn test_array_16_neg() -> Array { ] } -fn test_array_64() -> Array { +pub fn test_array_64() -> Array { array![ 1, 2, diff --git a/src/data_structures/src/vec.cairo b/src/data_structures/src/vec.cairo index eed2c782..e2a8e0b9 100644 --- a/src/data_structures/src/vec.cairo +++ b/src/data_structures/src/vec.cairo @@ -1,3 +1,5 @@ +use core::integer::u32_wrapping_add; +use core::nullable::NullableImpl; //! Vec implementation. //! //! # Example @@ -12,7 +14,7 @@ //! ... //! ``` -trait VecTrait { +pub trait VecTrait { /// Creates a new V instance. /// Returns /// * V The new vec instance. @@ -63,7 +65,7 @@ impl VecIndex> of Index { } } -struct Felt252Vec { +pub struct Felt252Vec { items: Felt252Dict, len: usize, } @@ -97,7 +99,7 @@ impl Felt252VecImpl, +Copy, +Felt252DictValue> of VecTrait, value: T) -> () { self.items.insert(self.len.into(), value); - self.len = integer::u32_wrapping_add(self.len, 1_usize); + self.len = u32_wrapping_add(self.len, 1_usize); } fn set(ref self: Felt252Vec, index: usize, value: T) { @@ -110,7 +112,7 @@ impl Felt252VecImpl, +Copy, +Felt252DictValue> of VecTrait { +pub struct NullableVec { items: Felt252Dict>, len: usize, } @@ -140,13 +142,13 @@ impl NullableVecImpl, +Copy> of VecTrait, T> { } fn push(ref self: NullableVec, value: T) -> () { - self.items.insert(self.len.into(), nullable_from_box(BoxTrait::new(value))); - self.len = integer::u32_wrapping_add(self.len, 1_usize); + self.items.insert(self.len.into(), NullableImpl::new(value)); + self.len = u32_wrapping_add(self.len, 1_usize); } fn set(ref self: NullableVec, index: usize, value: T) { assert(index < self.len(), 'Index out of bounds'); - self.items.insert(index.into(), nullable_from_box(BoxTrait::new(value))); + self.items.insert(index.into(), NullableImpl::new(value)); } fn len(self: @NullableVec) -> usize { diff --git a/src/encoding/Scarb.toml b/src/encoding/Scarb.toml index fab7f580..8bbc703b 100644 --- a/src/encoding/Scarb.toml +++ b/src/encoding/Scarb.toml @@ -3,6 +3,7 @@ name = "alexandria_encoding" version = "0.1.0" description = "Encoding utilities" homepage = "https://github.com/keep-starknet-strange/alexandria/tree/main/src/encoding" +edition = "2023_11" [tool] fmt.workspace = true diff --git a/src/encoding/src/base64.cairo b/src/encoding/src/base64.cairo index 14f6a9b8..a016af37 100644 --- a/src/encoding/src/base64.cairo +++ b/src/encoding/src/base64.cairo @@ -1,20 +1,16 @@ use alexandria_data_structures::array_ext::ArrayTraitExt; use alexandria_math::BitShift; -use core::array::ArrayTrait; -use core::option::OptionTrait; -use integer::BoundedInt; +use core::integer::BoundedInt; -const U6_MAX: u128 = 0x3F; - -trait Encoder { +pub trait Encoder { fn encode(data: T) -> Array; } -trait Decoder { +pub trait Decoder { fn decode(data: T) -> Array; } -impl Base64Encoder of Encoder> { +pub impl Base64Encoder of Encoder> { fn encode(data: Array) -> Array { let mut char_set = get_base64_char_set(); char_set.append('+'); @@ -23,7 +19,7 @@ impl Base64Encoder of Encoder> { } } -impl Base64UrlEncoder of Encoder> { +pub impl Base64UrlEncoder of Encoder> { fn encode(data: Array) -> Array { let mut char_set = get_base64_char_set(); char_set.append('-'); @@ -32,7 +28,7 @@ impl Base64UrlEncoder of Encoder> { } } -impl Base64FeltEncoder of Encoder { +pub impl Base64FeltEncoder of Encoder { fn encode(data: felt252) -> Array { let mut char_set = get_base64_char_set(); char_set.append('+'); @@ -41,7 +37,7 @@ impl Base64FeltEncoder of Encoder { } } -impl Base64UrlFeltEncoder of Encoder { +pub impl Base64UrlFeltEncoder of Encoder { fn encode(data: felt252) -> Array { let mut char_set = get_base64_char_set(); char_set.append('-'); @@ -50,7 +46,7 @@ impl Base64UrlFeltEncoder of Encoder { } } -fn encode_u8_array(mut bytes: Array, base64_chars: Span) -> Array { +pub fn encode_u8_array(mut bytes: Array, base64_chars: Span) -> Array { let mut result = array![]; if bytes.len() == 0 { return result; @@ -99,7 +95,7 @@ fn encode_u8_array(mut bytes: Array, base64_chars: Span) -> Array { result } -fn encode_felt(self: felt252, base64_chars: Span) -> Array { +pub fn encode_felt(self: felt252, base64_chars: Span) -> Array { let mut result = array![]; let mut num: u256 = self.into(); @@ -139,13 +135,13 @@ fn encode_felt(self: felt252, base64_chars: Span) -> Array { result } -impl Base64Decoder of Decoder> { +pub impl Base64Decoder of Decoder> { fn decode(data: Array) -> Array { inner_decode(data) } } -impl Base64UrlDecoder of Decoder> { +pub impl Base64UrlDecoder of Decoder> { fn decode(mut data: Array) -> Array { inner_decode(data) } diff --git a/src/encoding/src/lib.cairo b/src/encoding/src/lib.cairo index f3966341..b6515200 100644 --- a/src/encoding/src/lib.cairo +++ b/src/encoding/src/lib.cairo @@ -1,7 +1,7 @@ -mod base64; -mod reversible; -mod rlp; -mod sol_abi; +pub mod base64; +pub mod reversible; +pub mod rlp; +pub mod sol_abi; #[cfg(test)] mod tests; diff --git a/src/encoding/src/reversible.cairo b/src/encoding/src/reversible.cairo index 16fdaa67..06ce717d 100644 --- a/src/encoding/src/reversible.cairo +++ b/src/encoding/src/reversible.cairo @@ -1,10 +1,11 @@ -use integer::u512; +use core::integer::u512; +use core::num::traits::Zero; const SELECT_BYTE: u16 = 0x100; const SELECT_BIT: u8 = 0b10; /// Implies that there is an underlying byte order for type T that can be reversed -trait ReversibleBytes { +pub trait ReversibleBytes { /// Reverses the byte order or endianness of `self`. /// For example, the word `0x1122_u16` is reversed into `0x2211_u16`. /// # Returns @@ -13,7 +14,7 @@ trait ReversibleBytes { } /// Implies that there is an underlying bit order for type T that can be reversed -trait ReversibleBits { +pub trait ReversibleBits { /// Reverses the underlying ordering of the bit representation of `self`. /// For example, the word `0b10111010_u8` is reversed into `0b01011101`. /// # Returns @@ -22,10 +23,10 @@ trait ReversibleBits { } #[inline] -fn reversing< +pub fn reversing< T, +Copy, - +Zeroable, + +Zero, +TryInto>, +DivRem, +Drop, @@ -35,12 +36,12 @@ fn reversing< >( word: T, size: usize, step: T ) -> (T, T) { - let result = Zeroable::zero(); + let result = Zero::zero(); reversing_partial_result(word, result, size, step) } #[inline] -fn reversing_partial_result< +pub fn reversing_partial_result< T, +Copy, +DivRem, +TryInto>, +Drop, +MulEq, +Rem, +AddEq >( mut word: T, mut onto: T, size: usize, step: T diff --git a/src/encoding/src/rlp.cairo b/src/encoding/src/rlp.cairo index 10fa6184..1b75a851 100644 --- a/src/encoding/src/rlp.cairo +++ b/src/encoding/src/rlp.cairo @@ -3,7 +3,7 @@ use alexandria_numeric::integers::UIntBytes; // Possible RLP errors #[derive(Drop, Copy, PartialEq)] -enum RLPError { +pub enum RLPError { EmptyInput, InputTooShort, PayloadTooLong @@ -11,19 +11,19 @@ enum RLPError { // Possible RLP types #[derive(Drop, PartialEq)] -enum RLPType { +pub enum RLPType { String, List } #[derive(Drop, Copy, PartialEq)] -enum RLPItem { +pub enum RLPItem { String: Span, List: Span } #[generate_trait] -impl RLPImpl of RLPTrait { +pub impl RLPImpl of RLPTrait { /// Returns RLPType from the leading byte with /// its offset in the array as well as its size. /// diff --git a/src/encoding/src/sol_abi/decode.cairo b/src/encoding/src/sol_abi/decode.cairo index 1769856c..fce1555c 100644 --- a/src/encoding/src/sol_abi/decode.cairo +++ b/src/encoding/src/sol_abi/decode.cairo @@ -1,6 +1,6 @@ use alexandria_bytes::{Bytes, BytesTrait}; -use alexandria_encoding::sol_abi::SolBytesTrait; -use starknet::{ContractAddress, EthAddress, eth_address::U256IntoEthAddress}; +use alexandria_encoding::sol_abi::sol_bytes::SolBytesTrait; +use starknet::{ContractAddress, EthAddress}; /// Decode trait meant to provide an interface similar to Solidity's abi.decode /// function. It is meant to be used in a chain where the passed in `offset` is @@ -110,7 +110,7 @@ pub impl SolAbiDecodeByteArray of SolAbiDecodeTrait { fn decode(self: @Bytes, ref offset: usize) -> ByteArray { let (new_offset, decodedBytes) = self.read_u256(offset); offset = new_offset; - SolBytesTrait::bytes32(decodedBytes).to_byte_array() + SolBytesTrait::bytes32(decodedBytes).into() } } diff --git a/src/encoding/src/sol_abi/encode.cairo b/src/encoding/src/sol_abi/encode.cairo index 52faaf4a..e1463ba3 100644 --- a/src/encoding/src/sol_abi/encode.cairo +++ b/src/encoding/src/sol_abi/encode.cairo @@ -1,5 +1,5 @@ use alexandria_bytes::{Bytes, BytesTrait}; -use alexandria_math::U256BitShift; +use core::traits::TryInto; use starknet::{ContractAddress, EthAddress}; /// Encode selector trait meant to provide an interface similar to Solidity's @@ -175,13 +175,13 @@ pub impl SolAbiEncodeBytes of SolAbiEncodeTrait { pub impl SolAbiEncodeByteArray of SolAbiEncodeTrait { fn encode(mut self: Bytes, x: ByteArray) -> Bytes { let x_len: usize = x.len(); - self.concat(@BytesTrait::from_byte_array(x)); + self.concat(@x.into()); self.concat(@BytesTrait::zero(32 - (x_len % 32))); self } fn encode_packed(mut self: Bytes, x: ByteArray) -> Bytes { - self.concat(@BytesTrait::from_byte_array(x)); + self.concat(@x.into()); self } } @@ -206,13 +206,15 @@ pub impl SolAbiEncodeStarknetAddress of SolAbiEncodeTrait { pub impl SolAbiEncodeEthAddress of SolAbiEncodeTrait { fn encode(mut self: Bytes, x: EthAddress) -> Bytes { - self.append_u256(x.address.into()); + let x: felt252 = x.into(); + self.append_u256(x.into()); self } fn encode_packed(mut self: Bytes, x: EthAddress) -> Bytes { - let mut address256: u256 = x.address.into(); - address256 = U256BitShift::shl(address256, 96); // 12 * 8 + let x: felt252 = x.into(); + let mut address256: u256 = x.into(); + address256 = alexandria_math::U256BitShift::shl(address256, 96); // 12 * 8 self.concat(@BytesTrait::new(20, array![address256.high, address256.low])); self } diff --git a/src/encoding/src/sol_abi/encode_as.cairo b/src/encoding/src/sol_abi/encode_as.cairo index f05decfe..8109105d 100644 --- a/src/encoding/src/sol_abi/encode_as.cairo +++ b/src/encoding/src/sol_abi/encode_as.cairo @@ -63,15 +63,15 @@ pub impl SolAbiEncodeAsBytes31 of SolAbiEncodeAsTrait { pub impl SolAbiEncodeAsBytes of SolAbiEncodeAsTrait { fn encode_as(mut self: Bytes, byteSize: usize, x: Bytes) -> Bytes { - self.concat(@BytesTrait::new(byteSize, x.data)); + self.concat(@BytesTrait::new(byteSize, x.data())); self } } pub impl SolAbiEncodeAsByteArray of SolAbiEncodeAsTrait { fn encode_as(mut self: Bytes, byteSize: usize, x: ByteArray) -> Bytes { - let x: Bytes = BytesTrait::from_byte_array(x); - self.concat(@BytesTrait::new(byteSize, x.data)); + let x: Bytes = x.into(); + self.concat(@BytesTrait::new(byteSize, x.data())); self } } diff --git a/src/encoding/src/sol_abi/sol_bytes.cairo b/src/encoding/src/sol_abi/sol_bytes.cairo index 72d6377d..5906ebb0 100644 --- a/src/encoding/src/sol_abi/sol_bytes.cairo +++ b/src/encoding/src/sol_abi/sol_bytes.cairo @@ -1,5 +1,5 @@ -use alexandria_bytes::{Bytes, BytesTrait}; -use alexandria_encoding::sol_abi::SolAbiEncodeAsTrait; +use alexandria_bytes::bytes::{Bytes, BytesTrait}; +use alexandria_encoding::sol_abi::encode_as::SolAbiEncodeAsTrait; /// Solidity Bytes Trait meant to provide an interface similar to Solidity's /// bytesX types, like `bytes1`, `bytes2`, `bytes3`, ..., `bytes32`. Acts as diff --git a/src/encoding/src/tests/base64_felt_test.cairo b/src/encoding/src/tests/base64_felt_test.cairo index 5dac0fcc..e20d87fe 100644 --- a/src/encoding/src/tests/base64_felt_test.cairo +++ b/src/encoding/src/tests/base64_felt_test.cairo @@ -2,8 +2,6 @@ use alexandria_data_structures::array_ext::ArrayTraitExt; use alexandria_encoding::base64::{ Base64Encoder, Base64UrlEncoder, Base64FeltEncoder, Base64UrlFeltEncoder }; -use core::debug::PrintTrait; -use core::option::OptionTrait; use core::traits::TryInto; fn bytes_be(val: felt252) -> Array { diff --git a/src/encoding/src/tests/reversible_test.cairo b/src/encoding/src/tests/reversible_test.cairo index a2ae6a1d..b919f553 100644 --- a/src/encoding/src/tests/reversible_test.cairo +++ b/src/encoding/src/tests/reversible_test.cairo @@ -1,5 +1,5 @@ use alexandria_encoding::reversible::{ReversibleBits, ReversibleBytes}; -use integer::u512; +use core::integer::u512; #[test] #[available_gas(1000000)] diff --git a/src/encoding/src/tests/rlp_test.cairo b/src/encoding/src/tests/rlp_test.cairo index 3f3d29da..ab15cb66 100644 --- a/src/encoding/src/tests/rlp_test.cairo +++ b/src/encoding/src/tests/rlp_test.cairo @@ -1,8 +1,5 @@ use alexandria_encoding::rlp::{RLPError, RLPType, RLPTrait, RLPItem}; -use debug::PrintTrait; -use result::ResultTrait; - #[test] #[available_gas(99999999)] fn test_rlp_decode_type_byte() { diff --git a/src/encoding/src/tests/sol_abi.cairo b/src/encoding/src/tests/sol_abi.cairo index 12753bd2..39354a5f 100644 --- a/src/encoding/src/tests/sol_abi.cairo +++ b/src/encoding/src/tests/sol_abi.cairo @@ -1,20 +1,18 @@ use alexandria_bytes::utils::{BytesDebug, BytesDisplay}; use alexandria_bytes::{Bytes, BytesTrait}; use alexandria_encoding::sol_abi::{ - SolAbiEncodeTrait, SolAbiEncodeAsTrait, SolAbiEncodeSelectorTrait, SolAbiDecodeTrait, - SolBytesTrait + encode::SolAbiEncodeTrait, encode_as::SolAbiEncodeAsTrait, encode::SolAbiEncodeSelectorTrait, + decode::SolAbiDecodeTrait, sol_bytes::SolBytesTrait }; +use core::bytes_31; use core::to_byte_array::FormatAsByteArray; -use starknet::{ContractAddress, eth_address::U256IntoEthAddress, EthAddress}; +use starknet::{ContractAddress, EthAddress}; // Compare Bytes types up to the size of the data ( incase different values outside size range ) fn compare_bytes(actual: @Bytes, expected: @Bytes) -> bool { if actual.size() != expected.size() { return false; } - if actual.data.len() != expected.data.len() { - return false; - } let mut i: usize = 0; while i < actual .size() { @@ -74,6 +72,7 @@ fn encode_test() { .try_into() .expect('Couldn\'t convert to address'); let eth_address: EthAddress = 0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF_u256.into(); + let sba: ByteArray = (SolBytesTrait::bytes5(0x0000abcdef).into()); encoded = encoded .encode(0x1a_u8) .encode(0x101112131415161718191a1b1c1d1e1f_u128) @@ -85,9 +84,9 @@ fn encode_test() { .encode(false) .encode(true) .encode(1234567890_felt252) - .encode(bytes31_const::<0xabcdefabcdefabcdefabcdefabcdefabcdef>()) + .encode(0xabcdefabcdefabcdefabcdefabcdefabcdef) .encode(SolBytesTrait::bytes7(0xa0b0c0d0e0f)) - .encode(SolBytesTrait::bytes5(0x0000abcdef).to_byte_array()) + .encode(sba) .encode(address) .encode(eth_address); assert_eq!(encoded, expected, "Encode uints failed"); @@ -119,7 +118,8 @@ fn encode_packed_test() { .try_into() .expect('Couldn\'t convert to address'); let eth_address: EthAddress = 0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF_u256.into(); - let bytesArray: ByteArray = SolBytesTrait::bytes5(0xa0aaabacad_u128).to_byte_array(); + let bytesArray: ByteArray = SolBytesTrait::bytes5(0xa0aaabacad_u128).into(); + let bytes_31: bytes31 = 0x1234.try_into().unwrap(); encoded = encoded .encode_packed(0x8_u8) .encode_packed(0xa7a8a9aaabacadaeaf_u128) @@ -129,7 +129,7 @@ fn encode_packed_test() { .encode_packed(0x0fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbe_u256) .encode_packed(false) .encode_packed(true) - .encode_packed(bytes31_const::<0x1234>()) + .encode_packed(bytes_31) .encode_packed(SolBytesTrait::bytes10(0x0102030405060708090a_u128)) .encode_packed(0x1234567890_felt252) .encode_packed(address) @@ -150,11 +150,13 @@ fn encoded_as_test() { .encode_as(5, 0xa0b1c2_u256); assert_eq!(encoded, expected, "Encode as failed"); + let sba: ByteArray = SolBytesTrait::bytes10(0x0000a0b1c2c3c4c5c6c8).into(); + let bytes_31: bytes31 = 0xaabbcc.try_into().unwrap(); let mut encoded: Bytes = BytesTrait::new_empty(); encoded = encoded .encode_as(3, SolBytesTrait::bytes10(0x10111213141516171910)) - .encode_as(21, bytes31_const::<0xaabbcc>()) - .encode_as(5, SolBytesTrait::bytes10(0x0000a0b1c2c3c4c5c6c8).to_byte_array()); + .encode_as(21, bytes_31) + .encode_as(5, sba); assert_eq!(encoded, expected, "Encode as from bytes failed"); } @@ -252,14 +254,13 @@ fn decode_test() { let expected: ByteArray = SolBytesTrait::bytes32( 0xa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3000000000000000000000000_u256 ) - .to_byte_array(); + .into(); assert_eq!(decoded, expected, "Decode ByteArray failed"); assert_eq!(offset, 256, "Offset after decode ByteArray failed"); let decoded: bytes31 = encoded.decode(ref offset); - assert!( - decoded == bytes31_const::<0xa0aaab00000000000000000000000000ac>(), "Decode byte31 failed" - ); + let bytes_31: bytes31 = 0xa0aaab00000000000000000000000000ac.try_into().unwrap(); + assert!(decoded == bytes_31, "Decode byte31 failed"); assert_eq!(offset, 288, "Offset after decode byte31 failed"); let decoded: felt252 = encoded.decode(ref offset); @@ -296,7 +297,7 @@ fn sol_bytes_test() { 0x0000a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2_u256 ); let bytesVal18: Bytes = SolBytesTrait::bytes18(0xa0a1a2a3a4a5a6a7a8a9aaabacadaeaf_u128); - let bytesVal3: Bytes = SolBytesTrait::bytes3(bytes31_const::<0xb0b1b2>()); + let bytesVal3: Bytes = SolBytesTrait::bytes3(0xb0b1b2); let mut bytesValAcc: Bytes = BytesTrait::new_empty(); bytesValAcc.concat(@bytesVal18); bytesValAcc.concat(@bytesVal3); @@ -312,7 +313,7 @@ fn sol_bytes_test() { let bytesArray: ByteArray = SolBytesTrait::bytes32( 0xa6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b800000000000000000000000000_u256 ) - .to_byte_array(); + .into(); let bytesVal19: Bytes = SolBytesTrait::bytes19(bytesArray); let mut bytesValAcc: Bytes = BytesTrait::new_empty(); bytesValAcc.concat(@bytesVal6); diff --git a/src/linalg/Scarb.toml b/src/linalg/Scarb.toml index 65830b8f..f528372e 100644 --- a/src/linalg/Scarb.toml +++ b/src/linalg/Scarb.toml @@ -3,6 +3,7 @@ name = "alexandria_linalg" version = "0.1.0" description = "A set of linear algebra libraries and algorithms" homepage = "https://github.com/keep-starknet-strange/alexandria/tree/main/src/linalg" +edition = "2023_11" [tool] fmt.workspace = true diff --git a/src/linalg/src/dot.cairo b/src/linalg/src/dot.cairo index 0f8fa7a5..f388299b 100644 --- a/src/linalg/src/dot.cairo +++ b/src/linalg/src/dot.cairo @@ -1,3 +1,4 @@ +use core::num::traits::Zero; //! Dot product of two arrays /// Compute the dot product for 2 given arrays. @@ -6,14 +7,14 @@ /// * `ys` - The second sequence of len L. /// # Returns /// * `sum` - The dot product. -fn dot, +AddEq, +Zeroable, +Copy, +Drop,>( +pub fn dot, +AddEq, +Zero, +Copy, +Drop,>( mut xs: Span, mut ys: Span ) -> T { // [Check] Inputs assert(xs.len() == ys.len(), 'Arrays must have the same len'); // [Compute] Dot product in a loop - let mut sum = Zeroable::zero(); + let mut sum = Zero::zero(); while !xs .is_empty() { let x = *xs.pop_front().unwrap(); diff --git a/src/linalg/src/kron.cairo b/src/linalg/src/kron.cairo index d9885387..d74d6d90 100644 --- a/src/linalg/src/kron.cairo +++ b/src/linalg/src/kron.cairo @@ -1,8 +1,7 @@ -use core::array::SpanTrait; //! Kronecker product of two arrays #[derive(Drop, Copy, PartialEq)] -enum KronError { +pub enum KronError { UnequalLength, } @@ -12,7 +11,7 @@ enum KronError { /// * `ys` - The second sequence of len L. /// # Returns /// * `Result, KronError>` - The Kronecker product. -fn kron, +AddEq, +Zeroable, +Copy, +Drop,>( +pub fn kron, +Copy, +Drop,>( mut xs: Span, mut ys: Span ) -> Result, KronError> { // [Check] Inputs diff --git a/src/linalg/src/lib.cairo b/src/linalg/src/lib.cairo index e8cafce1..2387a899 100644 --- a/src/linalg/src/lib.cairo +++ b/src/linalg/src/lib.cairo @@ -1,6 +1,6 @@ -mod dot; -mod kron; -mod norm; +pub mod dot; +pub mod kron; +pub mod norm; #[cfg(test)] mod tests; diff --git a/src/linalg/src/norm.cairo b/src/linalg/src/norm.cairo index 68b00eae..6401347d 100644 --- a/src/linalg/src/norm.cairo +++ b/src/linalg/src/norm.cairo @@ -1,6 +1,7 @@ //! Norm of an T array. use alexandria_math::fast_root::fast_nr_optimize; use alexandria_math::pow; +use core::num::traits::Zero; /// Compute the norm for an T array. /// # Arguments @@ -9,7 +10,7 @@ use alexandria_math::pow; /// * `iter` - The number of iterations to run the algorithm /// # Returns /// * `u128` - The norm for the array. -fn norm, +Zeroable, +Copy>( +pub fn norm, +Zero, +Copy, +Drop>( mut xs: Span, ord: u128, iter: usize ) -> u128 { let mut norm: u128 = 0; diff --git a/src/math/Scarb.toml b/src/math/Scarb.toml index 24e03a68..7c948d99 100644 --- a/src/math/Scarb.toml +++ b/src/math/Scarb.toml @@ -3,6 +3,7 @@ name = "alexandria_math" version = "0.2.0" description = "A set of math libraries and algorithms" homepage = "https://github.com/keep-starknet-strange/alexandria/tree/main/src/math" +edition = "2023_11" [tool] fmt.workspace = true diff --git a/src/math/src/aliquot_sum.cairo b/src/math/src/aliquot_sum.cairo index 938a4a03..d7bdd31d 100644 --- a/src/math/src/aliquot_sum.cairo +++ b/src/math/src/aliquot_sum.cairo @@ -5,7 +5,7 @@ /// * `number` - The number to calculate the aliquot sum for. /// # Returns /// * `felt252` - The aliquot sum of the input number. -fn aliquot_sum(number: u128) -> u128 { +pub fn aliquot_sum(number: u128) -> u128 { if number == 0 { return 0; } diff --git a/src/math/src/armstrong_number.cairo b/src/math/src/armstrong_number.cairo index 0eae7df5..9d25314e 100644 --- a/src/math/src/armstrong_number.cairo +++ b/src/math/src/armstrong_number.cairo @@ -6,7 +6,7 @@ use super::{count_digits_of_base, pow}; /// * `num` - The number to be evaluated. /// # Returns /// * `bool` - A boolean value indicating is Armstrong Number. -fn is_armstrong_number(mut num: u128) -> bool { +pub fn is_armstrong_number(mut num: u128) -> bool { let mut original_num = num; let digits = count_digits_of_base(num, 10); loop { diff --git a/src/math/src/collatz_sequence.cairo b/src/math/src/collatz_sequence.cairo index 659a202b..583fa2eb 100644 --- a/src/math/src/collatz_sequence.cairo +++ b/src/math/src/collatz_sequence.cairo @@ -5,7 +5,7 @@ /// * `number` - The number to generate the Collatz sequence for. /// # Returns /// * `Array` - The Collatz sequence as an array of `felt252` numbers. -fn sequence(mut number: u128) -> Array { +pub fn sequence(mut number: u128) -> Array { let mut arr = array![]; if number == 0 { return arr; diff --git a/src/math/src/ed25519.cairo b/src/math/src/ed25519.cairo index c2539bd1..9534deaf 100644 --- a/src/math/src/ed25519.cairo +++ b/src/math/src/ed25519.cairo @@ -1,16 +1,15 @@ -use alexandria_data_structures::array_ext::{ArrayTraitExt, SpanTraitExt}; +use alexandria_data_structures::array_ext::SpanTraitExt; use alexandria_math::mod_arithmetics::{ add_mod, sub_mod, mult_mod, div_mod, pow_mod, add_inverse_mod, equality_mod }; use alexandria_math::sha512::{sha512, SHA512_LEN}; -use core::array::SpanTrait; -use core::box::BoxTrait; -use integer::u512; +use core::integer::u512; +use core::traits::TryInto; // As per RFC-8032: https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.7 // Variable namings in this function refer to naming in the RFC -const p: u256 = +pub const p: u256 = 57896044618658097711785492504343953926634992332820282019728792003956564819949; // 2^255 - 19 const d: u256 = 37095705934669439343138083508754565189542113879843219016388785533085940283555; // d of Edwards255519, i.e. -121665/121666 @@ -18,23 +17,24 @@ const l: u256 = 7237005577332262213973186563042994240857116359379907606001950938285454250989; // 2^252 + 27742317777372353535851937790883648493 const TWO_POW_8: u256 = 0x100; +const TWO_POW_8_NON_ZERO: NonZero = 0x100; #[derive(Drop, Copy)] -struct Point { +pub struct Point { x: u256, y: u256 } #[derive(Drop, Copy)] -struct ExtendedHomogeneousPoint { +pub struct ExtendedHomogeneousPoint { X: u256, Y: u256, Z: u256, T: u256, } -trait PointDoubling { +pub trait PointDoubling { fn double(self: T) -> T; } @@ -153,13 +153,10 @@ impl U256IntoSpanU8 of Into> { fn into(self: u256) -> Span { let mut ret = array![]; let mut remaining_value = self; - let two_pow_8_non_zero = TWO_POW_8.try_into().unwrap(); let mut i: u8 = 0; while (i < 32) { - let (temp_remaining, byte) = integer::U256DivRem::div_rem( - remaining_value, two_pow_8_non_zero - ); + let (temp_remaining, byte) = DivRem::div_rem(remaining_value, TWO_POW_8_NON_ZERO); ret.append(byte.try_into().unwrap()); remaining_value = temp_remaining; i += 1; @@ -290,7 +287,7 @@ fn check_group_equation( lhs == rhs } -fn verify_signature(msg: Span, signature: Span, pub_key: u256) -> bool { +pub fn verify_signature(msg: Span, signature: Span, pub_key: u256) -> bool { if (signature.len() != 2) { return false; } @@ -325,13 +322,13 @@ fn verify_signature(msg: Span, signature: Span, pub_key: u256) -> bool let pub_key_bytes: Span = pub_key.into(); let pub_key_bytes = pub_key_bytes.reverse().span(); - let hashable = r_bytes.snapshot.concat(pub_key_bytes.snapshot).concat(msg.snapshot); + let hashable = r_bytes.concat(pub_key_bytes).span().concat(msg); // k = SHA512(dom2(F, C) -> empty string || R -> half of sig || A -> pub_key || PH(M) -> identity function for msg) let k: Array = sha512(hashable); let k_u512: u512 = k.span().into(); - let l_non_zero: NonZero = integer::u256_try_as_non_zero(l).unwrap(); - let (_, k_reduced) = integer::u512_safe_div_rem_by_u256(k_u512, l_non_zero); + let l_non_zero: NonZero = l.try_into().unwrap(); + let (_, k_reduced) = core::integer::u512_safe_div_rem_by_u256(k_u512, l_non_zero); check_group_equation(s, R_extended, k_reduced, A_prime_ex) } diff --git a/src/math/src/extended_euclidean_algorithm.cairo b/src/math/src/extended_euclidean_algorithm.cairo index b11214d1..43672931 100644 --- a/src/math/src/extended_euclidean_algorithm.cairo +++ b/src/math/src/extended_euclidean_algorithm.cairo @@ -1,5 +1,5 @@ //! # Extended Euclidean Algorithm. -use integer::{u128_overflowing_sub, u128_overflowing_mul}; +use core::integer::{u128_overflowing_sub, u128_overflowing_mul, u128_wrapping_sub}; /// Extended Euclidean Algorithm. /// # Arguments @@ -9,7 +9,7 @@ use integer::{u128_overflowing_sub, u128_overflowing_mul}; /// * `gcd` - Greatest common divisor. /// * `x` - First Bezout coefficient. /// * `y` - Second Bezout coefficient. -fn extended_euclidean_algorithm(a: u128, b: u128) -> (u128, u128, u128) { +pub fn extended_euclidean_algorithm(a: u128, b: u128) -> (u128, u128, u128) { // Initialize variables. let mut old_r = a; let mut rem = b; @@ -36,9 +36,3 @@ fn update_step(ref a: u128, ref old_a: u128, quotient: u128) { old_a = temp; } -fn u128_wrapping_sub(a: u128, b: u128) -> u128 implicits(RangeCheck) nopanic { - match u128_overflowing_sub(a, b) { - Result::Ok(x) => x, - Result::Err(x) => x, - } -} diff --git a/src/math/src/fast_power.cairo b/src/math/src/fast_power.cairo index 7a851b49..467734d8 100644 --- a/src/math/src/fast_power.cairo +++ b/src/math/src/fast_power.cairo @@ -7,11 +7,8 @@ // * ` modulus ` - The modulus used in the calculation # Returns // * ` u128 ` - The result of ( base ^ power ) mod modulus -fn fast_power(base: u128, mut power: u128, modulus: u128) -> u128 { - // Return invalid input error - if base == 0 { - panic_with_felt252('II') - } +pub fn fast_power(base: u128, mut power: u128, modulus: u128) -> u128 { + assert!(base != 0, "fast_power: invalid input"); if modulus == 1 { return 0; diff --git a/src/math/src/fast_root.cairo b/src/math/src/fast_root.cairo index 9d7ba763..689068ba 100644 --- a/src/math/src/fast_root.cairo +++ b/src/math/src/fast_root.cairo @@ -9,7 +9,7 @@ use super::pow; /// * ` iter ` - The number of iterations to run the algorithm /// # Returns /// * ` u128 ` - The root of x with rounding. (e.g., sqrt(5) = 2.24 -> 2, sqrt(7) = 2.65 -> 3) -fn fast_nr_optimize(x: u128, r: u128, iter: usize) -> u128 { +pub fn fast_nr_optimize(x: u128, r: u128, iter: usize) -> u128 { if x == 0 { return 0; } @@ -36,7 +36,7 @@ fn fast_nr_optimize(x: u128, r: u128, iter: usize) -> u128 { /// * ` iter ` - The number of iterations to run the algorithm /// # Returns /// * ` u128 ` - The sqrt of x with rounding (e.g., sqrt(5) = 2.24 -> 2, sqrt(7) = 2.65 -> 3) -fn fast_sqrt(x: u128, iter: usize) -> u128 { +pub fn fast_sqrt(x: u128, iter: usize) -> u128 { fast_nr_optimize(x, 2, iter) } @@ -46,7 +46,7 @@ fn fast_sqrt(x: u128, iter: usize) -> u128 { /// * ` iter ` - The number of iterations to run the algorithm /// # Returns /// * ` u128 ` - The cubic root of x with rounding (e.g., cbrt(4) = 1.59 -> 2, cbrt(5) = 1.71 -> 2) -fn fast_cbrt(x: u128, iter: usize) -> u128 { +pub fn fast_cbrt(x: u128, iter: usize) -> u128 { fast_nr_optimize(x, 3, iter) } @@ -56,7 +56,7 @@ fn fast_cbrt(x: u128, iter: usize) -> u128 { /// * ` b ` - The divisor /// # Returns /// * ` u128 ` - The result of the division with rounding (e.g., 5/3 = 2, 7/3 = 2, 8/3 = 3) -fn round_div(a: u128, b: u128) -> u128 { +pub fn round_div(a: u128, b: u128) -> u128 { let remained = a % b; if b - remained <= remained { return a / b + 1; diff --git a/src/math/src/fibonacci.cairo b/src/math/src/fibonacci.cairo index acdef5f1..8fedfffe 100644 --- a/src/math/src/fibonacci.cairo +++ b/src/math/src/fibonacci.cairo @@ -5,7 +5,7 @@ // * `n` - The number of times to iterate // # Returns // * `felt252` - The nth number in the sequence -fn fib(a: felt252, b: felt252, n: felt252) -> felt252 { +pub fn fib(a: felt252, b: felt252, n: felt252) -> felt252 { match n { 0 => a, _ => fib(b, a + b, n - 1), diff --git a/src/math/src/gcd_of_n_numbers.cairo b/src/math/src/gcd_of_n_numbers.cairo index 4ce76a42..0efc779e 100644 --- a/src/math/src/gcd_of_n_numbers.cairo +++ b/src/math/src/gcd_of_n_numbers.cairo @@ -5,11 +5,10 @@ // * `n` - The array of numbers to calculate the gcd for // # Returns // * `felt252` - The gcd of input numbers -fn gcd(mut n: Span) -> u128 { +pub fn gcd(mut n: Span) -> u128 { // Return empty input error - if n.is_empty() { - panic_with_felt252('EI') - } + assert!(!n.is_empty(), "gcd-empty"); + let mut a = *n.pop_front().unwrap(); while let Option::Some(b) = n.pop_front() { a = gcd_two_numbers(a, *b); @@ -23,7 +22,7 @@ fn gcd(mut n: Span) -> u128 { // * `b` - The first number for which to calculate the gcd // # Returns // * `felt252` - The gcd of a and b -fn gcd_two_numbers(mut a: u128, mut b: u128) -> u128 { +pub fn gcd_two_numbers(mut a: u128, mut b: u128) -> u128 { while b != 0 { let r = a % b; a = b; diff --git a/src/math/src/i257.cairo b/src/math/src/i257.cairo index 0788e213..0304f5ae 100644 --- a/src/math/src/i257.cairo +++ b/src/math/src/i257.cairo @@ -1,27 +1,38 @@ -use core::zeroable::Zeroable; +use core::num::traits::Zero; // ====================== INT 257 ====================== // i257 represents a 129-bit integer. // The abs field holds the absolute value of the integer. // The is_negative field is true for negative integers, and false for non-negative integers. #[derive(Serde, Copy, Drop, Hash)] -struct i257 { +pub struct i257 { abs: u256, is_negative: bool, } -#[inline(always)] -fn i257_new(abs: u256, is_negative: bool) -> i257 { - if abs == 0 { - i257 { abs, is_negative: false } - } else { - i257 { abs, is_negative } +#[generate_trait] +pub impl I257Impl of I257Trait { + #[inline(always)] + fn new(abs: u256, is_negative: bool) -> i257 { + if abs == 0 { + i257 { abs, is_negative: false } + } else { + i257 { abs, is_negative } + } + } + + fn is_negative(self: i257) -> bool { + self.is_negative + } + + fn abs(self: i257) -> u256 { + self.abs } } impl I128Default of Default { fn default() -> i257 { - Zeroable::zero() + Zero::zero() } } @@ -33,8 +44,8 @@ impl i257Add of Add { // If both integers have the same sign, // the sum of their absolute values can be returned. if lhs.is_negative == rhs.is_negative { - let sum = integer::u256_checked_add(lhs.abs, rhs.abs).expect('i257_add Overflow'); - i257_new(sum, lhs.is_negative) + let sum = lhs.abs + rhs.abs; + I257Impl::new(sum, lhs.is_negative) } else { // If the integers have different signs, // the larger absolute value is subtracted from the smaller one. @@ -44,7 +55,7 @@ impl i257Add of Add { (rhs, lhs) }; let difference = larger.abs - smaller.abs; - i257_new(difference, larger.is_negative) + I257Impl::new(difference, larger.is_negative) } } } @@ -68,7 +79,7 @@ impl i257Sub of Sub { } // The subtraction of `lhs` to `rhs` is achieved by negating `rhs` sign and adding it to `lhs`. - let neg_b = i257_new(rhs.abs, !rhs.is_negative); + let neg_b = I257Impl::new(rhs.abs, !rhs.is_negative); lhs + neg_b } } @@ -90,8 +101,8 @@ impl i257Mul of Mul { // The sign of the product is the XOR of the signs of the operands. let is_negative = lhs.is_negative ^ rhs.is_negative; // The product is the product of the absolute values of the operands. - let abs = integer::u256_checked_mul(lhs.abs, rhs.abs).expect('i257_mul Overflow'); - i257_new(abs, is_negative) + let abs = lhs.abs * rhs.abs; + I257Impl::new(abs, is_negative) } } @@ -119,13 +130,13 @@ fn i257_div(lhs: i257, rhs: i257) -> i257 { if !is_negative { // If the operands are positive, the quotient is simply their absolute value quotient. - return i257_new(lhs.abs / rhs.abs, is_negative); + return I257Impl::new(lhs.abs / rhs.abs, is_negative); } // If the operands have different signs, rounding is necessary. // First, check if the quotient is an integer. if lhs.abs % rhs.abs == 0 { - return i257_new(lhs.abs / rhs.abs, is_negative); + return I257Impl::new(lhs.abs / rhs.abs, is_negative); } // If the quotient is not an integer, multiply the dividend by 10 to move the decimal point over. @@ -134,9 +145,9 @@ fn i257_div(lhs: i257, rhs: i257) -> i257 { // Check the last digit to determine rounding direction. if last_digit <= 5 { - i257_new(quotient / 10, is_negative) + I257Impl::new(quotient / 10, is_negative) } else { - i257_new((quotient / 10) + 1, is_negative) + I257Impl::new((quotient / 10) + 1, is_negative) } } @@ -189,7 +200,7 @@ impl i257RemEq of RemEq { // * `rhs` - The i257 divisor. // # Returns // * `(i257, i257)` - A tuple containing the quotient and the remainder of dividing `lhs` by `rhs`. -fn i257_div_rem(lhs: i257, rhs: i257) -> (i257, i257) { +pub fn i257_div_rem(lhs: i257, rhs: i257) -> (i257, i257) { let quotient = i257_div(lhs, rhs); let remainder = i257_rem(lhs, rhs); (quotient, remainder) @@ -255,15 +266,15 @@ impl i257Neg of Neg { } } -impl i257Zeroable of Zeroable { +impl i257Zeroable of Zero { fn zero() -> i257 { - i257_new(0, false) + I257Impl::new(0, false) } - fn is_zero(self: i257) -> bool { - assert(!self.is_negative, 'no negative zero'); - self.abs == 0 + fn is_zero(self: @i257) -> bool { + assert(!*self.is_negative, 'no negative zero'); + *self.abs == 0 } - fn is_non_zero(self: i257) -> bool { + fn is_non_zero(self: @i257) -> bool { !self.is_zero() } } @@ -273,7 +284,7 @@ impl i257Zeroable of Zeroable { // * `x` - The i257 integer to check. // # Panics // Panics if `x` is zero and is negative -fn i257_assert_no_negative_zero(x: i257) { +pub fn i257_assert_no_negative_zero(x: i257) { if x.abs == 0 { assert(!x.is_negative, 'negative zero'); } @@ -304,7 +315,7 @@ fn i257_max(lhs: i257, rhs: i257) -> i257 { fn i257_neg(x: i257) -> i257 { // The negation of an integer is obtained by flipping its is_negative. - i257_new(x.abs, !x.is_negative) + I257Impl::new(x.abs, !x.is_negative) } // Computes the minimum between two i257 integers. diff --git a/src/math/src/is_power_of_two.cairo b/src/math/src/is_power_of_two.cairo index 99de9563..2e5b3033 100644 --- a/src/math/src/is_power_of_two.cairo +++ b/src/math/src/is_power_of_two.cairo @@ -3,7 +3,7 @@ /// * `n` - The given number /// # Returns /// * `bool` - if the given number is power of 2 -fn is_power_of_two(n: u128) -> bool { +pub fn is_power_of_two(n: u128) -> bool { if n == 0 { return false; } diff --git a/src/math/src/is_prime.cairo b/src/math/src/is_prime.cairo index 7e7ab8d3..29f975c3 100644 --- a/src/math/src/is_prime.cairo +++ b/src/math/src/is_prime.cairo @@ -6,7 +6,7 @@ use alexandria_math::fast_root::fast_sqrt; /// * `iter` - The number of iterations to run when sqrting the number, the higher the more accurate (usually 10 is enough) /// # Returns /// * `bool` - if the given number is prime -fn is_prime(n: u128, iter: usize) -> bool { +pub fn is_prime(n: u128, iter: usize) -> bool { if n <= 1 { return false; } diff --git a/src/math/src/karatsuba.cairo b/src/math/src/karatsuba.cairo index a76057a7..a35a05c1 100644 --- a/src/math/src/karatsuba.cairo +++ b/src/math/src/karatsuba.cairo @@ -1,5 +1,5 @@ //! # Karatsuba Multiplication. -use cmp::max; +use core::cmp::max; use super::{pow, count_digits_of_base}; /// Algorithm to multiply two numbers in O(n^1.6) running time @@ -8,7 +8,7 @@ use super::{pow, count_digits_of_base}; /// * `y` - Second number to multiply. /// # Returns /// * `u128` - The product between x and y -fn multiply(x: u128, y: u128) -> u128 { +pub fn multiply(x: u128, y: u128) -> u128 { if x < 10 { return x * y; } diff --git a/src/math/src/keccak256.cairo b/src/math/src/keccak256.cairo index a1c9d15b..0ce54e66 100644 --- a/src/math/src/keccak256.cairo +++ b/src/math/src/keccak256.cairo @@ -1,3 +1,4 @@ +use core::integer::u128_byte_reverse; use keccak::cairo_keccak; #[generate_trait] @@ -29,8 +30,8 @@ impl U64Impl of U64Trait { /// Reverse the endianness of an u256 fn reverse_endianness(value: u256) -> u256 { - let new_low = integer::u128_byte_reverse(value.high); - let new_high = integer::u128_byte_reverse(value.low); + let new_low = u128_byte_reverse(value.high); + let new_high = u128_byte_reverse(value.low); u256 { low: new_low, high: new_high } } @@ -43,7 +44,7 @@ fn reverse_endianness(value: u256) -> u256 { /// # Returns /// /// A `u256` value representing the Keccak hash of the input bytes array. -fn keccak256(mut self: Span) -> u256 { +pub fn keccak256(mut self: Span) -> u256 { // Converts byte array to little endian 8 byte words array. let mut words64: Array = Default::default(); while self diff --git a/src/math/src/lcm_of_n_numbers.cairo b/src/math/src/lcm_of_n_numbers.cairo index 612a7cd0..e7c69b2c 100644 --- a/src/math/src/lcm_of_n_numbers.cairo +++ b/src/math/src/lcm_of_n_numbers.cairo @@ -2,7 +2,7 @@ use alexandria_math::gcd_of_n_numbers::gcd_two_numbers; #[derive(Drop, Copy, PartialEq)] -enum LCMError { +pub enum LCMError { EmptyInput, } @@ -11,7 +11,7 @@ enum LCMError { /// * `n` - The array of numbers to calculate the lcm for /// # Returns /// * `Result` - The lcm of input numbers -fn lcm, +Into, +Mul, +Div, +Copy, +Drop>( +pub fn lcm, +Into, +Mul, +Div, +Copy, +Drop>( mut n: Span ) -> Result { // Return empty input error diff --git a/src/math/src/lib.cairo b/src/math/src/lib.cairo index 8487e93f..ae087472 100644 --- a/src/math/src/lib.cairo +++ b/src/math/src/lib.cairo @@ -1,29 +1,31 @@ -mod aliquot_sum; -mod armstrong_number; -mod collatz_sequence; -mod ed25519; -mod extended_euclidean_algorithm; -mod fast_power; -mod fast_root; -mod fibonacci; -mod gcd_of_n_numbers; -mod i257; -mod is_power_of_two; -mod is_prime; -mod karatsuba; -mod keccak256; -mod lcm_of_n_numbers; -mod mod_arithmetics; -mod perfect_number; -mod sha256; -mod sha512; +pub mod aliquot_sum; +pub mod armstrong_number; +pub mod collatz_sequence; +pub mod ed25519; +pub mod extended_euclidean_algorithm; +pub mod fast_power; +pub mod fast_root; +pub mod fibonacci; +pub mod gcd_of_n_numbers; +pub mod i257; +pub mod is_power_of_two; +pub mod is_prime; +pub mod karatsuba; +pub mod keccak256; +pub mod lcm_of_n_numbers; +pub mod mod_arithmetics; +pub mod perfect_number; +pub mod sha256; +pub mod sha512; #[cfg(test)] mod tests; -mod trigonometry; -mod wad_ray_math; -mod zellers_congruence; -use integer::{ +pub mod trigonometry; +pub mod wad_ray_math; +pub mod zellers_congruence; + + +use core::integer::{ u8_wide_mul, u16_wide_mul, u32_wide_mul, u64_wide_mul, u128_wide_mul, u256_overflow_mul, u8_wrapping_add, u16_wrapping_add, u32_wrapping_add, u64_wrapping_add, u128_wrapping_add, u256_overflowing_add, u8_wrapping_sub, u16_wrapping_sub, u32_wrapping_sub, u64_wrapping_sub, @@ -36,7 +38,7 @@ use integer::{ /// * `exp` - The exponent. /// # Returns /// * `T` - The result of base raised to the power of exp. -fn pow, +Mul, +Div, +Rem, +PartialEq, +Into, +Drop, +Copy>( +pub fn pow, +Mul, +Div, +Rem, +PartialEq, +Into, +Drop, +Copy>( base: T, exp: T ) -> T { if exp == 0_u8.into() { @@ -65,12 +67,12 @@ fn count_digits_of_base(mut num: u128, base: u128) -> u128 { res } -trait BitShift { +pub trait BitShift { fn shl(x: T, n: T) -> T; fn shr(x: T, n: T) -> T; } -impl U8BitShift of BitShift { +pub impl U8BitShift of BitShift { fn shl(x: u8, n: u8) -> u8 { (u8_wide_mul(x, pow(2, n)) & BoundedInt::::max().into()).try_into().unwrap() } @@ -80,7 +82,7 @@ impl U8BitShift of BitShift { } } -impl U16BitShift of BitShift { +pub impl U16BitShift of BitShift { fn shl(x: u16, n: u16) -> u16 { (u16_wide_mul(x, pow(2, n)) & BoundedInt::::max().into()).try_into().unwrap() } @@ -90,7 +92,7 @@ impl U16BitShift of BitShift { } } -impl U32BitShift of BitShift { +pub impl U32BitShift of BitShift { fn shl(x: u32, n: u32) -> u32 { (u32_wide_mul(x, pow(2, n)) & BoundedInt::::max().into()).try_into().unwrap() } @@ -100,7 +102,7 @@ impl U32BitShift of BitShift { } } -impl U64BitShift of BitShift { +pub impl U64BitShift of BitShift { fn shl(x: u64, n: u64) -> u64 { (u64_wide_mul(x, pow(2, n)) & BoundedInt::::max().into()).try_into().unwrap() } @@ -110,7 +112,7 @@ impl U64BitShift of BitShift { } } -impl U128BitShift of BitShift { +pub impl U128BitShift of BitShift { fn shl(x: u128, n: u128) -> u128 { let (_, bottom_word) = u128_wide_mul(x, pow(2, n)); bottom_word @@ -121,7 +123,7 @@ impl U128BitShift of BitShift { } } -impl U256BitShift of BitShift { +pub impl U256BitShift of BitShift { fn shl(x: u256, n: u256) -> u256 { let (r, _) = u256_overflow_mul(x, pow(2, n)); r @@ -150,7 +152,7 @@ trait BitRotate { fn rotate_right(x: T, n: T) -> T; } -impl U8BitRotate of BitRotate { +pub impl U8BitRotate of BitRotate { fn rotate_left(x: u8, n: u8) -> u8 { let word = u8_wide_mul(x, pow(2, n)); let (quotient, remainder) = DivRem::div_rem(word, 0x100_u16.try_into().unwrap()); @@ -164,7 +166,7 @@ impl U8BitRotate of BitRotate { } } -impl U16BitRotate of BitRotate { +pub impl U16BitRotate of BitRotate { fn rotate_left(x: u16, n: u16) -> u16 { let word = u16_wide_mul(x, pow(2, n)); let (quotient, remainder) = DivRem::div_rem(word, 0x10000_u32.try_into().unwrap()); @@ -178,7 +180,7 @@ impl U16BitRotate of BitRotate { } } -impl U32BitRotate of BitRotate { +pub impl U32BitRotate of BitRotate { fn rotate_left(x: u32, n: u32) -> u32 { let word = u32_wide_mul(x, pow(2, n)); let (quotient, remainder) = DivRem::div_rem(word, 0x100000000_u64.try_into().unwrap()); @@ -192,7 +194,7 @@ impl U32BitRotate of BitRotate { } } -impl U64BitRotate of BitRotate { +pub impl U64BitRotate of BitRotate { fn rotate_left(x: u64, n: u64) -> u64 { let word = u64_wide_mul(x, pow(2, n)); let (quotient, remainder) = DivRem::div_rem( @@ -208,7 +210,7 @@ impl U64BitRotate of BitRotate { } } -impl U128BitRotate of BitRotate { +pub impl U128BitRotate of BitRotate { fn rotate_left(x: u128, n: u128) -> u128 { let (high, low) = u128_wide_mul(x, pow(2, n)); let word = u256 { low, high }; @@ -225,7 +227,7 @@ impl U128BitRotate of BitRotate { } } -impl U256BitRotate of BitRotate { +pub impl U256BitRotate of BitRotate { fn rotate_left(x: u256, n: u256) -> u256 { // Alternative solution since we cannot divide u512 yet BitShift::shl(x, n) + BitShift::shr(x, 256 - n) @@ -244,7 +246,7 @@ trait WrappingMath { fn wrapping_mul(self: T, rhs: T) -> T; } -impl WrappingMathImpl, +WrappingSub, +WrappingMul> of WrappingMath { +pub impl WrappingMathImpl, +WrappingSub, +WrappingMul> of WrappingMath { #[inline(always)] fn wrapping_add(self: T, rhs: T) -> T { WrappingAdd::::wrapping_add(self, rhs) @@ -273,105 +275,105 @@ trait WrappingMul { fn wrapping_mul(self: T, rhs: T) -> T; } -impl U8WrappingAdd of WrappingAdd { +pub impl U8WrappingAdd of WrappingAdd { #[inline(always)] fn wrapping_add(self: u8, rhs: u8) -> u8 { u8_wrapping_add(self, rhs) } } -impl U8WrappingSub of WrappingSub { +pub impl U8WrappingSub of WrappingSub { #[inline(always)] fn wrapping_sub(self: u8, rhs: u8) -> u8 { u8_wrapping_sub(self, rhs) } } -impl U8WrappingMul of WrappingMul { +pub impl U8WrappingMul of WrappingMul { #[inline(always)] fn wrapping_mul(self: u8, rhs: u8) -> u8 { (u8_wide_mul(self, rhs) & BoundedInt::::max().into()).try_into().unwrap() } } -impl U16WrappingAdd of WrappingAdd { +pub impl U16WrappingAdd of WrappingAdd { #[inline(always)] fn wrapping_add(self: u16, rhs: u16) -> u16 { u16_wrapping_add(self, rhs) } } -impl U16WrappingSub of WrappingSub { +pub impl U16WrappingSub of WrappingSub { #[inline(always)] fn wrapping_sub(self: u16, rhs: u16) -> u16 { u16_wrapping_sub(self, rhs) } } -impl U16WrappingMul of WrappingMul { +pub impl U16WrappingMul of WrappingMul { #[inline(always)] fn wrapping_mul(self: u16, rhs: u16) -> u16 { (u16_wide_mul(self, rhs) & BoundedInt::::max().into()).try_into().unwrap() } } -impl U32WrappingAdd of WrappingAdd { +pub impl U32WrappingAdd of WrappingAdd { #[inline(always)] fn wrapping_add(self: u32, rhs: u32) -> u32 { u32_wrapping_add(self, rhs) } } -impl U32WrappingSub of WrappingSub { +pub impl U32WrappingSub of WrappingSub { #[inline(always)] fn wrapping_sub(self: u32, rhs: u32) -> u32 { u32_wrapping_sub(self, rhs) } } -impl U32WrappingMul of WrappingMul { +pub impl U32WrappingMul of WrappingMul { #[inline(always)] fn wrapping_mul(self: u32, rhs: u32) -> u32 { (u32_wide_mul(self, rhs) & BoundedInt::::max().into()).try_into().unwrap() } } -impl U64WrappingAdd of WrappingAdd { +pub impl U64WrappingAdd of WrappingAdd { #[inline(always)] fn wrapping_add(self: u64, rhs: u64) -> u64 { u64_wrapping_add(self, rhs) } } -impl U64WrappingSub of WrappingSub { +pub impl U64WrappingSub of WrappingSub { #[inline(always)] fn wrapping_sub(self: u64, rhs: u64) -> u64 { u64_wrapping_sub(self, rhs) } } -impl U64WrappingMul of WrappingMul { +pub impl U64WrappingMul of WrappingMul { #[inline(always)] fn wrapping_mul(self: u64, rhs: u64) -> u64 { (u64_wide_mul(self, rhs) & BoundedInt::::max().into()).try_into().unwrap() } } -impl U128WrappingAdd of WrappingAdd { +pub impl U128WrappingAdd of WrappingAdd { #[inline(always)] fn wrapping_add(self: u128, rhs: u128) -> u128 { u128_wrapping_add(self, rhs) } } -impl U128WrappingSub of WrappingSub { +pub impl U128WrappingSub of WrappingSub { #[inline(always)] fn wrapping_sub(self: u128, rhs: u128) -> u128 { u128_wrapping_sub(self, rhs) } } -impl U128WrappingMul of WrappingMul { +pub impl U128WrappingMul of WrappingMul { #[inline(always)] fn wrapping_mul(self: u128, rhs: u128) -> u128 { let (_, low) = u128_wide_mul(self, rhs); @@ -379,7 +381,7 @@ impl U128WrappingMul of WrappingMul { } } -impl U256WrappingAdd of WrappingAdd { +pub impl U256WrappingAdd of WrappingAdd { #[inline(always)] fn wrapping_add(self: u256, rhs: u256) -> u256 { let (val, _) = u256_overflowing_add(self, rhs); @@ -387,7 +389,7 @@ impl U256WrappingAdd of WrappingAdd { } } -impl U256WrappingSub of WrappingSub { +pub impl U256WrappingSub of WrappingSub { #[inline(always)] fn wrapping_sub(self: u256, rhs: u256) -> u256 { let (val, _) = u256_overflow_sub(self, rhs); @@ -395,7 +397,7 @@ impl U256WrappingSub of WrappingSub { } } -impl U256WrappingMul of WrappingMul { +pub impl U256WrappingMul of WrappingMul { #[inline(always)] fn wrapping_mul(self: u256, rhs: u256) -> u256 { let (val, _) = u256_overflow_mul(self, rhs); diff --git a/src/math/src/mod_arithmetics.cairo b/src/math/src/mod_arithmetics.cairo index cb1bfa5a..d355556c 100644 --- a/src/math/src/mod_arithmetics.cairo +++ b/src/math/src/mod_arithmetics.cairo @@ -1,4 +1,4 @@ -use integer::u512; +use core::integer::{u512, u512_safe_div_rem_by_u256, u256_wide_mul}; /// Function that performs modular addition. /// # Arguments @@ -8,15 +8,15 @@ use integer::u512; /// # Returns /// * `u256` - result of modular addition #[inline(always)] -fn add_mod(a: u256, b: u256, modulo: u256) -> u256 { - let mod_non_zero: NonZero = integer::u256_try_as_non_zero(modulo).unwrap(); +pub fn add_mod(a: u256, b: u256, modulo: u256) -> u256 { + let mod_non_zero: NonZero = modulo.try_into().unwrap(); let low: u256 = a.low.into() + b.low.into(); let high: u256 = a.high.into() + b.high.into(); let carry: u256 = low.high.into() + high.low.into(); let add_u512: u512 = u512 { limb0: low.low, limb1: carry.low, limb2: carry.high + high.high, limb3: 0 }; - let (_, res) = integer::u512_safe_div_rem_by_u256(add_u512, mod_non_zero); + let (_, res) = u512_safe_div_rem_by_u256(add_u512, mod_non_zero); res } @@ -27,11 +27,10 @@ fn add_mod(a: u256, b: u256, modulo: u256) -> u256 { /// # Returns /// * `u256` - modular multiplicative inverse #[inline(always)] -fn mult_inverse(b: u256, modulo: u256) -> u256 { - match math::u256_guarantee_inv_mod_n(b, modulo.try_into().expect('inverse non zero')) { - Result::Ok((inv_a, _, _, _, _, _, _, _, _)) => inv_a.into(), - Result::Err(_) => 0 - } +pub fn mult_inverse(b: u256, modulo: u256) -> u256 { + math::u256_inv_mod(b, modulo.try_into().expect('inverse non zero')) + .expect('inverse non zero') + .into() } /// Function that return the modular additive inverse. @@ -41,7 +40,7 @@ fn mult_inverse(b: u256, modulo: u256) -> u256 { /// # Returns /// * `u256` - modular additive inverse #[inline(always)] -fn add_inverse_mod(b: u256, modulo: u256) -> u256 { +pub fn add_inverse_mod(b: u256, modulo: u256) -> u256 { modulo - b } @@ -53,14 +52,14 @@ fn add_inverse_mod(b: u256, modulo: u256) -> u256 { /// # Returns /// * `u256` - result of modular subtraction #[inline(always)] -fn sub_mod(mut a: u256, mut b: u256, modulo: u256) -> u256 { +pub fn sub_mod(mut a: u256, mut b: u256, modulo: u256) -> u256 { // reduce values a = a % modulo; b = b % modulo; - let (diff, overflow) = integer::u256_overflow_sub(a, b); + let (diff, overflow) = core::integer::u256_overflow_sub(a, b); if overflow { // Overflow back with add modulo - let (diff, _) = integer::u256_overflowing_add(diff, modulo); + let (diff, _) = core::integer::u256_overflowing_add(diff, modulo); diff } else { diff @@ -75,10 +74,10 @@ fn sub_mod(mut a: u256, mut b: u256, modulo: u256) -> u256 { /// # Returns /// * `u256` - result of modular multiplication #[inline(always)] -fn mult_mod(a: u256, b: u256, modulo: u256) -> u256 { - let mult: u512 = integer::u256_wide_mul(a, b); - let mod_non_zero: NonZero = integer::u256_try_as_non_zero(modulo).unwrap(); - let (_, rem_u256, _, _, _, _, _) = integer::u512_safe_divmod_by_u256(mult, mod_non_zero); +pub fn mult_mod(a: u256, b: u256, modulo: u256) -> u256 { + let mult: u512 = u256_wide_mul(a, b); + let mod_non_zero: NonZero = modulo.try_into().unwrap(); + let (_, rem_u256) = u512_safe_div_rem_by_u256(mult, mod_non_zero); rem_u256 } @@ -90,7 +89,7 @@ fn mult_mod(a: u256, b: u256, modulo: u256) -> u256 { /// # Returns /// * `u256` - result of modular division #[inline(always)] -fn div_mod(a: u256, b: u256, modulo: u256) -> u256 { +pub fn div_mod(a: u256, b: u256, modulo: u256) -> u256 { let modulo_nz = modulo.try_into().expect('0 modulo'); let inv = math::u256_inv_mod(b, modulo_nz).unwrap().into(); math::u256_mul_mod_n(a, inv, modulo_nz) @@ -103,32 +102,30 @@ fn div_mod(a: u256, b: u256, modulo: u256) -> u256 { /// * `modulo` - modulo. /// # Returns /// * `u256` - result of modular exponentiation -fn pow_mod(mut base: u256, mut pow: u256, modulo: u256) -> u256 { +pub fn pow_mod(mut base: u256, mut pow: u256, modulo: u256) -> u256 { let mut result: u256 = 1; - let mod_non_zero: NonZero = integer::u256_try_as_non_zero(modulo).unwrap(); + let mod_non_zero: NonZero = modulo.try_into().unwrap(); let mut mult: u512 = u512 { limb0: 0_u128, limb1: 0_u128, limb2: 0_u128, limb3: 0_u128 }; while (pow != 0) { if ((pow & 1) > 0) { - mult = integer::u256_wide_mul(result, base); - let (_, res_u256, _, _, _, _, _) = integer::u512_safe_divmod_by_u256( - mult, mod_non_zero - ); + mult = u256_wide_mul(result, base); + let (_, res_u256,) = u512_safe_div_rem_by_u256(mult, mod_non_zero); result = res_u256; } pow = pow / 2; - mult = integer::u256_wide_mul(base, base); - let (_, base_u256, _, _, _, _, _) = integer::u512_safe_divmod_by_u256(mult, mod_non_zero); + mult = u256_wide_mul(base, base); + let (_, base_u256) = u512_safe_div_rem_by_u256(mult, mod_non_zero); base = base_u256; }; result } -fn equality_mod(a: u256, b: u256, modulo: u256) -> bool { - let (_, a_rem) = integer::U256DivRem::div_rem(a, modulo.try_into().unwrap()); - let (_, b_rem) = integer::U256DivRem::div_rem(b, modulo.try_into().unwrap()); +pub fn equality_mod(a: u256, b: u256, modulo: u256) -> bool { + let (_, a_rem) = DivRem::div_rem(a, modulo.try_into().unwrap()); + let (_, b_rem) = DivRem::div_rem(b, modulo.try_into().unwrap()); a_rem == b_rem } diff --git a/src/math/src/perfect_number.cairo b/src/math/src/perfect_number.cairo index 554aec12..fde8dcd6 100644 --- a/src/math/src/perfect_number.cairo +++ b/src/math/src/perfect_number.cairo @@ -5,7 +5,7 @@ /// * `num` - The number to be checked. /// # Returns /// * `bool` - True if num is a perfect number, false otherwise. -fn is_perfect_number(num: u128) -> bool { +pub fn is_perfect_number(num: u128) -> bool { if num == 0 { return false; } @@ -29,7 +29,7 @@ fn is_perfect_number(num: u128) -> bool { /// * `max` - The maximum value to check for perfect numbers. /// # Returns /// * `Array` - An array of perfect numbers up to the max value. -fn perfect_numbers(max: u128) -> Array { +pub fn perfect_numbers(max: u128) -> Array { let mut res = array![]; let mut index = 1; diff --git a/src/math/src/sha256.cairo b/src/math/src/sha256.cairo index a36d8ff4..90eed9d3 100644 --- a/src/math/src/sha256.cairo +++ b/src/math/src/sha256.cairo @@ -1,4 +1,4 @@ -use integer::{u32_wrapping_add, BoundedInt}; +use core::integer::{u32_wrapping_add, BoundedInt}; fn ch(x: u32, y: u32, z: u32) -> u32 { (x & y) ^ ((x ^ BoundedInt::::max().into()) & z) @@ -44,7 +44,7 @@ fn ssig1(x: u32) -> u32 { result.try_into().unwrap() } -fn sha256(mut data: Array) -> Array { +pub fn sha256(mut data: Array) -> Array { let data_len: u64 = (data.len() * 8).into(); // add one diff --git a/src/math/src/sha512.cairo b/src/math/src/sha512.cairo index d885a3f5..ddfe2f08 100644 --- a/src/math/src/sha512.cairo +++ b/src/math/src/sha512.cairo @@ -1,35 +1,36 @@ -use integer::{u64_wrapping_add, bitwise, BoundedInt}; +use core::integer::{u64_wrapping_add, BoundedInt}; +use core::traits::{BitAnd, BitXor, BitOr}; use super::BitShift; // Variable naming is compliant to RFC-6234 (https://datatracker.ietf.org/doc/html/rfc6234) -const SHA512_LEN: usize = 64; +pub const SHA512_LEN: usize = 64; -const U64_BIT_NUM: u64 = 64; +pub const U64_BIT_NUM: u64 = 64; #[derive(Drop, Copy)] -struct Word64 { - data: u64, +pub struct Word64 { + pub data: u64, } impl WordBitAnd of BitAnd { fn bitand(lhs: Word64, rhs: Word64) -> Word64 { - let (v, _, _) = bitwise(lhs.data.into(), rhs.data.into()); - Word64 { data: v.try_into().unwrap() } + let data = BitAnd::bitand(lhs.data, rhs.data); + Word64 { data } } } impl WordBitXor of BitXor { fn bitxor(lhs: Word64, rhs: Word64) -> Word64 { - let (_, v, _) = bitwise(lhs.data.into(), rhs.data.into()); - Word64 { data: v.try_into().unwrap() } + let data = BitXor::bitxor(lhs.data, rhs.data); + Word64 { data } } } impl WordBitOr of BitOr { fn bitor(lhs: Word64, rhs: Word64) -> Word64 { - let (_, _, v) = bitwise(lhs.data.into(), rhs.data.into()); - Word64 { data: v.try_into().unwrap() } + let data = BitOr::bitor(lhs.data, rhs.data); + Word64 { data } } } @@ -45,33 +46,31 @@ impl WordAdd of Add { } } -trait WordOperations { +pub trait WordOperations { fn shr(self: T, n: u64) -> T; fn shl(self: T, n: u64) -> T; fn rotr(self: T, n: u64) -> T; fn rotl(self: T, n: u64) -> T; } -impl Word64WordOperations of WordOperations { +pub impl Word64WordOperations of WordOperations { fn shr(self: Word64, n: u64) -> Word64 { - Word64 { data: math_shr_u64(self.data.into(), n.into()) } + Word64 { data: math_shr_u64(self.data, n) } } fn shl(self: Word64, n: u64) -> Word64 { - Word64 { data: math_shl_u64(self.data.into(), n.into()) } + Word64 { data: math_shl_u64(self.data, n) } } fn rotr(self: Word64, n: u64) -> Word64 { - let (_, _, or) = bitwise( - math_shr_u64(self.data.into(), n.into()).into(), - math_shl_u64(self.data.into(), (U64_BIT_NUM - n.into())).into() + let data = BitOr::bitor( + math_shr_u64(self.data, n), math_shl_u64(self.data, (U64_BIT_NUM - n)) ); - Word64 { data: or.try_into().unwrap() } + Word64 { data } } fn rotl(self: Word64, n: u64) -> Word64 { - let (_, _, or) = bitwise( - math_shl_u64(self.data.into(), n.into()).into(), - math_shr_u64(self.data.into(), (U64_BIT_NUM - n.into())).into() + let data = BitOr::bitor( + math_shl_u64(self.data, n), math_shr_u64(self.data, (U64_BIT_NUM - n)) ); - Word64 { data: or.try_into().unwrap() } + Word64 { data } } } @@ -100,11 +99,9 @@ fn ssig1(x: Word64) -> Word64 { x.rotr(19) ^ x.rotr(61) ^ x.shr(6) } -fn fpow(mut base: u128, mut power: u128) -> u128 { +pub fn fpow(mut base: u128, mut power: u128) -> u128 { // Return invalid input error - if base == 0 { - panic_with_felt252('II') - } + assert!(base != 0, "fpow: invalid input"); let mut base_u128: u256 = base.into(); let mut result: u256 = 1; @@ -269,7 +266,7 @@ fn digest_hash(data: Span, msg_len: usize) -> Array { array![h_0, h_1, h_2, h_3, h_4, h_5, h_6, h_7] } -fn sha512(mut data: Array) -> Array { +pub fn sha512(mut data: Array) -> Array { let bit_numbers: u128 = (data.len() * 8).into(); let bit_numbers = bit_numbers & BoundedInt::::max().into(); diff --git a/src/math/src/tests/aliquot_sum_test.cairo b/src/math/src/tests/aliquot_sum_test.cairo index 9ff5da22..8480607a 100644 --- a/src/math/src/tests/aliquot_sum_test.cairo +++ b/src/math/src/tests/aliquot_sum_test.cairo @@ -3,34 +3,34 @@ use alexandria_math::aliquot_sum::aliquot_sum; #[test] #[available_gas(200000)] fn zero_test() { - assert!(aliquot_sum(0) == 0, "invalid result"); + assert_eq!(aliquot_sum(0), 0, "invalid result"); } #[test] #[available_gas(200000)] fn one_test() { - assert!(aliquot_sum(1) == 0, "invalid result"); + assert_eq!(aliquot_sum(1), 0, "invalid result"); } #[test] #[available_gas(200000)] fn one_digit_number_test() { - assert!(aliquot_sum(6) == 6, "invalid result"); + assert_eq!(aliquot_sum(6), 6, "invalid result"); } #[test] #[available_gas(2000000)] fn two_digit_number_test() { - assert!(aliquot_sum(15) == 9, "invalid result"); + assert_eq!(aliquot_sum(15), 9, "invalid result"); } #[test] #[available_gas(20000000)] fn three_digit_number_test() { - assert!(aliquot_sum(343) == 57, "invalid result"); + assert_eq!(aliquot_sum(343), 57, "invalid result"); } #[test] #[available_gas(2000000)] fn two_digit_prime_number_test() { - assert!(aliquot_sum(17) == 1, "invalid result"); + assert_eq!(aliquot_sum(17), 1, "invalid result"); } diff --git a/src/math/src/tests/extended_euclidean_algorithm_test.cairo b/src/math/src/tests/extended_euclidean_algorithm_test.cairo index 17428bc6..7bffcecb 100644 --- a/src/math/src/tests/extended_euclidean_algorithm_test.cairo +++ b/src/math/src/tests/extended_euclidean_algorithm_test.cairo @@ -1,15 +1,14 @@ -use alexandria_math::extended_euclidean_algorithm::{ - extended_euclidean_algorithm, u128_wrapping_sub -}; +use alexandria_math::extended_euclidean_algorithm::{extended_euclidean_algorithm,}; +use core::integer::u128_wrapping_sub; // Define a test case function to avoid code duplication. fn test_case(a: u128, b: u128, expected: (u128, u128, u128)) { let (gcd, x, y) = extended_euclidean_algorithm(a, b); let (expected_gcd, expected_x, expected_y) = expected; - assert!(gcd == expected_gcd, "gcd is incorrect"); + assert_eq!(gcd, expected_gcd, "gcd is incorrect"); - assert!(x == expected_x, "x is incorrect"); - assert!(y == expected_y, "y is incorrect"); + assert_eq!(x, expected_x, "x is incorrect"); + assert_eq!(y, expected_y, "y is incorrect"); } #[test] diff --git a/src/math/src/tests/fibonacci_test.cairo b/src/math/src/tests/fibonacci_test.cairo index 79effb3d..03b3430a 100644 --- a/src/math/src/tests/fibonacci_test.cairo +++ b/src/math/src/tests/fibonacci_test.cairo @@ -3,6 +3,6 @@ use alexandria_math::fibonacci::fib; #[test] #[available_gas(200000)] fn fibonacci_test() { - assert!(fib(0, 1, 10) == 55, "invalid result"); - assert!(fib(2, 4, 8) == 110, "invalid result"); + assert_eq!(fib(0, 1, 10), 55, "invalid result"); + assert_eq!(fib(2, 4, 8), 110, "invalid result"); } diff --git a/src/math/src/tests/gcd_of_n_numbers_test.cairo b/src/math/src/tests/gcd_of_n_numbers_test.cairo index c928deef..43293afd 100644 --- a/src/math/src/tests/gcd_of_n_numbers_test.cairo +++ b/src/math/src/tests/gcd_of_n_numbers_test.cairo @@ -31,7 +31,7 @@ fn gcd_single_test() { #[test] #[available_gas(1000000000)] -#[should_panic(expected: ('EI',))] +#[should_panic(expected: ("gcd-empty",))] fn gcd_empty_input_test() { let mut arr = array![]; gcd(arr.span()); diff --git a/src/math/src/tests/i257_test.cairo b/src/math/src/tests/i257_test.cairo index c4537503..2d5a732a 100644 --- a/src/math/src/tests/i257_test.cairo +++ b/src/math/src/tests/i257_test.cairo @@ -1,259 +1,253 @@ -use alexandria_math::i257::{i257, i257_div_rem, i257_assert_no_negative_zero}; +use alexandria_math::i257::{i257, I257Impl, i257_div_rem, i257_assert_no_negative_zero}; +use core::num::traits::Zero; #[test] fn i257_test_add() { // Test addition of two positive integers - let a = i257 { abs: 42, is_negative: false }; - let b = i257 { abs: 13, is_negative: false }; + let a = I257Impl::new(42, false); + let b = I257Impl::new(13, false); let result = a + b; - assert_eq!(result.abs, 55, "42 + 13 = 55"); - assert!(!result.is_negative, "42 + 13 -> positive"); + assert_eq!(result.abs(), 55, "42 + 13 = 55"); + assert!(!result.is_negative(), "42 + 13 -> positive"); // Test addition of two negative integers - let a = i257 { abs: 42, is_negative: true }; - let b = i257 { abs: 13, is_negative: true }; + let a = I257Impl::new(42, true); + let b = I257Impl::new(13, true); let result = a + b; - assert_eq!(result.abs, 55, "-42 - 13 = -55"); - assert!(result.is_negative, "-42 - 13 -> negative"); + assert_eq!(result.abs(), 55, "-42 - 13 = -55"); + assert!(result.is_negative(), "-42 - 13 -> negative"); // Test addition of a positive integer and a negative integer with the same magnitude - let a = i257 { abs: 42, is_negative: false }; - let b = i257 { abs: 42, is_negative: true }; + let a = I257Impl::new(42, false); + let b = I257Impl::new(42, true); let result = a + b; - assert_eq!(result.abs, 0, "42 - 42 = 0"); - assert!(!result.is_negative, "42 - 42 -> positive"); + assert_eq!(result.abs(), 0, "42 - 42 = 0"); + assert!(!result.is_negative(), "42 - 42 -> positive"); // Test addition of a positive integer and a negative integer with different magnitudes - let a = i257 { abs: 42, is_negative: false }; - let b = i257 { abs: 13, is_negative: true }; + let a = I257Impl::new(42, false); + let b = I257Impl::new(13, true); let result = a + b; - assert_eq!(result.abs, 29, "42 - 13 = 29"); - assert!(!result.is_negative, "42 - 13 -> positive"); + assert_eq!(result.abs(), 29, "42 - 13 = 29"); + assert!(!result.is_negative(), "42 - 13 -> positive"); // Test addition of a negative integer and a positive integer with different magnitudes - let a = i257 { abs: 42, is_negative: true }; - let b = i257 { abs: 13, is_negative: false }; + let a = I257Impl::new(42, true); + let b = I257Impl::new(13, false); let result = a + b; - assert_eq!(result.abs, 29, "-42 + 13 = -29"); - assert!(result.is_negative, "-42 + 13 -> negative"); + assert_eq!(result.abs(), 29, "-42 + 13 = -29"); + assert!(result.is_negative(), "-42 + 13 -> negative"); } #[test] fn i257_test_sub() { // Test subtraction of two positive integers with larger first - let a = i257 { abs: 42, is_negative: false }; - let b = i257 { abs: 13, is_negative: false }; + let a = I257Impl::new(42, false); + let b = I257Impl::new(13, false); let result = a - b; - assert_eq!(result.abs, 29, "42 - 13 = 29"); - assert!(!result.is_negative, "42 - 13 -> positive"); + assert_eq!(result.abs(), 29, "42 - 13 = 29"); + assert!(!result.is_negative(), "42 - 13 -> positive"); // Test subtraction of two positive integers with larger second - let a = i257 { abs: 13, is_negative: false }; - let b = i257 { abs: 42, is_negative: false }; + let a = I257Impl::new(13, false); + let b = I257Impl::new(42, false); let result = a - b; - assert_eq!(result.abs, 29, "13 - 42 = -29"); - assert!(result.is_negative, "13 - 42 -> negative"); + assert_eq!(result.abs(), 29, "13 - 42 = -29"); + assert!(result.is_negative(), "13 - 42 -> negative"); // Test subtraction of two negative integers with larger first - let a = i257 { abs: 42, is_negative: true }; - let b = i257 { abs: 13, is_negative: true }; + let a = I257Impl::new(42, true); + let b = I257Impl::new(13, true); let result = a - b; - assert_eq!(result.abs, 29, "-42 - -13 = 29"); - assert!(result.is_negative, "-42 - -13 -> negative"); + assert_eq!(result.abs(), 29, "-42 - -13 = 29"); + assert!(result.is_negative(), "-42 - -13 -> negative"); // Test subtraction of two negative integers with larger second - let a = i257 { abs: 13, is_negative: true }; - let b = i257 { abs: 42, is_negative: true }; + let a = I257Impl::new(13, true); + let b = I257Impl::new(42, true); let result = a - b; - assert_eq!(result.abs, 29, "-13 - -42 = 29"); - assert!(!result.is_negative, "-13 - -42 -> positive"); + assert_eq!(result.abs(), 29, "-13 - -42 = 29"); + assert!(!result.is_negative(), "-13 - -42 -> positive"); // Test subtraction of a positive integer and a negative integer with the same magnitude - let a = i257 { abs: 42, is_negative: false }; - let b = i257 { abs: 42, is_negative: true }; + let a = I257Impl::new(42, false); + let b = I257Impl::new(42, true); let result = a - b; - assert_eq!(result.abs, 84, "42 - -42 = 84"); - assert!(!result.is_negative, "42 - -42 -> postive"); + assert_eq!(result.abs(), 84, "42 - -42 = 84"); + assert!(!result.is_negative(), "42 - -42 -> postive"); // Test subtraction of a negative integer and a positive integer with the same magnitude - let a = i257 { abs: 42, is_negative: true }; - let b = i257 { abs: 42, is_negative: false }; + let a = I257Impl::new(42, true); + let b = I257Impl::new(42, false); let result = a - b; - assert_eq!(result.abs, 84, "-42 - 42 = -84"); - assert!(result.is_negative, "-42 - 42 -> negative"); + assert_eq!(result.abs(), 84, "-42 - 42 = -84"); + assert!(result.is_negative(), "-42 - 42 -> negative"); // Test subtraction of a positive integer and a negative integer with different magnitudes - let a = i257 { abs: 100, is_negative: false }; - let b = i257 { abs: 42, is_negative: true }; + let a = I257Impl::new(100, false); + let b = I257Impl::new(42, true); let result = a - b; - assert_eq!(result.abs, 142, "100 - - 42 = 142"); - assert!(!result.is_negative, "100 - - 42 -> postive"); + assert_eq!(result.abs(), 142, "100 - - 42 = 142"); + assert!(!result.is_negative(), "100 - - 42 -> postive"); // Test subtraction of a negative integer and a positive integer with different magnitudes - let a = i257 { abs: 42, is_negative: true }; - let b = i257 { abs: 100, is_negative: false }; + let a = I257Impl::new(42, true); + let b = I257Impl::new(100, false); let result = a - b; - assert_eq!(result.abs, 142, "-42 - 100 = -142"); - assert!(result.is_negative, "-42 - 100 -> negative"); + assert_eq!(result.abs(), 142, "-42 - 100 = -142"); + assert!(result.is_negative(), "-42 - 100 -> negative"); // Test subtraction resulting in zero - let a = i257 { abs: 42, is_negative: false }; - let b = i257 { abs: 42, is_negative: false }; + let a = I257Impl::new(42, false); + let b = I257Impl::new(42, false); let result = a - b; - assert_eq!(result.abs, 0, "42 - 42 = 0"); - assert!(!result.is_negative, "42 - 42 -> positive"); + assert_eq!(result.abs(), 0, "42 - 42 = 0"); + assert!(!result.is_negative(), "42 - 42 -> positive"); } #[test] fn i257_test_mul() { // Test multiplication of positive integers - let a = i257 { abs: 10, is_negative: false }; - let b = i257 { abs: 5, is_negative: false }; + let a = I257Impl::new(10, false); + let b = I257Impl::new(5, false); let result = a * b; - assert_eq!(result.abs, 50, "10 * 5 = 50"); - assert!(!result.is_negative, "10 * 5 -> positive"); + assert_eq!(result.abs(), 50, "10 * 5 = 50"); + assert!(!result.is_negative(), "10 * 5 -> positive"); // Test multiplication of negative integers - let a = i257 { abs: 10, is_negative: true }; - let b = i257 { abs: 5, is_negative: true }; + let a = I257Impl::new(10, true); + let b = I257Impl::new(5, true); let result = a * b; - assert_eq!(result.abs, 50, "-10 * -5 = 50"); - assert!(!result.is_negative, "-10 * -5 -> positive"); + assert_eq!(result.abs(), 50, "-10 * -5 = 50"); + assert!(!result.is_negative(), "-10 * -5 -> positive"); // Test multiplication of positive and negative integers - let a = i257 { abs: 10, is_negative: false }; - let b = i257 { abs: 5, is_negative: true }; + let a = I257Impl::new(10, false); + let b = I257Impl::new(5, true); let result = a * b; - assert_eq!(result.abs, 50, "10 * -5 = -50"); - assert!(result.is_negative, "10 * -5 -> negative"); + assert_eq!(result.abs(), 50, "10 * -5 = -50"); + assert!(result.is_negative(), "10 * -5 -> negative"); // Test multiplication by zero - let a = i257 { abs: 10, is_negative: false }; - let b = i257 { abs: 0, is_negative: false }; + let a = I257Impl::new(10, false); + let b = I257Impl::new(0, false); let result = a * b; - assert_eq!(result.abs, 0, "10 * 0 = 0"); - assert!(!result.is_negative, "10 * 0 -> positive"); + assert_eq!(result.abs(), 0, "10 * 0 = 0"); + assert!(!result.is_negative(), "10 * 0 -> positive"); } #[test] fn i257_test_is_zero() { - let a = i257 { abs: 0, is_negative: false }; + let a = I257Impl::new(0, false); assert!(a.is_zero(), "should be true"); } -#[test] -#[should_panic(expected: ('no negative zero',))] -fn i257_test_is_zero_panic() { - let a = i257 { abs: 0, is_negative: true }; - let _x = a.is_zero(); -} - #[test] fn i257_test_div_no_rem() { // Test division of positive integers - let a = i257 { abs: 10, is_negative: false }; - let b = i257 { abs: 5, is_negative: false }; + let a = I257Impl::new(10, false); + let b = I257Impl::new(5, false); let result = a / b; - assert_eq!(result.abs, 2, "10 // 5 = 2"); - assert!(!result.is_negative, "10 // 5 -> positive"); + assert_eq!(result.abs(), 2, "10 // 5 = 2"); + assert!(!result.is_negative(), "10 // 5 -> positive"); // Test division of negative integers - let a = i257 { abs: 10, is_negative: true }; - let b = i257 { abs: 5, is_negative: true }; + let a = I257Impl::new(10, true); + let b = I257Impl::new(5, true); let result = a / b; - assert_eq!(result.abs, 2, "-10 // -5 = 2"); - assert!(!result.is_negative, "-10 // -5 -> positive"); + assert_eq!(result.abs(), 2, "-10 // -5 = 2"); + assert!(!result.is_negative(), "-10 // -5 -> positive"); // Test division of positive and negative integers - let a = i257 { abs: 10, is_negative: false }; - let b = i257 { abs: 5, is_negative: true }; + let a = I257Impl::new(10, false); + let b = I257Impl::new(5, true); let result = a / b; - assert_eq!(result.abs, 2, "10 // -5 = -2"); - assert!(result.is_negative, "10 // -5 -> negative"); + assert_eq!(result.abs(), 2, "10 // -5 = -2"); + assert!(result.is_negative(), "10 // -5 -> negative"); // Test division with a = zero - let a = i257 { abs: 0, is_negative: false }; - let b = i257 { abs: 10, is_negative: false }; + let a = I257Impl::new(0, false); + let b = I257Impl::new(10, false); let result = a / b; - assert_eq!(result.abs, 0, "0 // 10 = 0"); - assert!(!result.is_negative, "0 // 10 -> positive"); + assert_eq!(result.abs(), 0, "0 // 10 = 0"); + assert!(!result.is_negative(), "0 // 10 -> positive"); // Test division with a = zero - let a = i257 { abs: 0, is_negative: false }; - let b = i257 { abs: 10, is_negative: false }; + let a = I257Impl::new(0, false); + let b = I257Impl::new(10, false); let result = a / b; - assert_eq!(result.abs, 0, "0 // 10 = 0"); - assert!(!result.is_negative, "0 // 10 -> positive"); + assert_eq!(result.abs(), 0, "0 // 10 = 0"); + assert!(!result.is_negative(), "0 // 10 -> positive"); } #[test] fn i257_test_div_rem() { // Test division and remainder of positive integers - let a = i257 { abs: 13, is_negative: false }; - let b = i257 { abs: 5, is_negative: false }; + let a = I257Impl::new(13, false); + let b = I257Impl::new(5, false); let (q, r) = i257_div_rem(a, b); - assert!(q.abs == 2 && r.abs == 3, "13 // 5 = 2 r 3"); - assert!(!q.is_negative && !r.is_negative, "13 // 5 -> positive"); + assert!(q.abs() == 2 && r.abs() == 3, "13 // 5 = 2 r 3"); + assert!(!q.is_negative() && !r.is_negative(), "13 // 5 -> positive"); // Test division and remainder of negative integers - let a = i257 { abs: 13, is_negative: true }; - let b = i257 { abs: 5, is_negative: true }; + let a = I257Impl::new(13, true); + let b = I257Impl::new(5, true); let (q, r) = i257_div_rem(a, b); - assert!(q.abs == 2 && r.abs == 3, "-13 // -5 = 2 r -3"); - assert!(!q.is_negative && r.is_negative, "-13 // -5 -> positive"); + assert!(q.abs() == 2 && r.abs() == 3, "-13 // -5 = 2 r -3"); + assert!(!q.is_negative() && r.is_negative(), "-13 // -5 -> positive"); // Test division and remainder of positive and negative integers - let a = i257 { abs: 13, is_negative: false }; - let b = i257 { abs: 5, is_negative: true }; + let a = I257Impl::new(13, false); + let b = I257Impl::new(5, true); let (q, r) = i257_div_rem(a, b); - assert!(q.abs == 3 && r.abs == 2, "13 // -5 = -3 r -2"); - assert!(q.is_negative && r.is_negative, "13 // -5 -> negative"); + assert!(q.abs() == 3 && r.abs() == 2, "13 // -5 = -3 r -2"); + assert!(q.is_negative() && r.is_negative(), "13 // -5 -> negative"); // Test division with a = zero - let a = i257 { abs: 0, is_negative: false }; - let b = i257 { abs: 10, is_negative: false }; + let a = I257Impl::new(0, false); + let b = I257Impl::new(10, false); let (q, r) = i257_div_rem(a, b); - assert!(q.abs == 0 && r.abs == 0, "0 // 10 = 0 r 0"); - assert!(!q.is_negative && !r.is_negative, "0 // 10 -> positive"); + assert!(q.abs() == 0 && r.abs() == 0, "0 // 10 = 0 r 0"); + assert!(!q.is_negative() && !r.is_negative(), "0 // 10 -> positive"); // Test division and remainder with a negative dividend and positive divisor - let a = i257 { abs: 13, is_negative: true }; - let b = i257 { abs: 5, is_negative: false }; + let a = I257Impl::new(13, true); + let b = I257Impl::new(5, false); let (q, r) = i257_div_rem(a, b); - assert!(q.abs == 3 && r.abs == 2, "-13 // 5 = -3 r 2"); - assert!(q.is_negative && !r.is_negative, "-13 // 5 -> negative"); + assert!(q.abs() == 3 && r.abs() == 2, "-13 // 5 = -3 r 2"); + assert!(q.is_negative() && !r.is_negative(), "-13 // 5 -> negative"); } #[test] fn i257_test_partial_ord() { // Test two postive integers - let a = i257 { abs: 13, is_negative: false }; - let b = i257 { abs: 5, is_negative: false }; + let a = I257Impl::new(13, false); + let b = I257Impl::new(5, false); assert!(a > b, "13 > 5"); assert!(a >= b, "13 >= 5"); assert!(b < a, "5 < 13"); assert!(b <= a, "5 <= 13"); // Test `a` postive and `b` negative - let a = i257 { abs: 13, is_negative: false }; - let b = i257 { abs: 5, is_negative: true }; + let a = I257Impl::new(13, false); + let b = I257Impl::new(5, true); assert!(a > b, "13 > -5"); assert!(a >= b, "13 >= -5"); assert!(b < a, "-5 < 13"); assert!(b <= a, "-5 <= 13"); // Test `a` negative and `b` postive - let a = i257 { abs: 13, is_negative: true }; - let b = i257 { abs: 5, is_negative: false }; + let a = I257Impl::new(13, true); + let b = I257Impl::new(5, false); assert!(b > a, "5 > -13"); assert!(b >= a, "5 >= -13"); assert!(a < b, "-13 < 5"); assert!(a <= b, "5 <= -13"); // Test `a` negative and `b` negative - let a = i257 { abs: 13, is_negative: true }; - let b = i257 { abs: 5, is_negative: true }; + let a = I257Impl::new(13, true); + let b = I257Impl::new(5, true); assert!(b > a, "-5 > -13"); assert!(b >= a, "-13 >= -5"); assert!(a < b, "-13 < -5"); @@ -263,80 +257,73 @@ fn i257_test_partial_ord() { #[test] fn i257_test_eq_not_eq() { // Test two postive integers - let a = i257 { abs: 13, is_negative: false }; - let b = i257 { abs: 5, is_negative: false }; + let a = I257Impl::new(13, false); + let b = I257Impl::new(5, false); assert!(a != b, "13 != 5"); // Test `a` postive and `b` negative - let a = i257 { abs: 13, is_negative: false }; - let b = i257 { abs: 5, is_negative: true }; + let a = I257Impl::new(13, false); + let b = I257Impl::new(5, true); assert!(a != b, "13 != -5"); // Test `a` negative and `b` postive - let a = i257 { abs: 13, is_negative: true }; - let b = i257 { abs: 5, is_negative: false }; + let a = I257Impl::new(13, true); + let b = I257Impl::new(5, false); assert!(a != b, "-13 != 5"); // Test `a` negative and `b` negative - let a = i257 { abs: 13, is_negative: true }; - let b = i257 { abs: 5, is_negative: true }; + let a = I257Impl::new(13, true); + let b = I257Impl::new(5, true); assert!(a != b, "-13 != -5"); } #[test] fn i257_test_equality() { // Test equal with two positive integers - let a = i257 { abs: 13, is_negative: false }; - let b = i257 { abs: 13, is_negative: false }; + let a = I257Impl::new(13, false); + let b = I257Impl::new(13, false); assert!(a == b, "13 == 13"); // Test equal with two negative integers - let a = i257 { abs: 13, is_negative: true }; - let b = i257 { abs: 13, is_negative: true }; + let a = I257Impl::new(13, true); + let b = I257Impl::new(13, true); assert!(a == b, "-13 == -13"); // Test not equal with two postive integers - let a = i257 { abs: 13, is_negative: false }; - let b = i257 { abs: 5, is_negative: false }; + let a = I257Impl::new(13, false); + let b = I257Impl::new(5, false); assert!(a != b, "13 != 5"); // Test not equal with `a` postive and `b` negative - let a = i257 { abs: 13, is_negative: false }; - let b = i257 { abs: 5, is_negative: true }; + let a = I257Impl::new(13, false); + let b = I257Impl::new(5, true); assert!(a != b, "13 != -5"); // Test not equal with `a` negative and `b` postive - let a = i257 { abs: 13, is_negative: true }; - let b = i257 { abs: 5, is_negative: false }; + let a = I257Impl::new(13, true); + let b = I257Impl::new(5, false); assert!(a != b, "-13 != 5"); // Test not equal with `a` negative and `b` negative - let a = i257 { abs: 13, is_negative: true }; - let b = i257 { abs: 5, is_negative: true }; + let a = I257Impl::new(13, true); + let b = I257Impl::new(5, true); assert!(a != b, "-13 != -5"); } -#[test] -#[should_panic] -fn i257_test_check_sign_zero() { - let x = i257 { abs: 0, is_negative: true }; - i257_assert_no_negative_zero(x); -} - #[test] fn i257_test_div_sign_zero() { - let x = i257 { abs: 0, is_negative: false } / i257 { abs: 3, is_negative: true }; - assert_eq!(x.abs, 0, "incorrect abs"); - assert!(!x.is_negative, "incorrect sign"); + let x = I257Impl::new(0, false) / I257Impl::new(3, true); + assert_eq!(x.abs(), 0, "incorrect abs"); + assert!(!x.is_negative(), "incorrect sign"); } #[test] fn i257_test_into() { let x: i257 = 35.into(); - assert_eq!(x.abs, 35, "incorrect into value"); - assert!(!x.is_negative, "incorrect into sign"); + assert_eq!(x.abs(), 35, "incorrect into value"); + assert!(!x.is_negative(), "incorrect into sign"); let y: i257 = 258973.into(); - assert_eq!(y.abs, 258973, "incorrect into value"); - assert!(!y.is_negative, "incorrect into sign"); + assert_eq!(y.abs(), 258973, "incorrect into value"); + assert!(!y.is_negative(), "incorrect into sign"); } diff --git a/src/math/src/tests/is_power_of_two_test.cairo b/src/math/src/tests/is_power_of_two_test.cairo index 117460c9..2d421d6e 100644 --- a/src/math/src/tests/is_power_of_two_test.cairo +++ b/src/math/src/tests/is_power_of_two_test.cairo @@ -27,5 +27,5 @@ fn is_power_of_two_test_4() { #[test] #[available_gas(200000)] fn is_power_of_two_test_5() { - assert!(is_power_of_two(0) == false, "invalid result"); + assert_eq!(is_power_of_two(0), false, "invalid result"); } diff --git a/src/math/src/tests/math_test.cairo b/src/math/src/tests/math_test.cairo index c14567a1..3d25be1b 100644 --- a/src/math/src/tests/math_test.cairo +++ b/src/math/src/tests/math_test.cairo @@ -1,5 +1,5 @@ use alexandria_math::{count_digits_of_base, pow, BitShift, BitRotate, WrappingMath}; -use integer::BoundedInt; +use core::integer::BoundedInt; // Test power function #[test] diff --git a/src/math/src/tests/zellers_congruence_test.cairo b/src/math/src/tests/zellers_congruence_test.cairo index 60abbf8f..77943d0c 100644 --- a/src/math/src/tests/zellers_congruence_test.cairo +++ b/src/math/src/tests/zellers_congruence_test.cairo @@ -9,7 +9,7 @@ fn test_case(day: u128, month: u128, year: u128, expected: u128, error_expected: } // Otherwise, unwrap the day and check it else { let day = day.unwrap(); - assert!(day == expected, "day is invalid"); + assert_eq!(day, expected, "day is invalid"); } } diff --git a/src/math/src/trigonometry.cairo b/src/math/src/trigonometry.cairo index 6ea488e9..f5a14789 100644 --- a/src/math/src/trigonometry.cairo +++ b/src/math/src/trigonometry.cairo @@ -9,7 +9,7 @@ use core::traits::TryInto; // * `u64` - sin(x) * 1e8 // # Example // * fast_sin(3000000000) = (true, 50000000) -fn fast_sin_inner(x: u64) -> (bool, u64) { +pub fn fast_sin_inner(x: u64) -> (bool, u64) { let multipier = 100000000_u64; let hollyst: u64 = 1745329_u64; let sin_table = array![ @@ -67,7 +67,7 @@ fn fast_sin_inner(x: u64) -> (bool, u64) { // * `i64` - sin(x) * 1e8 // # Example // * fast_sin(3000000000) = 50000000 -fn fast_sin(x: i64) -> i64 { +pub fn fast_sin(x: i64) -> i64 { let mut a = x; if x < 0 { a = -x; @@ -94,7 +94,7 @@ fn fast_sin(x: i64) -> i64 { // * `i64` - cos(x) * 1e8 // # Example // * fast_cos(6000000000) = 50000000 -fn fast_cos(x: i64) -> i64 { +pub fn fast_cos(x: i64) -> i64 { let mut a = x + consteval_int!(90_i64 * 100000000_i64); if x < 0 { a = -x; @@ -117,7 +117,7 @@ fn fast_cos(x: i64) -> i64 { // * `i64` - tan(x) * 1e8 // # Example // * fast_tan(4500000000) = 100000000 -fn fast_tan(x: i64) -> i64 { +pub fn fast_tan(x: i64) -> i64 { let multipier = 100000000_u64; let mut a = x; if x < 0 { diff --git a/src/math/src/wad_ray_math.cairo b/src/math/src/wad_ray_math.cairo index 94a51565..140af871 100644 --- a/src/math/src/wad_ray_math.cairo +++ b/src/math/src/wad_ray_math.cairo @@ -4,39 +4,39 @@ /// Operations are rounded. If a value is >=.5, will be rounded up, otherwise rounded down. /// https://github.com/aave/aave-v3-core/blob/master/contracts/protocol/libraries/math/WadRayMath.sol -const WAD: u256 = 1_000_000_000_000_000_000; // 1e18 -const HALF_WAD: u256 = 500_000_000_000_000_000; // 0.5e18 -const RAY: u256 = 1_000_000_000_000_000_000_000_000_000; // 1e27 -const HALF_RAY: u256 = 500_000_000_000_000_000_000_000_000; // 0.5e27 -const WAD_RAY_RATIO: u256 = 1_000_000_000; // 1e9 -const HALF_WAD_RAY_RATIO: u256 = 500_000_000; // 0.5e9 +pub(crate) const WAD: u256 = 1_000_000_000_000_000_000; // 1e18 +pub(crate) const HALF_WAD: u256 = 500_000_000_000_000_000; // 0.5e18 +pub(crate) const RAY: u256 = 1_000_000_000_000_000_000_000_000_000; // 1e27 +pub(crate) const HALF_RAY: u256 = 500_000_000_000_000_000_000_000_000; // 0.5e27 +pub(crate) const WAD_RAY_RATIO: u256 = 1_000_000_000; // 1e9 +pub(crate) const HALF_WAD_RAY_RATIO: u256 = 500_000_000; // 0.5e9 /// Return the wad value /// # Returns /// * `u256` - The value -fn wad() -> u256 { +pub fn wad() -> u256 { return WAD; } /// Return the ray value /// # Returns /// * `u256` - The value -fn ray() -> u256 { +pub fn ray() -> u256 { return RAY; } /// Return the half wad value /// # Returns /// * `u256` - The value -fn half_wad() -> u256 { +pub fn half_wad() -> u256 { return HALF_WAD; } /// Return the half ray value /// # Returns /// * `u256` - The value -fn half_ray() -> u256 { +pub fn half_ray() -> u256 { return HALF_RAY; } @@ -47,7 +47,7 @@ fn half_ray() -> u256 { /// * b Wad /// # Returns /// * a*b, in wad -fn wad_mul(a: u256, b: u256) -> u256 { +pub fn wad_mul(a: u256, b: u256) -> u256 { return (a * b + HALF_WAD) / WAD; } @@ -57,7 +57,7 @@ fn wad_mul(a: u256, b: u256) -> u256 { /// * b Wad /// # Returns /// * a/b, in wad -fn wad_div(a: u256, b: u256) -> u256 { +pub fn wad_div(a: u256, b: u256) -> u256 { return (a * WAD + (b / 2)) / b; } @@ -67,7 +67,7 @@ fn wad_div(a: u256, b: u256) -> u256 { /// * b Ray /// # Returns /// * a raymul b -fn ray_mul(a: u256, b: u256) -> u256 { +pub fn ray_mul(a: u256, b: u256) -> u256 { return (a * b + HALF_RAY) / RAY; } @@ -77,7 +77,7 @@ fn ray_mul(a: u256, b: u256) -> u256 { /// * b Ray /// # Returns /// * a raydiv b -fn ray_div(a: u256, b: u256) -> u256 { +pub fn ray_div(a: u256, b: u256) -> u256 { return (a * RAY + (b / 2)) / b; } @@ -86,7 +86,7 @@ fn ray_div(a: u256, b: u256) -> u256 { /// * a Ray /// # Returns /// * a converted to wad, rounded half up to the nearest wad -fn ray_to_wad(a: u256) -> u256 { +pub fn ray_to_wad(a: u256) -> u256 { return (HALF_WAD_RAY_RATIO + a) / WAD_RAY_RATIO; } @@ -95,7 +95,7 @@ fn ray_to_wad(a: u256) -> u256 { /// * a Wad /// # Returns /// * a converted to ray -fn wad_to_ray(a: u256) -> u256 { +pub fn wad_to_ray(a: u256) -> u256 { return a * WAD_RAY_RATIO; } diff --git a/src/math/src/zellers_congruence.cairo b/src/math/src/zellers_congruence.cairo index 43dd4db7..0c874af4 100644 --- a/src/math/src/zellers_congruence.cairo +++ b/src/math/src/zellers_congruence.cairo @@ -18,7 +18,7 @@ /// ``` /// # TODO /// - Change the return type to `Result` -fn day_of_week(mut date: u128, mut month: u128, mut year: u128) -> Option { +pub fn day_of_week(mut date: u128, mut month: u128, mut year: u128) -> Option { // Check input parameters if !check_input_parameters(date, month, year) { return Option::None; @@ -46,7 +46,7 @@ fn day_of_week(mut date: u128, mut month: u128, mut year: u128) -> Option /// # Returns /// * `true` - If the input parameters are valid /// * `false` - If the input parameters are invalid -fn check_input_parameters(date: u128, month: u128, year: u128) -> bool { +pub fn check_input_parameters(date: u128, month: u128, year: u128) -> bool { // Check the date // Must be in the range 1 to 31 if date < 1 { diff --git a/src/merkle_tree/Scarb.toml b/src/merkle_tree/Scarb.toml index dc148cf9..7daebb83 100644 --- a/src/merkle_tree/Scarb.toml +++ b/src/merkle_tree/Scarb.toml @@ -3,6 +3,7 @@ name = "alexandria_merkle_tree" version = "0.1.0" description = "Merkle tree related stuff" homepage = "https://github.com/keep-starknet-strange/alexandria/tree/src/merkle_tree" +edition = "2023_11" [tool] fmt.workspace = true diff --git a/src/merkle_tree/src/lib.cairo b/src/merkle_tree/src/lib.cairo index 44b79b55..4138a58b 100644 --- a/src/merkle_tree/src/lib.cairo +++ b/src/merkle_tree/src/lib.cairo @@ -1,6 +1,7 @@ -mod merkle_tree; -mod storage_proof; - +pub mod merkle_tree; +pub mod storage_proof; #[cfg(test)] mod tests; + +use storage_proof::BinaryNodeImpl; diff --git a/src/merkle_tree/src/merkle_tree.cairo b/src/merkle_tree/src/merkle_tree.cairo index 887c6a10..093509f5 100644 --- a/src/merkle_tree/src/merkle_tree.cairo +++ b/src/merkle_tree/src/merkle_tree.cairo @@ -26,7 +26,7 @@ /// Hasher trait. -trait HasherTrait { +pub trait HasherTrait { fn new() -> T; fn hash(ref self: T, data1: felt252, data2: felt252) -> felt252; } @@ -35,30 +35,28 @@ trait HasherTrait { // Hasher representations. #[derive(Drop, Copy)] -struct Hasher {} +pub struct Hasher {} /// Hasher impls. -mod pedersen { - use hash::HashStateTrait; +pub mod pedersen { use super::{Hasher, HasherTrait}; - impl PedersenHasherImpl of HasherTrait { + pub impl PedersenHasherImpl of HasherTrait { fn new() -> Hasher { Hasher {} } fn hash(ref self: Hasher, data1: felt252, data2: felt252) -> felt252 { - pedersen::pedersen(data1, data2) + core::pedersen::pedersen(data1, data2) } } } -mod poseidon { - use hash::HashStateTrait; - use poseidon::hades_permutation; +pub mod poseidon { + use core::poseidon::hades_permutation; use super::{Hasher, HasherTrait}; - impl PoseidonHasherImpl of HasherTrait { + pub impl PoseidonHasherImpl of HasherTrait { fn new() -> Hasher { Hasher {} } @@ -72,12 +70,12 @@ mod poseidon { /// MerkleTree representation. #[derive(Drop)] -struct MerkleTree { +pub struct MerkleTree { hasher: T } /// MerkleTree trait. -trait MerkleTreeTrait { +pub trait MerkleTreeTrait { /// Create a new merkle tree instance. fn new() -> MerkleTree; /// Compute the merkle root of a given proof. @@ -91,7 +89,7 @@ trait MerkleTreeTrait { } /// MerkleTree Legacy implementation. -impl MerkleTreeImpl, +Copy, +Drop> of MerkleTreeTrait { +pub impl MerkleTreeImpl, +Copy, +Drop> of MerkleTreeTrait { /// Create a new merkle tree instance. fn new() -> MerkleTree { MerkleTree { hasher: HasherTrait::new() } diff --git a/src/merkle_tree/src/storage_proof.cairo b/src/merkle_tree/src/storage_proof.cairo index a13112bc..813cb325 100644 --- a/src/merkle_tree/src/storage_proof.cairo +++ b/src/merkle_tree/src/storage_proof.cairo @@ -1,41 +1,76 @@ -use hash::HashStateTrait; -use pedersen::PedersenTrait; -use poseidon::PoseidonTrait; +use core::hash::HashStateTrait; +use core::pedersen::PedersenTrait; +use core::poseidon::PoseidonTrait; #[derive(Drop)] -struct BinaryNode { +pub struct BinaryNode { left: felt252, right: felt252, } +#[generate_trait] +pub impl BinaryNodeImpl of BinaryNodeTrait { + fn new(left: felt252, right: felt252) -> BinaryNode { + BinaryNode { left, right } + } +} + #[derive(Drop, Copy)] -struct EdgeNode { - child: felt252, +pub struct EdgeNode { path: felt252, + child: felt252, length: u8, } +#[generate_trait] +pub impl EdgeNodeImpl of EdgeNodeTrait { + fn new(path: felt252, child: felt252, length: u8) -> EdgeNode { + EdgeNode { path, child, length } + } +} + #[derive(Drop)] -enum TrieNode { +pub enum TrieNode { Binary: BinaryNode, Edge: EdgeNode, } #[derive(Destruct)] -struct ContractData { +pub struct ContractData { class_hash: felt252, nonce: felt252, contract_state_hash_version: felt252, storage_proof: Array } +#[generate_trait] +pub impl ContractDataImpl of ContractDataTrait { + fn new( + class_hash: felt252, + nonce: felt252, + contract_state_hash_version: felt252, + storage_proof: Array + ) -> ContractData { + ContractData { class_hash, nonce, contract_state_hash_version, storage_proof } + } +} + #[derive(Destruct)] -struct ContractStateProof { +pub struct ContractStateProof { class_commitment: felt252, contract_proof: Array, contract_data: ContractData } +#[generate_trait] +pub impl ContractStateProofImpl of ContractStateProofTrait { + fn new( + class_commitment: felt252, contract_proof: Array, contract_data: ContractData + ) -> ContractStateProof { + ContractStateProof { class_commitment, contract_proof, contract_data, } + } +} + /// Verify Starknet storage proof. For reference see: /// - ([state](https://docs.starknet.io/documentation/architecture_and_concepts/State/starknet-state/)) /// - ([pathfinder_getproof API endpoint](https://github.com/eqlabs/pathfinder/blob/main/doc/rpc/pathfinder_rpc_api.json)) @@ -47,7 +82,7 @@ struct ContractStateProof { /// * `proof` - `ContractStateProof` representing storage proof /// # Returns /// * `felt252` - `value` at `storage_address` if verified, panic otherwise. -fn verify( +pub fn verify( expected_state_commitment: felt252, contract_address: felt252, storage_address: felt252, @@ -86,7 +121,7 @@ fn traverse(expected_path: felt252, proof: Array) -> (felt252, felt252 let expected_path_u256: u256 = expected_path.into(); let leaf = *match nodes.pop_back().unwrap() { - TrieNode::Binary(_) => panic_with_felt252('invalid leaf type'), + TrieNode::Binary(_) => panic!("expected Edge got Leaf"), TrieNode::Edge(edge) => edge }; diff --git a/src/merkle_tree/src/tests/storage_proof_test_data.cairo b/src/merkle_tree/src/tests/storage_proof_test_data.cairo index 75d6a242..cd0e572f 100644 --- a/src/merkle_tree/src/tests/storage_proof_test_data.cairo +++ b/src/merkle_tree/src/tests/storage_proof_test_data.cairo @@ -1,8 +1,9 @@ use alexandria_merkle_tree::storage_proof::{ - ContractStateProof, ContractData, TrieNode, BinaryNode, EdgeNode + ContractStateProof, ContractData, TrieNode, BinaryNode, EdgeNode, BinaryNodeImpl, EdgeNodeImpl, + ContractStateProofImpl, ContractDataImpl }; -fn balance_proof() -> ContractStateProof { +pub(crate) fn balance_proof() -> ContractStateProof { // func _balances(user : felt) -> (res : Uint256): // get_storage_var_address('_balances', 0x063c94d6B73eA2284338f464f86F33E12642149F763Cd8E76E035E8E6A5Bb0e6) // storage_address = 0x4ae51d08cd202d1472587dfe63dbf2d5ec767cbf4218b59b7ab71956780c6ee @@ -10,288 +11,286 @@ fn balance_proof() -> ContractStateProof { // 0x00da114221cb83fa859dbdb4c44beeaa0bb37c7537ad5ae66fe5e0efd20e6eb3 \ // 0x4ae51d08cd202d1472587dfe63dbf2d5ec767cbf4218b59b7ab71956780c6ee - ContractStateProof { + ContractStateProofImpl::new( class_commitment: 0x5eed4c30c17df1a41905c9824f2a296b6f77e91f0f017290752a60fbb8f9ff7, contract_proof: array![ TrieNode::Binary( - BinaryNode { - left: 0x74b59299e8315ce3c9d679b0a439f8bd6d55f1f7544b98852c85c953ec57e8, - right: 0x2390819e385bb1876e077b5ed4a4bae52c0e16ae7efee4c889c3d5247f6fb60, - } + BinaryNodeImpl::new( + 0x74b59299e8315ce3c9d679b0a439f8bd6d55f1f7544b98852c85c953ec57e8, + 0x2390819e385bb1876e077b5ed4a4bae52c0e16ae7efee4c889c3d5247f6fb60 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x5ef3be75d230f16f9f62058cd51f33fe511f132400e24ede72fe931d9afcd59, - right: 0x404d825da685c12746a2b2b7089c13561135ac529a6624b848951993331de4f, - } + BinaryNodeImpl::new( + 0x5ef3be75d230f16f9f62058cd51f33fe511f132400e24ede72fe931d9afcd59, + 0x404d825da685c12746a2b2b7089c13561135ac529a6624b848951993331de4f + ) ), TrieNode::Binary( - BinaryNode { - left: 0x5cbf312528ca49ab9012f368994adcb85f778360c68d61ddfa94e5db04e39bf, - right: 0x4df940db2395b5a8929cf658e36b45e88431aa9b0a1513e5318d81e83af66ca, - } + BinaryNodeImpl::new( + 0x5cbf312528ca49ab9012f368994adcb85f778360c68d61ddfa94e5db04e39bf, + 0x4df940db2395b5a8929cf658e36b45e88431aa9b0a1513e5318d81e83af66ca + ) ), TrieNode::Binary( - BinaryNode { - left: 0x5e002697a7591f4cb36f024142c249493ea69f2820aae9842b085d9cd20a825, - right: 0x78e4c02f55114f6b4989788d52e2d03bd3416f720d090215a7f95d1178166c6, - } + BinaryNodeImpl::new( + 0x5e002697a7591f4cb36f024142c249493ea69f2820aae9842b085d9cd20a825, + 0x78e4c02f55114f6b4989788d52e2d03bd3416f720d090215a7f95d1178166c6 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x4ad60a445f0a47f285861868f332f310b405acc3366a44483b534daefc4061b, - right: 0x4a3bff604eb492f216f053a8756d7c3cb2f80649c4a3fea7d5ed939b24c784c, - } + BinaryNodeImpl::new( + 0x4ad60a445f0a47f285861868f332f310b405acc3366a44483b534daefc4061b, + 0x4a3bff604eb492f216f053a8756d7c3cb2f80649c4a3fea7d5ed939b24c784c + ) ), TrieNode::Binary( - BinaryNode { - left: 0x316045f83427fc1a617bb370fa2b1a7a03d462b264729424f52c6ae00e1f71a, - right: 0x7ca38911fbfba4481ea60591a97b01861825c1f908dd7fc3141192b79b55d43, - } + BinaryNodeImpl::new( + 0x316045f83427fc1a617bb370fa2b1a7a03d462b264729424f52c6ae00e1f71a, + 0x7ca38911fbfba4481ea60591a97b01861825c1f908dd7fc3141192b79b55d43 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x17bf798cac821552f0e3d804dd9876e286c63d64d64aca19aea00ea9110ff58, - right: 0x33b2593a0e40d4ed0ddb6d8b7b824a2bde13062dc405c2394a8a797c35b4b32, - } + BinaryNodeImpl::new( + 0x17bf798cac821552f0e3d804dd9876e286c63d64d64aca19aea00ea9110ff58, + 0x33b2593a0e40d4ed0ddb6d8b7b824a2bde13062dc405c2394a8a797c35b4b32 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x1a78b3285e1f816ec7fdeeecbd7de855c3fe50e49cb9d294c0fbe698a8f0964, - right: 0x737aebdf31cbf55171144bd658e0e82862541b0af78d3241e13de77015f1ce3, - } + BinaryNodeImpl::new( + 0x1a78b3285e1f816ec7fdeeecbd7de855c3fe50e49cb9d294c0fbe698a8f0964, + 0x737aebdf31cbf55171144bd658e0e82862541b0af78d3241e13de77015f1ce3 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x7267f91ecdc6e579864613a406750bc80363a2be5ff863f020e5531eb8d947a, - right: 0x65bcc933abbb3c71cf3edd535204f34eb58a7329a53688039733420571f45fc, - } + BinaryNodeImpl::new( + 0x7267f91ecdc6e579864613a406750bc80363a2be5ff863f020e5531eb8d947a, + 0x65bcc933abbb3c71cf3edd535204f34eb58a7329a53688039733420571f45fc + ) ), TrieNode::Binary( - BinaryNode { - left: 0xac490c5cda65c26fe042c08d9bec48f399db1b0c551eb3fcbcf5fc51643beb, - right: 0x574edd4ea6655ada56844d7b7797af4fb66fa8e86361ee201d817de885ab751, - } + BinaryNodeImpl::new( + 0xac490c5cda65c26fe042c08d9bec48f399db1b0c551eb3fcbcf5fc51643beb, + 0x574edd4ea6655ada56844d7b7797af4fb66fa8e86361ee201d817de885ab751 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x54407ae16b65fd67d64fc8528f7240cd4c6914041dd9e3bf7c56cbab58eb42e, - right: 0x5e7d51e63c8c33f864418dd61e720cfcda9363d9b6b1c5de11f68b2d0a9a448, - } + BinaryNodeImpl::new( + 0x54407ae16b65fd67d64fc8528f7240cd4c6914041dd9e3bf7c56cbab58eb42e, + 0x5e7d51e63c8c33f864418dd61e720cfcda9363d9b6b1c5de11f68b2d0a9a448 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x4550dba3e8b473bc2b4cc6c99c43ec90864930f4ec06affb267f24ad16df0b5, - right: 0x545515cd797a277cdb88ab7efaa63ea979220696e51c6173de23984ff1746c4, - } + BinaryNodeImpl::new( + 0x4550dba3e8b473bc2b4cc6c99c43ec90864930f4ec06affb267f24ad16df0b5, + 0x545515cd797a277cdb88ab7efaa63ea979220696e51c6173de23984ff1746c4 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x14fa907e7e9633b6f3dcabfe07e8dac02e0aea480949bfd0f8dea13ecb5c50c, - right: 0x5448b1aac9acedab60b5401d6330bfabd397f1086ab42948ed1fa81e38a2157, - } + BinaryNodeImpl::new( + 0x14fa907e7e9633b6f3dcabfe07e8dac02e0aea480949bfd0f8dea13ecb5c50c, + 0x5448b1aac9acedab60b5401d6330bfabd397f1086ab42948ed1fa81e38a2157 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x1139a46c5e89fbcc483b8726d3e7707122b57ccdf955df4216cb1a93ffffd7a, - right: 0x6729ff6fec2dfcc6535bc4eea26fc4eb65e0285d4f8ae0fe6be4c343d9bb720, - } + BinaryNodeImpl::new( + 0x1139a46c5e89fbcc483b8726d3e7707122b57ccdf955df4216cb1a93ffffd7a, + 0x6729ff6fec2dfcc6535bc4eea26fc4eb65e0285d4f8ae0fe6be4c343d9bb720 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x3d7dcabc79ce522ffb88b167edfd51896a6430a456250290f2ac1cdbe6572b3, - right: 0x990164dd962c5d48dd9a98cd8845bfdd483cbc07bbbfcd2c19daee84992e28, - } + BinaryNodeImpl::new( + 0x3d7dcabc79ce522ffb88b167edfd51896a6430a456250290f2ac1cdbe6572b3, + 0x990164dd962c5d48dd9a98cd8845bfdd483cbc07bbbfcd2c19daee84992e28 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x59cc416528b7228ed0064a393ed60462f5e556d5a236f7b94ea8d510641cd64, - right: 0x325c342f00e73f97c8a1ff2462c754dbb27b967223954f690e1d069e5088599, - } + BinaryNodeImpl::new( + 0x59cc416528b7228ed0064a393ed60462f5e556d5a236f7b94ea8d510641cd64, + 0x325c342f00e73f97c8a1ff2462c754dbb27b967223954f690e1d069e5088599 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x3c976052cb6c461679e159c1b711e8d0261d240745931ea399edf389848f99d, - right: 0x4f65e0c2b833c972c02ad133e6aa152a6e9d15bca277c2b163bc09c8b2e2b1c, - } + BinaryNodeImpl::new( + 0x3c976052cb6c461679e159c1b711e8d0261d240745931ea399edf389848f99d, + 0x4f65e0c2b833c972c02ad133e6aa152a6e9d15bca277c2b163bc09c8b2e2b1c + ) ), TrieNode::Binary( - BinaryNode { - left: 0x338b6575ed50d84769024e54decfde68968be33bb266f1faa0a0fd9157e47e9, - right: 0x130c2fd7a701ec84b9ef42c9a45cb115581c268de360db13e748c1c2c62cc03, - } + BinaryNodeImpl::new( + 0x338b6575ed50d84769024e54decfde68968be33bb266f1faa0a0fd9157e47e9, + 0x130c2fd7a701ec84b9ef42c9a45cb115581c268de360db13e748c1c2c62cc03 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x57a2288b799d131ce7d6c934ce288e5dcc72214871e92f25420d6cb70de6f57, - right: 0x3be816d1fe67968529d322c2d550b3968dc846a938d4878c97f3e974c17f9b, - } + BinaryNodeImpl::new( + 0x57a2288b799d131ce7d6c934ce288e5dcc72214871e92f25420d6cb70de6f57, + 0x3be816d1fe67968529d322c2d550b3968dc846a938d4878c97f3e974c17f9b + ) ), TrieNode::Binary( - BinaryNode { - left: 0x14f24c1f2b88d01188f4d72cfe1857668cb5507a92516cf356a618363aa369c, - right: 0x19a3203d5b1ec5a02c56f8672694f766a2a1f073430cca00362b71b19dc71f2, - } + BinaryNodeImpl::new( + 0x14f24c1f2b88d01188f4d72cfe1857668cb5507a92516cf356a618363aa369c, + 0x19a3203d5b1ec5a02c56f8672694f766a2a1f073430cca00362b71b19dc71f2 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x2b54c34d1145942663561aba685c1afd12e991739a30d109fdbe17ff1416f60, - right: 0x547e87abcc29a44e0f57f5bd4c9ca5bddb73a8a24ef1faf188aab963158df04, - } + BinaryNodeImpl::new( + 0x2b54c34d1145942663561aba685c1afd12e991739a30d109fdbe17ff1416f60, + 0x547e87abcc29a44e0f57f5bd4c9ca5bddb73a8a24ef1faf188aab963158df04 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x412b79bf0b5c3ac8eeca6ffc739aa9c48a0fb9834f9f683ef75400023547ea4, - right: 0x412022f2d1d47198766e74d76a6933348a922727170ed03c6a73b1c854bc11f, - } + BinaryNodeImpl::new( + 0x412b79bf0b5c3ac8eeca6ffc739aa9c48a0fb9834f9f683ef75400023547ea4, + 0x412022f2d1d47198766e74d76a6933348a922727170ed03c6a73b1c854bc11f + ) ), TrieNode::Edge( - EdgeNode { - path: 0x221cb83fa859dbdb4c44beeaa0bb37c7537ad5ae66fe5e0efd20e6eb3, - length: 229, - child: 0x1fe7bef4bd2a37b56eab84508f217fd2a85694bbeb95e98049faa0de0a2011c, - } + EdgeNodeImpl::new( + 0x221cb83fa859dbdb4c44beeaa0bb37c7537ad5ae66fe5e0efd20e6eb3, + 0x1fe7bef4bd2a37b56eab84508f217fd2a85694bbeb95e98049faa0de0a2011c, + 229 + ) ) ], - contract_data: ContractData { + contract_data: ContractDataImpl::new( class_hash: 0x1cb96b938da26c060d5fd807eef8b580c49490926393a5eeb408a89f84b9b46, nonce: 0x0, contract_state_hash_version: 0, storage_proof: array![ TrieNode::Binary( - BinaryNode { - left: 0x5b1f6f4ba862f9d83fb1c6cbfc8ab6ccf8864ff40f9cd1e86b653978b7da18e, - right: 0x6a14610de840e87de4c10fca04caa9fe93f854b6e3dd528dde1eedddf0ce84, - } + BinaryNodeImpl::new( + 0x5b1f6f4ba862f9d83fb1c6cbfc8ab6ccf8864ff40f9cd1e86b653978b7da18e, + 0x6a14610de840e87de4c10fca04caa9fe93f854b6e3dd528dde1eedddf0ce84 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x1e43960a3be85b1ad5a3b198617b0740b684e87a44e9e688f39cfa491cda57a, - right: 0x51ae9c0371c2f844155d26505bb26cf312e37aeae8e5610135579225c63b78e, - } + BinaryNodeImpl::new( + 0x1e43960a3be85b1ad5a3b198617b0740b684e87a44e9e688f39cfa491cda57a, + 0x51ae9c0371c2f844155d26505bb26cf312e37aeae8e5610135579225c63b78e + ) ), TrieNode::Binary( - BinaryNode { - left: 0x418949d2696cf64b33ea5f45d97bd2b21a0a664bebf96321902a01cd3b48d2a, - right: 0x6fd4f5c829467a9ceeb891549993fb83b8003588d8c8cff156bd1c099dbc5ef, - } + BinaryNodeImpl::new( + 0x418949d2696cf64b33ea5f45d97bd2b21a0a664bebf96321902a01cd3b48d2a, + 0x6fd4f5c829467a9ceeb891549993fb83b8003588d8c8cff156bd1c099dbc5ef + ) ), TrieNode::Binary( - BinaryNode { - left: 0x7d07c08fa0f20455453f16b278ca6f710553339a2dbb8f58e15925a6217643, - right: 0x47129129d16cb646a2c34f7c9c067c9acaad81b6839b6fc09e8b80c34bebde7, - } + BinaryNodeImpl::new( + 0x7d07c08fa0f20455453f16b278ca6f710553339a2dbb8f58e15925a6217643, + 0x47129129d16cb646a2c34f7c9c067c9acaad81b6839b6fc09e8b80c34bebde7 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x175c91990d2333c3de3f370030f901f1872a24aa5f6da397a213e2a5b0d16b9, - right: 0x65a68f50434c58e521c95a1397ed91a10eed6e0aa2c417ca08d54caf39a0708, - } + BinaryNodeImpl::new( + 0x175c91990d2333c3de3f370030f901f1872a24aa5f6da397a213e2a5b0d16b9, + 0x65a68f50434c58e521c95a1397ed91a10eed6e0aa2c417ca08d54caf39a0708 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x4849c87d07ba2a2b8349c3bf55638b549888e9c04f42220f1df86aa41483a8b, - right: 0x19f7fc3721a344be4598e7973ee3b1b5fb1451b4d7d7bab65d6f9528ad171cc, - } + BinaryNodeImpl::new( + 0x4849c87d07ba2a2b8349c3bf55638b549888e9c04f42220f1df86aa41483a8b, + 0x19f7fc3721a344be4598e7973ee3b1b5fb1451b4d7d7bab65d6f9528ad171cc + ) ), TrieNode::Binary( - BinaryNode { - left: 0x68eac761b78dc264977294b7d2971160597048591ddd82a566c69f084d35843, - right: 0x384b4f58bf7f2cad7d361fc4f39061e9441f61053cb92aa4ca7591c1d2ce332, - } + BinaryNodeImpl::new( + 0x68eac761b78dc264977294b7d2971160597048591ddd82a566c69f084d35843, + 0x384b4f58bf7f2cad7d361fc4f39061e9441f61053cb92aa4ca7591c1d2ce332 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x8530109039a3265f9bed7d53935d934d8b3c243559c824f936212d82568d7, - right: 0x609f90d6f706eb20ed763dda2409b873303257a4bd21efec3f0cef4f1e1bb15, - } + BinaryNodeImpl::new( + 0x8530109039a3265f9bed7d53935d934d8b3c243559c824f936212d82568d7, + 0x609f90d6f706eb20ed763dda2409b873303257a4bd21efec3f0cef4f1e1bb15 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x214a3f760450952ded394c66f9e771c743c8fc1b94408c3d75d7218e3c4ea0d, - right: 0x4acaaa512264bfad4c4fae98f7ffc61af4ab6ef12f691a93eb77498e28bd981, - } + BinaryNodeImpl::new( + 0x214a3f760450952ded394c66f9e771c743c8fc1b94408c3d75d7218e3c4ea0d, + 0x4acaaa512264bfad4c4fae98f7ffc61af4ab6ef12f691a93eb77498e28bd981 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x132a39f6d01334cea3f78df8fc6562de3b12ecbb59c039c04d5114dcc786e4f, - right: 0x589c451d11284e28647bd8f69cc52316340bdbb06cc8dfd3e58693521867b8f, - } + BinaryNodeImpl::new( + 0x132a39f6d01334cea3f78df8fc6562de3b12ecbb59c039c04d5114dcc786e4f, + 0x589c451d11284e28647bd8f69cc52316340bdbb06cc8dfd3e58693521867b8f + ) ), TrieNode::Binary( - BinaryNode { - left: 0x283b8a927ca6f39030687e134a0fbb62581152c8c356c39398c10d6439137b4, - right: 0x26c8829289038b3fd39cbb84a77d5b581d207b02da385fd6bdb784831b7042c, - } + BinaryNodeImpl::new( + 0x283b8a927ca6f39030687e134a0fbb62581152c8c356c39398c10d6439137b4, + 0x26c8829289038b3fd39cbb84a77d5b581d207b02da385fd6bdb784831b7042c + ) ), TrieNode::Binary( - BinaryNode { - left: 0x5a6263b13773bb2b02b60016825a626f4811d6f4a2015de7c6b1a34475ae518, - right: 0x74de5b7ad01a7652cb6f8bdd7eec2087063cd4c1c9774d8c571f42de2de790e, - } + BinaryNodeImpl::new( + 0x5a6263b13773bb2b02b60016825a626f4811d6f4a2015de7c6b1a34475ae518, + 0x74de5b7ad01a7652cb6f8bdd7eec2087063cd4c1c9774d8c571f42de2de790e + ) ), TrieNode::Binary( - BinaryNode { - left: 0x19dc54d0aadb395e9592f85ed9ba3766e8427c20ed1511ad626ebfbf61c3f03, - right: 0x260370da71cc1846829b69960e450b73a2f0155e2e4a9c2bee14246696c5e20, - } + BinaryNodeImpl::new( + 0x19dc54d0aadb395e9592f85ed9ba3766e8427c20ed1511ad626ebfbf61c3f03, + 0x260370da71cc1846829b69960e450b73a2f0155e2e4a9c2bee14246696c5e20 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x14e0a63dd9f386828c7af13462d186926013c4c21c0665540a7cdbaf8129998, - right: 0x22fb7449e5d36d92fedc78b6748bbd197ea244a7154b2535efa1cd83d8922ee, - } + BinaryNodeImpl::new( + 0x14e0a63dd9f386828c7af13462d186926013c4c21c0665540a7cdbaf8129998, + 0x22fb7449e5d36d92fedc78b6748bbd197ea244a7154b2535efa1cd83d8922ee + ) ), TrieNode::Binary( - BinaryNode { - left: 0x4ad9584d03093e399559c74959224dbc546d4fd5645a04663717e7f26e1ae73, - right: 0x1c6e23d891ecf1b564372671373a1fb6c532be0125891e8aaafe8426e9795d8, - } + BinaryNodeImpl::new( + 0x4ad9584d03093e399559c74959224dbc546d4fd5645a04663717e7f26e1ae73, + 0x1c6e23d891ecf1b564372671373a1fb6c532be0125891e8aaafe8426e9795d8 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x9ac60824ab502ac8be539b6dfeb05a3f71b74e948388bf5eb739fa53481afd, - right: 0x696b378cb1848e77e9ceaab566a5f42dde26de2fd5cfcbaa2fd97d03aeea47, - } + BinaryNodeImpl::new( + 0x9ac60824ab502ac8be539b6dfeb05a3f71b74e948388bf5eb739fa53481afd, + 0x696b378cb1848e77e9ceaab566a5f42dde26de2fd5cfcbaa2fd97d03aeea47 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x46a09c16ff0771585b796f48e96ddc36e7916b397c7cbd60de12618c427552d, - right: 0x12842effc2e3ad5ef995ec99f002b6540049f1368187625c08086a83523fe73, - } + BinaryNodeImpl::new( + 0x46a09c16ff0771585b796f48e96ddc36e7916b397c7cbd60de12618c427552d, + 0x12842effc2e3ad5ef995ec99f002b6540049f1368187625c08086a83523fe73 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x70854f31bd97611b9896baad3d44f7de4fc20d4ab1fd4a62fb4fa7eebb2affc, - right: 0x518745f6fb6490d53796a377b1c04923a58041d8c8063fcd6d2d3c7e7b06d19, - } + BinaryNodeImpl::new( + 0x70854f31bd97611b9896baad3d44f7de4fc20d4ab1fd4a62fb4fa7eebb2affc, + 0x518745f6fb6490d53796a377b1c04923a58041d8c8063fcd6d2d3c7e7b06d19 + ) ), TrieNode::Edge( - EdgeNode { - path: 0x3, - length: 2, - child: 0x1c5f3e73c9e969b9c5a621955d4813de68ca42a777fd4915ac5e71a73219893, - } + EdgeNodeImpl::new( + 0x3, 0x1c5f3e73c9e969b9c5a621955d4813de68ca42a777fd4915ac5e71a73219893, 2, + ) ), TrieNode::Binary( - BinaryNode { - left: 0x59e2516845b39a0f0771e257685ac06e3c3f1f479825521be982162dd249b24, - right: 0x1e4a53612070bf13d7677c61cb5448713d8479d57fba3d50059227d57ba0522, - } + BinaryNodeImpl::new( + 0x59e2516845b39a0f0771e257685ac06e3c3f1f479825521be982162dd249b24, + 0x1e4a53612070bf13d7677c61cb5448713d8479d57fba3d50059227d57ba0522, + ) ), TrieNode::Edge( - EdgeNode { - path: 0x108cd202d1472587dfe63dbf2d5ec767cbf4218b59b7ab71956780c6ee, - length: 230, - child: 0x78bc9be7c9e60005, - } + EdgeNodeImpl::new( + 0x108cd202d1472587dfe63dbf2d5ec767cbf4218b59b7ab71956780c6ee, + 0x78bc9be7c9e60005, + 230, + ) ) ], - } - } + ) + ) } -fn total_balance_proof() -> ContractStateProof { +pub(crate) fn total_balance_proof() -> ContractStateProof { // func _total_supply() -> (res : Uint256): // get_storage_var_address('_total_supply') // storage_address = 0x37a9774624a0e3e0d8e6b72bd35514f62b3e8e70fbaff4ed27181de4ffd4604; @@ -299,276 +298,276 @@ fn total_balance_proof() -> ContractStateProof { // 0x00da114221cb83fa859dbdb4c44beeaa0bb37c7537ad5ae66fe5e0efd20e6eb3 \ // 0x37a9774624a0e3e0d8e6b72bd35514f62b3e8e70fbaff4ed27181de4ffd4604 - ContractStateProof { + ContractStateProofImpl::new( class_commitment: 0x5eed4c30c17df1a41905c9824f2a296b6f77e91f0f017290752a60fbb8f9ff7, contract_proof: array![ TrieNode::Binary( - BinaryNode { - left: 0x74b59299e8315ce3c9d679b0a439f8bd6d55f1f7544b98852c85c953ec57e8, - right: 0x2390819e385bb1876e077b5ed4a4bae52c0e16ae7efee4c889c3d5247f6fb60, - } + BinaryNodeImpl::new( + 0x74b59299e8315ce3c9d679b0a439f8bd6d55f1f7544b98852c85c953ec57e8, + 0x2390819e385bb1876e077b5ed4a4bae52c0e16ae7efee4c889c3d5247f6fb60 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x5ef3be75d230f16f9f62058cd51f33fe511f132400e24ede72fe931d9afcd59, - right: 0x404d825da685c12746a2b2b7089c13561135ac529a6624b848951993331de4f, - } + BinaryNodeImpl::new( + 0x5ef3be75d230f16f9f62058cd51f33fe511f132400e24ede72fe931d9afcd59, + 0x404d825da685c12746a2b2b7089c13561135ac529a6624b848951993331de4f + ) ), TrieNode::Binary( - BinaryNode { - left: 0x5cbf312528ca49ab9012f368994adcb85f778360c68d61ddfa94e5db04e39bf, - right: 0x4df940db2395b5a8929cf658e36b45e88431aa9b0a1513e5318d81e83af66ca, - } + BinaryNodeImpl::new( + 0x5cbf312528ca49ab9012f368994adcb85f778360c68d61ddfa94e5db04e39bf, + 0x4df940db2395b5a8929cf658e36b45e88431aa9b0a1513e5318d81e83af66ca + ) ), TrieNode::Binary( - BinaryNode { - left: 0x5e002697a7591f4cb36f024142c249493ea69f2820aae9842b085d9cd20a825, - right: 0x78e4c02f55114f6b4989788d52e2d03bd3416f720d090215a7f95d1178166c6, - } + BinaryNodeImpl::new( + 0x5e002697a7591f4cb36f024142c249493ea69f2820aae9842b085d9cd20a825, + 0x78e4c02f55114f6b4989788d52e2d03bd3416f720d090215a7f95d1178166c6 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x4ad60a445f0a47f285861868f332f310b405acc3366a44483b534daefc4061b, - right: 0x4a3bff604eb492f216f053a8756d7c3cb2f80649c4a3fea7d5ed939b24c784c, - } + BinaryNodeImpl::new( + 0x4ad60a445f0a47f285861868f332f310b405acc3366a44483b534daefc4061b, + 0x4a3bff604eb492f216f053a8756d7c3cb2f80649c4a3fea7d5ed939b24c784c + ) ), TrieNode::Binary( - BinaryNode { - left: 0x316045f83427fc1a617bb370fa2b1a7a03d462b264729424f52c6ae00e1f71a, - right: 0x7ca38911fbfba4481ea60591a97b01861825c1f908dd7fc3141192b79b55d43, - } + BinaryNodeImpl::new( + 0x316045f83427fc1a617bb370fa2b1a7a03d462b264729424f52c6ae00e1f71a, + 0x7ca38911fbfba4481ea60591a97b01861825c1f908dd7fc3141192b79b55d43 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x17bf798cac821552f0e3d804dd9876e286c63d64d64aca19aea00ea9110ff58, - right: 0x33b2593a0e40d4ed0ddb6d8b7b824a2bde13062dc405c2394a8a797c35b4b32, - } + BinaryNodeImpl::new( + 0x17bf798cac821552f0e3d804dd9876e286c63d64d64aca19aea00ea9110ff58, + 0x33b2593a0e40d4ed0ddb6d8b7b824a2bde13062dc405c2394a8a797c35b4b32 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x1a78b3285e1f816ec7fdeeecbd7de855c3fe50e49cb9d294c0fbe698a8f0964, - right: 0x737aebdf31cbf55171144bd658e0e82862541b0af78d3241e13de77015f1ce3, - } + BinaryNodeImpl::new( + 0x1a78b3285e1f816ec7fdeeecbd7de855c3fe50e49cb9d294c0fbe698a8f0964, + 0x737aebdf31cbf55171144bd658e0e82862541b0af78d3241e13de77015f1ce3 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x7267f91ecdc6e579864613a406750bc80363a2be5ff863f020e5531eb8d947a, - right: 0x65bcc933abbb3c71cf3edd535204f34eb58a7329a53688039733420571f45fc, - } + BinaryNodeImpl::new( + 0x7267f91ecdc6e579864613a406750bc80363a2be5ff863f020e5531eb8d947a, + 0x65bcc933abbb3c71cf3edd535204f34eb58a7329a53688039733420571f45fc + ) ), TrieNode::Binary( - BinaryNode { - left: 0xac490c5cda65c26fe042c08d9bec48f399db1b0c551eb3fcbcf5fc51643beb, - right: 0x574edd4ea6655ada56844d7b7797af4fb66fa8e86361ee201d817de885ab751, - } + BinaryNodeImpl::new( + 0xac490c5cda65c26fe042c08d9bec48f399db1b0c551eb3fcbcf5fc51643beb, + 0x574edd4ea6655ada56844d7b7797af4fb66fa8e86361ee201d817de885ab751 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x54407ae16b65fd67d64fc8528f7240cd4c6914041dd9e3bf7c56cbab58eb42e, - right: 0x5e7d51e63c8c33f864418dd61e720cfcda9363d9b6b1c5de11f68b2d0a9a448, - } + BinaryNodeImpl::new( + 0x54407ae16b65fd67d64fc8528f7240cd4c6914041dd9e3bf7c56cbab58eb42e, + 0x5e7d51e63c8c33f864418dd61e720cfcda9363d9b6b1c5de11f68b2d0a9a448 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x4550dba3e8b473bc2b4cc6c99c43ec90864930f4ec06affb267f24ad16df0b5, - right: 0x545515cd797a277cdb88ab7efaa63ea979220696e51c6173de23984ff1746c4, - } + BinaryNodeImpl::new( + 0x4550dba3e8b473bc2b4cc6c99c43ec90864930f4ec06affb267f24ad16df0b5, + 0x545515cd797a277cdb88ab7efaa63ea979220696e51c6173de23984ff1746c4 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x14fa907e7e9633b6f3dcabfe07e8dac02e0aea480949bfd0f8dea13ecb5c50c, - right: 0x5448b1aac9acedab60b5401d6330bfabd397f1086ab42948ed1fa81e38a2157, - } + BinaryNodeImpl::new( + 0x14fa907e7e9633b6f3dcabfe07e8dac02e0aea480949bfd0f8dea13ecb5c50c, + 0x5448b1aac9acedab60b5401d6330bfabd397f1086ab42948ed1fa81e38a2157 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x1139a46c5e89fbcc483b8726d3e7707122b57ccdf955df4216cb1a93ffffd7a, - right: 0x6729ff6fec2dfcc6535bc4eea26fc4eb65e0285d4f8ae0fe6be4c343d9bb720, - } + BinaryNodeImpl::new( + 0x1139a46c5e89fbcc483b8726d3e7707122b57ccdf955df4216cb1a93ffffd7a, + 0x6729ff6fec2dfcc6535bc4eea26fc4eb65e0285d4f8ae0fe6be4c343d9bb720 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x3d7dcabc79ce522ffb88b167edfd51896a6430a456250290f2ac1cdbe6572b3, - right: 0x990164dd962c5d48dd9a98cd8845bfdd483cbc07bbbfcd2c19daee84992e28, - } + BinaryNodeImpl::new( + 0x3d7dcabc79ce522ffb88b167edfd51896a6430a456250290f2ac1cdbe6572b3, + 0x990164dd962c5d48dd9a98cd8845bfdd483cbc07bbbfcd2c19daee84992e28 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x59cc416528b7228ed0064a393ed60462f5e556d5a236f7b94ea8d510641cd64, - right: 0x325c342f00e73f97c8a1ff2462c754dbb27b967223954f690e1d069e5088599, - } + BinaryNodeImpl::new( + 0x59cc416528b7228ed0064a393ed60462f5e556d5a236f7b94ea8d510641cd64, + 0x325c342f00e73f97c8a1ff2462c754dbb27b967223954f690e1d069e5088599 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x3c976052cb6c461679e159c1b711e8d0261d240745931ea399edf389848f99d, - right: 0x4f65e0c2b833c972c02ad133e6aa152a6e9d15bca277c2b163bc09c8b2e2b1c, - } + BinaryNodeImpl::new( + 0x3c976052cb6c461679e159c1b711e8d0261d240745931ea399edf389848f99d, + 0x4f65e0c2b833c972c02ad133e6aa152a6e9d15bca277c2b163bc09c8b2e2b1c + ) ), TrieNode::Binary( - BinaryNode { - left: 0x338b6575ed50d84769024e54decfde68968be33bb266f1faa0a0fd9157e47e9, - right: 0x130c2fd7a701ec84b9ef42c9a45cb115581c268de360db13e748c1c2c62cc03, - } + BinaryNodeImpl::new( + 0x338b6575ed50d84769024e54decfde68968be33bb266f1faa0a0fd9157e47e9, + 0x130c2fd7a701ec84b9ef42c9a45cb115581c268de360db13e748c1c2c62cc03 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x57a2288b799d131ce7d6c934ce288e5dcc72214871e92f25420d6cb70de6f57, - right: 0x3be816d1fe67968529d322c2d550b3968dc846a938d4878c97f3e974c17f9b, - } + BinaryNodeImpl::new( + 0x57a2288b799d131ce7d6c934ce288e5dcc72214871e92f25420d6cb70de6f57, + 0x3be816d1fe67968529d322c2d550b3968dc846a938d4878c97f3e974c17f9b + ) ), TrieNode::Binary( - BinaryNode { - left: 0x14f24c1f2b88d01188f4d72cfe1857668cb5507a92516cf356a618363aa369c, - right: 0x19a3203d5b1ec5a02c56f8672694f766a2a1f073430cca00362b71b19dc71f2, - } + BinaryNodeImpl::new( + 0x14f24c1f2b88d01188f4d72cfe1857668cb5507a92516cf356a618363aa369c, + 0x19a3203d5b1ec5a02c56f8672694f766a2a1f073430cca00362b71b19dc71f2 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x2b54c34d1145942663561aba685c1afd12e991739a30d109fdbe17ff1416f60, - right: 0x547e87abcc29a44e0f57f5bd4c9ca5bddb73a8a24ef1faf188aab963158df04, - } + BinaryNodeImpl::new( + 0x2b54c34d1145942663561aba685c1afd12e991739a30d109fdbe17ff1416f60, + 0x547e87abcc29a44e0f57f5bd4c9ca5bddb73a8a24ef1faf188aab963158df04 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x412b79bf0b5c3ac8eeca6ffc739aa9c48a0fb9834f9f683ef75400023547ea4, - right: 0x412022f2d1d47198766e74d76a6933348a922727170ed03c6a73b1c854bc11f, - } + BinaryNodeImpl::new( + 0x412b79bf0b5c3ac8eeca6ffc739aa9c48a0fb9834f9f683ef75400023547ea4, + 0x412022f2d1d47198766e74d76a6933348a922727170ed03c6a73b1c854bc11f + ) ), TrieNode::Edge( - EdgeNode { - path: 0x221cb83fa859dbdb4c44beeaa0bb37c7537ad5ae66fe5e0efd20e6eb3, - length: 229, - child: 0x1fe7bef4bd2a37b56eab84508f217fd2a85694bbeb95e98049faa0de0a2011c, - } + EdgeNodeImpl::new( + 0x221cb83fa859dbdb4c44beeaa0bb37c7537ad5ae66fe5e0efd20e6eb3, + 0x1fe7bef4bd2a37b56eab84508f217fd2a85694bbeb95e98049faa0de0a2011c, + 229 + ) ) ], - contract_data: ContractData { + contract_data: ContractDataImpl::new( class_hash: 0x1cb96b938da26c060d5fd807eef8b580c49490926393a5eeb408a89f84b9b46, nonce: 0x0, contract_state_hash_version: 0, storage_proof: array![ TrieNode::Binary( - BinaryNode { - left: 0x5b1f6f4ba862f9d83fb1c6cbfc8ab6ccf8864ff40f9cd1e86b653978b7da18e, - right: 0x6a14610de840e87de4c10fca04caa9fe93f854b6e3dd528dde1eedddf0ce84, - } + BinaryNodeImpl::new( + 0x5b1f6f4ba862f9d83fb1c6cbfc8ab6ccf8864ff40f9cd1e86b653978b7da18e, + 0x6a14610de840e87de4c10fca04caa9fe93f854b6e3dd528dde1eedddf0ce84 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x520667ac8a496785d0cd5cb089b0cb29945b562e83710fc86af2efc8036c70b, - right: 0x37ac663feac78c6874c9b590da7a95c81300999b98a3e81e67e68da3ea4c0da, - } + BinaryNodeImpl::new( + 0x520667ac8a496785d0cd5cb089b0cb29945b562e83710fc86af2efc8036c70b, + 0x37ac663feac78c6874c9b590da7a95c81300999b98a3e81e67e68da3ea4c0da + ) ), TrieNode::Binary( - BinaryNode { - left: 0x349bdf44a6242b9a59f1a2f7e80fa1ac46537ba79a87dfdc1242dd5e56c0e3d, - right: 0x4aa5bab04c0c8736256a8af971e3586fd7cf2b4c9bfcba5b0e41d6deb2c0210, - } + BinaryNodeImpl::new( + 0x349bdf44a6242b9a59f1a2f7e80fa1ac46537ba79a87dfdc1242dd5e56c0e3d, + 0x4aa5bab04c0c8736256a8af971e3586fd7cf2b4c9bfcba5b0e41d6deb2c0210 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x6f80e375bf182b03a572efa3d173f5e24d24c46767b539b09d5da71a6660f30, - right: 0x3a1195997ac1a9c0916fedc1e517f898107f3b7c77a296f9a35ff81151439aa, - } + BinaryNodeImpl::new( + 0x6f80e375bf182b03a572efa3d173f5e24d24c46767b539b09d5da71a6660f30, + 0x3a1195997ac1a9c0916fedc1e517f898107f3b7c77a296f9a35ff81151439aa + ) ), TrieNode::Binary( - BinaryNode { - left: 0x2647b8aa91f2bb4e1d69f4980edd96682f598cc48cbb20dbbf936ffc377b4e, - right: 0x39e7026a6f18dd6f708a8952c7b0aacbbf1db905218054297477d8c25318568, - } + BinaryNodeImpl::new( + 0x2647b8aa91f2bb4e1d69f4980edd96682f598cc48cbb20dbbf936ffc377b4e, + 0x39e7026a6f18dd6f708a8952c7b0aacbbf1db905218054297477d8c25318568 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x4e2a00cf57be57bbd118c9ab71895c7047183735ece0939e77788ec10e71012, - right: 0x41312dcf660136c32c91f58e3ee95369d19d412d64fa1ec4a23c294764bc882, - } + BinaryNodeImpl::new( + 0x4e2a00cf57be57bbd118c9ab71895c7047183735ece0939e77788ec10e71012, + 0x41312dcf660136c32c91f58e3ee95369d19d412d64fa1ec4a23c294764bc882 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x39e3c2bf03259269187def48eb867ad895db833facb97a2f470b582d36f437b, - right: 0x39bee0562de69bee56148afe63102e5b02f90a03633490a052bce4e34c2875f, - } + BinaryNodeImpl::new( + 0x39e3c2bf03259269187def48eb867ad895db833facb97a2f470b582d36f437b, + 0x39bee0562de69bee56148afe63102e5b02f90a03633490a052bce4e34c2875f + ) ), TrieNode::Binary( - BinaryNode { - left: 0x45db82dc29b036f35b7c66fc8dd13697daf088bbc927d25ca4cc9f1817a0089, - right: 0x52deda355e21ebb91d0c9b184691a18b1839ce7955120aa7fd80a6938d56f5d, - } + BinaryNodeImpl::new( + 0x45db82dc29b036f35b7c66fc8dd13697daf088bbc927d25ca4cc9f1817a0089, + 0x52deda355e21ebb91d0c9b184691a18b1839ce7955120aa7fd80a6938d56f5d + ) ), TrieNode::Binary( - BinaryNode { - left: 0x3e4394e2845c925b8472c7ee03cefe64c395a560bd75900088b10add7f51625, - right: 0xfb1ea9c19ce64ee5d00bb19cf5faac2872da0745a58ebf9079b2f6ff92ebda, - } + BinaryNodeImpl::new( + 0x3e4394e2845c925b8472c7ee03cefe64c395a560bd75900088b10add7f51625, + 0xfb1ea9c19ce64ee5d00bb19cf5faac2872da0745a58ebf9079b2f6ff92ebda + ) ), TrieNode::Binary( - BinaryNode { - left: 0x7043bd6bb907453c60db302e508991260904d039f410ff97d38bd2d60ca5d75, - right: 0x76886a77ca42c2dacb8780c85afc14182b1d8e41b60f93d2599218ebd557aa7, - } + BinaryNodeImpl::new( + 0x7043bd6bb907453c60db302e508991260904d039f410ff97d38bd2d60ca5d75, + 0x76886a77ca42c2dacb8780c85afc14182b1d8e41b60f93d2599218ebd557aa7 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x6e005e3c288932475c89a0027ab76f54305e52fdf76e1276822eafdd5467a8, - right: 0x6135e891729cd592e022cf5d41eff16aa7961d989e4d825f68c580578c4570, - } + BinaryNodeImpl::new( + 0x6e005e3c288932475c89a0027ab76f54305e52fdf76e1276822eafdd5467a8, + 0x6135e891729cd592e022cf5d41eff16aa7961d989e4d825f68c580578c4570 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x7fff05dc95866ab7824f986bf1397186f762e29492dd7a8acbe40f50f1d27ee, - right: 0x1bdf43fbab99379bdda54fbf68f8559e53e1d8a06856335bbe90c007de0e41b, - } + BinaryNodeImpl::new( + 0x7fff05dc95866ab7824f986bf1397186f762e29492dd7a8acbe40f50f1d27ee, + 0x1bdf43fbab99379bdda54fbf68f8559e53e1d8a06856335bbe90c007de0e41b + ) ), TrieNode::Binary( - BinaryNode { - left: 0x6ab794547fdc0c0df16d2b50d0888e9879e7d65f09b472d760035a9a2e20902, - right: 0x53fcb3fd666b04e0a47c1217ad463562592c6b9667e6ce6170b29f4caeb04f4, - } + BinaryNodeImpl::new( + 0x6ab794547fdc0c0df16d2b50d0888e9879e7d65f09b472d760035a9a2e20902, + 0x53fcb3fd666b04e0a47c1217ad463562592c6b9667e6ce6170b29f4caeb04f4 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x6635812b09537421c48fe6a76a0879044797b1f29dd64575cd43b033fcd5f1c, - right: 0x4e330b33f2a61e74481081c85f43cc04d16aa379f2b5a78c9b18759a49fcff1, - } + BinaryNodeImpl::new( + 0x6635812b09537421c48fe6a76a0879044797b1f29dd64575cd43b033fcd5f1c, + 0x4e330b33f2a61e74481081c85f43cc04d16aa379f2b5a78c9b18759a49fcff1 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x2958f83f705b6e469df752f5b3164daa32cf7b5ecb5f70d45ca1414ff506a07, - right: 0xfb5f65d6e84d9fcff953b7104fdd986deb87abf0d6718b6e428ba97a21238d, - } + BinaryNodeImpl::new( + 0x2958f83f705b6e469df752f5b3164daa32cf7b5ecb5f70d45ca1414ff506a07, + 0xfb5f65d6e84d9fcff953b7104fdd986deb87abf0d6718b6e428ba97a21238d + ) ), TrieNode::Binary( - BinaryNode { - left: 0x792f8b2826c608d0505c83ce3f3856aed9e0e5fe4ee000f5bfefc2d1ffbc61c, - right: 0x8677c2610258f9e59456fcae3d2308fb62f1d402c2dabf849dbd756ccef424, - } + BinaryNodeImpl::new( + 0x792f8b2826c608d0505c83ce3f3856aed9e0e5fe4ee000f5bfefc2d1ffbc61c, + 0x8677c2610258f9e59456fcae3d2308fb62f1d402c2dabf849dbd756ccef424 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x1701d58385b31302c77262266e4111e079c00344b991941fedd06dbd01d9396, - right: 0x7f986636ccc6810f859e062b93905d7ff21ac6bd902de9ee8c0701d623793fd, - } + BinaryNodeImpl::new( + 0x1701d58385b31302c77262266e4111e079c00344b991941fedd06dbd01d9396, + 0x7f986636ccc6810f859e062b93905d7ff21ac6bd902de9ee8c0701d623793fd + ) ), TrieNode::Binary( - BinaryNode { - left: 0x4c9bfbf1f1530a1af3243e828cc0d7985b54c8c1f0c8b8b5189e49d5040068b, - right: 0x1b10ed0481c3d5d12f0a2eaa7a67078550c2654cbafc33763802a90cf3203b3, - } + BinaryNodeImpl::new( + 0x4c9bfbf1f1530a1af3243e828cc0d7985b54c8c1f0c8b8b5189e49d5040068b, + 0x1b10ed0481c3d5d12f0a2eaa7a67078550c2654cbafc33763802a90cf3203b3 + ) ), TrieNode::Binary( - BinaryNode { - left: 0x2d0cea7e0eec26969fff766b2e37d001249103fc62a621a3ff6692325fc1096, - right: 0xea434f6ac5a646ee23bfe12099993ea0626f4d7aa7598fe0933cfc3ce140f7, - } + BinaryNodeImpl::new( + 0x2d0cea7e0eec26969fff766b2e37d001249103fc62a621a3ff6692325fc1096, + 0xea434f6ac5a646ee23bfe12099993ea0626f4d7aa7598fe0933cfc3ce140f7 + ) ), TrieNode::Edge( - EdgeNode { - path: 0x74624a0e3e0d8e6b72bd35514f62b3e8e70fbaff4ed27181de4ffd4604, - length: 232, - child: 0x275077fb6c1316d13a907, - } + EdgeNodeImpl::new( + 0x74624a0e3e0d8e6b72bd35514f62b3e8e70fbaff4ed27181de4ffd4604, + 0x275077fb6c1316d13a907, + 232 + ) ) ], - } - } + ) + ) } diff --git a/src/numeric/Scarb.toml b/src/numeric/Scarb.toml index 2968fe57..0bc1dbc9 100644 --- a/src/numeric/Scarb.toml +++ b/src/numeric/Scarb.toml @@ -3,6 +3,7 @@ name = "alexandria_numeric" version = "0.1.0" description = "A set of numerical analysis libraries and algorithms" homepage = "https://github.com/keep-starknet-strange/alexandria/tree/main/src/numeric" +edition = "2023_11" [tool] fmt.workspace = true diff --git a/src/numeric/src/cumprod.cairo b/src/numeric/src/cumprod.cairo index 1e0351d0..bde344ec 100644 --- a/src/numeric/src/cumprod.cairo +++ b/src/numeric/src/cumprod.cairo @@ -5,7 +5,7 @@ /// * `sequence` - The sequence to operate. /// # Returns /// * `Array` - The cumulative product of sequence. -fn cumprod, +Copy, +Drop,>(mut sequence: Span) -> Array { +pub fn cumprod, +Copy, +Drop,>(mut sequence: Span) -> Array { // [Check] Inputs assert(sequence.len() >= 1, 'Array must have at least 1 elt'); diff --git a/src/numeric/src/cumsum.cairo b/src/numeric/src/cumsum.cairo index caf9f95c..c1a16be5 100644 --- a/src/numeric/src/cumsum.cairo +++ b/src/numeric/src/cumsum.cairo @@ -5,7 +5,7 @@ /// * `sequence` - The sequence to operate. /// # Returns /// * `Array` - The cumulative sum of sequence. -fn cumsum, +Copy, +Drop,>(mut sequence: Span) -> Array { +pub fn cumsum, +Copy, +Drop,>(mut sequence: Span) -> Array { // [Check] Inputs assert(sequence.len() >= 1, 'Array must have at least 1 elt'); diff --git a/src/numeric/src/diff.cairo b/src/numeric/src/diff.cairo index 84d5ca72..96308b72 100644 --- a/src/numeric/src/diff.cairo +++ b/src/numeric/src/diff.cairo @@ -1,3 +1,4 @@ +use core::num::traits::Zero; //! The discrete difference of the elements. /// Compute the discrete difference of a sorted sequence. @@ -5,7 +6,7 @@ /// * `sequence` - The sorted sequence to operate. /// # Returns /// * `Array` - The discrete difference of sorted sequence. -fn diff, +Sub, +Copy, +Drop, +Zeroable,>( +pub fn diff, +Sub, +Copy, +Drop, +Zero,>( mut sequence: Span ) -> Array { // [Check] Inputs @@ -13,7 +14,7 @@ fn diff, +Sub, +Copy, +Drop, +Zeroable,>( // [Compute] Interpolation let mut prev_value = *sequence.pop_front().unwrap(); - let mut array = array![Zeroable::zero()]; + let mut array = array![Zero::zero()]; while let Option::Some(current_value) = sequence .pop_front() { assert(*current_value >= prev_value, 'Sequence must be sorted'); diff --git a/src/numeric/src/integers.cairo b/src/numeric/src/integers.cairo index fbd4f8b7..286cbf2e 100644 --- a/src/numeric/src/integers.cairo +++ b/src/numeric/src/integers.cairo @@ -1,6 +1,6 @@ use alexandria_math::BitShift; -trait UIntBytes { +pub trait UIntBytes { fn from_bytes(input: Span) -> Option; fn to_bytes(self: T) -> Span; fn bytes_used(self: T) -> u8; diff --git a/src/numeric/src/interpolate.cairo b/src/numeric/src/interpolate.cairo index 81787928..2477aa30 100644 --- a/src/numeric/src/interpolate.cairo +++ b/src/numeric/src/interpolate.cairo @@ -1,8 +1,9 @@ use alexandria_searching::binary_search::binary_search_closest as search; +use core::num::traits::Zero; //! One-dimensional linear interpolation for monotonically increasing sample points. #[derive(Serde, Copy, Drop, PartialEq)] -enum Interpolation { +pub enum Interpolation { Linear, Nearest, ConstantLeft, @@ -10,7 +11,7 @@ enum Interpolation { } #[derive(Serde, Copy, Drop, PartialEq)] -enum Extrapolation { +pub enum Extrapolation { Null, Constant, } @@ -24,17 +25,8 @@ enum Extrapolation { /// * `extrapolation` - The extrapolation method to use. /// # Returns /// * `T` - The interpolated y at x. -fn interpolate< - T, - +PartialOrd, - +NumericLiteral, - +Add, - +Sub, - +Mul, - +Div, - +Zeroable, - +Copy, - +Drop, +pub fn interpolate< + T, +PartialOrd, +Add, +Sub, +Mul, +Div, +Zero, +Copy, +Drop, >( x: T, xs: Span, ys: Span, interpolation: Interpolation, extrapolation: Extrapolation ) -> T { @@ -45,13 +37,13 @@ fn interpolate< // [Check] Extrapolation if x <= *xs[0] { return match extrapolation { - Extrapolation::Null => Zeroable::zero(), + Extrapolation::Null => Zero::zero(), Extrapolation::Constant => *ys[0], }; } if x >= *xs[xs.len() - 1] { return match extrapolation { - Extrapolation::Null => Zeroable::zero(), + Extrapolation::Null => Zero::zero(), Extrapolation::Constant => *ys[xs.len() - 1], }; } @@ -97,17 +89,8 @@ fn interpolate< } } -fn interpolate_fast< - T, - impl TPartialOrd: PartialOrd, - impl TNumericLiteral: NumericLiteral, - impl TAdd: Add, - impl TSub: Sub, - impl TMul: Mul, - impl TDiv: Div, - impl TZeroable: Zeroable, - impl TCopy: Copy, - impl TDrop: Drop, +pub fn interpolate_fast< + T, +PartialOrd, +Add, +Sub, +Mul, +Div, +Zero, +Copy, +Drop, >( x: T, xs: Span, ys: Span, interpolation: Interpolation, extrapolation: Extrapolation ) -> T { @@ -118,14 +101,14 @@ fn interpolate_fast< // [Check] Extrapolation if x <= *xs[0] { let y = match extrapolation { - Extrapolation::Null => Zeroable::zero(), + Extrapolation::Null => Zero::zero(), Extrapolation::Constant => *ys[0], }; return y; } if x >= *xs[xs.len() - 1] { let y = match extrapolation { - Extrapolation::Null => Zeroable::zero(), + Extrapolation::Null => Zero::zero(), Extrapolation::Constant => *ys[xs.len() - 1], }; return y; diff --git a/src/numeric/src/lib.cairo b/src/numeric/src/lib.cairo index e9585afb..c3e61a43 100644 --- a/src/numeric/src/lib.cairo +++ b/src/numeric/src/lib.cairo @@ -1,9 +1,9 @@ -mod cumprod; -mod cumsum; -mod diff; -mod integers; -mod interpolate; +pub mod cumprod; +pub mod cumsum; +pub mod diff; +pub mod integers; +pub mod interpolate; #[cfg(test)] mod tests; -mod trapezoidal_rule; +pub mod trapezoidal_rule; diff --git a/src/numeric/src/trapezoidal_rule.cairo b/src/numeric/src/trapezoidal_rule.cairo index 0cdd0073..8d86aa7d 100644 --- a/src/numeric/src/trapezoidal_rule.cairo +++ b/src/numeric/src/trapezoidal_rule.cairo @@ -1,3 +1,4 @@ +use core::num::traits::Zero; //! Integrate using the composite trapezoidal rule /// Integrate y(x). @@ -6,10 +7,9 @@ /// * `ys` - The ordinate sequence of len L. /// # Returns /// * `T` - The approximate integral. -fn trapezoidal_rule< +pub fn trapezoidal_rule< T, +PartialOrd, - +NumericLiteral, +Add, +AddEq, +Sub, @@ -17,7 +17,7 @@ fn trapezoidal_rule< +Div, +Copy, +Drop, - +Zeroable, + +Zero, +Into, >( xs: Span, ys: Span @@ -28,7 +28,7 @@ fn trapezoidal_rule< // [Compute] Trapezoidal rule let mut index = 0; - let mut value = Zeroable::zero(); + let mut value = Zero::zero(); while index + 1 != xs .len() { diff --git a/src/searching/Scarb.toml b/src/searching/Scarb.toml index d786b5c5..44d1ffe5 100644 --- a/src/searching/Scarb.toml +++ b/src/searching/Scarb.toml @@ -3,6 +3,7 @@ name = "alexandria_searching" version = "0.1.0" description = "A set of searching algorithms" homepage = "https://github.com/keep-starknet-strange/alexandria/tree/src/searching" +edition = "2023_11" [tool] fmt.workspace = true diff --git a/src/searching/src/binary_search.cairo b/src/searching/src/binary_search.cairo index 2dc8ac84..8c7cc785 100644 --- a/src/searching/src/binary_search.cairo +++ b/src/searching/src/binary_search.cairo @@ -1,4 +1,4 @@ -fn binary_search, +Drop, +PartialEq, +PartialOrd>( +pub fn binary_search, +Drop, +PartialEq, +PartialOrd>( span: Span, val: T ) -> Option { // Initial check @@ -27,7 +27,7 @@ fn binary_search, +Drop, +PartialEq, +PartialOrd>( } } -fn binary_search_closest, impl TDrop: Drop, impl TOr: PartialOrd>( +pub fn binary_search_closest, impl TDrop: Drop, impl TOr: PartialOrd>( span: Span, val: T ) -> Option { // Initial check diff --git a/src/searching/src/bm_search.cairo b/src/searching/src/bm_search.cairo index fd3beb4f..ac7b6555 100644 --- a/src/searching/src/bm_search.cairo +++ b/src/searching/src/bm_search.cairo @@ -1,12 +1,12 @@ // The Boyer-Moore string search algorithm -use dict::Felt252DictTrait; +use core::dict::Felt252DictTrait; /// Find `pattern` in `text` and return the index of every match. /// * `text` - The text to search in. /// * `pattern` - The pattern to search for. /// # Returns /// * `Array` - The index of every match. -fn bm_search(text: @ByteArray, pattern: @ByteArray) -> Array { +pub fn bm_search(text: @ByteArray, pattern: @ByteArray) -> Array { let mut positions: Array = array![]; // Array to store the indices of every match let text_len = text.len(); // Length of the text let pattern_len = pattern.len(); // Length of the pattern @@ -17,7 +17,7 @@ fn bm_search(text: @ByteArray, pattern: @ByteArray) -> Array { } // Dictionary to store the last occurrence of each character in the pattern - let mut char_dict = felt252_dict_new::(); + let mut char_dict = Default::default(); let mut pattern_index = 0; // Index of the current character in the pattern // Build the character dictionary diff --git a/src/searching/src/dijkstra.cairo b/src/searching/src/dijkstra.cairo index 500a7a66..5604e413 100644 --- a/src/searching/src/dijkstra.cairo +++ b/src/searching/src/dijkstra.cairo @@ -1,27 +1,44 @@ -use nullable::FromNullableResult; +use core::nullable::{FromNullableResult, match_nullable}; //! Dijkstra algorithm using priority queue #[derive(Copy, Drop)] -struct Node { +pub struct Node { source: u32, dest: u32, weight: u128 } +#[generate_trait] +pub impl NodeGetters of NodeGettersTrait { + fn weight(self: @Node) -> @u128 { + self.weight + } + + fn dest(self: @Node) -> @u32 { + self.dest + } + + fn source(self: @Node) -> @u32 { + self.source + } +} + /// Graph representation. -struct Graph { - nodes: Array, +pub struct Graph { + pub(crate) nodes: Array, adj_nodes: Felt252Dict, } /// Graph trait. -trait GraphTrait { +pub trait GraphTrait { /// Create a new graph instance. fn new() -> Graph>>; /// add an edge to graph fn add_edge(ref self: Graph>>, source: u32, dest: u32, weight: u128); /// return shortest path from s fn shortest_path(ref self: Graph>>, source: u32) -> Felt252Dict; + /// return shortest path from s + fn adj_nodes(ref self: Graph>>, source: felt252) -> Nullable>; } impl DestructGraph, +Felt252DictValue> of Destruct> { @@ -60,15 +77,20 @@ impl GraphImpl of GraphTrait { // add node self.nodes.append(node); // add adj node - self.adj_nodes.insert(source.into(), nullable_from_box(BoxTrait::new(nodes.span()))); + self.adj_nodes.insert(source.into(), NullableTrait::new(nodes.span())); } fn shortest_path(ref self: Graph>>, source: u32) -> Felt252Dict { dijkstra(ref self, source) } + + + fn adj_nodes(ref self: Graph>>, source: felt252) -> Nullable> { + self.adj_nodes.get(source) + } } -fn dijkstra(ref self: Graph>>, source: u32) -> Felt252Dict { +pub fn dijkstra(ref self: Graph>>, source: u32) -> Felt252Dict { let mut priority_queue = array![]; let mut visited_node = array![]; let mut dist: Felt252Dict = Default::default(); diff --git a/src/searching/src/levenshtein_distance.cairo b/src/searching/src/levenshtein_distance.cairo index 83b8c0e2..1d18ef3b 100644 --- a/src/searching/src/levenshtein_distance.cairo +++ b/src/searching/src/levenshtein_distance.cairo @@ -1,12 +1,12 @@ // The Levenshtein Distance -use dict::Felt252DictTrait; +use core::dict::Felt252DictTrait; /// Compute the edit distance between two byte arrays /// * `arr1` - The first byte array. /// * `arr2` - The second byte array. /// # Returns /// * `usize` - The edit distance between the two byte arrays. -fn levenshtein_distance(arr1: @ByteArray, arr2: @ByteArray) -> usize { +pub fn levenshtein_distance(arr1: @ByteArray, arr2: @ByteArray) -> usize { // Get the lengths of both arrays let arr1_len = arr1.len(); let arr2_len = arr2.len(); @@ -17,7 +17,7 @@ fn levenshtein_distance(arr1: @ByteArray, arr2: @ByteArray) -> usize { } // Initialize a dictionary to store previous distances, with keys and values as indices - let mut prev_distances = felt252_dict_new::(); + let mut prev_distances = Default::default(); let mut index: usize = 0; // Break the loop when index equals the length of the first array plus 1 while index != arr1_len + 1 { diff --git a/src/searching/src/lib.cairo b/src/searching/src/lib.cairo index c3921eb1..5466f013 100644 --- a/src/searching/src/lib.cairo +++ b/src/searching/src/lib.cairo @@ -1,7 +1,7 @@ -mod binary_search; -mod bm_search; -mod dijkstra; -mod levenshtein_distance; +pub mod binary_search; +pub mod bm_search; +pub mod dijkstra; +pub mod levenshtein_distance; #[cfg(test)] mod tests; diff --git a/src/searching/src/tests/bm_search_test.cairo b/src/searching/src/tests/bm_search_test.cairo index 959a0824..37b2d38c 100644 --- a/src/searching/src/tests/bm_search_test.cairo +++ b/src/searching/src/tests/bm_search_test.cairo @@ -1,29 +1,5 @@ use alexandria_searching::bm_search::bm_search; - -// Check if two arrays are equal. -/// * `a` - The first array. -/// * `b` - The second array. -/// # Returns -/// * `bool` - True if the arrays are equal, false otherwise. -fn is_equal(mut a: Span, mut b: Span) -> bool { - if a.len() != b.len() { - return false; - } - loop { - match a.pop_front() { - Option::Some(val1) => { - let val2 = b.pop_front().unwrap(); - if *val1 != *val2 { - break false; - } - }, - Option::None => { break true; }, - }; - } -} - - #[test] #[available_gas(5000000)] fn bm_search_test_1() { @@ -64,7 +40,7 @@ fn bm_search_test_1() { let positions = bm_search(@text, @pattern); let ground_truth: Array = array![1, 11, 20]; - assert!(is_equal(positions.span(), ground_truth.span()), "invalid result"); + assert_eq!(positions.span(), ground_truth.span(), "invalid result"); } #[test] @@ -105,7 +81,7 @@ fn bm_search_test_2() { let positions = bm_search(@text, @pattern); let ground_truth: Array = array![]; - assert!(is_equal(positions.span(), ground_truth.span()), "invalid result"); + assert_eq!(positions.span(), ground_truth.span(), "invalid result"); } #[test] @@ -146,5 +122,5 @@ fn bm_search_test_3() { let positions = bm_search(@text, @pattern); let ground_truth: Array = array![3, 13, 22]; - assert!(is_equal(positions.span(), ground_truth.span()), "invalid result"); + assert_eq!(positions.span(), ground_truth.span(), "invalid result"); } diff --git a/src/searching/src/tests/dijkstra_test.cairo b/src/searching/src/tests/dijkstra_test.cairo index bd39e379..3c62d0ce 100644 --- a/src/searching/src/tests/dijkstra_test.cairo +++ b/src/searching/src/tests/dijkstra_test.cairo @@ -1,5 +1,5 @@ -use alexandria_searching::dijkstra::{Graph, Node, GraphTrait}; -use nullable::FromNullableResult; +use alexandria_searching::dijkstra::{Graph, Node, GraphTrait, NodeGetters}; +use core::nullable::{FromNullableResult, match_nullable}; #[test] @@ -16,32 +16,32 @@ fn add_edge() { GraphTrait::add_edge(ref graph, 2, 1, 2); GraphTrait::add_edge(ref graph, 2, 3, 3); - assert!(graph.nodes.len() == 6, "wrong node number"); - let val = graph.adj_nodes.get(source.into()); + assert_eq!(graph.nodes.len(), 6, "wrong node number"); + let val = graph.adj_nodes(source.into()); let span = match match_nullable(val) { - FromNullableResult::Null => { panic_with_felt252('No value found') }, + FromNullableResult::Null => { panic!("No value found") }, FromNullableResult::NotNull(val) => { val.unbox() }, }; - assert!(span.len() == 4, "wrong nb of adj edge for node 0"); + assert_eq!(span.len(), 4, "wrong nb of adj edge for node 0"); let new_node = *span.get(1).unwrap().unbox(); - assert!(new_node.dest == dest + 1, "Wrong dest in adj edge"); - assert!(new_node.weight == weight + 1, "Wrong weight in adj edge"); + assert_eq!(*new_node.dest(), dest + 1, "Wrong dest in adj edge"); + assert_eq!(*new_node.weight(), weight + 1, "Wrong weight in adj edge"); let new_node = *span.get(3).unwrap().unbox(); - assert!(new_node.dest == dest + 3, "Wrong dest in adj edge"); - assert!(new_node.weight == weight + 3, "Wrong weight in adj edge"); + assert_eq!(*new_node.dest(), dest + 3, "Wrong dest in adj edge"); + assert_eq!(*new_node.weight(), weight + 3, "Wrong weight in adj edge"); - let val = graph.adj_nodes.get(2.into()); + let val = graph.adj_nodes(2.into()); let span = match match_nullable(val) { - FromNullableResult::Null => { panic_with_felt252('No value found') }, + FromNullableResult::Null => { panic!("No value found") }, FromNullableResult::NotNull(val) => { val.unbox() }, }; - assert!(span.len() == 2, "wrong nb of adj edge for node 2"); + assert_eq!(span.len(), 2, "wrong nb of adj edge for node 2"); } @@ -59,12 +59,12 @@ fn calculate_shortest_path() { let mut results: Felt252Dict = GraphTrait::shortest_path(ref graph, 0_u32); - assert!(results.get(0.into()) == 0, "Wrong weight for node 0"); - assert!(results.get(1.into()) == 5, "Wrong weight for node 1"); - assert!(results.get(2.into()) == 3, "Wrong weight for node 2"); - assert!(results.get(3.into()) == 2, "Wrong weight for node 3"); - assert!(results.get(4.into()) == 3, "Wrong weight for node 4"); - assert!(results.get(5.into()) == 3, "Wrong weight for node 5"); + assert_eq!(results.get(0.into()), 0, "Wrong weight for node 0"); + assert_eq!(results.get(1.into()), 5, "Wrong weight for node 1"); + assert_eq!(results.get(2.into()), 3, "Wrong weight for node 2"); + assert_eq!(results.get(3.into()), 2, "Wrong weight for node 3"); + assert_eq!(results.get(4.into()), 3, "Wrong weight for node 4"); + assert_eq!(results.get(5.into()), 3, "Wrong weight for node 5"); } #[test] @@ -80,11 +80,11 @@ fn calculate_shortest_path_random() { let mut results: Felt252Dict = GraphTrait::shortest_path(ref graph, 0_u32); - assert!(results.get(0.into()) == 0, "Wrong weight for node 0"); - assert!(results.get(2.into()) == 4, "Wrong weight for node 2"); - assert!(results.get(3.into()) == 5, "Wrong weight for node 3"); - assert!(results.get(1.into()) == 8, "Wrong weight for node 1"); - assert!(results.get(4.into()) == 7, "Wrong weight for node 4"); + assert_eq!(results.get(0.into()), 0, "Wrong weight for node 0"); + assert_eq!(results.get(2.into()), 4, "Wrong weight for node 2"); + assert_eq!(results.get(3.into()), 5, "Wrong weight for node 3"); + assert_eq!(results.get(1.into()), 8, "Wrong weight for node 1"); + assert_eq!(results.get(4.into()), 7, "Wrong weight for node 4"); } @@ -101,11 +101,11 @@ fn calculate_shortest_path_node_visited() { let mut results: Felt252Dict = GraphTrait::shortest_path(ref graph, 0_u32); - assert!(results.get(0.into()) == 0, "Wrong weight for node 0"); - assert!(results.get(1.into()) == 5, "Wrong weight for node 1"); - assert!(results.get(2.into()) == 3, "Wrong weight for node 2"); - assert!(results.get(3.into()) == 2, "Wrong weight for node 3"); - assert!(results.get(4.into()) == 3, "Wrong weight for node 4"); - assert!(results.get(5.into()) == 3, "Wrong weight for node 5"); + assert_eq!(results.get(0.into()), 0, "Wrong weight for node 0"); + assert_eq!(results.get(1.into()), 5, "Wrong weight for node 1"); + assert_eq!(results.get(2.into()), 3, "Wrong weight for node 2"); + assert_eq!(results.get(3.into()), 2, "Wrong weight for node 3"); + assert_eq!(results.get(4.into()), 3, "Wrong weight for node 4"); + assert_eq!(results.get(5.into()), 3, "Wrong weight for node 5"); } diff --git a/src/sorting/Scarb.toml b/src/sorting/Scarb.toml index 25c7db37..5a1ab819 100644 --- a/src/sorting/Scarb.toml +++ b/src/sorting/Scarb.toml @@ -3,6 +3,7 @@ name = "alexandria_sorting" version = "0.1.0" description = "A set of sorting algorithms" homepage = "https://github.com/keep-starknet-strange/alexandria/tree/src/sorting" +edition = "2023_11" [tool] fmt.workspace = true diff --git a/src/sorting/src/bubble_sort.cairo b/src/sorting/src/bubble_sort.cairo index 1a03a995..77683e75 100644 --- a/src/sorting/src/bubble_sort.cairo +++ b/src/sorting/src/bubble_sort.cairo @@ -5,7 +5,7 @@ /// * `array` - Array to sort /// # Returns /// * `Array` - Sorted array -fn bubble_sort_elements, +Drop, +PartialOrd, +PartialEq>( +pub fn bubble_sort_elements, +Drop, +PartialOrd, +PartialEq>( mut array: Array, asc: bool ) -> Array { if array.len() <= 1 { diff --git a/src/sorting/src/lib.cairo b/src/sorting/src/lib.cairo index d03cd063..c3b97c63 100644 --- a/src/sorting/src/lib.cairo +++ b/src/sorting/src/lib.cairo @@ -1,54 +1,12 @@ -mod bubble_sort; -mod merge_sort; -mod quick_sort; +pub mod bubble_sort; +pub mod merge_sort; +pub mod quick_sort; #[cfg(test)] mod tests; -use alexandria_data_structures::vec::{Felt252Vec, VecTrait}; -// Check if two arrays are equal. -/// * `a` - The first array. -/// * `b` - The second array. -/// # Returns -/// * `bool` - True if the arrays are equal, false otherwise. -fn is_equal(mut a: Span, mut b: Span) -> bool { - if a.len() != b.len() { - return false; - } - loop { - match a.pop_front() { - Option::Some(val1) => { - let val2 = b.pop_front().unwrap(); - if *val1 != *val2 { - break false; - } - }, - Option::None => { break true; }, - }; - } -} +use bubble_sort::bubble_sort_elements; +use merge_sort::merge; +// use quick_sort::quick_sort; // Cannot do as name collide. -/// * `a` - The first Felt252Vec. -/// * `b` - The second array. -/// # Returns -/// * `bool` - True if the arrays are equal, false otherwise. -fn is_equal_vec(mut a: Felt252Vec, mut b: Span) -> bool { - if a.len() != b.len() { - return false; - } - - let mut compare_id = 0; - - loop { - if compare_id == b.len() { - break true; - } - - if a[compare_id] != *b[compare_id] { - break false; - } - - compare_id += 1; - } -} diff --git a/src/sorting/src/merge_sort.cairo b/src/sorting/src/merge_sort.cairo index 9149a385..37c1b872 100644 --- a/src/sorting/src/merge_sort.cairo +++ b/src/sorting/src/merge_sort.cairo @@ -5,7 +5,7 @@ /// * `arr` - Array to sort /// # Returns /// * `Array` - Sorted array -fn merge, +Drop, +PartialOrd>(mut arr: Array) -> Array { +pub fn merge, +Drop, +PartialOrd>(mut arr: Array) -> Array { let len = arr.len(); if len <= 1 { return arr; diff --git a/src/sorting/src/quick_sort.cairo b/src/sorting/src/quick_sort.cairo index 3ac96414..99601d95 100644 --- a/src/sorting/src/quick_sort.cairo +++ b/src/sorting/src/quick_sort.cairo @@ -6,7 +6,7 @@ use alexandria_data_structures::vec::{Felt252Vec, VecTrait}; /// * `Felt252Vec` - Array to sort /// # Returns /// * `Felt252Vec` - Sorted array -fn quick_sort, +Drop, +PartialOrd, +PartialEq, +Felt252DictValue>( +pub fn quick_sort, +Drop, +PartialOrd, +PartialEq, +Felt252DictValue>( mut array: Felt252Vec ) -> Felt252Vec { let array_size = array.len(); diff --git a/src/sorting/src/tests/bubble_sort_test.cairo b/src/sorting/src/tests/bubble_sort_test.cairo index 38dec131..9ad7c4b0 100644 --- a/src/sorting/src/tests/bubble_sort_test.cairo +++ b/src/sorting/src/tests/bubble_sort_test.cairo @@ -1,157 +1,157 @@ -use alexandria_sorting::{is_equal, bubble_sort}; +use alexandria_sorting::bubble_sort_elements; #[test] #[available_gas(20000000000000)] -fn bubblesort_test() { +fn bubble_sort_test() { let data = array![4_u32, 2, 1, 3, 5, 0]; let correct = array![0_u32, 1, 2, 3, 4, 5]; - let sorted = bubble_sort::bubble_sort_elements(data, true); + let sorted = bubble_sort_elements(data, true); - assert!(is_equal(sorted.span(), correct.span()), "invalid result"); + assert_eq!(sorted.span(), correct.span(), "invalid result"); } #[test] #[available_gas(2000000)] -fn bubblesort_test_empty() { - let data = array![]; +fn bubble_sort_test_empty() { + let data: Array = array![]; let correct = array![]; - let sorted = bubble_sort::bubble_sort_elements(data, true); + let sorted = bubble_sort_elements(data, true); - assert!(is_equal(sorted.span(), correct.span()), "invalid result"); + assert_eq!(sorted.span(), correct.span(), "invalid result"); } #[test] #[available_gas(2000000)] -fn bubblesort_test_one_element() { +fn bubble_sort_test_one_element() { let data = array![2_u32]; let correct = array![2_u32]; - let sorted = bubble_sort::bubble_sort_elements(data, true); + let sorted = bubble_sort_elements(data, true); - assert!(is_equal(sorted.span(), correct.span()), "invalid result"); + assert_eq!(sorted.span(), correct.span(), "invalid result"); } #[test] #[available_gas(2000000)] -fn bubblesort_test_pre_sorted() { +fn bubble_sort_test_pre_sorted() { let data = array![1_u32, 2, 3, 4]; let correct = array![1_u32, 2, 3, 4]; - let sorted = bubble_sort::bubble_sort_elements(data, true); + let sorted = bubble_sort_elements(data, true); - assert!(is_equal(sorted.span(), correct.span()), "invalid result"); + assert_eq!(sorted.span(), correct.span(), "invalid result"); } #[test] #[available_gas(2000000)] -fn bubblesort_test_pre_sorted_decreasing() { +fn bubble_sort_test_pre_sorted_decreasing() { let data = array![4_u32, 3, 2, 1]; let correct = array![1_u32, 2, 3, 4]; - let sorted = bubble_sort::bubble_sort_elements(data, true); + let sorted = bubble_sort_elements(data, true); - assert!(is_equal(sorted.span(), correct.span()), "invalid result"); + assert_eq!(sorted.span(), correct.span(), "invalid result"); } #[test] #[available_gas(2000000)] -fn bubblesort_test_pre_sorted_2_same_values() { +fn bubble_sort_test_pre_sorted_2_same_values() { let data = array![1_u32, 2, 2, 4]; let correct = array![1_u32, 2, 2, 4]; - let sorted = bubble_sort::bubble_sort_elements(data, true); + let sorted = bubble_sort_elements(data, true); - assert!(is_equal(sorted.span(), correct.span()), "invalid result"); + assert_eq!(sorted.span(), correct.span(), "invalid result"); } #[test] #[available_gas(2000000)] -fn bubblesort_test_2_same_values() { +fn bubble_sort_test_2_same_values() { let data = array![1_u32, 2, 4, 2]; let correct = array![1_u32, 2, 2, 4]; - let sorted = bubble_sort::bubble_sort_elements(data, true); + let sorted = bubble_sort_elements(data, true); - assert!(is_equal(sorted.span(), correct.span()), "invalid result"); + assert_eq!(sorted.span(), correct.span(), "invalid result"); } #[test] #[available_gas(20000000000000)] -fn bubblesort_test_dsc() { +fn bubble_sort_test_dsc() { let data = array![4_u32, 2, 1, 3, 5, 0]; let correct = array![5_u32, 4, 3, 2, 1, 0]; - let sorted = bubble_sort::bubble_sort_elements(data, false); + let sorted = bubble_sort_elements(data, false); - assert!(is_equal(sorted.span(), correct.span()), "invalid result"); + assert_eq!(sorted.span(), correct.span(), "invalid result"); } #[test] #[available_gas(2000000)] -fn bubblesort_test_empty_dsc() { - let data = array![]; +fn bubble_sort_test_empty_dsc() { + let data: Array = array![]; let correct = array![]; - let sorted = bubble_sort::bubble_sort_elements(data, false); + let sorted = bubble_sort_elements(data, false); - assert!(is_equal(sorted.span(), correct.span()), "invalid result"); + assert_eq!(sorted.span(), correct.span(), "invalid result"); } #[test] #[available_gas(2000000)] -fn bubblesort_test_one_element_dsc() { +fn bubble_sort_test_one_element_dsc() { let data = array![2_u32]; let correct = array![2_u32]; - let sorted = bubble_sort::bubble_sort_elements(data, false); + let sorted = bubble_sort_elements(data, false); - assert!(is_equal(sorted.span(), correct.span()), "invalid result"); + assert_eq!(sorted.span(), correct.span(), "invalid result"); } #[test] #[available_gas(2000000)] -fn bubblesort_test_pre_sorted_dsc() { +fn bubble_sort_test_pre_sorted_dsc() { let data = array![1_u32, 2, 3, 4]; let correct = array![4_u32, 3, 2, 1]; - let sorted = bubble_sort::bubble_sort_elements(data, false); + let sorted = bubble_sort_elements(data, false); - assert!(is_equal(sorted.span(), correct.span()), "invalid result"); + assert_eq!(sorted.span(), correct.span(), "invalid result"); } #[test] #[available_gas(2000000)] -fn bubblesort_test_pre_sorted_decreasing_dsc() { +fn bubble_sort_test_pre_sorted_decreasing_dsc() { let data = array![4_u32, 3, 2, 1]; let correct = array![4_u32, 3, 2, 1]; - let sorted = bubble_sort::bubble_sort_elements(data, false); + let sorted = bubble_sort_elements(data, false); - assert!(is_equal(sorted.span(), correct.span()), "invalid result"); + assert_eq!(sorted.span(), correct.span(), "invalid result"); } #[test] #[available_gas(2000000)] -fn bubblesort_test_pre_sorted_2_same_values_dsc() { +fn bubble_sort_test_pre_sorted_2_same_values_dsc() { let data = array![1_u32, 2, 2, 4]; let correct = array![4_u32, 2, 2, 1]; - let sorted = bubble_sort::bubble_sort_elements(data, false); + let sorted = bubble_sort_elements(data, false); - assert!(is_equal(sorted.span(), correct.span()), "invalid result"); + assert_eq!(sorted.span(), correct.span(), "invalid result"); } #[test] #[available_gas(2000000)] -fn bubblesort_test_2_same_values_dsc() { +fn bubble_sort_test_2_same_values_dsc() { let data = array![1_u32, 2, 4, 2]; let correct = array![4_u32, 2, 2, 1]; - let sorted = bubble_sort::bubble_sort_elements(data, false); + let sorted = bubble_sort_elements(data, false); - assert!(is_equal(sorted.span(), correct.span()), "invalid result"); + assert_eq!(sorted.span(), correct.span(), "invalid result"); } diff --git a/src/sorting/src/tests/merge_sort_test.cairo b/src/sorting/src/tests/merge_sort_test.cairo index 1a15f74f..6ba5c156 100644 --- a/src/sorting/src/tests/merge_sort_test.cairo +++ b/src/sorting/src/tests/merge_sort_test.cairo @@ -1,79 +1,79 @@ -use alexandria_sorting::{is_equal, merge_sort::merge}; +use alexandria_sorting::merge; #[test] #[available_gas(2000000000)] -fn mergesort_test() { +fn merge_sort_test() { let data = array![7_u32, 4, 2, 6, 1, 3, 5, 8, 0]; let correct = array![0_u32, 1, 2, 3, 4, 5, 6, 7, 8].span(); let sorted = merge(data).span(); - assert!(is_equal(sorted, correct), "invalid result"); + assert_eq!(sorted, correct, "invalid result"); } #[test] #[available_gas(2000000)] -fn mergesort_test_2_pre_sorted_decreasing() { +fn merge_sort_test_2_pre_sorted_decreasing() { let data = array![4_u32, 3, 2, 1]; let correct = array![1_u32, 2, 3, 4]; let sorted = merge(data); - assert!(is_equal(sorted.span(), correct.span()), "invalid result"); + assert_eq!(sorted.span(), correct.span(), "invalid result"); } #[test] #[available_gas(2000000)] -fn mergesort_test_empty() { - let data = array![]; +fn merge_sort_test_empty() { + let data: Array = array![]; let correct = array![]; let sorted = merge(data); - assert!(is_equal(sorted.span(), correct.span()), "invalid result"); + assert_eq!(sorted.span(), correct.span(), "invalid result"); } #[test] #[available_gas(2000000)] -fn mergesort_test_one_element() { +fn merge_sort_test_one_element() { let data = array![2_u32]; let correct = array![2_u32]; let sorted = merge(data); - assert!(is_equal(sorted.span(), correct.span()), "invalid result"); + assert_eq!(sorted.span(), correct.span(), "invalid result"); } #[test] #[available_gas(2000000)] -fn mergesort_test_pre_sorted() { +fn merge_sort_test_pre_sorted() { let data = array![1_u32, 2, 3, 4]; let correct = array![1_u32, 2, 3, 4]; let sorted = merge(data); - assert!(is_equal(sorted.span(), correct.span()), "invalid result"); + assert_eq!(sorted.span(), correct.span(), "invalid result"); } #[test] #[available_gas(2000000)] -fn mergesort_test_2_same_values() { +fn merge_sort_test_2_same_values() { let data = array![1_u32, 2, 3, 2, 4]; let correct = array![1_u32, 2, 2, 3, 4]; let sorted = merge(data); - assert!(is_equal(sorted.span(), correct.span()), "invalid result"); + assert_eq!(sorted.span(), correct.span(), "invalid result"); } #[test] #[available_gas(2000000)] -fn mergesort_test_2_same_values_pre_sorted() { +fn merge_sort_test_2_same_values_pre_sorted() { let data = array![1_u32, 2, 2, 3, 4]; let correct = array![1_u32, 2, 2, 3, 4]; let sorted = merge(data); - assert!(is_equal(sorted.span(), correct.span()), "invalid result"); + assert_eq!(sorted.span(), correct.span(), "invalid result"); } diff --git a/src/sorting/src/tests/quick_sort_test.cairo b/src/sorting/src/tests/quick_sort_test.cairo index cc96033e..8aa58ee9 100644 --- a/src/sorting/src/tests/quick_sort_test.cairo +++ b/src/sorting/src/tests/quick_sort_test.cairo @@ -1,7 +1,29 @@ use alexandria_data_structures::vec::{Felt252Vec, VecTrait}; -use alexandria_sorting::{is_equal, is_equal_vec, quick_sort}; -use core::option::OptionTrait; - +use alexandria_sorting::quick_sort; + +/// * `a` - The first Felt252Vec. +/// * `b` - The second array. +/// # Returns +/// * `bool` - True if the arrays are equal, false otherwise. +fn is_equal_vec(mut a: Felt252Vec, mut b: Span) -> bool { + if a.len() != b.len() { + return false; + } + + let mut compare_id = 0; + + loop { + if compare_id == b.len() { + break true; + } + + if a[compare_id] != *b[compare_id] { + break false; + } + + compare_id += 1; + } +} #[test] #[available_gas(20000000000000)] diff --git a/src/storage/Scarb.toml b/src/storage/Scarb.toml index 4b8afb82..e483c83d 100644 --- a/src/storage/Scarb.toml +++ b/src/storage/Scarb.toml @@ -3,6 +3,7 @@ name = "alexandria_storage" version = "0.3.0" description = "Starknet storage utilities" homepage = "https://github.com/keep-starknet-strange/alexandria/tree/src/storage" +edition = "2023_11" [tool] fmt.workspace = true diff --git a/src/storage/src/lib.cairo b/src/storage/src/lib.cairo index 15b64dee..0c74cf8a 100644 --- a/src/storage/src/lib.cairo +++ b/src/storage/src/lib.cairo @@ -1,4 +1,6 @@ -mod list; +pub mod list; #[cfg(test)] mod tests; + +pub use list::{List, ListTrait}; diff --git a/src/storage/src/list.cairo b/src/storage/src/list.cairo index da8ac8dd..ffa074f0 100644 --- a/src/storage/src/list.cairo +++ b/src/storage/src/list.cairo @@ -1,22 +1,20 @@ -use integer::U32DivRem; -use poseidon::poseidon_hash_span; +use core::poseidon::poseidon_hash_span; +use core::traits::DivRem; use starknet::storage_access::{ - Store, StorageBaseAddress, storage_address_to_felt252, storage_address_from_base, - storage_base_address_from_felt252 + Store, StorageBaseAddress, storage_address_from_base, storage_base_address_from_felt252 }; -use starknet::{storage_read_syscall, storage_write_syscall, SyscallResult, SyscallResultTrait}; +use starknet::{SyscallResult, SyscallResultTrait}; const POW2_8: u32 = 256; // 2^8 #[derive(Drop)] -struct List { - address_domain: u32, - base: StorageBaseAddress, +pub struct List { + pub(crate) address_domain: u32, + pub(crate) base: StorageBaseAddress, len: u32, // number of elements in array - storage_size: u8 } -trait ListTrait { +pub trait ListTrait { /// Instantiates a new List with the given base address. /// /// @@ -147,13 +145,15 @@ trait ListTrait { /// An `Array` containing all the elements of the List, encapsulated /// in `SyscallResult`. fn array(self: @List) -> SyscallResult>; + + + fn storage_size(self: @List) -> u8; } impl ListImpl, +Drop, +Store> of ListTrait { #[inline(always)] fn new(address_domain: u32, base: StorageBaseAddress) -> List { - let storage_size: u8 = Store::::size(); - List { address_domain, base, len: 0, storage_size } + List { address_domain, base, len: 0 } } #[inline(always)] @@ -164,12 +164,12 @@ impl ListImpl, +Drop, +Store> of ListTrait { fn append_span(ref self: List, mut span: Span) -> SyscallResult<()> { let mut index = self.len; self.len += span.len(); - + let storage_size = self.storage_size(); loop { match span.pop_front() { Option::Some(v) => { let (base, offset) = calculate_base_and_offset_for_index( - self.base, index, self.storage_size + self.base, index, storage_size ); match Store::write_at_offset(self.address_domain, base, offset, *v) { Result::Ok(_) => {}, @@ -194,7 +194,7 @@ impl ListImpl, +Drop, +Store> of ListTrait { fn append(ref self: List, value: T) -> SyscallResult { let (base, offset) = calculate_base_and_offset_for_index( - self.base, self.len, self.storage_size + self.base, self.len, self.storage_size() ); Store::write_at_offset(self.address_domain, base, offset, value)?; @@ -211,7 +211,7 @@ impl ListImpl, +Drop, +Store> of ListTrait { } let (base, offset) = calculate_base_and_offset_for_index( - *self.base, index, *self.storage_size + *self.base, index, self.storage_size() ); let t = Store::read_at_offset(*self.address_domain, base, offset)?; Result::Ok(Option::Some(t)) @@ -220,7 +220,7 @@ impl ListImpl, +Drop, +Store> of ListTrait { fn set(ref self: List, index: u32, value: T) -> SyscallResult<()> { assert(index < self.len, 'List index out of bounds'); let (base, offset) = calculate_base_and_offset_for_index( - self.base, index, self.storage_size + self.base, index, self.storage_size() ); Store::write_at_offset(self.address_domain, base, offset, value) } @@ -266,6 +266,10 @@ impl ListImpl, +Drop, +Store> of ListTrait { Result::Err(e) => Result::Err(e) } } + + fn storage_size(self: @List) -> u8 { + Store::::size() + } } impl AListIndexViewImpl, +Drop, +Store> of IndexView, u32, T> { @@ -311,12 +315,10 @@ fn calculate_base_and_offset_for_index( list_base: StorageBaseAddress, index: u32, storage_size: u8 ) -> (StorageBaseAddress, u8) { let max_elements = POW2_8 / storage_size.into(); - let (key, offset) = U32DivRem::div_rem(index, max_elements.try_into().unwrap()); + let (key, offset) = DivRem::div_rem(index, max_elements.try_into().unwrap()); // hash the base address and the key which is the segment number - let addr_elements = array![ - storage_address_to_felt252(storage_address_from_base(list_base)), key.into() - ]; + let addr_elements = array![storage_address_from_base(list_base).into(), key.into()]; let segment_base = storage_base_address_from_felt252(poseidon_hash_span(addr_elements.span())); (segment_base, offset.try_into().unwrap() * storage_size) @@ -325,8 +327,7 @@ fn calculate_base_and_offset_for_index( impl ListStore> of Store> { fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult> { let len: u32 = Store::read(address_domain, base).unwrap_syscall(); - let storage_size: u8 = Store::::size(); - Result::Ok(List { address_domain, base, len, storage_size }) + Result::Ok(List { address_domain, base, len }) } #[inline(always)] @@ -338,8 +339,7 @@ impl ListStore> of Store> { address_domain: u32, base: StorageBaseAddress, offset: u8 ) -> SyscallResult> { let len: u32 = Store::read_at_offset(address_domain, base, offset).unwrap_syscall(); - let storage_size: u8 = Store::::size(); - Result::Ok(List { address_domain, base, len, storage_size }) + Result::Ok(List { address_domain, base, len }) } #[inline(always)] diff --git a/src/storage/src/tests/list_test.cairo b/src/storage/src/tests/list_test.cairo index 91e0a4f9..8cb1ebeb 100644 --- a/src/storage/src/tests/list_test.cairo +++ b/src/storage/src/tests/list_test.cairo @@ -22,7 +22,7 @@ trait IAListHolder { #[starknet::contract] mod AListHolder { - use alexandria_storage::list::{List, ListTrait}; + use alexandria_storage::{List, ListTrait}; use starknet::ContractAddress; #[storage] @@ -111,20 +111,20 @@ mod AListHolder { #[cfg(test)] mod tests { use AListHolder::{addressesContractMemberStateTrait, numbersContractMemberStateTrait}; - use alexandria_storage::list::{List, ListTrait}; - use debug::PrintTrait; + use alexandria_storage::{List, ListTrait}; use starknet::{ - ClassHash, ContractAddress, deploy_syscall, SyscallResultTrait, - testing::set_contract_address, storage_address_from_base, storage_address_to_felt252, - storage_base_address_from_felt252, StorageBaseAddress + ClassHash, ContractAddress, syscalls::deploy_syscall, SyscallResultTrait, + testing::set_contract_address, + storage_access::{ + storage_base_address_from_felt252, storage_address_from_base, StorageBaseAddress + } }; use super::{AListHolder, IAListHolderDispatcher, IAListHolderDispatcherTrait}; impl StorageBaseAddressPartialEq of PartialEq { fn eq(lhs: @StorageBaseAddress, rhs: @StorageBaseAddress) -> bool { - storage_address_to_felt252( - storage_address_from_base(*lhs) - ) == storage_address_to_felt252(storage_address_from_base(*rhs)) + let left: felt252 = storage_address_from_base(*lhs).into(); + left == storage_address_from_base(*rhs).into() } fn ne(lhs: @StorageBaseAddress, rhs: @StorageBaseAddress) -> bool { @@ -162,14 +162,14 @@ mod tests { assert_eq!(addresses_list.address_domain, 0, "Address domain should be 0"); assert_eq!(addresses_list.len(), 0, "Initial length should be 0"); assert_eq!(addresses_list.base.into(), addresses_address, "Base address mismatch"); - assert_eq!(addresses_list.storage_size, 1, "Storage size should be 1"); + assert_eq!(addresses_list.storage_size(), 1, "Storage size should be 1"); let numbers_address = contract_state.numbers.address(); let numbers_list = ListTrait::::new(0, numbers_address); assert_eq!(numbers_list.address_domain, 0, "Address domain should be 0"); assert_eq!(numbers_list.len(), 0, "Initial length should be 0"); assert_eq!(numbers_list.base.into(), numbers_address, "Base address mismatch"); - assert_eq!(numbers_list.storage_size, 2, "Storage size should be 2"); + assert_eq!(numbers_list.storage_size(), 2, "Storage size should be 2"); // Check if both addresses and numbers lists are initialized to be empty assert_eq!(contract.do_get_len(), (0, 0), "Initial lengths should be 0"); @@ -212,7 +212,7 @@ mod tests { assert_eq!(empty_list.address_domain, 0, "Address domain should be 0"); assert_eq!(empty_list.len(), 0, "Length should be 0"); assert_eq!(empty_list.base.into(), storage_address, "Base address mismatch"); - assert_eq!(empty_list.storage_size, 1, "Storage size should be 1"); + assert_eq!(empty_list.storage_size(), 1, "Storage size should be 1"); } @@ -233,7 +233,7 @@ mod tests { assert_eq!(addresses_list.address_domain, 0, "Address domain should be 0"); assert_eq!(addresses_list.len(), 2, "Length should be 2"); assert_eq!(addresses_list.base.into(), addresses_address, "Base address mismatch"); - assert_eq!(addresses_list.storage_size, 1, "Storage size should be 1"); + assert_eq!(addresses_list.storage_size(), 1, "Storage size should be 1"); let numbers_address = contract_state.numbers.address(); let numbers_list = ListTrait::::fetch(0, numbers_address).expect('List fetch failed'); diff --git a/src/utils/Scarb.toml b/src/utils/Scarb.toml index 3bff61b7..12196633 100644 --- a/src/utils/Scarb.toml +++ b/src/utils/Scarb.toml @@ -3,6 +3,7 @@ name = "alexandria_utils" version = "0.1.0" description = "Cairo utilities" homepage = "https://github.com/keep-starknet-strange/alexandria/tree/src/utils" +edition = "2023_11" [tool] fmt.workspace = true diff --git a/src/utils/src/fmt.cairo b/src/utils/src/fmt.cairo index 0bd27aa3..1a61bc0f 100644 --- a/src/utils/src/fmt.cairo +++ b/src/utils/src/fmt.cairo @@ -1,12 +1,12 @@ use core::fmt::{Display, Debug, Formatter, Error}; -use starknet::{ContractAddress, EthAddress, ClassHash, StorageAddress, StorageBaseAddress}; +use starknet::{ContractAddress, EthAddress, ClassHash, StorageAddress}; /// Display mod display_felt252_based { use core::fmt::{Display, Formatter, Error}; use core::to_byte_array::AppendFormattedToByteArray; - impl TDisplay, +Copy> of Display { + pub impl TDisplay, +Copy> of Display { fn fmt(self: @T, ref f: Formatter) -> Result<(), Error> { let value: felt252 = (*self).into(); Display::::fmt(@value.into(), ref f) @@ -14,16 +14,16 @@ mod display_felt252_based { } } -impl EthAddressDisplay = display_felt252_based::TDisplay; -impl ContractAddressDisplay = display_felt252_based::TDisplay; -impl ClassHashDisplay = display_felt252_based::TDisplay; -impl StorageAddressDisplay = display_felt252_based::TDisplay; +pub impl EthAddressDisplay = display_felt252_based::TDisplay; +pub impl ContractAddressDisplay = display_felt252_based::TDisplay; +pub impl ClassHashDisplay = display_felt252_based::TDisplay; +pub impl StorageAddressDisplay = display_felt252_based::TDisplay; /// Debug mod debug_display_based { use core::fmt::{Display, Debug, Formatter, Error}; use core::to_byte_array::AppendFormattedToByteArray; - impl TDebug> of Debug { + pub impl TDebug> of Debug { fn fmt(self: @T, ref f: Formatter) -> Result<(), Error> { Display::fmt(self, ref f) } @@ -31,10 +31,10 @@ mod debug_display_based { } -impl EthAddressDebug = debug_display_based::TDebug; -impl ContractAddressDebug = debug_display_based::TDebug; -impl ClassHashDebug = debug_display_based::TDebug; -impl StorageAddressDebug = debug_display_based::TDebug; +pub impl EthAddressDebug = debug_display_based::TDebug; +pub impl ContractAddressDebug = debug_display_based::TDebug; +pub impl ClassHashDebug = debug_display_based::TDebug; +pub impl StorageAddressDebug = debug_display_based::TDebug; impl ArrayTDebug, +Copy> of Debug> { fn fmt(self: @Array, ref f: Formatter) -> Result<(), Error> { @@ -42,7 +42,7 @@ impl ArrayTDebug, +Copy> of Debug> { } } -impl SpanTDebug, +Copy> of Debug> { +pub impl SpanTDebug, +Copy> of Debug> { fn fmt(self: @Span, ref f: Formatter) -> Result<(), Error> { let mut self = *self; write!(f, "[")?; diff --git a/src/utils/src/lib.cairo b/src/utils/src/lib.cairo index bd1b1d1b..4294b191 100644 --- a/src/utils/src/lib.cairo +++ b/src/utils/src/lib.cairo @@ -1 +1 @@ -mod fmt; +pub mod fmt;