Skip to content

Commit

Permalink
bytes_to_bytes8 cost annihiltation
Browse files Browse the repository at this point in the history
  • Loading branch information
ClementWalter committed Jan 23, 2025
1 parent 9822828 commit b7656c4
Showing 1 changed file with 116 additions and 61 deletions.
177 changes: 116 additions & 61 deletions cairo/src/utils/bytes.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -288,77 +288,132 @@ func bytes_to_bytes8_little_endian{range_check_ptr}(dst: felt*, bytes_len: felt,
return ();
}

let (local pow256) = get_label_location(pow256_table);
let (full_u64_word_count, local last_input_num_bytes) = unsigned_div_rem(bytes_len, 8);
local range_check_ptr = range_check_ptr;

tempvar dst_index = 0;
tempvar bytes_index = bytes_len - 1;
tempvar bytes8 = 0;
tempvar bytes8_index = 7;

body:
let dst_index = [ap - 4];
let bytes_index = [ap - 3];
let bytes8 = [ap - 2];
let bytes8_index = [ap - 1];

let bytes_len = [fp - 4];
let bytes = cast([fp - 3], felt*);
let pow256 = cast([fp], felt*);
let current_byte = bytes[bytes_len - 1 - bytes_index];
let current_pow = pow256[bytes8_index];
tempvar less_than_8;
%{ ids.less_than_8 = int(ids.bytes_len < 8) %}
tempvar bytes8 = dst;
tempvar bytes = bytes;

tempvar bytes8 = bytes8 + current_byte * current_pow;
static_assert bytes8 == [ap - 2];
static_assert bytes == [ap - 1];

jmp skip_full_word_loop if less_than_8 != 0;

full_word_loop:
let bytes8 = cast([ap - 2], felt*);
let bytes = cast([ap - 1], felt*);

assert [bytes8] = bytes[0] + bytes[1] * 256 + bytes[2] * 256 ** 2 + bytes[3] * 256 ** 3 + bytes[
4
] * 256 ** 4 + bytes[5] * 256 ** 5 + bytes[6] * 256 ** 6 + bytes[7] * 256 ** 7;
tempvar continue_loop;
tempvar bytes8 = bytes8 + 1;
tempvar bytes = bytes + 8;
%{ ids.continue_loop = int(ids.bytes_len - (ids.bytes8 - memory[fp - 5]) * 8 >= 8) %}

jmp full_word_loop if continue_loop != 0;

skip_full_word_loop:
let bytes8 = cast([ap - 2], felt*);
let bytes = cast([ap - 1], felt*);

tempvar remaining;
%{ ids.remaining = 2 * (ids.bytes_len - (ids.bytes8 - memory[fp - 5]) * 8) + 1 %}
static_assert bytes8 == [ap - 3];
static_assert bytes == [ap - 2];
jmp rel remaining;
jmp remaining_0;
jmp remaining_1;
jmp remaining_2;
jmp remaining_3;
jmp remaining_4;
jmp remaining_5;
jmp remaining_6;
jmp remaining_7;

remaining_7:
let dst = cast([fp - 5], felt*);
let bytes_len = cast([fp - 4], felt);
let bytes8 = cast([ap - 3], felt*);
let bytes = cast([ap - 2], felt*);
assert (bytes8 - dst) * 8 = bytes_len - 7;
assert [bytes8] = bytes[0] + bytes[1] * 256 + bytes[2] * 256 ** 2 + bytes[3] * 256 ** 3 + bytes[
4
] * 256 ** 4 + bytes[5] * 256 ** 5 + bytes[6] * 256 ** 6;
let range_check_ptr = [fp - 6];
return ();

jmp next if bytes_index != 0;
jmp end_word_not_full if bytes8_index != 0;
remaining_6:
let dst = cast([fp - 5], felt*);
let bytes_len = cast([fp - 4], felt);
let bytes8 = cast([ap - 3], felt*);
let bytes = cast([ap - 2], felt*);
assert (bytes8 - dst) * 8 = bytes_len - 6;
assert [bytes8] = bytes[0] + bytes[1] * 256 + bytes[2] * 256 ** 2 + bytes[3] * 256 ** 3 + bytes[
4
] * 256 ** 4 + bytes[5] * 256 ** 5;
let range_check_ptr = [fp - 6];
return ();

