1+ // ! Implementation of the SHA-256 cryptographic hash function.
2+ // !
3+ // ! This module provides functions to compute SHA-256 hashes of data.
4+ // ! The input data can be an array of 32-bit words, or a `ByteArray`.
5+ // !
6+ // ! # Examples
7+ // !
8+ // ! ```
9+ // ! use core::sha256::compute_sha256_byte_array;
10+ // !
11+ // ! let data = "Hello";
12+ // ! let hash = compute_sha256_byte_array(@data);
13+ // ! assert!(hash == [0x185f8db3, 0x2271fe25, 0xf561a6fc, 0x938b2e26, 0x4306ec30, 0x4eda5180,
14+ // ! 0x7d17648, 0x26381969]);
15+ // ! ```
116use crate :: starknet :: SyscallResultTrait ;
217
318/// A handle to the state of a SHA-256 hash.
419#[derive(Copy , Drop )]
520pub (crate ) extern type Sha256StateHandle ;
621
7- /// Initializes a new SHA-256 state handle.
22+ /// Initializes a new SHA-256 state handle with the given initial state .
823extern fn sha256_state_handle_init (state : Box <[u32 ; 8 ]>) -> Sha256StateHandle nopanic ;
924
10- /// returns the state of a SHA-256 hash.
25+ /// Returns the final state of a SHA-256 hash computation .
1126extern fn sha256_state_handle_digest (state : Sha256StateHandle ) -> Box <[u32 ; 8 ]> nopanic ;
1227
28+ /// Initial hash values for SHA-256 as specified in FIPS 180-4.
1329const SHA256_INITIAL_STATE : [u32 ; 8 ] = [
1430 0x6a09e667 , 0xbb67ae85 , 0x3c6ef372 , 0xa54ff53a , 0x510e527f , 0x9b05688c , 0x1f83d9ab , 0x5be0cd19 ,
1531];
1632
17- /// Computes the SHA-256 hash of the input array.
18- /// input is an array of 32-bit words.
19- /// use last_input_word when the number of bytes in the last input word is less than 4.
20- /// last_input_num_bytes is the number of bytes in the last input word (must be less than 4).
21- /// return the SHA-256 hash of the `input array` + `last_input_word` as big endian.
33+ /// Computes the SHA-256 hash of an array of 32-bit words.
34+ ///
35+ /// # Arguments
36+ ///
37+ /// * `input` - An array of `u32` values to hash
38+ /// * `last_input_word` - The final word when input is not word-aligned
39+ /// * `last_input_num_bytes` - Number of bytes in the last input word (must be less than 4)
40+ ///
41+ /// # Returns
42+ ///
43+ /// * The SHA-256 hash of the `input array` + `last_input_word` as big endian
44+ ///
45+ /// # Examples
46+ ///
47+ /// ```
48+ /// use core::sha256::compute_sha256_u32_array;
49+ ///
50+ /// let hash = compute_sha256_u32_array(array![0x68656c6c], 0x6f, 1);
51+ /// assert!(hash == [0x2cf24dba, 0x5fb0a30e, 0x26e83b2a, 0xc5b9e29e, 0x1b161e5c, 0x1fa7425e,
52+ /// 0x73043362, 0x938b9824]);
53+ /// ```
2254pub fn compute_sha256_u32_array (
2355 mut input : Array <u32 >, last_input_word : u32 , last_input_num_bytes : u32 ,
2456) -> [u32 ; 8 ] {
@@ -34,7 +66,18 @@ pub fn compute_sha256_u32_array(
3466 sha256_state_handle_digest (state ). unbox ()
3567}
3668
37- /// Computes the SHA-256 hash of the input ByteArray.
69+ /// Computes the SHA-256 hash of the input `ByteArray`.
70+ ///
71+ /// # Examples
72+ ///
73+ /// ```
74+ /// use core::sha256::compute_sha256_byte_array;
75+ ///
76+ // ! let data = "Hello";
77+ // ! let hash = compute_sha256_byte_array(@data);
78+ // ! assert!(hash == [0x185f8db3, 0x2271fe25, 0xf561a6fc, 0x938b2e26, 0x4306ec30, 0x4eda5180,
79+ // ! 0x7d17648, 0x26381969]);
80+ /// ```
3881pub fn compute_sha256_byte_array (arr : @ ByteArray ) -> [u32 ; 8 ] {
3982 let mut word_arr = array! [];
4083 let len = arr . len ();
@@ -49,6 +92,7 @@ pub fn compute_sha256_byte_array(arr: @ByteArray) -> [u32; 8] {
4992 word_arr . append (word );
5093 index = index + 4 ;
5194 };
95+
5296 let last = match rem {
5397 0 => 0 ,
5498 1 => arr . at (len - 1 ). unwrap (). into (),
@@ -57,14 +101,21 @@ pub fn compute_sha256_byte_array(arr: @ByteArray) -> [u32; 8] {
57101 + arr . at (len - 2 ). unwrap (). into () * 0x100
58102 + arr . at (len - 3 ). unwrap (). into () * 0x10000 ,
59103 };
104+
60105 compute_sha256_u32_array (word_arr , last , rem . into ())
61106}
62107
63- /// Adds padding to the input array for SHA-256. The padding is defined as follows:
64- /// 1. Append a single bit with value 1 to the end of the array.
65- /// 2. Append zeros until the length of the array is 448 mod 512.
66- /// 3. Append the length of the array in bits as a 64-bit number.
67- /// use last_input_word when the number of bytes in the last input word is less than 4.
108+ /// Adds padding to the input array according to the SHA-256 specification.
109+ ///
110+ /// The padding follows FIPS 180-4:
111+ /// 1. Append a single '1' bit to
112+ /// 2. Append zeros until data length ≡ 448 (mod 512)
113+ /// 3. Append the original message length as a 64-bit big-endian integer
114+ ///
115+ /// # Arguments
116+ /// * `arr` - Array to pad (modified in place)
117+ /// * `last_input_word` - Final word for non-word-aligned inputs
118+ /// * `last_input_num_bytes` - Number of valid bytes in last_input_word
68119fn add_sha256_padding (ref arr : Array <u32 >, last_input_word : u32 , last_input_num_bytes : u32 ) {
69120 let len = arr . len ();
70121 if last_input_num_bytes == 0 {
0 commit comments