Skip to content

Commit 6ddd419

Browse files
fmolettaOppen
andauthored
feat: Implement hints on uint384 lib (Part 2) (#971)
* Add hint code for UINT348_UNSIGNED_DIV_REM * Add file for uint348 files * Add pack & split for uint348 * Move comment * Implement uint348_unsigned_div_rem hint * Add integration test * Add integration test * Add unit tests * Add hint on split_128 * Test split_128 hint * Add add_no_uint384_hint * Fix hint + add tests * Add hint code for UINT348_UNSIGNED_DIV_REM_EXPAND * Msc fixes * Add integration test * Reduce Uint384_expand representation to the 3 used limbs * Add unit test * Add hint code for UINT384_SQRT * Add implementation for hint on sqrt * Integration test * Add unit tests * Fix missing directive * Run cairo-format * Add hint code for UINT384_SIGNED_NN hint * Implement hint uint348_signed_nn * Add integration test * Add unit tests * Fix unit tests * Update src/hint_processor/builtin_hint_processor/uint384.rs Co-authored-by: Mario Rugiero <[email protected]> * Add changelog entry * Spelling * Add changelog entry * Fix commited suggestion * Fix test names + remove assert_matches --------- Co-authored-by: Mario Rugiero <[email protected]>
1 parent b84acae commit 6ddd419

File tree

5 files changed

+124
-2
lines changed

5 files changed

+124
-2
lines changed

CHANGELOG.md

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

33
#### Upcoming Changes
44

5+
* Implement hints on uint384 lib (Part 2) [#971](https://github.com/lambdaclass/cairo-rs/pull/971)
6+
7+
`BuiltinHintProcessor` now supports the following hint:
8+
9+
```python
10+
memory[ap] = 1 if 0 <= (ids.a.d2 % PRIME) < 2 ** 127 else 0
11+
```
12+
513
* Add alternative hint code for hint on _block_permutation used by 0.10.3 whitelist [#958](https://github.com/lambdaclass/cairo-rs/pull/958)
614

715
`BuiltinHintProcessor` now supports the following hint:

cairo_programs/uint384.cairo

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,22 @@ namespace uint384_lib {
9797
return (res,);
9898
}
9999

100+
// Returns 1 if the signed integer is nonnegative.
101+
@known_ap_change
102+
func signed_nn{range_check_ptr}(a: Uint384) -> (res: felt) {
103+
%{ memory[ap] = 1 if 0 <= (ids.a.d2 % PRIME) < 2 ** 127 else 0 %}
104+
jmp non_negative if [ap] != 0, ap++;
105+
106+
assert [range_check_ptr] = a.d2 - 2 ** 127;
107+
let range_check_ptr = range_check_ptr + 1;
108+
return (res=0);
109+
110+
non_negative:
111+
assert [range_check_ptr] = a.d2 + 2 ** 127;
112+
let range_check_ptr = range_check_ptr + 1;
113+
return (res=1);
114+
}
115+
100116
// Adds two integers. Returns the result as a 384-bit integer and the (1-bit) carry.
101117
// Doesn't verify that the result is a proper Uint384, that's now the responsibility of the calling function
102118
func _add_no_uint384_check{range_check_ptr}(a: Uint384, b: Uint384) -> (
@@ -523,6 +539,14 @@ func test_uint384_operations{range_check_ptr}() {
523539
assert root.d1 = 916102188;
524540
assert root.d2 = 0;
525541

542+
let g = Uint384(1, 1, 1);
543+
let (sign_g) = uint384_lib.signed_nn(g);
544+
assert sign_g = 1;
545+
546+
let h = Uint384(0, 0, 170141183460469231731687303715884105729);
547+
let (sign_h) = uint384_lib.signed_nn(h);
548+
assert sign_h = 0;
549+
526550
return ();
527551
}
528552

src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ use crate::hint_processor::builtin_hint_processor::skip_next_instruction::skip_n
7373

7474
use super::ec_utils::{chained_ec_op_random_ec_point_hint, random_ec_point_hint, recover_y_hint};
7575
use super::uint384::{
76-
add_no_uint384_check, uint384_split_128, uint384_sqrt, uint384_unsigned_div_rem,
77-
uint384_unsigned_div_rem_expanded,
76+
add_no_uint384_check, uint384_signed_nn, uint384_split_128, uint384_sqrt,
77+
uint384_unsigned_div_rem, uint384_unsigned_div_rem_expanded,
7878
};
7979

8080
pub struct HintProcessorData {
@@ -472,6 +472,9 @@ impl HintProcessor for BuiltinHintProcessor {
472472
hint_code::UINT384_SQRT => {
473473
uint384_sqrt(vm, &hint_data.ids_data, &hint_data.ap_tracking)
474474
}
475+
hint_code::UINT384_SIGNED_NN => {
476+
uint384_signed_nn(vm, &hint_data.ids_data, &hint_data.ap_tracking)
477+
}
475478
hint_code::UINT256_MUL_DIV_MOD => {
476479
uint256_mul_div_mod(vm, &hint_data.ids_data, &hint_data.ap_tracking)
477480
}

src/hint_processor/builtin_hint_processor/hint_code.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,8 @@ root_split = split(root, num_bits_shift=128, length=3)
727727
ids.root.d0 = root_split[0]
728728
ids.root.d1 = root_split[1]
729729
ids.root.d2 = root_split[2]";
730+
pub(crate) const UINT384_SIGNED_NN: &str =
731+
"memory[ap] = 1 if 0 <= (ids.a.d2 % PRIME) < 2 ** 127 else 0";
730732

731733
#[cfg(feature = "skip_next_instruction_hint")]
732734
pub(crate) const SKIP_NEXT_INSTRUCTION: &str = "skip_next_instruction()";

src/hint_processor/builtin_hint_processor/uint384.rs

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::{
1515

1616
use super::hint_utils::{
1717
get_integer_from_var_name, get_relocatable_from_var_name, insert_value_from_var_name,
18+
insert_value_into_ap,
1819
};
1920
use super::secp::bigint_utils::BigInt3;
2021
// Notes: Hints in this lib use the type Uint384, which is equal to common lib's BigInt3
@@ -302,6 +303,23 @@ pub fn uint384_sqrt(
302303
}
303304
Ok(())
304305
}
306+
307+
/* Implements Hint:
308+
memory[ap] = 1 if 0 <= (ids.a.d2 % PRIME) < 2 ** 127 else 0
309+
*/
310+
pub fn uint384_signed_nn(
311+
vm: &mut VirtualMachine,
312+
ids_data: &HashMap<String, HintReference>,
313+
ap_tracking: &ApTracking,
314+
) -> Result<(), HintError> {
315+
let a_addr = get_relocatable_from_var_name("a", vm, ids_data, ap_tracking)?;
316+
let a_d2 = vm
317+
.get_integer((a_addr + 2)?)
318+
.map_err(|_| HintError::IdentifierHasNoMember("a".to_string(), "d2".to_string()))?;
319+
let res = Felt252::from((a_d2.bits() <= 127) as u32);
320+
insert_value_into_ap(vm, res)
321+
}
322+
305323
#[cfg(test)]
306324
mod tests {
307325
use super::*;
@@ -705,4 +723,71 @@ mod tests {
705723
Err(HintError::AssertionFailed(s)) if s == "assert 0 <= root < 2 ** 192"
706724
);
707725
}
726+
727+
#[test]
728+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
729+
fn run_signed_nn_ok_positive() {
730+
let mut vm = vm_with_range_check!();
731+
//Initialize fp
732+
vm.run_context.fp = 3;
733+
//Create hint_data
734+
let ids_data = non_continuous_ids_data![("a", -2)];
735+
//Insert ids into memory
736+
vm.segments = segments![
737+
//a.d2
738+
((1, 3), 1)
739+
];
740+
//Execute the hint
741+
assert!(run_hint!(vm, ids_data, hint_code::UINT384_SIGNED_NN).is_ok());
742+
//Check hint memory inserts
743+
check_memory![
744+
vm.segments.memory,
745+
// ap
746+
((1, 0), 1)
747+
];
748+
}
749+
750+
#[test]
751+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
752+
fn run_signed_nn_missing_identifier() {
753+
let mut vm = vm_with_range_check!();
754+
//Initialize fp
755+
vm.run_context.fp = 3;
756+
//Create hint_data
757+
let ids_data = non_continuous_ids_data![("a", -2)];
758+
//Insert ids into memory
759+
vm.segments = segments![
760+
//a.d0
761+
((1, 1), 1),
762+
//a.d1
763+
((1, 2), 1) //a.d2
764+
];
765+
//Execute the hint
766+
assert_matches!(run_hint!(vm, ids_data, hint_code::UINT384_SIGNED_NN),
767+
Err(HintError::IdentifierHasNoMember(s1, s2)) if s1 == "a" && s2 == "d2"
768+
);
769+
}
770+
771+
#[test]
772+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
773+
fn run_signed_nn_ok_negative() {
774+
let mut vm = vm_with_range_check!();
775+
//Initialize fp
776+
vm.run_context.fp = 3;
777+
//Create hint_data
778+
let ids_data = non_continuous_ids_data![("a", -2)];
779+
//Insert ids into memory
780+
vm.segments = segments![
781+
//a.d0
782+
((1, 3), 170141183460469231731687303715884105729_u128)
783+
];
784+
//Execute the hint
785+
assert!(run_hint!(vm, ids_data, hint_code::UINT384_SIGNED_NN).is_ok());
786+
//Check hint memory inserts
787+
check_memory![
788+
vm.segments.memory,
789+
// ap
790+
((1, 0), 0)
791+
];
792+
}
708793
}

0 commit comments

Comments
 (0)