From 886b82e6da7b77bd768ce4b1763d27bd863987ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20P=2E=20Centeno?= Date: Fri, 14 Apr 2023 18:16:51 -0300 Subject: [PATCH 01/13] Implement hint from `get_felt_bitlength` (Garaga) --- cairo_programs/garaga.cairo | 344 ++++++++++++++++++ .../builtin_hint_processor_definition.rs | 4 + .../builtin_hint_processor/garaga.rs | 24 ++ .../builtin_hint_processor/hint_code.rs | 3 + .../builtin_hint_processor/mod.rs | 1 + src/tests/cairo_run_test.rs | 7 + 6 files changed, 383 insertions(+) create mode 100644 cairo_programs/garaga.cairo create mode 100644 src/hint_processor/builtin_hint_processor/garaga.rs diff --git a/cairo_programs/garaga.cairo b/cairo_programs/garaga.cairo new file mode 100644 index 0000000000..e301e934bc --- /dev/null +++ b/cairo_programs/garaga.cairo @@ -0,0 +1,344 @@ +%builtins range_check bitwise + +from starkware.cairo.common.uint256 import ( + Uint256, + uint256_reverse_endian, + uint256_unsigned_div_rem, + uint256_mul, + uint256_add, + uint256_pow2, +) + +from starkware.cairo.common.cairo_builtins import BitwiseBuiltin +from starkware.cairo.common.registers import get_label_location +from starkware.cairo.common.math import unsigned_div_rem as felt_divmod, split_felt +from starkware.cairo.common.math_cmp import is_le +from starkware.cairo.common.alloc import alloc +from starkware.cairo.common.pow import pow + +// y MUST be a power of 2 +func bitwise_divmod{range_check_ptr, bitwise_ptr: BitwiseBuiltin*}(x: felt, y: felt) -> ( + q: felt, r: felt +) { + assert bitwise_ptr.x = x; + assert bitwise_ptr.y = y - 1; + let x_and_y = bitwise_ptr.x_and_y; + + let bitwise_ptr = bitwise_ptr + BitwiseBuiltin.SIZE; + return (q=(x - x_and_y) / y, r=x_and_y); +} +func felt_divmod_no_input_check{range_check_ptr}(value, div) -> (q: felt, r: felt) { + // let r = [range_check_ptr]; + // let q = [range_check_ptr + 1]; + // let range_check_ptr = range_check_ptr + 2; + alloc_locals; + local r; + local q; + %{ + from starkware.cairo.common.math_utils import assert_integer + assert_integer(ids.div) + assert 0 < ids.div <= PRIME // range_check_builtin.bound, \ + f'div={hex(ids.div)} is out of the valid range.' + ids.q, ids.r = divmod(ids.value, ids.div) + %} + + assert [range_check_ptr] = div - 1 - r; + let range_check_ptr = range_check_ptr + 1; + // assert_le(r, div - 1); + + assert value = q * div + r; + return (q, r); +} + +func get_felt_bitlength{range_check_ptr, bitwise_ptr: BitwiseBuiltin*}(x: felt) -> felt { + alloc_locals; + local bit_length; + %{ + x = ids.x + ids.bit_length = x.bit_length() + %} + + // Next two lines Not necessary : will fail if pow2(bit_length) is too big, unknown cell. + // let le = is_le(bit_length, 252); + // assert le = 1; + assert bitwise_ptr[0].x = x; + let n = pow2(bit_length); + assert bitwise_ptr[0].y = n - 1; + tempvar word = bitwise_ptr[0].x_and_y; + assert word = x; + + assert bitwise_ptr[1].x = x; + + let n = pow2(bit_length - 1); + + assert bitwise_ptr[1].y = n - 1; + tempvar word = bitwise_ptr[1].x_and_y; + assert word = x - n; + + let bitwise_ptr = bitwise_ptr + 2 * BitwiseBuiltin.SIZE; + return bit_length; +} + +func pow2(i) -> felt { + let (data_address) = get_label_location(data); + return [data_address + i]; + + data: + dw 0x1; + dw 0x2; + dw 0x4; + dw 0x8; + dw 0x10; + dw 0x20; + dw 0x40; + dw 0x80; + dw 0x100; + dw 0x200; + dw 0x400; + dw 0x800; + dw 0x1000; + dw 0x2000; + dw 0x4000; + dw 0x8000; + dw 0x10000; + dw 0x20000; + dw 0x40000; + dw 0x80000; + dw 0x100000; + dw 0x200000; + dw 0x400000; + dw 0x800000; + dw 0x1000000; + dw 0x2000000; + dw 0x4000000; + dw 0x8000000; + dw 0x10000000; + dw 0x20000000; + dw 0x40000000; + dw 0x80000000; + dw 0x100000000; + dw 0x200000000; + dw 0x400000000; + dw 0x800000000; + dw 0x1000000000; + dw 0x2000000000; + dw 0x4000000000; + dw 0x8000000000; + dw 0x10000000000; + dw 0x20000000000; + dw 0x40000000000; + dw 0x80000000000; + dw 0x100000000000; + dw 0x200000000000; + dw 0x400000000000; + dw 0x800000000000; + dw 0x1000000000000; + dw 0x2000000000000; + dw 0x4000000000000; + dw 0x8000000000000; + dw 0x10000000000000; + dw 0x20000000000000; + dw 0x40000000000000; + dw 0x80000000000000; + dw 0x100000000000000; + dw 0x200000000000000; + dw 0x400000000000000; + dw 0x800000000000000; + dw 0x1000000000000000; + dw 0x2000000000000000; + dw 0x4000000000000000; + dw 0x8000000000000000; + dw 0x10000000000000000; + dw 0x20000000000000000; + dw 0x40000000000000000; + dw 0x80000000000000000; + dw 0x100000000000000000; + dw 0x200000000000000000; + dw 0x400000000000000000; + dw 0x800000000000000000; + dw 0x1000000000000000000; + dw 0x2000000000000000000; + dw 0x4000000000000000000; + dw 0x8000000000000000000; + dw 0x10000000000000000000; + dw 0x20000000000000000000; + dw 0x40000000000000000000; + dw 0x80000000000000000000; + dw 0x100000000000000000000; + dw 0x200000000000000000000; + dw 0x400000000000000000000; + dw 0x800000000000000000000; + dw 0x1000000000000000000000; + dw 0x2000000000000000000000; + dw 0x4000000000000000000000; + dw 0x8000000000000000000000; + dw 0x10000000000000000000000; + dw 0x20000000000000000000000; + dw 0x40000000000000000000000; + dw 0x80000000000000000000000; + dw 0x100000000000000000000000; + dw 0x200000000000000000000000; + dw 0x400000000000000000000000; + dw 0x800000000000000000000000; + dw 0x1000000000000000000000000; + dw 0x2000000000000000000000000; + dw 0x4000000000000000000000000; + dw 0x8000000000000000000000000; + dw 0x10000000000000000000000000; + dw 0x20000000000000000000000000; + dw 0x40000000000000000000000000; + dw 0x80000000000000000000000000; + dw 0x100000000000000000000000000; + dw 0x200000000000000000000000000; + dw 0x400000000000000000000000000; + dw 0x800000000000000000000000000; + dw 0x1000000000000000000000000000; + dw 0x2000000000000000000000000000; + dw 0x4000000000000000000000000000; + dw 0x8000000000000000000000000000; + dw 0x10000000000000000000000000000; + dw 0x20000000000000000000000000000; + dw 0x40000000000000000000000000000; + dw 0x80000000000000000000000000000; + dw 0x100000000000000000000000000000; + dw 0x200000000000000000000000000000; + dw 0x400000000000000000000000000000; + dw 0x800000000000000000000000000000; + dw 0x1000000000000000000000000000000; + dw 0x2000000000000000000000000000000; + dw 0x4000000000000000000000000000000; + dw 0x8000000000000000000000000000000; + dw 0x10000000000000000000000000000000; + dw 0x20000000000000000000000000000000; + dw 0x40000000000000000000000000000000; + dw 0x80000000000000000000000000000000; + dw 0x100000000000000000000000000000000; + dw 0x200000000000000000000000000000000; + dw 0x400000000000000000000000000000000; + dw 0x800000000000000000000000000000000; + dw 0x1000000000000000000000000000000000; + dw 0x2000000000000000000000000000000000; + dw 0x4000000000000000000000000000000000; + dw 0x8000000000000000000000000000000000; + dw 0x10000000000000000000000000000000000; + dw 0x20000000000000000000000000000000000; + dw 0x40000000000000000000000000000000000; + dw 0x80000000000000000000000000000000000; + dw 0x100000000000000000000000000000000000; + dw 0x200000000000000000000000000000000000; + dw 0x400000000000000000000000000000000000; + dw 0x800000000000000000000000000000000000; + dw 0x1000000000000000000000000000000000000; + dw 0x2000000000000000000000000000000000000; + dw 0x4000000000000000000000000000000000000; + dw 0x8000000000000000000000000000000000000; + dw 0x10000000000000000000000000000000000000; + dw 0x20000000000000000000000000000000000000; + dw 0x40000000000000000000000000000000000000; + dw 0x80000000000000000000000000000000000000; + dw 0x100000000000000000000000000000000000000; + dw 0x200000000000000000000000000000000000000; + dw 0x400000000000000000000000000000000000000; + dw 0x800000000000000000000000000000000000000; + dw 0x1000000000000000000000000000000000000000; + dw 0x2000000000000000000000000000000000000000; + dw 0x4000000000000000000000000000000000000000; + dw 0x8000000000000000000000000000000000000000; + dw 0x10000000000000000000000000000000000000000; + dw 0x20000000000000000000000000000000000000000; + dw 0x40000000000000000000000000000000000000000; + dw 0x80000000000000000000000000000000000000000; + dw 0x100000000000000000000000000000000000000000; + dw 0x200000000000000000000000000000000000000000; + dw 0x400000000000000000000000000000000000000000; + dw 0x800000000000000000000000000000000000000000; + dw 0x1000000000000000000000000000000000000000000; + dw 0x2000000000000000000000000000000000000000000; + dw 0x4000000000000000000000000000000000000000000; + dw 0x8000000000000000000000000000000000000000000; + dw 0x10000000000000000000000000000000000000000000; + dw 0x20000000000000000000000000000000000000000000; + dw 0x40000000000000000000000000000000000000000000; + dw 0x80000000000000000000000000000000000000000000; + dw 0x100000000000000000000000000000000000000000000; + dw 0x200000000000000000000000000000000000000000000; + dw 0x400000000000000000000000000000000000000000000; + dw 0x800000000000000000000000000000000000000000000; + dw 0x1000000000000000000000000000000000000000000000; + dw 0x2000000000000000000000000000000000000000000000; + dw 0x4000000000000000000000000000000000000000000000; + dw 0x8000000000000000000000000000000000000000000000; + dw 0x10000000000000000000000000000000000000000000000; + dw 0x20000000000000000000000000000000000000000000000; + dw 0x40000000000000000000000000000000000000000000000; + dw 0x80000000000000000000000000000000000000000000000; + dw 0x100000000000000000000000000000000000000000000000; + dw 0x200000000000000000000000000000000000000000000000; + dw 0x400000000000000000000000000000000000000000000000; + dw 0x800000000000000000000000000000000000000000000000; + dw 0x1000000000000000000000000000000000000000000000000; + dw 0x2000000000000000000000000000000000000000000000000; + dw 0x4000000000000000000000000000000000000000000000000; + dw 0x8000000000000000000000000000000000000000000000000; + dw 0x10000000000000000000000000000000000000000000000000; + dw 0x20000000000000000000000000000000000000000000000000; + dw 0x40000000000000000000000000000000000000000000000000; + dw 0x80000000000000000000000000000000000000000000000000; + dw 0x100000000000000000000000000000000000000000000000000; + dw 0x200000000000000000000000000000000000000000000000000; + dw 0x400000000000000000000000000000000000000000000000000; + dw 0x800000000000000000000000000000000000000000000000000; + dw 0x1000000000000000000000000000000000000000000000000000; + dw 0x2000000000000000000000000000000000000000000000000000; + dw 0x4000000000000000000000000000000000000000000000000000; + dw 0x8000000000000000000000000000000000000000000000000000; + dw 0x10000000000000000000000000000000000000000000000000000; + dw 0x20000000000000000000000000000000000000000000000000000; + dw 0x40000000000000000000000000000000000000000000000000000; + dw 0x80000000000000000000000000000000000000000000000000000; + dw 0x100000000000000000000000000000000000000000000000000000; + dw 0x200000000000000000000000000000000000000000000000000000; + dw 0x400000000000000000000000000000000000000000000000000000; + dw 0x800000000000000000000000000000000000000000000000000000; + dw 0x1000000000000000000000000000000000000000000000000000000; + dw 0x2000000000000000000000000000000000000000000000000000000; + dw 0x4000000000000000000000000000000000000000000000000000000; + dw 0x8000000000000000000000000000000000000000000000000000000; + dw 0x10000000000000000000000000000000000000000000000000000000; + dw 0x20000000000000000000000000000000000000000000000000000000; + dw 0x40000000000000000000000000000000000000000000000000000000; + dw 0x80000000000000000000000000000000000000000000000000000000; + dw 0x100000000000000000000000000000000000000000000000000000000; + dw 0x200000000000000000000000000000000000000000000000000000000; + dw 0x400000000000000000000000000000000000000000000000000000000; + dw 0x800000000000000000000000000000000000000000000000000000000; + dw 0x1000000000000000000000000000000000000000000000000000000000; + dw 0x2000000000000000000000000000000000000000000000000000000000; + dw 0x4000000000000000000000000000000000000000000000000000000000; + dw 0x8000000000000000000000000000000000000000000000000000000000; + dw 0x10000000000000000000000000000000000000000000000000000000000; + dw 0x20000000000000000000000000000000000000000000000000000000000; + dw 0x40000000000000000000000000000000000000000000000000000000000; + dw 0x80000000000000000000000000000000000000000000000000000000000; + dw 0x100000000000000000000000000000000000000000000000000000000000; + dw 0x200000000000000000000000000000000000000000000000000000000000; + dw 0x400000000000000000000000000000000000000000000000000000000000; + dw 0x800000000000000000000000000000000000000000000000000000000000; + dw 0x1000000000000000000000000000000000000000000000000000000000000; + dw 0x2000000000000000000000000000000000000000000000000000000000000; + dw 0x4000000000000000000000000000000000000000000000000000000000000; + dw 0x8000000000000000000000000000000000000000000000000000000000000; + dw 0x10000000000000000000000000000000000000000000000000000000000000; + dw 0x20000000000000000000000000000000000000000000000000000000000000; + dw 0x40000000000000000000000000000000000000000000000000000000000000; + dw 0x80000000000000000000000000000000000000000000000000000000000000; + dw 0x100000000000000000000000000000000000000000000000000000000000000; + dw 0x200000000000000000000000000000000000000000000000000000000000000; + dw 0x400000000000000000000000000000000000000000000000000000000000000; +} + +func main{range_check_ptr: felt, bitwise_ptr: BitwiseBuiltin*}() { + let x = get_felt_bitlength(42); + assert x = 6; + 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 58fc12429d..1cca1d3118 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 @@ -72,6 +72,7 @@ use felt::Felt252; use crate::hint_processor::builtin_hint_processor::skip_next_instruction::skip_next_instruction; use super::ec_utils::{chained_ec_op_random_ec_point_hint, random_ec_point_hint, recover_y_hint}; +use super::garaga::get_felt_bitlenght; use super::uint384::{ add_no_uint384_check, uint384_signed_nn, uint384_split_128, uint384_sqrt, uint384_unsigned_div_rem, uint384_unsigned_div_rem_expanded, @@ -350,6 +351,9 @@ impl HintProcessor for BuiltinHintProcessor { &hint_data.ap_tracking, ), hint_code::DIV_MOD_N_SAFE_DIV => div_mod_n_safe_div(exec_scopes), + hint_code::GET_FELT_BITLENGTH => { + get_felt_bitlenght(vm, &hint_data.ids_data, &hint_data.ap_tracking) + } hint_code::GET_POINT_FROM_X => get_point_from_x( vm, exec_scopes, diff --git a/src/hint_processor/builtin_hint_processor/garaga.rs b/src/hint_processor/builtin_hint_processor/garaga.rs new file mode 100644 index 0000000000..091819b129 --- /dev/null +++ b/src/hint_processor/builtin_hint_processor/garaga.rs @@ -0,0 +1,24 @@ +use std::collections::HashMap; + +use crate::{ + hint_processor::hint_processor_definition::HintReference, + serde::deserialize_program::ApTracking, + vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, +}; + +use super::hint_utils::{get_integer_from_var_name, insert_value_from_var_name}; + +/// Implements hint: +/// ```python +/// x = ids.x, +/// ids.bit_length = x.bit_length() +/// ``` +pub fn get_felt_bitlenght( + vm: &mut VirtualMachine, + ids_data: &HashMap, + ap_tracking: &ApTracking, +) -> Result<(), HintError> { + let x = get_integer_from_var_name("x", vm, ids_data, ap_tracking)?; + let bit_length = x.bits() as usize; + insert_value_from_var_name("bit_length", bit_length, vm, ids_data, ap_tracking) +} diff --git a/src/hint_processor/builtin_hint_processor/hint_code.rs b/src/hint_processor/builtin_hint_processor/hint_code.rs index 1b6e765eb2..3a1f252f15 100644 --- a/src/hint_processor/builtin_hint_processor/hint_code.rs +++ b/src/hint_processor/builtin_hint_processor/hint_code.rs @@ -443,6 +443,9 @@ value = res = div_mod(a, b, N)"#; pub const DIV_MOD_N_SAFE_DIV: &str = r#"value = k = safe_div(res * b - a, N)"#; +pub const GET_FELT_BITLENGTH: &str = r#"x = ids.x +ids.bit_length = x.bit_length()"#; + pub const GET_POINT_FROM_X: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack x_cube_int = pack(ids.x_cube, PRIME) % SECP_P diff --git a/src/hint_processor/builtin_hint_processor/mod.rs b/src/hint_processor/builtin_hint_processor/mod.rs index 19348b601c..68225dee6d 100644 --- a/src/hint_processor/builtin_hint_processor/mod.rs +++ b/src/hint_processor/builtin_hint_processor/mod.rs @@ -6,6 +6,7 @@ pub mod dict_hint_utils; pub mod dict_manager; pub mod ec_utils; pub mod find_element_hint; +pub mod garaga; pub mod hint_code; pub mod hint_utils; pub mod keccak_utils; diff --git a/src/tests/cairo_run_test.rs b/src/tests/cairo_run_test.rs index ef2da718e2..7f800fc6f4 100644 --- a/src/tests/cairo_run_test.rs +++ b/src/tests/cairo_run_test.rs @@ -1315,3 +1315,10 @@ fn cairo_run_efficient_secp256r1_ec() { let program_data = include_bytes!("../../cairo_programs/efficient_secp256r1_ec.json"); run_program_simple(program_data.as_slice()); } + +#[test] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +fn cairo_run_garaga() { + let program_data = include_bytes!("../../cairo_programs/garaga.json"); + run_program_simple(program_data.as_slice()); +} From 6c0e7005555533c9b4a0fcfb579883c149c5e4dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20P=2E=20Centeno?= Date: Fri, 14 Apr 2023 18:45:23 -0300 Subject: [PATCH 02/13] Update changelog --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b23d95862..367f8a7ea8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ #### Upcoming Changes +* Implement hint on `get_felt_bitlength` [#993](https://github.com/lambdaclass/cairo-rs/pull/993) + + `BuiltinHintProcessor` now supports the following hint: + ```python + x = ids.x + ids.bit_length = x.bit_length() + ``` + Used by the [`Garaga` library function `get_felt_bitlength`](https://github.com/keep-starknet-strange/garaga/blob/249f8a372126b3a839f9c1e1080ea8c6f9374c0c/src/utils.cairo#L54) + * Add missing `\n` character in traceback string [#997](https://github.com/lambdaclass/cairo-rs/pull/997) * BugFix: Add missing `\n` character after traceback lines when the filename is missing ("Unknown Location") From 894fe24b11841ea03759d1f3e4ca1ac9919505c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20P=2E=20Centeno?= Date: Mon, 17 Apr 2023 15:49:55 -0300 Subject: [PATCH 03/13] Fix format --- .../builtin_hint_processor/builtin_hint_processor_definition.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 aa0a280949..92be4bcc4d 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 @@ -356,7 +356,7 @@ impl HintProcessor for BuiltinHintProcessor { hint_code::DIV_MOD_N_SAFE_DIV => div_mod_n_safe_div(exec_scopes, "a", "b"), hint_code::GET_FELT_BITLENGTH => { get_felt_bitlenght(vm, &hint_data.ids_data, &hint_data.ap_tracking) - }, + } hint_code::GET_POINT_FROM_X => get_point_from_x( vm, exec_scopes, From 1b8c586227397aa322873534ad45a10ad9fa7010 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20P=2E=20Centeno?= Date: Mon, 17 Apr 2023 17:05:00 -0300 Subject: [PATCH 04/13] Use WASM-compatible `HashMap` --- src/hint_processor/builtin_hint_processor/garaga.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hint_processor/builtin_hint_processor/garaga.rs b/src/hint_processor/builtin_hint_processor/garaga.rs index 091819b129..ea5af8bf99 100644 --- a/src/hint_processor/builtin_hint_processor/garaga.rs +++ b/src/hint_processor/builtin_hint_processor/garaga.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use crate::stdlib::collections::HashMap; use crate::{ hint_processor::hint_processor_definition::HintReference, From b7f9019710e9168d6433309f6279f97f15ff11ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20P=2E=20Centeno?= Date: Mon, 17 Apr 2023 17:54:28 -0300 Subject: [PATCH 05/13] Fix broken imports --- .../builtin_hint_processor_definition.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) 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 ef7ed2236c..4aeb7ac951 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 @@ -78,10 +78,7 @@ 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::{ - add_no_uint384_check, uint384_signed_nn, uint384_split_128, uint384_sqrt, - uint384_unsigned_div_rem, uint384_unsigned_div_rem_expanded, -}; +use super::garaga::get_felt_bitlenght; pub struct HintProcessorData { pub code: String, From 40fc879a6c6642bd114a415f27bcecb03eb66ffa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20P=2E=20Centeno?= Date: Mon, 17 Apr 2023 18:09:19 -0300 Subject: [PATCH 06/13] Import WASM-compatible `String` --- src/hint_processor/builtin_hint_processor/garaga.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hint_processor/builtin_hint_processor/garaga.rs b/src/hint_processor/builtin_hint_processor/garaga.rs index ea5af8bf99..59a5af3183 100644 --- a/src/hint_processor/builtin_hint_processor/garaga.rs +++ b/src/hint_processor/builtin_hint_processor/garaga.rs @@ -1,4 +1,5 @@ use crate::stdlib::collections::HashMap; +use crate::stdlib::prelude::String; use crate::{ hint_processor::hint_processor_definition::HintReference, From 7675a93e89096ccc5dc82c8b66ad6863b5fd66d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20P=2E=20Centeno?= Date: Tue, 18 Apr 2023 15:36:03 -0300 Subject: [PATCH 07/13] Add a unit test for bit lenght hint --- .../builtin_hint_processor/garaga.rs | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/hint_processor/builtin_hint_processor/garaga.rs b/src/hint_processor/builtin_hint_processor/garaga.rs index 59a5af3183..9b34408cef 100644 --- a/src/hint_processor/builtin_hint_processor/garaga.rs +++ b/src/hint_processor/builtin_hint_processor/garaga.rs @@ -23,3 +23,45 @@ pub fn get_felt_bitlenght( let bit_length = x.bits() as usize; insert_value_from_var_name("bit_length", bit_length, vm, ids_data, ap_tracking) } + +#[cfg(test)] +mod tests { + use crate::any_box; + use crate::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor; + use crate::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; + use crate::hint_processor::hint_processor_definition::HintProcessor; + use crate::hint_processor::hint_processor_utils::felt_to_u32; + use crate::types::exec_scope::ExecutionScopes; + use crate::types::relocatable::MaybeRelocatable; + use crate::vm::errors::memory_errors::MemoryError; + use crate::vm::vm_memory::memory::Memory; + use crate::vm::vm_memory::memory_segments::MemorySegmentManager; + use crate::{hint_processor::builtin_hint_processor::hint_code, utils::test_utils::*}; + use assert_matches::assert_matches; + + use super::*; + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn test_7_bit_length_is_3() { + let ids_data = non_continuous_ids_data![ + ("x", 0), // located at `fp + 0`. + ("bit_length", 1) // located at `fp + 1`. + ]; + + let mut vm = vm!(); + vm.run_context.fp = 0; + vm.segments = segments![ + ((1, 0), 7) // Inits `x` to `7`. + // Don't initialize `fp + 1` for `bit_length`! + ]; + + assert_matches!( + run_hint!(vm, ids_data, hint_code::GET_FELT_BITLENGTH), + Ok(()) + ); + + let bit_length = felt_to_u32(&vm.get_integer((1, 1).into()).unwrap()).unwrap(); + assert_eq!(bit_length, 3); + } +} From eb8629177d00c38791b830932dd19417f7581d60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20P=2E=20Centeno?= Date: Tue, 18 Apr 2023 15:36:37 -0300 Subject: [PATCH 08/13] Fix typo --- .../builtin_hint_processor/builtin_hint_processor_definition.rs | 2 +- src/hint_processor/builtin_hint_processor/garaga.rs | 2 +- src/hint_processor/builtin_hint_processor/hint_code.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) 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 d37be120bf..df35669a33 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 @@ -358,7 +358,7 @@ impl HintProcessor for BuiltinHintProcessor { &hint_data.ids_data, &hint_data.ap_tracking, ), - hint_code::GET_FELT_BITLENGTH => { + hint_code::GET_FELT_BIT_LENGTH => { get_felt_bitlenght(vm, &hint_data.ids_data, &hint_data.ap_tracking) } hint_code::DIV_MOD_N_PACKED_DIVMOD_EXTERNAL_N => div_mod_n_packed_external_n( diff --git a/src/hint_processor/builtin_hint_processor/garaga.rs b/src/hint_processor/builtin_hint_processor/garaga.rs index 9b34408cef..6598c6969a 100644 --- a/src/hint_processor/builtin_hint_processor/garaga.rs +++ b/src/hint_processor/builtin_hint_processor/garaga.rs @@ -57,7 +57,7 @@ mod tests { ]; assert_matches!( - run_hint!(vm, ids_data, hint_code::GET_FELT_BITLENGTH), + run_hint!(vm, ids_data, hint_code::GET_FELT_BIT_LENGTH), Ok(()) ); diff --git a/src/hint_processor/builtin_hint_processor/hint_code.rs b/src/hint_processor/builtin_hint_processor/hint_code.rs index e331e6b4aa..68aa352533 100644 --- a/src/hint_processor/builtin_hint_processor/hint_code.rs +++ b/src/hint_processor/builtin_hint_processor/hint_code.rs @@ -456,7 +456,7 @@ value = res = div_mod(a, b, N)"#; pub const DIV_MOD_N_SAFE_DIV: &str = r#"value = k = safe_div(res * b - a, N)"#; -pub const GET_FELT_BITLENGTH: &str = r#"x = ids.x +pub const GET_FELT_BIT_LENGTH: &str = r#"x = ids.x ids.bit_length = x.bit_length()"#; pub const DIV_MOD_N_SAFE_DIV_PLUS_ONE: &str = From 178237a207ebee58f89a264bd975a147b436f68a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20P=2E=20Centeno?= Date: Wed, 19 Apr 2023 14:47:11 -0300 Subject: [PATCH 09/13] Add test cases --- .../builtin_hint_processor/garaga.rs | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/hint_processor/builtin_hint_processor/garaga.rs b/src/hint_processor/builtin_hint_processor/garaga.rs index 6598c6969a..b777eb7b9c 100644 --- a/src/hint_processor/builtin_hint_processor/garaga.rs +++ b/src/hint_processor/builtin_hint_processor/garaga.rs @@ -38,6 +38,7 @@ mod tests { use crate::vm::vm_memory::memory_segments::MemorySegmentManager; use crate::{hint_processor::builtin_hint_processor::hint_code, utils::test_utils::*}; use assert_matches::assert_matches; + use felt::Felt252; use super::*; @@ -52,8 +53,8 @@ mod tests { let mut vm = vm!(); vm.run_context.fp = 0; vm.segments = segments![ - ((1, 0), 7) // Inits `x` to `7`. - // Don't initialize `fp + 1` for `bit_length`! + ((1, 0), 7) // Inits `ids.x` to `7`. + // Don't initialize `fp + 1` for `ids.bit_length`! ]; assert_matches!( @@ -64,4 +65,30 @@ mod tests { let bit_length = felt_to_u32(&vm.get_integer((1, 1).into()).unwrap()).unwrap(); assert_eq!(bit_length, 3); } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn test_in_range() { + for i in 0..252 { + let x: Felt252 = Felt252::new(1) << i; + + let ids_data = non_continuous_ids_data![ + ("x", 0), // located at `fp + 0`. + ("bit_length", 1) // located at `fp + 1`. + ]; + + let mut vm = vm!(); + vm.run_context.fp = 0; + add_segments!(vm, 2); // Alloc space for `ids.x` and `ids.bit_length` + vm.insert_value((1, 0).into(), x).unwrap(); + + assert_matches!( + run_hint!(vm, ids_data, hint_code::GET_FELT_BIT_LENGTH), + Ok(()) + ); + + let bit_length = felt_to_u32(&vm.get_integer((1, 1).into()).unwrap()).unwrap(); + assert_eq!(bit_length, i + 1); + } + } } From d0d808108fcc85df9950724e17be34a35bd588fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20P=2E=20Centeno?= Date: Wed, 19 Apr 2023 15:22:43 -0300 Subject: [PATCH 10/13] Refactor tests --- .../builtin_hint_processor/garaga.rs | 60 +++++++------------ 1 file changed, 21 insertions(+), 39 deletions(-) diff --git a/src/hint_processor/builtin_hint_processor/garaga.rs b/src/hint_processor/builtin_hint_processor/garaga.rs index b777eb7b9c..1fdda4a713 100644 --- a/src/hint_processor/builtin_hint_processor/garaga.rs +++ b/src/hint_processor/builtin_hint_processor/garaga.rs @@ -30,65 +30,47 @@ mod tests { use crate::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor; use crate::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; use crate::hint_processor::hint_processor_definition::HintProcessor; - use crate::hint_processor::hint_processor_utils::felt_to_u32; use crate::types::exec_scope::ExecutionScopes; - use crate::types::relocatable::MaybeRelocatable; - use crate::vm::errors::memory_errors::MemoryError; - use crate::vm::vm_memory::memory::Memory; - use crate::vm::vm_memory::memory_segments::MemorySegmentManager; use crate::{hint_processor::builtin_hint_processor::hint_code, utils::test_utils::*}; - use assert_matches::assert_matches; use felt::Felt252; + use num_traits::One; use super::*; - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn test_7_bit_length_is_3() { + fn run_hint(x: Felt252) -> Result { + let mut vm = vm!(); let ids_data = non_continuous_ids_data![ ("x", 0), // located at `fp + 0`. ("bit_length", 1) // located at `fp + 1`. ]; - let mut vm = vm!(); vm.run_context.fp = 0; - vm.segments = segments![ - ((1, 0), 7) // Inits `ids.x` to `7`. - // Don't initialize `fp + 1` for `ids.bit_length`! - ]; + add_segments!(vm, 2); // Alloc space for `ids.x` and `ids.bit_length` + vm.insert_value((1, 0).into(), x).unwrap(); - assert_matches!( - run_hint!(vm, ids_data, hint_code::GET_FELT_BIT_LENGTH), - Ok(()) - ); + match run_hint!(vm, ids_data, hint_code::GET_FELT_BIT_LENGTH) { + Ok(()) => Ok(vm.get_integer((1, 1).into()).unwrap().into_owned()), + Err(e) => Err(e), + } + } - let bit_length = felt_to_u32(&vm.get_integer((1, 1).into()).unwrap()).unwrap(); - assert_eq!(bit_length, 3); + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn test_simple() { + let bit_length_result = run_hint(Felt252::new(7)); + assert!(bit_length_result.is_ok()); + assert_eq!(bit_length_result.unwrap(), Felt252::from(3)); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_in_range() { - for i in 0..252 { - let x: Felt252 = Felt252::new(1) << i; - - let ids_data = non_continuous_ids_data![ - ("x", 0), // located at `fp + 0`. - ("bit_length", 1) // located at `fp + 1`. - ]; - - let mut vm = vm!(); - vm.run_context.fp = 0; - add_segments!(vm, 2); // Alloc space for `ids.x` and `ids.bit_length` - vm.insert_value((1, 0).into(), x).unwrap(); - - assert_matches!( - run_hint!(vm, ids_data, hint_code::GET_FELT_BIT_LENGTH), - Ok(()) - ); + for i in 0..252usize { + let x: Felt252 = Felt252::one() << i; - let bit_length = felt_to_u32(&vm.get_integer((1, 1).into()).unwrap()).unwrap(); - assert_eq!(bit_length, i + 1); + let bit_length_result = run_hint(x); + assert!(bit_length_result.is_ok()); + assert_eq!(bit_length_result.unwrap(), Felt252::from(i + 1)); } } } From ff1eb9ba304c5baa40267815bbe81d74cf4713fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20P=2E=20Centeno?= Date: Wed, 19 Apr 2023 18:01:34 -0300 Subject: [PATCH 11/13] Add a wraparound test --- src/hint_processor/builtin_hint_processor/garaga.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/hint_processor/builtin_hint_processor/garaga.rs b/src/hint_processor/builtin_hint_processor/garaga.rs index 1fdda4a713..af79a6513c 100644 --- a/src/hint_processor/builtin_hint_processor/garaga.rs +++ b/src/hint_processor/builtin_hint_processor/garaga.rs @@ -33,7 +33,7 @@ mod tests { use crate::types::exec_scope::ExecutionScopes; use crate::{hint_processor::builtin_hint_processor::hint_code, utils::test_utils::*}; use felt::Felt252; - use num_traits::One; + use num_traits::{Bounded, One, Zero}; use super::*; @@ -65,7 +65,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_in_range() { - for i in 0..252usize { + for i in 0..252_usize { let x: Felt252 = Felt252::one() << i; let bit_length_result = run_hint(x); @@ -73,4 +73,13 @@ mod tests { assert_eq!(bit_length_result.unwrap(), Felt252::from(i + 1)); } } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn test_wraparound() { + let x = Felt252::max_value() + Felt252::one(); + let bit_length_result = run_hint(x); + assert!(bit_length_result.is_ok()); + assert_eq!(bit_length_result.unwrap(), Felt252::zero()); + } } From e8f0984325eeea3d09fe7213453a12ba972fd772 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20P=2E=20Centeno?= Date: Wed, 19 Apr 2023 18:29:50 -0300 Subject: [PATCH 12/13] Fix missing import for wasm-tests --- src/hint_processor/builtin_hint_processor/garaga.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hint_processor/builtin_hint_processor/garaga.rs b/src/hint_processor/builtin_hint_processor/garaga.rs index af79a6513c..38ec2ffda3 100644 --- a/src/hint_processor/builtin_hint_processor/garaga.rs +++ b/src/hint_processor/builtin_hint_processor/garaga.rs @@ -35,6 +35,9 @@ mod tests { use felt::Felt252; use num_traits::{Bounded, One, Zero}; + #[cfg(target_arch = "wasm32")] + use wasm_bindgen_test::*; + use super::*; fn run_hint(x: Felt252) -> Result { From 65bf7f690c5027d1989f3cb3ff0254e86e2161ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20P=2E=20Centeno?= Date: Wed, 19 Apr 2023 19:31:39 -0300 Subject: [PATCH 13/13] Remove unused match clause. --- src/hint_processor/builtin_hint_processor/garaga.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/hint_processor/builtin_hint_processor/garaga.rs b/src/hint_processor/builtin_hint_processor/garaga.rs index 38ec2ffda3..5bb4aada88 100644 --- a/src/hint_processor/builtin_hint_processor/garaga.rs +++ b/src/hint_processor/builtin_hint_processor/garaga.rs @@ -41,20 +41,18 @@ mod tests { use super::*; fn run_hint(x: Felt252) -> Result { - let mut vm = vm!(); let ids_data = non_continuous_ids_data![ ("x", 0), // located at `fp + 0`. ("bit_length", 1) // located at `fp + 1`. ]; + let mut vm = vm!(); vm.run_context.fp = 0; add_segments!(vm, 2); // Alloc space for `ids.x` and `ids.bit_length` vm.insert_value((1, 0).into(), x).unwrap(); - match run_hint!(vm, ids_data, hint_code::GET_FELT_BIT_LENGTH) { - Ok(()) => Ok(vm.get_integer((1, 1).into()).unwrap().into_owned()), - Err(e) => Err(e), - } + run_hint!(vm, ids_data, hint_code::GET_FELT_BIT_LENGTH).unwrap(); + Ok(vm.get_integer((1, 1).into()).unwrap().into_owned()) } #[test]