From 6f666494a08394eaf6457ac166ad55156e59a575 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s?= Date: Tue, 18 Apr 2023 13:29:58 -0300 Subject: [PATCH 1/3] Add NewHint#14 --- cairo_programs/highest_bitlen.cairo | 30 +++++++++++ .../builtin_hint_processor_definition.rs | 8 +-- .../builtin_hint_processor/hint_code.rs | 3 ++ .../secp/bigint_utils.rs | 54 +++++++++++++++++++ src/tests/cairo_run_test.rs | 7 +++ 5 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 cairo_programs/highest_bitlen.cairo diff --git a/cairo_programs/highest_bitlen.cairo b/cairo_programs/highest_bitlen.cairo new file mode 100644 index 0000000000..d0b21807be --- /dev/null +++ b/cairo_programs/highest_bitlen.cairo @@ -0,0 +1,30 @@ +%builtins range_check + +from starkware.cairo.common.cairo_secp.bigint import BigInt3 + +func get_highlen{range_check_ptr}(scalar_u: BigInt3, scalar_v: BigInt3) -> felt { + alloc_locals; + local len_hi; + + %{ ids.len_hi = max(ids.scalar_u.d2.bit_length(), ids.scalar_v.d2.bit_length())-1 %} + + return len_hi; +} + +func test_highest_len{range_check_ptr}() { + assert get_highlen(BigInt3(0, 0, 8), BigInt3(0, 0, 0)) = 3; + assert get_highlen(BigInt3(0, 0, 0), BigInt3(0, 0, 1)) = 0; + assert get_highlen(BigInt3(0, 0, 2), BigInt3(0, 0, 1)) = 1; + + // This overflows + let res = get_highlen(BigInt3(0, 0, 0), BigInt3(0, 0, 0)); + assert res = 3618502788666131213697322783095070105623107215331596699973092056135872020480; + + return (); +} + +func main{range_check_ptr}() { + test_highest_len(); + + return (); +} diff --git a/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs b/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs index 76db67251d..eaf0ed773f 100644 --- a/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs +++ b/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs @@ -27,7 +27,7 @@ use crate::{ poseidon_utils::{n_greater_than_10, n_greater_than_2}, pow_utils::pow, secp::{ - bigint_utils::{bigint_to_uint256, nondet_bigint3}, + bigint_utils::{bigint_to_uint256, hi_max_bitlen, nondet_bigint3}, ec_utils::{ compute_doubling_slope, compute_slope, ec_double_assign_new_x, ec_double_assign_new_y, ec_mul_inner, ec_negate, fast_ec_add_assign_new_x, @@ -62,6 +62,7 @@ use crate::{ add_no_uint384_check, uint384_signed_nn, uint384_split_128, uint384_sqrt, uint384_unsigned_div_rem, uint384_unsigned_div_rem_expanded, }, + uint384_extension::unsigned_div_rem_uint768_by_uint384, usort::{ usort_body, usort_enter_scope, verify_multiplicity_assert, verify_multiplicity_body, verify_usort, @@ -79,8 +80,6 @@ use felt::Felt252; #[cfg(feature = "skip_next_instruction_hint")] use crate::hint_processor::builtin_hint_processor::skip_next_instruction::skip_next_instruction; -use super::uint384_extension::unsigned_div_rem_uint768_by_uint384; - pub struct HintProcessorData { pub code: String, pub ap_tracking: ApTracking, @@ -531,6 +530,9 @@ impl HintProcessor for BuiltinHintProcessor { hint_code::UINT256_MUL_DIV_MOD => { uint256_mul_div_mod(vm, &hint_data.ids_data, &hint_data.ap_tracking) } + hint_code::HI_MAX_BITLEN => { + hi_max_bitlen(vm, &hint_data.ids_data, &hint_data.ap_tracking) + } #[cfg(feature = "skip_next_instruction_hint")] hint_code::SKIP_NEXT_INSTRUCTION => skip_next_instruction(vm), code => Err(HintError::UnknownHint(code.to_string())), diff --git a/src/hint_processor/builtin_hint_processor/hint_code.rs b/src/hint_processor/builtin_hint_processor/hint_code.rs index 2e14f1ca65..3bc935599c 100644 --- a/src/hint_processor/builtin_hint_processor/hint_code.rs +++ b/src/hint_processor/builtin_hint_processor/hint_code.rs @@ -815,5 +815,8 @@ ids.remainder.d1 = remainder_split[1] ids.remainder.d2 = remainder_split[2]"; pub const UINT384_SIGNED_NN: &str = "memory[ap] = 1 if 0 <= (ids.a.d2 % PRIME) < 2 ** 127 else 0"; +pub const HI_MAX_BITLEN: &str = + "ids.len_hi = max(ids.scalar_u.d2.bit_length(), ids.scalar_v.d2.bit_length())-1"; + #[cfg(feature = "skip_next_instruction_hint")] pub const SKIP_NEXT_INSTRUCTION: &str = "skip_next_instruction()"; diff --git a/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs b/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs index cdba93b806..d4c518b29d 100644 --- a/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs +++ b/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs @@ -15,6 +15,7 @@ use crate::{ vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, }; use felt::Felt252; +use num_traits::Bounded; #[derive(Debug, PartialEq)] pub(crate) struct BigInt3<'a> { @@ -100,6 +101,31 @@ pub fn bigint_to_uint256( insert_value_from_var_name("low", low, vm, ids_data, ap_tracking) } +// Implements hint +// %{ ids.len_hi = max(ids.scalar_u.d2.bit_length(), ids.scalar_v.d2.bit_length())-1 %} +pub fn hi_max_bitlen( + vm: &mut VirtualMachine, + ids_data: &HashMap, + ap_tracking: &ApTracking, +) -> Result<(), HintError> { + let scalar_u = BigInt3::from_var_name("scalar_u", vm, ids_data, ap_tracking)?; + let scalar_v = BigInt3::from_var_name("scalar_v", vm, ids_data, ap_tracking)?; + + let len_hi_u = scalar_u.d2.bits(); + let len_hi_v = scalar_v.d2.bits(); + + let len_hi = len_hi_u.max(len_hi_v); + + // equal to `len_hi.wrapping_sub(1)` + let res = if len_hi == 0 { + Felt252::max_value() + } else { + (len_hi - 1).into() + }; + + insert_value_from_var_name("len_hi", res, vm, ids_data, ap_tracking) +} + #[cfg(test)] mod tests { use super::*; @@ -246,4 +272,32 @@ mod tests { let r = BigInt3::from_var_name("x", &vm, &ids_data, &ApTracking::default()); assert_matches!(r, Err(HintError::UnknownIdentifier(x)) if x == "x") } + + #[test] + fn run_hi_max_bitlen_ok() { + let hint_code = + "ids.len_hi = max(ids.scalar_u.d2.bit_length(), ids.scalar_v.d2.bit_length())-1"; + + let mut vm = vm_with_range_check!(); + + // Initialize RunContext + run_context!(vm, 0, 7, 0); + + vm.segments = segments![ + ((1, 0), 0), + ((1, 1), 0), + ((1, 2), 1), + ((1, 3), 0), + ((1, 4), 0), + ((1, 5), 1) + ]; + // Create hint_data + let ids_data = non_continuous_ids_data![("scalar_u", 0), ("scalar_v", 3), ("len_hi", 6)]; + assert_matches!( + run_hint!(vm, ids_data, hint_code, exec_scopes_ref!()), + Ok(()) + ); + //Check hint memory inserts + check_memory![vm.segments.memory, ((1, 6), 0)]; + } } diff --git a/src/tests/cairo_run_test.rs b/src/tests/cairo_run_test.rs index 4e42fe4b4b..dc79c0d20d 100644 --- a/src/tests/cairo_run_test.rs +++ b/src/tests/cairo_run_test.rs @@ -1343,3 +1343,10 @@ fn cairo_run_is_zero() { let program_data = include_bytes!("../../cairo_programs/is_zero.json"); run_program_simple(program_data.as_slice()); } + +#[test] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +fn cairo_run_highest_bitlen() { + let program_data = include_bytes!("../../cairo_programs/highest_bitlen.json"); + run_program_simple(program_data.as_slice()); +} From 7d64d2e4b57f36c8094b1a0c5544e7c6d5bb3a5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s?= Date: Tue, 18 Apr 2023 14:23:05 -0300 Subject: [PATCH 2/3] Update changelog --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 095db26230..3301d18783 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ #### Upcoming Changes +* Add missing hint on cairo_secp lib [#1008](https://github.com/lambdaclass/cairo-rs/pull/1008): + + `BuiltinHintProcessor` now supports the following hint: + + ```python + ids.len_hi = max(ids.scalar_u.d2.bit_length(), ids.scalar_v.d2.bit_length())-1 + ``` + * Implement hint on uint384_extension lib [#983](https://github.com/lambdaclass/cairo-rs/pull/983) `BuiltinHintProcessor` now supports the following hint: From f86ec276b05d89c358ee128b76dc8d7f4c81e64c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s?= Date: Tue, 18 Apr 2023 15:54:55 -0300 Subject: [PATCH 3/3] Change assert_matches for assert + is_ok --- .../builtin_hint_processor/secp/bigint_utils.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs b/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs index d4c518b29d..d27c8007be 100644 --- a/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs +++ b/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs @@ -293,10 +293,7 @@ mod tests { ]; // Create hint_data let ids_data = non_continuous_ids_data![("scalar_u", 0), ("scalar_v", 3), ("len_hi", 6)]; - assert_matches!( - run_hint!(vm, ids_data, hint_code, exec_scopes_ref!()), - Ok(()) - ); + assert!(run_hint!(vm, ids_data, hint_code, exec_scopes_ref!()).is_ok()); //Check hint memory inserts check_memory![vm.segments.memory, ((1, 6), 0)]; }