let last_input_num_bytes = [fp + 1];
assert [dst + dst_index] = bytes8;
let range_check_ptr = [fp + 2];
remaining_5:
let dst = cast([fp - 5], felt*);
let bytes_len = cast([fp - 4], felt);
let bytes8 = cast([ap - 3], felt*);
let bytes = cast([ap - 2], felt*);
assert (bytes8 - dst) * 8 = bytes_len - 5;
assert [bytes8] = bytes[0] + bytes[1] * 256 + bytes[2] * 256 ** 2 + bytes[3] * 256 ** 3 + bytes[
4
] * 256 ** 4;
let range_check_ptr = [fp - 6];
return ();

next:
jmp regular if bytes8_index != 0;
remaining_4:
let dst = cast([fp - 5], felt*);
let bytes_len = cast([fp - 4], felt);
let bytes8 = cast([ap - 3], felt*);
let bytes = cast([ap - 2], felt*);
assert (bytes8 - dst) * 8 = bytes_len - 4;
assert [bytes8] = bytes[0] + bytes[1] * 256 + bytes[2] * 256 ** 2 + bytes[3] * 256 ** 3;
let range_check_ptr = [fp - 6];
return ();

assert [dst + dst_index] = bytes8;
remaining_3:
let dst = cast([fp - 5], felt*);
let bytes_len = cast([fp - 4], felt);
let bytes8 = cast([ap - 3], felt*);
let bytes = cast([ap - 2], felt*);
assert (bytes8 - dst) * 8 = bytes_len - 3;
assert [bytes8] = bytes[0] + bytes[1] * 256 + bytes[2] * 256 ** 2;
let range_check_ptr = [fp - 6];
return ();

tempvar dst_index = dst_index + 1;
tempvar bytes_index = bytes_index - 1;
tempvar bytes8 = 0;
tempvar bytes8_index = 7;
static_assert dst_index == [ap - 4];
static_assert bytes_index == [ap - 3];
static_assert bytes8 == [ap - 2];
static_assert bytes8_index == [ap - 1];
jmp body;

regular:
tempvar dst_index = dst_index;
tempvar bytes_index = bytes_index - 1;
tempvar bytes8 = bytes8;
tempvar bytes8_index = bytes8_index - 1;
static_assert dst_index == [ap - 4];
static_assert bytes_index == [ap - 3];
static_assert bytes8 == [ap - 2];
static_assert bytes8_index == [ap - 1];
jmp body;
remaining_2:
let dst = cast([fp - 5], felt*);
let bytes_len = cast([fp - 4], felt);
let bytes8 = cast([ap - 3], felt*);
let bytes = cast([ap - 2], felt*);
assert (bytes8 - dst) * 8 = bytes_len - 2;
assert [bytes8] = bytes[0] + bytes[1] * 256;
let range_check_ptr = [fp - 6];
return ();

end_word_not_full:
assert [dst + dst_index] = bytes8;
let range_check_ptr = [fp + 2];
remaining_1:
let dst = cast([fp - 5], felt*);
let bytes_len = cast([fp - 4], felt);
let bytes8 = cast([ap - 3], felt*);
let bytes = cast([ap - 2], felt*);
assert (bytes8 - dst) * 8 = bytes_len - 1;
assert [bytes8] = bytes[0];
let range_check_ptr = [fp - 6];
return ();

pow256_table:
dw 256 ** 7;
dw 256 ** 6;
dw 256 ** 5;
dw 256 ** 4;
dw 256 ** 3;
dw 256 ** 2;
dw 256 ** 1;
dw 256 ** 0;
remaining_0:
let dst = cast([fp - 5], felt*);
let bytes_len = cast([fp - 4], felt);
let bytes8 = cast([ap - 3], felt*);
let bytes = cast([ap - 2], felt*);
assert (bytes8 - dst) * 8 = bytes_len;
let range_check_ptr = [fp - 6];
return ();
}

func keccak{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, keccak_ptr: KeccakBuiltin*}(
Expand Down

0 comments on commit b7656c4

Please sign in to comment.