Skip to content

Commit 8bebf62

Browse files
authored
Updated Split concept to allow more efficient Byte reads. (#8555)
1 parent c1be7b8 commit 8bebf62

File tree

7 files changed

+7621
-7669
lines changed

7 files changed

+7621
-7669
lines changed

corelib/src/byte_array.cairo

Lines changed: 180 additions & 130 deletions
Large diffs are not rendered by default.

corelib/src/bytes_31.cairo

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -125,50 +125,6 @@ pub(crate) impl U128IntoBytes31 of Into<u128, bytes31> {
125125
}
126126
}
127127

128-
/// Splits a `bytes31` into two `bytes31`s at the given index (LSB's index is 0).
129-
/// The input `bytes31` and the output `bytes31`s are represented using `felt252`s to improve
130-
/// performance.
131-
///
132-
/// Note: this function assumes that:
133-
/// 1. `word` is validly convertible to a `bytes31` which has no more than `len` bytes of data.
134-
/// 2. `index <= len`.
135-
/// 3. `len <= BYTES_IN_BYTES31`.
136-
/// If these assumptions are not met, it can corrupt the `bytes31`. Thus, this should be a
137-
/// private function. We could add masking/assertions but it would be more expensive.
138-
pub(crate) fn split_bytes31(word: felt252, len: usize, index: usize) -> (felt252, felt252) {
139-
if index == 0 {
140-
return (0, word);
141-
}
142-
if index == len {
143-
return (word, 0);
144-
}
145-
146-
let u256 { low, high } = word.into();
147-
148-
if index == BYTES_IN_U128 {
149-
return (low.into(), high.into());
150-
}
151-
152-
if len <= BYTES_IN_U128 {
153-
let result = split_u128(low, index);
154-
return (result.low.into(), result.high.into());
155-
}
156-
157-
// len > BYTES_IN_U128
158-
if index < BYTES_IN_U128 {
159-
let low_result = split_u128(low, index);
160-
let right = high.into() * one_shift_left_bytes_u128(BYTES_IN_U128 - index).into()
161-
+ low_result.high.into();
162-
return (low_result.low.into(), right);
163-
}
164-
165-
// len > BYTES_IN_U128 && index > BYTES_IN_U128
166-
167-
let high_result = split_u128(high, index - BYTES_IN_U128);
168-
let left = high_result.low.into() * POW_2_128 + low.into();
169-
return (left, high_result.high.into());
170-
}
171-
172128
/// Returns `1 << (8 * n_bytes)` as `u128`, where `n_bytes` must be < `BYTES_IN_U128`.
173129
///
174130
/// Panics if `n_bytes >= BYTES_IN_U128`.

corelib/src/test/bytes31_test.cairo

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use crate::bytes_31::{bytes31_const, split_bytes31};
1+
use crate::byte_array::split_bytes31_for_testing as split_bytes31;
2+
use crate::bytes_31::bytes31_const;
23

34
const POW_2_248: felt252 = 0x100000000000000000000000000000000000000000000000000000000000000;
45

@@ -137,32 +138,32 @@ fn test_u128_into_bytes31() {
137138

138139
#[test]
139140
fn test_split_bytes31() {
140-
let (left, right) = split_bytes31(0x1122, 2, 1);
141+
let (left, right) = split_bytes31(0x1122, 1);
141142
assert(left == 0x22, 'bad split (2, 1) left');
142143
assert(right == 0x11, 'bad split (2, 1) right');
143144

144145
let x = 0x112233445566778899aabbccddeeff00112233;
145-
let (left, right) = split_bytes31(x, 19, 0);
146+
let (left, right) = split_bytes31(x, 0);
146147
assert(left == 0, 'bad split (19, 0) left');
147148
assert(right == 0x112233445566778899aabbccddeeff00112233, 'bad split (19, 0) right');
148149

149-
let (left, right) = split_bytes31(x, 19, 1);
150+
let (left, right) = split_bytes31(x, 1);
150151
assert(left == 0x33, 'bad split (19, 1) left');
151152
assert(right == 0x112233445566778899aabbccddeeff001122, 'bad split (19, 1) right');
152153

153-
let (left, right) = split_bytes31(x, 19, 15);
154+
let (left, right) = split_bytes31(x, 15);
154155
assert(left == 0x5566778899aabbccddeeff00112233, 'bad split (19, 15) left');
155156
assert(right == 0x11223344, 'bad split (19, 15) right');
156157

157-
let (left, right) = split_bytes31(x, 19, 16);
158+
let (left, right) = split_bytes31(x, 16);
158159
assert(left == 0x445566778899aabbccddeeff00112233, 'bad split (19, 16) left');
159160
assert(right == 0x112233, 'bad split (19, 16) right');
160161

161-
let (left, right) = split_bytes31(x, 19, 18);
162+
let (left, right) = split_bytes31(x, 18);
162163
assert(left == 0x2233445566778899aabbccddeeff00112233, 'bad split (19, 18) left');
163164
assert(right == 0x11, 'bad split (19, 18) right');
164165

165-
let (left, right) = split_bytes31(x, 19, 19);
166+
let (left, right) = split_bytes31(x, 19);
166167
assert(left == 0x112233445566778899aabbccddeeff00112233, 'bad split (19, 19) left');
167168
assert(right == 0, 'bad split (19, 19) right');
168169
}

crates/cairo-lang-starknet/cairo_level_tests/abi_dispatchers_tests.cairo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ fn test_validate_gas_cost() {
112112
assert!(
113113
call_building_gas_usage == 3930
114114
&& serialization_gas_usage == 27670
115-
&& entry_point_gas_usage == 100930,
115+
&& entry_point_gas_usage == 104530,
116116
"Unexpected gas_usage:
117117
call_building: `{call_building_gas_usage}`.
118118
serialization: `{serialization_gas_usage}`.

0 commit comments

Comments
 (0)