Skip to content

Commit 66e168b

Browse files
author
Gilad Chase
committed
refactor(sha256): Compute ByteArray sha256 via iterator
1 parent 0d59aa2 commit 66e168b

File tree

4 files changed

+12024
-13770
lines changed

4 files changed

+12024
-13770
lines changed

corelib/src/sha256.cairo

Lines changed: 69 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
//! assert!(hash == [0x185f8db3, 0x2271fe25, 0xf561a6fc, 0x938b2e26, 0x4306ec30, 0x4eda5180,
1414
//! 0x7d17648, 0x26381969]);
1515
//! ```
16+
#[feature("byte-span")]
17+
use core::byte_array::ToByteSpanTrait;
18+
#[feature("bounded-int-utils")]
19+
use core::internal::bounded_int::upcast;
1620
use starknet::SyscallResultTrait;
1721

1822
/// A handle to the state of a SHA-256 hash.
@@ -81,30 +85,29 @@ pub fn compute_sha256_u32_array(
8185
/// 0x7d17648, 0x26381969]);
8286
/// ```
8387
pub fn compute_sha256_byte_array(arr: @ByteArray) -> [u32; 8] {
88+
let mut iter = arr.span().into_iter();
8489
let mut word_arr = array![];
85-
let len = arr.len();
86-
let rem = len % 4;
87-
let mut index = 0;
88-
let rounded_len = len - rem;
89-
while index != rounded_len {
90-
let word = arr.at(index + 3).unwrap().into()
91-
+ arr.at(index + 2).unwrap().into() * 0x100
92-
+ arr.at(index + 1).unwrap().into() * 0x10000
93-
+ arr.at(index).unwrap().into() * 0x1000000;
94-
word_arr.append(word);
95-
index = index + 4;
96-
}
97-
98-
let last = match rem {
99-
0 => 0,
100-
1 => arr.at(len - 1).unwrap().into(),
101-
2 => arr.at(len - 1).unwrap().into() + arr.at(len - 2).unwrap().into() * 0x100,
102-
_ => arr.at(len - 1).unwrap().into()
103-
+ arr.at(len - 2).unwrap().into() * 0x100
104-
+ arr.at(len - 3).unwrap().into() * 0x10000,
90+
91+
let (last_word, last_word_len) = loop {
92+
let Some(b0) = iter.next() else {
93+
break (0, 0);
94+
};
95+
let Some(b1) = iter.next() else {
96+
break (upcast(b0), 1);
97+
};
98+
let b0_b1 = conversions::shift_append_byte(b0, b1);
99+
let Some(b2) = iter.next() else {
100+
break (upcast(b0_b1), 2);
101+
};
102+
let b0_b1_b2 = conversions::shift_append_byte(b0_b1, b2);
103+
let Some(b3) = iter.next() else {
104+
break (upcast(b0_b1_b2), 3);
105+
};
106+
107+
word_arr.append(upcast(conversions::shift_append_byte(b0_b1_b2, b3)));
105108
};
106109

107-
compute_sha256_u32_array(word_arr, last, rem.into())
110+
compute_sha256_u32_array(word_arr, last_word, last_word_len)
108111
}
109112

110113
/// Adds padding to the input array according to the SHA-256 specification.
@@ -208,3 +211,48 @@ fn append_zeros(ref arr: Array<u32>, count: felt252) {
208211
}
209212
arr.append(0);
210213
}
214+
215+
mod conversions {
216+
#[feature("bounded-int-utils")]
217+
use core::internal::bounded_int::{self, AddHelper, BoundedInt, MulHelper, UnitInt};
218+
219+
impl U8Shift of MulHelper<u8, UnitInt<0x100>> {
220+
type Result = BoundedInt<0, 0xFF00>;
221+
}
222+
impl U8ShiftAddU8 of AddHelper<U8Shift::Result, u8> {
223+
type Result = BoundedInt<0, 0xFFFF>;
224+
}
225+
impl U16Shift of MulHelper<U8ShiftAddU8::Result, UnitInt<0x100>> {
226+
type Result = BoundedInt<0, 0xFFFF00>;
227+
}
228+
impl U16ShiftAddU8 of AddHelper<U16Shift::Result, u8> {
229+
type Result = BoundedInt<0, 0xFFFFFF>;
230+
}
231+
impl U24Shift of MulHelper<U16ShiftAddU8::Result, UnitInt<0x100>> {
232+
type Result = BoundedInt<0, 0xFFFFFF00>;
233+
}
234+
impl U24ShiftAddU8 of AddHelper<U24Shift::Result, u8> {
235+
type Result = BoundedInt<0, 0xFFFFFFFF>;
236+
}
237+
trait ShiftAppendByte<T, MulResult> {
238+
impl Mul: MulHelper<T, UnitInt<0x100>>;
239+
impl Add: AddHelper<MulResult, u8>;
240+
}
241+
242+
// Blanket implementation for any type with appropriate helpers.
243+
impl ShiftAppendByteImpl<
244+
T, impl MH: MulHelper<T, UnitInt<0x100>>, impl AH: AddHelper<MH::Result, u8>,
245+
> of ShiftAppendByte<T, MH::Result> {}
246+
247+
/// Shifts a word left by one byte position and appends a new byte.
248+
pub fn shift_append_byte<
249+
T,
250+
MulResult,
251+
impl SAB: ShiftAppendByte<T, MulResult>,
252+
+core::metaprogramming::TypeEqual<MulResult, SAB::Mul::Result>,
253+
>(
254+
word: T, byte: u8,
255+
) -> SAB::Add::Result {
256+
bounded_int::add::<_, _, SAB::Add>(bounded_int::mul::<_, _, SAB::Mul>(word, 0x100), byte)
257+
}
258+
}

0 commit comments

Comments
 (0)