miden_stdlib_sys/stdlib/crypto/
hashes.rs1use alloc::vec::Vec;
6
7use crate::{
8 felt,
9 intrinsics::{assert_eq, Digest, Felt, Word},
10};
11
12extern "C" {
13 #[link_name = "std::crypto::hashes::blake3::hash_1to1"]
19 fn extern_blake3_hash_1to1(
20 e1: u32,
21 e2: u32,
22 e3: u32,
23 e4: u32,
24 e5: u32,
25 e6: u32,
26 e7: u32,
27 e8: u32,
28 ptr: *mut u8,
29 );
30
31 #[link_name = "std::crypto::hashes::blake3::hash_2to1"]
37 fn extern_blake3_hash_2to1(
38 e1: u32,
39 e2: u32,
40 e3: u32,
41 e4: u32,
42 e5: u32,
43 e6: u32,
44 e7: u32,
45 e8: u32,
46 e9: u32,
47 e10: u32,
48 e11: u32,
49 e12: u32,
50 e13: u32,
51 e14: u32,
52 e15: u32,
53 e16: u32,
54 ptr: *mut u8,
55 );
56}
57
58extern "C" {
59 #[link_name = "std::crypto::hashes::sha256::hash_1to1"]
65 fn extern_sha256_hash_1to1(
66 e1: u32,
67 e2: u32,
68 e3: u32,
69 e4: u32,
70 e5: u32,
71 e6: u32,
72 e7: u32,
73 e8: u32,
74 ptr: *mut u8,
75 );
76
77 #[link_name = "std::crypto::hashes::sha256::hash_2to1"]
83 fn extern_sha256_hash_2to1(
84 e1: u32,
85 e2: u32,
86 e3: u32,
87 e4: u32,
88 e5: u32,
89 e6: u32,
90 e7: u32,
91 e8: u32,
92 e9: u32,
93 e10: u32,
94 e11: u32,
95 e12: u32,
96 e13: u32,
97 e14: u32,
98 e15: u32,
99 e16: u32,
100 ptr: *mut u8,
101 );
102}
103
104extern "C" {
105 #[link_name = "std::crypto::hashes::rpo::hash_memory"]
114 pub fn extern_hash_memory(ptr: u32, num_elements: u32, result_ptr: *mut Felt);
115
116 #[link_name = "std::crypto::hashes::rpo::hash_memory_words"]
126 pub fn extern_hash_memory_words(start_addr: u32, end_addr: u32, result_ptr: *mut Felt);
127}
128
129#[inline(always)]
131fn hash_1to1(
132 input: [u8; 32],
133 extern_hash_1to1: unsafe extern "C" fn(u32, u32, u32, u32, u32, u32, u32, u32, *mut u8),
134) -> [u8; 32] {
135 use crate::intrinsics::WordAligned;
136 let input = unsafe { core::mem::transmute::<[u8; 32], [u32; 8]>(input) };
137 unsafe {
138 let mut ret_area = ::core::mem::MaybeUninit::<WordAligned<[u8; 32]>>::uninit();
139 let ptr = ret_area.as_mut_ptr() as *mut u8;
140 extern_hash_1to1(
141 input[0], input[1], input[2], input[3], input[4], input[5], input[6], input[7], ptr,
142 );
143 ret_area.assume_init().into_inner()
144 }
145}
146
147#[inline(always)]
149fn hash_2to1(
150 input: [u8; 64],
151 extern_hash_2to1: unsafe extern "C" fn(
152 u32,
153 u32,
154 u32,
155 u32,
156 u32,
157 u32,
158 u32,
159 u32,
160 u32,
161 u32,
162 u32,
163 u32,
164 u32,
165 u32,
166 u32,
167 u32,
168 *mut u8,
169 ),
170) -> [u8; 32] {
171 let input = unsafe { core::mem::transmute::<[u8; 64], [u32; 16]>(input) };
172 unsafe {
173 let mut ret_area = ::core::mem::MaybeUninit::<[u8; 32]>::uninit();
174 let ptr = ret_area.as_mut_ptr() as *mut u8;
175 extern_hash_2to1(
176 input[0], input[1], input[2], input[3], input[4], input[5], input[6], input[7],
177 input[8], input[9], input[10], input[11], input[12], input[13], input[14], input[15],
178 ptr,
179 );
180 ret_area.assume_init()
181 }
182}
183
184#[inline]
186pub fn blake3_hash_1to1(input: [u8; 32]) -> [u8; 32] {
187 hash_1to1(input, extern_blake3_hash_1to1)
188}
189
190#[inline]
192pub fn blake3_hash_2to1(input: [u8; 64]) -> [u8; 32] {
193 hash_2to1(input, extern_blake3_hash_2to1)
194}
195
196#[inline]
198pub fn sha256_hash_1to1(input: [u8; 32]) -> [u8; 32] {
199 hash_1to1(input, extern_sha256_hash_1to1)
200}
201
202#[inline]
204pub fn sha256_hash_2to1(input: [u8; 64]) -> [u8; 32] {
205 hash_2to1(input, extern_sha256_hash_2to1)
206}
207
208#[inline]
218pub fn hash_elements(elements: Vec<Felt>) -> Digest {
219 let rust_ptr = elements.as_ptr().addr() as u32;
220 let element_count = elements.len();
221 let num_elements = element_count as u32;
222
223 unsafe {
224 let mut ret_area = core::mem::MaybeUninit::<Word>::uninit();
225 let result_ptr = ret_area.as_mut_ptr() as *mut Felt;
226 let miden_ptr = rust_ptr / 4;
227 assert_eq(Felt::from_u32(miden_ptr % 4), felt!(0));
229
230 if element_count.is_multiple_of(4) {
231 let start_addr = miden_ptr;
232 let end_addr = start_addr + num_elements;
233 extern_hash_memory_words(start_addr, end_addr, result_ptr);
234 } else {
235 extern_hash_memory(miden_ptr, num_elements, result_ptr);
236 }
237
238 Digest::from_word(ret_area.assume_init().reverse())
239 }
240}
241
242#[inline]
250pub fn hash_words(words: &[Word]) -> Digest {
251 let rust_ptr = words.as_ptr().addr() as u32;
252
253 unsafe {
254 let mut ret_area = core::mem::MaybeUninit::<Word>::uninit();
255 let result_ptr = ret_area.as_mut_ptr() as *mut Felt;
256 let miden_ptr = rust_ptr / 4;
257 assert_eq(Felt::from_u32(miden_ptr % 4), felt!(0));
259
260 let start_addr = miden_ptr;
261 let end_addr = start_addr + (words.len() as u32 * 4);
262 extern_hash_memory_words(start_addr, end_addr, result_ptr);
263
264 Digest::from_word(ret_area.assume_init().reverse())
265 }
266}