From 0c1704e101e49c60ab676ad61dbf2b2a1375e0ff Mon Sep 17 00:00:00 2001 From: meship-starkware Date: Tue, 30 Sep 2025 16:29:04 +0300 Subject: [PATCH] starknet_os: change all encoding to le in naive blake --- .../starkware/starknet/core/os/encrypt.cairo | 11 +++--- .../starknet/core/os/naive_blake.cairo | 36 +++++++++---------- .../src/program_hash.json | 6 ++-- .../blake2s/implementation.rs | 3 +- .../state_diff_encryption/utils.rs | 8 ++--- 5 files changed, 30 insertions(+), 34 deletions(-) diff --git a/crates/apollo_starknet_os_program/src/cairo/starkware/starknet/core/os/encrypt.cairo b/crates/apollo_starknet_os_program/src/cairo/starkware/starknet/core/os/encrypt.cairo index b68b919e0c3..43b5b12943b 100644 --- a/crates/apollo_starknet_os_program/src/cairo/starkware/starknet/core/os/encrypt.cairo +++ b/crates/apollo_starknet_os_program/src/cairo/starkware/starknet/core/os/encrypt.cairo @@ -6,7 +6,7 @@ from starkware.cairo.common.registers import get_fp_and_pc from starkware.starknet.core.os.naive_blake import ( calc_blake_hash, naive_encode_felt252s_to_u32s, - u256_to_felt, + felt_from_le_u32s, create_initial_state_for_blake2s, blake_with_opcode_for_single_16_length_word, ) @@ -197,21 +197,22 @@ func encrypt_inner{range_check_ptr, encrypted_dst: felt*}( assert blake_output[6] = encoded_symmetric_key[6]; assert blake_output[7] = encoded_symmetric_key[7]; let blake_output = &blake_output[8]; - // Write encoded index to blake output - since index is small, manually encode as [0, 0, 0, 0, 0, 0, 0, index]. - assert blake_output[0] = 0; + // Write encoded index to blake output - since index is small, + // manually encode in little-endian notion as [index, 0, 0, 0, 0, 0, 0, 0]. + assert blake_output[0] = index; assert blake_output[1] = 0; assert blake_output[2] = 0; assert blake_output[3] = 0; assert blake_output[4] = 0; assert blake_output[5] = 0; assert blake_output[6] = 0; - assert blake_output[7] = index; + assert blake_output[7] = 0; let blake_output = &blake_output[8]; // Calculate blake hash modulo prime. blake_with_opcode_for_single_16_length_word( data=blake_encoding_start, out=blake_output, initial_state=initial_state ); - let hash = u256_to_felt(u256=blake_output); + let hash = felt_from_le_u32s(u32s=blake_output); let blake_output = &blake_output[8]; // Encrypt the current element. diff --git a/crates/apollo_starknet_os_program/src/cairo/starkware/starknet/core/os/naive_blake.cairo b/crates/apollo_starknet_os_program/src/cairo/starkware/starknet/core/os/naive_blake.cairo index a48da28c796..f2b8a830313 100644 --- a/crates/apollo_starknet_os_program/src/cairo/starkware/starknet/core/os/naive_blake.cairo +++ b/crates/apollo_starknet_os_program/src/cairo/starkware/starknet/core/os/naive_blake.cairo @@ -1,6 +1,14 @@ from starkware.cairo.common.alloc import alloc from starkware.cairo.common.cairo_blake2s.blake2s import blake_with_opcode +// Gets a felt that represent a 256-bit unsigned integer stored as an array of eight 32-bit unsigned integers +// represented in little-endian notation. Return the felt representation of the integer modulo prime. +func felt_from_le_u32s(u32s: felt*) -> felt { + let value = u32s[7] * 2 ** 224 + u32s[6] * 2 ** 192 + u32s[5] * 2 ** 160 + u32s[4] * 2 ** 128 + + u32s[3] * 2 ** 96 + u32s[2] * 2 ** 64 + u32s[1] * 2 ** 32 + u32s[0]; + return value; +} + // Computes blake2s of `input` of size 16 felts, representing 32 bits each. // The initial state is the standard BLAKE2s IV XORed with the parameter block P[0] = 0x01010020. func blake_with_opcode_for_single_16_length_word(data: felt*, out: felt*, initial_state: felt*) { @@ -51,10 +59,9 @@ func create_initial_state_for_blake2s() -> (initial_state: felt*) { } // Encodes a list of felt252s to a list of u32s, each felt is mapped to eight u32s. -// Returns the length of the resulting list of u32s. func naive_encode_felt252s_to_u32s( packed_values_len: felt, packed_values: felt*, unpacked_u32s: felt* -) -> felt { +) { alloc_locals; local end: felt* = &packed_values[packed_values_len]; @@ -65,41 +72,30 @@ func naive_encode_felt252s_to_u32s( loop: if (end == packed_values) { - return out - unpacked_u32s; + return (); } // TODO(Noa): Assert that the limbs represent a number in the range [0, PRIME-1]. // Assert that the limbs represent the number. - assert packed_values[0] = ( - (out[7] + (2 ** 32 * out[6])) + - 2 ** (32 * 2) * (out[5] + 2 ** 32 * out[4]) + - 2 ** (32 * 4) * (out[3] + 2 ** 32 * out[2]) + - 2 ** (32 * 6) * (out[1] + 2 ** 32 * out[0]) - ); + let actual_value = felt_from_le_u32s(u32s=out); + assert packed_values[0] = actual_value; tempvar out = &out[8]; tempvar packed_values = &packed_values[1]; jmp loop; } -// Gets a felt that represent a 256-bit unsigned integer stored as an array of eight 32-bit unsigned integers -// represented in little-endian notation. Return the felt representation of the integer modulo prime. -func u256_to_felt(u256: felt*) -> felt { - let hash = u256[7] * 2 ** 224 + u256[6] * 2 ** 192 + u256[5] * 2 ** 160 + u256[4] * 2 ** 128 + - u256[3] * 2 ** 96 + u256[2] * 2 ** 64 + u256[1] * 2 ** 32 + u256[0]; - return hash; -} - // / Encodes a slice of `Felt` values into 32-bit words, then hashes the resulting byte stream // / with Blake2s-256 and returns the 256-bit digest to a 252-bit field element `Felt`. func calc_blake_hash{range_check_ptr: felt}(data_len: felt, data: felt*) -> (hash: felt) { alloc_locals; let (local encoded_data: felt*) = alloc(); - let encoded_data_len = naive_encode_felt252s_to_u32s( + naive_encode_felt252s_to_u32s( packed_values_len=data_len, packed_values=data, unpacked_u32s=encoded_data ); let (local blake_output: felt*) = alloc(); - blake_with_opcode(len=encoded_data_len, data=encoded_data, out=blake_output); - let hash = u256_to_felt(u256=blake_output); + let encoded_data_length = 8 * data_len; + blake_with_opcode(len=encoded_data_length, data=encoded_data, out=blake_output); + let hash = felt_from_le_u32s(u32s=blake_output); return (hash=hash); } diff --git a/crates/apollo_starknet_os_program/src/program_hash.json b/crates/apollo_starknet_os_program/src/program_hash.json index 81ff11d63f3..3dbdc89c5fd 100644 --- a/crates/apollo_starknet_os_program/src/program_hash.json +++ b/crates/apollo_starknet_os_program/src/program_hash.json @@ -1,5 +1,5 @@ { - "os": "0x7f1ad76d2bc6845ae61c5ccb2f8aae2e2ff1418b5572bebcdf2dd832556a6b0", - "aggregator": "0x31a2d2cf5b673b718d9a9ed527fc343c2744ec3bd1daf1a7b9f1a4a1fa3d21d", - "aggregator_with_prefix": "0x4460a2cd0996f05489f8339d50f317d07b06f26dd2ecd5a5540368d2cef2a9d" + "os": "0x411bcd3d0448fcf9ced52a49731e9e81ecbb52d86c862d575716b8b2c38aed1", + "aggregator": "0x11009a80eecd0085c7890ee149d4c837f5c08ab1f076ad2ec714bd29eb77052", + "aggregator_with_prefix": "0x228933088f4fd745ab9c1bee3571779d6ca2a86117fa8b5a17cabeddf01404e" } \ No newline at end of file diff --git a/crates/starknet_os/src/hints/hint_implementation/blake2s/implementation.rs b/crates/starknet_os/src/hints/hint_implementation/blake2s/implementation.rs index fc68b49b7a5..27861575e65 100644 --- a/crates/starknet_os/src/hints/hint_implementation/blake2s/implementation.rs +++ b/crates/starknet_os/src/hints/hint_implementation/blake2s/implementation.rs @@ -95,13 +95,12 @@ pub(crate) fn naive_unpack_felt252s_to_u32s( HintArgs { vm, ids_data, ap_tracking, .. }: HintArgs<'_>, ) -> OsHintResult { let (unpacked_u32s, vals) = unpack_setup(vm, ids_data, ap_tracking)?; - let out: Vec = vals .into_iter() .map(|val| val.to_biguint()) .flat_map(|mut val| { let mut limbs = vec![BigUint::from(0_u32); 8]; - for limb in limbs.iter_mut().rev() { + for limb in limbs.iter_mut() { let (q, r) = val.div_rem(&POW2_32); *limb = r; val = q; diff --git a/crates/starknet_os/src/hints/hint_implementation/state_diff_encryption/utils.rs b/crates/starknet_os/src/hints/hint_implementation/state_diff_encryption/utils.rs index 4eb76a9b5fd..71c311e83ea 100644 --- a/crates/starknet_os/src/hints/hint_implementation/state_diff_encryption/utils.rs +++ b/crates/starknet_os/src/hints/hint_implementation/state_diff_encryption/utils.rs @@ -118,10 +118,10 @@ fn calc_blake_hash(data: &[Felt]) -> Felt { pub fn naive_encode_felts_to_u32s(felts: Vec) -> Vec { let mut unpacked_u32s = Vec::new(); for felt in felts { - let felt_as_be_bytes = felt.to_bytes_be(); - // big: 8 limbs, big‐endian order. - for chunk in felt_as_be_bytes.chunks_exact(4) { - unpacked_u32s.push(u32::from_be_bytes(chunk.try_into().unwrap())); + let felt_as_le_bytes = felt.to_bytes_le(); + // big: 8 limbs, little-endian order. + for chunk in felt_as_le_bytes.chunks_exact(4) { + unpacked_u32s.push(u32::from_le_bytes(chunk.try_into().unwrap())); } } unpacked_u32s