1use crate::stdlib::{borrow::Cow, collections::HashMap, prelude::*};
2
3use crate::types::errors::math_errors::MathError;
4use crate::Felt252;
5use crate::{
6 hint_processor::{
7 builtin_hint_processor::{
8 blake2s_hash::{blake2s_compress, IV},
9 hint_utils::{get_ptr_from_var_name, get_relocatable_from_var_name},
10 },
11 hint_processor_definition::HintReference,
12 hint_processor_utils::felt_to_u32,
13 },
14 math_utils::pow2_const_nz,
15 serde::deserialize_program::ApTracking,
16 types::relocatable::{MaybeRelocatable, Relocatable},
17 vm::{errors::hint_errors::HintError, vm_core::VirtualMachine},
18};
19
20use num_traits::ToPrimitive;
21
22use super::hint_utils::get_integer_from_var_name;
23
24fn get_fixed_size_u32_array<const T: usize>(
25 h_range: &Vec<Cow<Felt252>>,
26) -> Result<[u32; T], HintError> {
27 let mut u32_vec = Vec::<u32>::with_capacity(h_range.len());
28 for num in h_range {
29 u32_vec.push(num.to_u32().ok_or(HintError::BigintToU32Fail)?);
30 }
31 u32_vec
32 .try_into()
33 .map_err(|_| HintError::FixedSizeArrayFail(T))
34}
35
36fn get_maybe_relocatable_array_from_u32(array: &Vec<u32>) -> Vec<MaybeRelocatable> {
37 let mut new_array = Vec::<MaybeRelocatable>::with_capacity(array.len());
38 for element in array {
39 new_array.push(MaybeRelocatable::from(Felt252::from(*element)));
40 }
41 new_array
42}
43
44fn compute_blake2s_func(vm: &mut VirtualMachine, output_ptr: Relocatable) -> Result<(), HintError> {
50 let h = get_fixed_size_u32_array::<8>(&vm.get_integer_range((output_ptr - 26)?, 8)?)?;
51 let message = get_fixed_size_u32_array::<16>(&vm.get_integer_range((output_ptr - 18)?, 16)?)?;
52 let t = felt_to_u32(vm.get_integer((output_ptr - 2)?)?.as_ref())?;
53 let f = felt_to_u32(vm.get_integer((output_ptr - 1)?)?.as_ref())?;
54 let new_state =
55 get_maybe_relocatable_array_from_u32(&blake2s_compress(&h, &message, t, 0, f, 0));
56 vm.load_data(output_ptr, &new_state)
57 .map_err(HintError::Memory)?;
58 Ok(())
59}
60
61pub fn compute_blake2s(
66 vm: &mut VirtualMachine,
67 ids_data: &HashMap<String, HintReference>,
68 ap_tracking: &ApTracking,
69) -> Result<(), HintError> {
70 let output = get_ptr_from_var_name("output", vm, ids_data, ap_tracking)?;
71 compute_blake2s_func(vm, output)
72}
73
74pub fn finalize_blake2s(
97 vm: &mut VirtualMachine,
98 ids_data: &HashMap<String, HintReference>,
99 ap_tracking: &ApTracking,
100) -> Result<(), HintError> {
101 const N_PACKED_INSTANCES: usize = 7;
102 let blake2s_ptr_end = get_ptr_from_var_name("blake2s_ptr_end", vm, ids_data, ap_tracking)?;
103 let message: [u32; 16] = [0; 16];
104 let mut modified_iv = IV;
105 modified_iv[0] = IV[0] ^ 0x01010020;
106 let output = blake2s_compress(&modified_iv, &message, 0, 0, 0xffffffff, 0);
107 let mut padding = modified_iv.to_vec();
108 padding.extend(message);
109 padding.extend([0, 0xffffffff]);
110 padding.extend(output);
111 let padding = padding.as_slice();
112 let mut full_padding = Vec::<u32>::with_capacity(padding.len() * N_PACKED_INSTANCES);
113 for _ in 0..N_PACKED_INSTANCES - 1 {
114 full_padding.extend_from_slice(padding);
115 }
116 let data = get_maybe_relocatable_array_from_u32(&full_padding);
117 vm.load_data(blake2s_ptr_end, &data)
118 .map_err(HintError::Memory)?;
119 Ok(())
120}
121
122pub fn finalize_blake2s_v3(
145 vm: &mut VirtualMachine,
146 ids_data: &HashMap<String, HintReference>,
147 ap_tracking: &ApTracking,
148) -> Result<(), HintError> {
149 const N_PACKED_INSTANCES: usize = 7;
150 let blake2s_ptr_end = get_ptr_from_var_name("blake2s_ptr_end", vm, ids_data, ap_tracking)?;
151 let message: [u32; 16] = [0; 16];
152 let mut modified_iv = IV;
153 modified_iv[0] = IV[0] ^ 0x01010020;
154 let output = blake2s_compress(&modified_iv, &message, 0, 0, 0xffffffff, 0);
155 let mut padding = message.to_vec();
156 padding.extend(modified_iv);
157 padding.extend([0, 0xffffffff]);
158 padding.extend(output);
159 let padding = padding.as_slice();
160 let mut full_padding = Vec::<u32>::with_capacity(padding.len() * N_PACKED_INSTANCES);
161 for _ in 0..N_PACKED_INSTANCES - 1 {
162 full_padding.extend_from_slice(padding);
163 }
164 let data = get_maybe_relocatable_array_from_u32(&full_padding);
165 vm.load_data(blake2s_ptr_end, &data)
166 .map_err(HintError::Memory)?;
167 Ok(())
168}
169
170pub fn blake2s_add_uint256(
177 vm: &mut VirtualMachine,
178 ids_data: &HashMap<String, HintReference>,
179 ap_tracking: &ApTracking,
180) -> Result<(), HintError> {
181 let data_ptr = get_ptr_from_var_name("data", vm, ids_data, ap_tracking)?;
183 let low_addr = get_relocatable_from_var_name("low", vm, ids_data, ap_tracking)?;
184 let high_addr = get_relocatable_from_var_name("high", vm, ids_data, ap_tracking)?;
185 let mut low = vm.get_integer(low_addr)?.into_owned();
186 let mut high = vm.get_integer(high_addr)?.into_owned();
187 let b = pow2_const_nz(32);
190 let mut data = Vec::<MaybeRelocatable>::with_capacity(8);
191 for _ in 0..4 {
192 let (q, r) = low.div_rem(b);
193 data.push(r.into());
194 low = q;
195 }
196 for _ in 0..4 {
197 let (q, r) = high.div_rem(b);
198 data.push(r.into());
199 high = q;
200 }
201 vm.load_data(data_ptr, &data).map_err(HintError::Memory)?;
203 Ok(())
204}
205
206pub fn blake2s_add_uint256_bigend(
213 vm: &mut VirtualMachine,
214 ids_data: &HashMap<String, HintReference>,
215 ap_tracking: &ApTracking,
216) -> Result<(), HintError> {
217 let data_ptr = get_ptr_from_var_name("data", vm, ids_data, ap_tracking)?;
219 let low_addr = get_relocatable_from_var_name("low", vm, ids_data, ap_tracking)?;
220 let high_addr = get_relocatable_from_var_name("high", vm, ids_data, ap_tracking)?;
221 let mut low = vm.get_integer(low_addr)?.into_owned();
222 let mut high = vm.get_integer(high_addr)?.into_owned();
223 let b = pow2_const_nz(32);
225 let mut data = Vec::<MaybeRelocatable>::with_capacity(8);
226 for _ in 0..4 {
228 let (q, r) = low.div_rem(b);
229 data.push(r.into());
230 low = q;
231 }
232 for _ in 0..4 {
234 let (q, r) = high.div_rem(b);
235 data.push(r.into());
236 high = q;
237 }
238 data.reverse();
240 vm.load_data(data_ptr, &data).map_err(HintError::Memory)?;
242 Ok(())
243}
244
245pub fn example_blake2s_compress(
267 vm: &mut VirtualMachine,
268 ids_data: &HashMap<String, HintReference>,
269 ap_tracking: &ApTracking,
270) -> Result<(), HintError> {
271 let blake2s_start = get_ptr_from_var_name("blake2s_start", vm, ids_data, ap_tracking)?;
272 let output = get_ptr_from_var_name("output", vm, ids_data, ap_tracking)?;
273 let n_bytes = get_integer_from_var_name("n_bytes", vm, ids_data, ap_tracking).map(|x| {
274 x.to_u32()
275 .ok_or_else(|| HintError::Math(MathError::Felt252ToU32Conversion(Box::new(x))))
276 })??;
277
278 let message = get_fixed_size_u32_array::<16>(&vm.get_integer_range(blake2s_start, 16)?)?;
279 let mut modified_iv = IV;
280 modified_iv[0] = IV[0] ^ 0x01010020;
281 let new_state = blake2s_compress(&modified_iv, &message, n_bytes, 0, 0xffffffff, 0);
282 let new_state: Vec<MaybeRelocatable> = new_state
283 .iter()
284 .map(|x| MaybeRelocatable::from(*x as usize))
285 .collect();
286 vm.segments.write_arg(output, &new_state)?;
287 Ok(())
288}
289
290#[cfg(test)]
291mod tests {
292 use super::*;
293 use crate::hint_processor::builtin_hint_processor::hint_code;
294 use crate::types::errors::math_errors::MathError;
295 use crate::{
296 any_box,
297 hint_processor::{
298 builtin_hint_processor::builtin_hint_processor_definition::{
299 BuiltinHintProcessor, HintProcessorData,
300 },
301 hint_processor_definition::HintProcessorLogic,
302 },
303 relocatable,
304 utils::test_utils::*,
305 vm::errors::memory_errors::MemoryError,
306 };
307 use assert_matches::assert_matches;
308
309 #[cfg(target_arch = "wasm32")]
310 use wasm_bindgen_test::*;
311
312 #[test]
313 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
314 fn compute_blake2s_output_offset_zero() {
315 let hint_code = "from starkware.cairo.common.cairo_blake2s.blake2s_utils import compute_blake2s_func\ncompute_blake2s_func(segments=segments, output_ptr=ids.output)";
316 let mut vm = vm!();
318 vm.run_context.fp = 1;
320 vm.segments = segments![((1, 0), (2, 5))];
322 let ids_data = ids_data!["output"];
324 assert_matches!(
326 run_hint!(vm, ids_data, hint_code),
327 Err(HintError::Math(MathError::RelocatableSubUsizeNegOffset(bx)))
328 if *bx == (relocatable!(2,5), 26)
329 );
330 }
331
332 #[test]
333 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
334 fn compute_blake2s_output_empty_segment() {
335 let hint_code = "from starkware.cairo.common.cairo_blake2s.blake2s_utils import compute_blake2s_func\ncompute_blake2s_func(segments=segments, output_ptr=ids.output)";
336 let mut vm = vm!();
338 vm.run_context.fp = 1;
340 vm.segments = segments![((1, 0), (2, 26))];
342 add_segments!(vm, 1);
343 let ids_data = ids_data!["output"];
345 assert_matches!(
347 run_hint!(vm, ids_data, hint_code),
348 Err(HintError::Memory(MemoryError::UnknownMemoryCell(
349 bx
350 ))) if *bx == Relocatable::from((2, 0))
351 );
352 }
353
354 #[test]
355 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
356 fn compute_blake2s_output_not_relocatable() {
357 let hint_code = "from starkware.cairo.common.cairo_blake2s.blake2s_utils import compute_blake2s_func\ncompute_blake2s_func(segments=segments, output_ptr=ids.output)";
358 let mut vm = vm!();
360 vm.run_context.fp = 1;
362 vm.segments = segments![((1, 0), 12)];
364 let ids_data = ids_data!["output"];
366 assert_matches!(
368 run_hint!(vm, ids_data, hint_code),
369 Err(HintError::IdentifierNotRelocatable(bx))
370 if bx.as_ref() == "output"
371 );
372 }
373
374 #[test]
375 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
376 fn compute_blake2s_output_input_bigger_than_u32() {
377 let hint_code = "from starkware.cairo.common.cairo_blake2s.blake2s_utils import compute_blake2s_func\ncompute_blake2s_func(segments=segments, output_ptr=ids.output)";
378 let mut vm = vm!();
380 vm.run_context.fp = 1;
383 vm.segments = segments![
384 ((1, 0), (2, 26)),
385 ((2, 0), 7842562439562793675803603603688959_i128),
386 ((2, 1), 7842562439562793675803603603688959_i128),
387 ((2, 2), 7842562439562793675803603603688959_i128),
388 ((2, 3), 7842562439562793675803603603688959_i128),
389 ((2, 4), 7842562439562793675803603603688959_i128),
390 ((2, 5), 7842562439562793675803603603688959_i128),
391 ((2, 6), 7842562439562793675803603603688959_i128),
392 ((2, 7), 7842562439562793675803603603688959_i128)
393 ];
394 let ids_data = ids_data!["output"];
396 assert_matches!(
398 run_hint!(vm, ids_data, hint_code),
399 Err(HintError::BigintToU32Fail)
400 );
401 }
402
403 #[test]
404 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
405 fn compute_blake2s_output_input_relocatable() {
406 let hint_code = "from starkware.cairo.common.cairo_blake2s.blake2s_utils import compute_blake2s_func\ncompute_blake2s_func(segments=segments, output_ptr=ids.output)";
407 let mut vm = vm!();
409 vm.run_context.fp = 1;
411 vm.segments = segments![((1, 0), (2, 26)), ((2, 0), (5, 5))];
413 let ids_data = ids_data!["output"];
415 assert_matches!(
417 run_hint!(vm, ids_data, hint_code),
418 Err(HintError::Memory(MemoryError::ExpectedInteger(
419 bx
420 ))) if *bx == Relocatable::from((2, 0))
421 );
422 }
423
424 #[test]
425 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
426 fn finalize_blake2s_valid() {
427 let hint_code = "# Add dummy pairs of input and output.\nfrom starkware.cairo.common.cairo_blake2s.blake2s_utils import IV, blake2s_compress\n\n_n_packed_instances = int(ids.N_PACKED_INSTANCES)\nassert 0 <= _n_packed_instances < 20\n_blake2s_input_chunk_size_felts = int(ids.INPUT_BLOCK_FELTS)\nassert 0 <= _blake2s_input_chunk_size_felts < 100\n\nmessage = [0] * _blake2s_input_chunk_size_felts\nmodified_iv = [IV[0] ^ 0x01010020] + IV[1:]\noutput = blake2s_compress(\n message=message,\n h=modified_iv,\n t0=0,\n t1=0,\n f0=0xffffffff,\n f1=0,\n)\npadding = (modified_iv + message + [0, 0xffffffff] + output) * (_n_packed_instances - 1)\nsegments.write_arg(ids.blake2s_ptr_end, padding)";
428 let mut vm = vm!();
430 vm.run_context.fp = 1;
432 vm.segments = segments![((1, 0), (2, 0))];
434 add_segments!(vm, 1);
435 let ids_data = ids_data!["blake2s_ptr_end"];
437 assert_matches!(run_hint!(vm, ids_data, hint_code), Ok(()));
439 let expected_data: [u32; 204] = [
441 1795745351, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635,
442 1541459225, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4294967295, 813310313,
443 2491453561, 3491828193, 2085238082, 1219908895, 514171180, 4245497115, 4193177630,
444 1795745351, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635,
445 1541459225, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4294967295, 813310313,
446 2491453561, 3491828193, 2085238082, 1219908895, 514171180, 4245497115, 4193177630,
447 1795745351, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635,
448 1541459225, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4294967295, 813310313,
449 2491453561, 3491828193, 2085238082, 1219908895, 514171180, 4245497115, 4193177630,
450 1795745351, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635,
451 1541459225, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4294967295, 813310313,
452 2491453561, 3491828193, 2085238082, 1219908895, 514171180, 4245497115, 4193177630,
453 1795745351, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635,
454 1541459225, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4294967295, 813310313,
455 2491453561, 3491828193, 2085238082, 1219908895, 514171180, 4245497115, 4193177630,
456 1795745351, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635,
457 1541459225, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4294967295, 813310313,
458 2491453561, 3491828193, 2085238082, 1219908895, 514171180, 4245497115, 4193177630,
459 ];
460 let data = get_fixed_size_u32_array::<204>(
462 &vm.segments
463 .memory
464 .get_integer_range(relocatable!(2, 0), 204)
465 .unwrap(),
466 )
467 .unwrap();
468 assert_eq!(expected_data, data);
469 }
470
471 #[test]
472 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
473 fn finalize_blake2s_invalid_segment_taken() {
474 let hint_code = "# Add dummy pairs of input and output.\nfrom starkware.cairo.common.cairo_blake2s.blake2s_utils import IV, blake2s_compress\n\n_n_packed_instances = int(ids.N_PACKED_INSTANCES)\nassert 0 <= _n_packed_instances < 20\n_blake2s_input_chunk_size_felts = int(ids.INPUT_BLOCK_FELTS)\nassert 0 <= _blake2s_input_chunk_size_felts < 100\n\nmessage = [0] * _blake2s_input_chunk_size_felts\nmodified_iv = [IV[0] ^ 0x01010020] + IV[1:]\noutput = blake2s_compress(\n message=message,\n h=modified_iv,\n t0=0,\n t1=0,\n f0=0xffffffff,\n f1=0,\n)\npadding = (modified_iv + message + [0, 0xffffffff] + output) * (_n_packed_instances - 1)\nsegments.write_arg(ids.blake2s_ptr_end, padding)";
475 let mut vm = vm!();
477 vm.run_context.fp = 1;
479 vm.segments = segments![((1, 0), (2, 0)), ((2, 0), (2, 0))];
481 let ids_data = ids_data!["blake2s_ptr_end"];
482 assert_matches!(
484 run_hint!(vm, ids_data, hint_code),
485 Err(HintError::Memory(
486 MemoryError::InconsistentMemory(bx)
487 )) if *bx == (Relocatable::from((2, 0)),
488 MaybeRelocatable::from((2, 0)),
489 MaybeRelocatable::from(Felt252::from(1795745351)))
490 );
491 }
492
493 #[test]
494 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
495 fn finalize_blake2s_invalid_no_ids() {
496 let hint_code = "# Add dummy pairs of input and output.\nfrom starkware.cairo.common.cairo_blake2s.blake2s_utils import IV, blake2s_compress\n\n_n_packed_instances = int(ids.N_PACKED_INSTANCES)\nassert 0 <= _n_packed_instances < 20\n_blake2s_input_chunk_size_felts = int(ids.INPUT_BLOCK_FELTS)\nassert 0 <= _blake2s_input_chunk_size_felts < 100\n\nmessage = [0] * _blake2s_input_chunk_size_felts\nmodified_iv = [IV[0] ^ 0x01010020] + IV[1:]\noutput = blake2s_compress(\n message=message,\n h=modified_iv,\n t0=0,\n t1=0,\n f0=0xffffffff,\n f1=0,\n)\npadding = (modified_iv + message + [0, 0xffffffff] + output) * (_n_packed_instances - 1)\nsegments.write_arg(ids.blake2s_ptr_end, padding)";
497 let mut vm = vm!();
499 vm.run_context.fp = 1;
501 assert_matches!(
503 run_hint!(vm, HashMap::new(), hint_code),
504 Err(HintError::UnknownIdentifier(bx)) if bx.as_ref() == "blake2s_ptr_end"
505 );
506 }
507
508 #[test]
509 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
510 fn blake2s_add_uint256_valid_zero() {
511 let hint_code = "B = 32\nMASK = 2 ** 32 - 1\nsegments.write_arg(ids.data, [(ids.low >> (B * i)) & MASK for i in range(4)])\nsegments.write_arg(ids.data + 4, [(ids.high >> (B * i)) & MASK for i in range(4)])";
512 let mut vm = vm!();
514 vm.run_context.fp = 3;
516 vm.segments = segments![((1, 0), (2, 0)), ((1, 1), 0), ((1, 2), 0)];
518 vm.segments.add();
519 let ids_data = ids_data!["data", "high", "low"];
520 assert_matches!(run_hint!(vm, ids_data, hint_code), Ok(()));
522 check_memory![
524 vm.segments.memory,
525 ((2, 0), 0),
526 ((2, 1), 0),
527 ((2, 2), 0),
528 ((2, 3), 0),
529 ((2, 4), 0),
530 ((2, 5), 0),
531 ((2, 6), 0),
532 ((2, 7), 0)
533 ];
534 assert!(vm
535 .segments
536 .memory
537 .get(&MaybeRelocatable::from((2, 8)))
538 .is_none());
539 }
540
541 #[test]
542 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
543 fn blake2s_add_uint256_valid_non_zero() {
544 let hint_code = "B = 32\nMASK = 2 ** 32 - 1\nsegments.write_arg(ids.data, [(ids.low >> (B * i)) & MASK for i in range(4)])\nsegments.write_arg(ids.data + 4, [(ids.high >> (B * i)) & MASK for i in range(4)])";
545 let mut vm = vm!();
547 vm.run_context.fp = 3;
549 vm.segments = segments![((1, 0), (2, 0)), ((1, 1), 25), ((1, 2), 20)];
551 vm.segments.add();
552 let ids_data = ids_data!["data", "high", "low"];
553 assert_matches!(run_hint!(vm, ids_data, hint_code), Ok(()));
555 check_memory![
557 vm.segments.memory,
558 ((2, 0), 20),
559 ((2, 1), 0),
560 ((2, 2), 0),
561 ((2, 3), 0),
562 ((2, 4), 25),
563 ((2, 5), 0),
564 ((2, 6), 0),
565 ((2, 7), 0)
566 ];
567 assert!(vm
568 .segments
569 .memory
570 .get(&MaybeRelocatable::from((2, 8)))
571 .is_none());
572 }
573
574 #[test]
575 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
576 fn blake2s_add_uint256_bigend_valid_zero() {
577 let hint_code = "B = 32\nMASK = 2 ** 32 - 1\nsegments.write_arg(ids.data, [(ids.high >> (B * (3 - i))) & MASK for i in range(4)])\nsegments.write_arg(ids.data + 4, [(ids.low >> (B * (3 - i))) & MASK for i in range(4)])";
578 let mut vm = vm!();
580 vm.run_context.fp = 3;
582 vm.segments = segments![((1, 0), (2, 0)), ((1, 1), 0), ((1, 2), 0)];
584 add_segments!(vm, 1);
585 let ids_data = ids_data!["data", "high", "low"];
586 assert_matches!(run_hint!(vm, ids_data, hint_code), Ok(()));
588 check_memory![
590 vm.segments.memory,
591 ((2, 0), 0),
592 ((2, 1), 0),
593 ((2, 2), 0),
594 ((2, 3), 0),
595 ((2, 4), 0),
596 ((2, 5), 0),
597 ((2, 6), 0),
598 ((2, 7), 0)
599 ];
600 assert!(vm
601 .segments
602 .memory
603 .get(&MaybeRelocatable::from((2, 8)))
604 .is_none());
605 }
606
607 #[test]
608 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
609 fn blake2s_add_uint256_bigend_valid_non_zero() {
610 let hint_code = "B = 32\nMASK = 2 ** 32 - 1\nsegments.write_arg(ids.data, [(ids.high >> (B * (3 - i))) & MASK for i in range(4)])\nsegments.write_arg(ids.data + 4, [(ids.low >> (B * (3 - i))) & MASK for i in range(4)])";
611 let mut vm = vm!();
613 vm.run_context.fp = 3;
615 vm.segments = segments![((1, 0), (2, 0)), ((1, 1), 25), ((1, 2), 20)];
617 vm.segments.add();
618 let ids_data = ids_data!["data", "high", "low"];
619 assert_matches!(run_hint!(vm, ids_data, hint_code), Ok(()));
621 check_memory![
623 vm.segments.memory,
624 ((2, 0), 0),
625 ((2, 1), 0),
626 ((2, 2), 0),
627 ((2, 3), 25),
628 ((2, 4), 0),
629 ((2, 5), 0),
630 ((2, 6), 0),
631 ((2, 7), 20)
632 ];
633 assert!(vm
634 .segments
635 .memory
636 .get(&MaybeRelocatable::from((2, 8)))
637 .is_none());
638 }
639
640 #[test]
641 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
642 fn example_blake2s_compress_n_bytes_over_u32() {
643 let mut vm = vm!();
645 vm.run_context.fp = 3;
647 vm.segments = segments![((1, 0), 9999999999_u64), ((1, 1), (1, 0)), ((1, 2), (2, 0))];
649 let ids_data = ids_data!["n_bytes", "output", "blake2s_start"];
650 assert_matches!(run_hint!(vm, ids_data, hint_code::EXAMPLE_BLAKE2S_COMPRESS), Err(HintError::Math(MathError::Felt252ToU32Conversion(bx))) if *bx == Felt252::from(9999999999_u64));
652 }
653
654 #[test]
655 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
656 fn example_blake2s_empty_input() {
657 let mut vm = vm!();
659 vm.run_context.fp = 3;
661 vm.segments = segments![((1, 0), 9), ((1, 1), (1, 0)), ((1, 2), (2, 0))];
663 let ids_data = ids_data!["n_bytes", "output", "blake2s_start"];
664 assert_matches!(run_hint!(vm, ids_data, hint_code::EXAMPLE_BLAKE2S_COMPRESS), Err(HintError::Memory(MemoryError::UnknownMemoryCell(bx))) if *bx == (2, 0).into());
666 }
667}