miden_stdlib_sys/stdlib/crypto/
hashes.rs1use alloc::vec::Vec;
6
7use crate::{
8 felt,
9 intrinsics::{assert_eq, Digest, Felt, Word},
10};
11
12#[link(wasm_import_module = "miden:core-stdlib/stdlib-crypto-hashes-blake3@1.0.0")]
13extern "C" {
14 #[link_name = "hash-one-to-one"]
20 fn extern_blake3_hash_1to1(
21 e1: u32,
22 e2: u32,
23 e3: u32,
24 e4: u32,
25 e5: u32,
26 e6: u32,
27 e7: u32,
28 e8: u32,
29 ptr: *mut u8,
30 );
31
32 #[link_name = "hash-two-to-one"]
38 fn extern_blake3_hash_2to1(
39 e1: u32,
40 e2: u32,
41 e3: u32,
42 e4: u32,
43 e5: u32,
44 e6: u32,
45 e7: u32,
46 e8: u32,
47 e9: u32,
48 e10: u32,
49 e11: u32,
50 e12: u32,
51 e13: u32,
52 e14: u32,
53 e15: u32,
54 e16: u32,
55 ptr: *mut u8,
56 );
57}
58
59#[link(wasm_import_module = "miden:core-stdlib/stdlib-crypto-hashes-sha256@1.0.0")]
60extern "C" {
61 #[link_name = "sha256-hash-one-to-one"]
67 fn extern_sha256_hash_1to1(
68 e1: u32,
69 e2: u32,
70 e3: u32,
71 e4: u32,
72 e5: u32,
73 e6: u32,
74 e7: u32,
75 e8: u32,
76 ptr: *mut u8,
77 );
78
79 #[link_name = "sha256-hash-two-to-one"]
85 fn extern_sha256_hash_2to1(
86 e1: u32,
87 e2: u32,
88 e3: u32,
89 e4: u32,
90 e5: u32,
91 e6: u32,
92 e7: u32,
93 e8: u32,
94 e9: u32,
95 e10: u32,
96 e11: u32,
97 e12: u32,
98 e13: u32,
99 e14: u32,
100 e15: u32,
101 e16: u32,
102 ptr: *mut u8,
103 );
104}
105
106#[link(wasm_import_module = "miden:core-stdlib/stdlib-crypto-hashes-rpo@1.0.0")]
107extern "C" {
108 #[link_name = "hash-memory"]
117 pub fn extern_hash_memory(ptr: u32, num_elements: u32, result_ptr: *mut Felt);
118}
119
120#[inline(always)]
122fn hash_1to1(
123 input: [u8; 32],
124 extern_hash_1to1: unsafe extern "C" fn(u32, u32, u32, u32, u32, u32, u32, u32, *mut u8),
125) -> [u8; 32] {
126 use crate::intrinsics::WordAligned;
127 let input = unsafe { core::mem::transmute::<[u8; 32], [u32; 8]>(input) };
128 unsafe {
129 let mut ret_area = ::core::mem::MaybeUninit::<WordAligned<[u8; 32]>>::uninit();
130 let ptr = ret_area.as_mut_ptr() as *mut u8;
131 extern_hash_1to1(
132 input[0], input[1], input[2], input[3], input[4], input[5], input[6], input[7], ptr,
133 );
134 ret_area.assume_init().into_inner()
135 }
136}
137
138#[inline(always)]
140fn hash_2to1(
141 input: [u8; 64],
142 extern_hash_2to1: unsafe extern "C" fn(
143 u32,
144 u32,
145 u32,
146 u32,
147 u32,
148 u32,
149 u32,
150 u32,
151 u32,
152 u32,
153 u32,
154 u32,
155 u32,
156 u32,
157 u32,
158 u32,
159 *mut u8,
160 ),
161) -> [u8; 32] {
162 let input = unsafe { core::mem::transmute::<[u8; 64], [u32; 16]>(input) };
163 unsafe {
164 let mut ret_area = ::core::mem::MaybeUninit::<[u8; 32]>::uninit();
165 let ptr = ret_area.as_mut_ptr() as *mut u8;
166 extern_hash_2to1(
167 input[0], input[1], input[2], input[3], input[4], input[5], input[6], input[7],
168 input[8], input[9], input[10], input[11], input[12], input[13], input[14], input[15],
169 ptr,
170 );
171 ret_area.assume_init()
172 }
173}
174
175#[inline]
177pub fn blake3_hash_1to1(input: [u8; 32]) -> [u8; 32] {
178 hash_1to1(input, extern_blake3_hash_1to1)
179}
180
181#[inline]
183pub fn blake3_hash_2to1(input: [u8; 64]) -> [u8; 32] {
184 hash_2to1(input, extern_blake3_hash_2to1)
185}
186
187#[inline]
189pub fn sha256_hash_1to1(input: [u8; 32]) -> [u8; 32] {
190 hash_1to1(input, extern_sha256_hash_1to1)
191}
192
193#[inline]
195pub fn sha256_hash_2to1(input: [u8; 64]) -> [u8; 32] {
196 hash_2to1(input, extern_sha256_hash_2to1)
197}
198
199#[inline]
207pub fn hash_elements(elements: Vec<Felt>) -> Digest {
208 let rust_ptr = elements.as_ptr().addr() as u32;
209
210 unsafe {
211 let mut ret_area = core::mem::MaybeUninit::<Word>::uninit();
212 let result_ptr = ret_area.as_mut_ptr() as *mut Felt;
213 let miden_ptr = rust_ptr / 4;
214 assert_eq(Felt::from_u32(miden_ptr % 4), felt!(0));
216
217 extern_hash_memory(miden_ptr, elements.len() as u32, result_ptr);
218
219 Digest::from_word(ret_area.assume_init().reverse())
220 }
221}