Skip to content

Commit 84c5eea

Browse files
committed
Added hints felt unpacking for blake.
1 parent 5c56712 commit 84c5eea

File tree

4 files changed

+200
-1
lines changed

4 files changed

+200
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#### Upcoming Changes
44

5+
* feat: Support hints for new blake felt serialization library code [#1994](https://github.com/lambdaclass/cairo-vm/pull/1994)
6+
57
* feat: Limited padding of builtin segments to >=16 [#1981](https://github.com/lambdaclass/cairo-vm/pull/1981)
68

79
* fix: Enforce `disable_trace_padding` used only in `proof_mode` [#1984](https://github.com/lambdaclass/cairo-vm/pull/1984)

vm/src/hint_processor/builtin_hint_processor/blake2s_utils.rs

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::hint_processor::hint_processor_utils::felt_to_usize;
12
use crate::stdlib::{borrow::Cow, collections::HashMap, prelude::*};
23

34
use crate::types::errors::math_errors::MathError;
@@ -17,6 +18,8 @@ use crate::{
1718
vm::{errors::hint_errors::HintError, vm_core::VirtualMachine},
1819
};
1920

21+
use num_bigint::BigUint;
22+
use num_integer::Integer;
2023
use num_traits::ToPrimitive;
2124

2225
use super::hint_utils::get_integer_from_var_name;
@@ -242,6 +245,83 @@ pub fn blake2s_add_uint256_bigend(
242245
Ok(())
243246
}
244247

248+
/* Implements Hint:
249+
memory[ap] = (ids.end != ids.packed_values) and (memory[ids.packed_values] < 2**63)
250+
*/
251+
pub fn blake2s_unpack_nondet_jmp(
252+
vm: &mut VirtualMachine,
253+
ids_data: &HashMap<String, HintReference>,
254+
ap_tracking: &ApTracking,
255+
) -> Result<(), HintError> {
256+
let end = get_ptr_from_var_name("end", vm, ids_data, ap_tracking)?;
257+
let packed_values = get_ptr_from_var_name("packed_values", vm, ids_data, ap_tracking)?;
258+
let ap = vm.get_ap();
259+
260+
if end == packed_values {
261+
vm.insert_value(ap, 0)?
262+
} else {
263+
let val = vm.get_integer(packed_values)?.into_owned();
264+
vm.insert_value(
265+
ap,
266+
(val.to_biguint() < (BigUint::from(1_u32) << 63)) as usize,
267+
)?
268+
}
269+
Ok(())
270+
}
271+
272+
/* Implements Hint:
273+
offset = 0
274+
for i in range(ids.packed_values_len):
275+
val = (memory[ids.packed_values + i] % PRIME)
276+
val_len = 2 if val < 2**63 else 8
277+
if val_len == 8:
278+
val += 2**255
279+
for i in range(val_len - 1, -1, -1):
280+
val, memory[ids.unpacked_u32s + offset + i] = divmod(val, 2**32)
281+
assert val == 0
282+
offset += val_len
283+
*/
284+
pub fn blake2s_unpack_felts(
285+
vm: &mut VirtualMachine,
286+
ids_data: &HashMap<String, HintReference>,
287+
ap_tracking: &ApTracking,
288+
) -> Result<(), HintError> {
289+
let packed_values_len =
290+
get_integer_from_var_name("packed_values_len", vm, ids_data, ap_tracking)?;
291+
let packed_values = get_ptr_from_var_name("packed_values", vm, ids_data, ap_tracking)?;
292+
let unpacked_u32s = get_ptr_from_var_name("unpacked_u32s", vm, ids_data, ap_tracking)?;
293+
294+
let vals = vm.get_integer_range(packed_values, felt_to_usize(&packed_values_len)?)?;
295+
let pow2 = |exp: u32| BigUint::from(1_u32) << exp;
296+
297+
// Split value into either 2 or 8 32-bit limbs.
298+
let out: Vec<MaybeRelocatable> = vals
299+
.into_iter()
300+
.map(|val| val.to_biguint())
301+
.flat_map(|val| {
302+
if val < pow2(63) {
303+
let (high, low) = val.div_rem(&(pow2(32)));
304+
vec![high, low]
305+
} else {
306+
let mut limbs = vec![BigUint::from(0_u32); 8];
307+
let mut val: BigUint = val + (pow2(255));
308+
for i in (0..8).rev() {
309+
let (q, r) = val.div_rem(&(pow2(32)));
310+
limbs[i] = r;
311+
val = q;
312+
}
313+
limbs
314+
}
315+
})
316+
.map(Felt252::from)
317+
.map(MaybeRelocatable::from)
318+
.collect();
319+
320+
vm.load_data(unpacked_u32s, &out)
321+
.map_err(HintError::Memory)?;
322+
Ok(())
323+
}
324+
245325
/* Implements Hint:
246326
%{
247327
from starkware.cairo.common.cairo_blake2s.blake2s_utils import IV, blake2s_compress
@@ -604,6 +684,106 @@ mod tests {
604684
.is_none());
605685
}
606686

687+
#[test]
688+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
689+
fn blake2s_unpack_nondet_jmp_ends() {
690+
let hint_code =
691+
"memory[ap] = (ids.end != ids.packed_values) and (memory[ids.packed_values] < 2**63)";
692+
//Create vm
693+
let mut vm = vm!();
694+
//Insert ids into memory
695+
vm.segments = segments![((1, 0), (1, 2)), ((1, 1), (1, 2)), ((1, 2), 123)];
696+
vm.set_fp(3);
697+
vm.set_ap(3);
698+
let ids_data = ids_data!["end", "packed_values", "value"];
699+
//Execute the hint
700+
assert_matches!(run_hint!(vm, ids_data, hint_code), Ok(()));
701+
//Check data ptr
702+
check_memory![vm.segments.memory, ((1, 3), 0)];
703+
}
704+
705+
#[test]
706+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
707+
fn blake2s_unpack_nondet_jmp_small() {
708+
let hint_code =
709+
"memory[ap] = (ids.end != ids.packed_values) and (memory[ids.packed_values] < 2**63)";
710+
//Create vm
711+
let mut vm = vm!();
712+
//Insert ids into memory
713+
vm.segments = segments![((1, 0), (1, 3)), ((1, 1), (1, 2)), ((1, 2), 123)];
714+
vm.set_fp(3);
715+
vm.set_ap(3);
716+
let ids_data = ids_data!["end", "packed_values", "value"];
717+
//Execute the hint
718+
assert_matches!(run_hint!(vm, ids_data, hint_code), Ok(()));
719+
//Check data ptr
720+
check_memory![vm.segments.memory, ((1, 3), 1)];
721+
}
722+
723+
#[test]
724+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
725+
fn blake2s_unpack_nondet_jmp_big() {
726+
let hint_code =
727+
"memory[ap] = (ids.end != ids.packed_values) and (memory[ids.packed_values] < 2**63)";
728+
//Create vm
729+
let mut vm = vm!();
730+
//Insert ids into memory
731+
vm.segments = segments![
732+
((1, 0), (1, 3)),
733+
((1, 1), (1, 2)),
734+
((1, 2), 0x10000000000000000)
735+
];
736+
vm.set_fp(3);
737+
vm.set_ap(3);
738+
let ids_data = ids_data!["end", "packed_values", "value"];
739+
//Execute the hint
740+
assert_matches!(run_hint!(vm, ids_data, hint_code), Ok(()));
741+
//Check data ptr
742+
check_memory![vm.segments.memory, ((1, 3), 0)];
743+
}
744+
745+
#[test]
746+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
747+
fn blake2s_unpack_felts() {
748+
let hint_code = hint_code::BLAKE2S_UNPACK_FELTS;
749+
//Create vm
750+
let mut vm = vm!();
751+
//Insert ids into memory
752+
vm.segments = segments![
753+
((1, 0), 2),
754+
((1, 1), (1, 3)),
755+
((1, 2), (2, 0)),
756+
((1, 3), 0x123456781234),
757+
((1, 4), 0x1234abcd5678efab1234abcd)
758+
];
759+
vm.set_fp(5);
760+
vm.set_ap(5);
761+
let ids_data = ids_data![
762+
"packed_values_len",
763+
"packed_values",
764+
"unpacked_u32s",
765+
"small_value",
766+
"big_value"
767+
];
768+
vm.segments.add();
769+
//Execute the hint
770+
assert_matches!(run_hint!(vm, ids_data, hint_code), Ok(()));
771+
//Check data ptr
772+
check_memory![
773+
vm.segments.memory,
774+
((2, 0), 0x1234),
775+
((2, 1), 0x56781234),
776+
((2, 2), 0x80000000),
777+
((2, 3), 0),
778+
((2, 4), 0),
779+
((2, 5), 0),
780+
((2, 6), 0),
781+
((2, 7), 0x1234abcd),
782+
((2, 8), 0x5678efab),
783+
((2, 9), 0x1234abcd)
784+
];
785+
}
786+
607787
#[test]
608788
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
609789
fn blake2s_add_uint256_bigend_valid_non_zero() {

vm/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#[cfg(feature = "cairo-0-secp-hints")]
22
use super::secp::cairo0_hints;
33
use super::{
4-
blake2s_utils::finalize_blake2s_v3,
4+
blake2s_utils::{blake2s_unpack_felts, blake2s_unpack_nondet_jmp, finalize_blake2s_v3},
55
ec_recover::{
66
ec_recover_divmod_n_packed, ec_recover_product_div_m, ec_recover_product_mod,
77
ec_recover_sub_a_b,
@@ -360,6 +360,12 @@ impl HintProcessorLogic for BuiltinHintProcessor {
360360
hint_code::BLAKE2S_ADD_UINT256_BIGEND => {
361361
blake2s_add_uint256_bigend(vm, &hint_data.ids_data, &hint_data.ap_tracking)
362362
}
363+
hint_code::BLAKE2S_UNPACK_NONDET_JMP => {
364+
blake2s_unpack_nondet_jmp(vm, &hint_data.ids_data, &hint_data.ap_tracking)
365+
}
366+
hint_code::BLAKE2S_UNPACK_FELTS => {
367+
blake2s_unpack_felts(vm, &hint_data.ids_data, &hint_data.ap_tracking)
368+
}
363369
hint_code::UNSAFE_KECCAK => {
364370
unsafe_keccak(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking)
365371
}

vm/src/hint_processor/builtin_hint_processor/hint_code.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,17 @@ segments.write_arg(ids.data + 4, [(ids.high >> (B * i)) & MASK for i in range(4)
426426
MASK = 2 ** 32 - 1
427427
segments.write_arg(ids.data, [(ids.high >> (B * (3 - i))) & MASK for i in range(4)])
428428
segments.write_arg(ids.data + 4, [(ids.low >> (B * (3 - i))) & MASK for i in range(4)])"#}),
429+
(BLAKE2S_UNPACK_NONDET_JMP, indoc! {r#"memory[ap] = (ids.end != ids.packed_values) and (memory[ids.packed_values] < 2**63)"#}),
430+
(BLAKE2S_UNPACK_FELTS, indoc! {r#"offset = 0
431+
for i in range(ids.packed_values_len):
432+
val = (memory[ids.packed_values + i] % PRIME)
433+
val_len = 2 if val < 2**63 else 8
434+
if val_len == 8:
435+
val += 2**255
436+
for i in range(val_len - 1, -1, -1):
437+
val, memory[ids.unpacked_u32s + offset + i] = divmod(val, 2**32)
438+
assert val == 0
439+
offset += val_len"#}),
429440
(EXAMPLE_BLAKE2S_COMPRESS, indoc! {r#"from starkware.cairo.common.cairo_blake2s.blake2s_utils import IV, blake2s_compress
430441
431442
_blake2s_input_chunk_size_felts = int(ids.BLAKE2S_INPUT_CHUNK_SIZE_FELTS)

0 commit comments

Comments
 (0)