Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```

* Update `starknet-crypto` to version `0.4.3` [#1011](https://github.com/lambdaclass/cairo-rs/pull/1011)
* The new version carries an 85% reduction in execution time for ECDSA signature verification

Expand Down
30 changes: 30 additions & 0 deletions cairo_programs/highest_bitlen.cairo
Original file line number Diff line number Diff line change
@@ -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 ();
}
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -537,6 +536,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)
}
hint_code::QUAD_BIT => quad_bit(vm, &hint_data.ids_data, &hint_data.ap_tracking),
#[cfg(feature = "skip_next_instruction_hint")]
hint_code::SKIP_NEXT_INSTRUCTION => skip_next_instruction(vm),
Expand Down
3 changes: 3 additions & 0 deletions src/hint_processor/builtin_hint_processor/hint_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,9 @@ 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";

pub const QUAD_BIT: &str = r#"ids.quad_bit = (
8 * ((ids.scalar_v >> ids.m) & 1)
+ 4 * ((ids.scalar_u >> ids.m) & 1)
Expand Down
51 changes: 51 additions & 0 deletions src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down Expand Up @@ -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<String, HintReference>,
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::*;
Expand Down Expand Up @@ -246,4 +272,29 @@ 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!(run_hint!(vm, ids_data, hint_code, exec_scopes_ref!()).is_ok());
//Check hint memory inserts
check_memory![vm.segments.memory, ((1, 6), 0)];
}
}
7 changes: 7 additions & 0 deletions src/tests/cairo_run_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1357,3 +1357,10 @@ fn cairo_run_quad_bit() {
let program_data = include_bytes!("../../cairo_programs/quad_bit.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());
}