Skip to content

Commit

Permalink
feat(hints): Implement NewHint#39 (lambdaclass#1037)
Browse files Browse the repository at this point in the history
* Add test

* Ignore builtin segments in get_memory_holes

* Improve test

* Add memory holes check for cairo_run_test tests

* Fix broken condition

* Make memory_holes check optional & customizable

* Fix bounds

* Add a test with deliberately created memory holes

* Fix test value

* Remove duplicated tests + add memory hole value to some tests

* Add memory holes value + remove duplicated tests + fix typo

* Fix test values

* Add changelog entry

* Link PR in Changelog

* Mark breaking change in changelog

* fmt

* Fix test value

* Fix codecov-patch diff

* Add hint code

* Add integration test

* Add untracked file

* Add changelog entry

* Rename hint

* Fix test

* Fix test

* Add hint code + hint impl + unit test

* fmt

* Add integration test

* Add changelog entry

* Implement hint + add tests

* Add changelog entry

* Remove indent from hint string

* Add wasm import

* Update CHANGELOG.md

* Update CHANGELOG.md
  • Loading branch information
fmoletta authored and kariy committed Jun 23, 2023
1 parent b8e08dd commit e0c3199
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 1 deletion.
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,27 @@

#### Upcoming Changes

<<<<<<< HEAD
* Implement hint on ec_recover.json whitelist [#1037](https://github.com/lambdaclass/cairo-rs/pull/1037):
=======
* Implement hint for `starkware.cairo.common.cairo_keccak.keccak.finalize_keccak` as described by whitelist `starknet/security/whitelists/cairo_keccak.json` [#1041](https://github.com/lambdaclass/cairo-rs/pull/1041)
>>>>>>> 50c90d944bc090578824bb50bed1b1ada5a5fbc0
`BuiltinHintProcessor` now supports the following hint:

```python
%{
<<<<<<< HEAD
from starkware.cairo.common.cairo_secp.secp_utils import pack
from starkware.python.math_utils import div_mod, safe_div

a = pack(ids.a, PRIME)
b = pack(ids.b, PRIME)
product = a * b
m = pack(ids.m, PRIME)

value = res = product % m
=======
# Add dummy pairs of input and output.
_keccak_state_size_felts = int(ids.KECCAK_STATE_SIZE_FELTS)
_block_size = int(ids.BLOCK_SIZE)
Expand All @@ -16,6 +31,7 @@
inp = [0] * _keccak_state_size_felts
padding = (inp + keccak_func(inp)) * _block_size
segments.write_arg(ids.keccak_ptr_end, padding)
>>>>>>> 50c90d944bc090578824bb50bed1b1ada5a5fbc0
%}
```

Expand Down Expand Up @@ -52,6 +68,8 @@
%}
```

<<<<<<< HEAD
=======
* Implement hints on field_arithmetic lib (Part 2) [#1004](https://github.com/lambdaclass/cairo-rs/pull/1004)

`BuiltinHintProcessor` now supports the following hint:
Expand Down Expand Up @@ -110,6 +128,7 @@
ids.x_inverse_mod_p.high = x_inverse_mod_p_split[1]
```

>>>>>>> fb731257da6fc2842abff103fccab964ae87bb38
* BREAKING CHANGE: Fix `CairoRunner::get_memory_holes` [#1027](https://github.com/lambdaclass/cairo-rs/pull/1027):

* Skip builtin segements when counting memory holes
Expand Down
25 changes: 25 additions & 0 deletions cairo_programs/ec_recover.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,33 @@ func test_sub_a_b_hint{range_check_ptr: felt}() {
return();
}

func test_product_mod_hint{range_check_ptr: felt}() {

tempvar a = BigInt3(60, 0, 0);
tempvar b = BigInt3(2, 0, 0);
tempvar m = BigInt3(100, 0, 0);

%{
from starkware.cairo.common.cairo_secp.secp_utils import pack
from starkware.python.math_utils import div_mod, safe_div
a = pack(ids.a, PRIME)
b = pack(ids.b, PRIME)
product = a * b
m = pack(ids.m, PRIME)
value = res = product % m
%}

let (res) = nondet_bigint3();
assert res = BigInt3(20,0,0);

return();
}

func main{range_check_ptr: felt}() {
test_div_mod_n_packed_hint();
test_sub_a_b_hint();
test_product_mod_hint();
return();
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::{
ec_recover::{ec_recover_divmod_n_packed, ec_recover_sub_a_b},
ec_recover::{ec_recover_divmod_n_packed, ec_recover_product_mod, ec_recover_sub_a_b},
field_arithmetic::uint384_div,
vrf::{fq::uint512_unsigned_div_rem, inv_mod_p_uint512::inv_mod_p_uint512},
};
Expand Down Expand Up @@ -603,6 +603,9 @@ impl HintProcessor for BuiltinHintProcessor {
hint_code::EC_RECOVER_SUB_A_B => {
ec_recover_sub_a_b(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking)
}
hint_code::EC_RECOVER_PRODUCT_MOD => {
ec_recover_product_mod(vm, exec_scopes, &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())),
Expand Down
73 changes: 73 additions & 0 deletions src/hint_processor/builtin_hint_processor/ec_recover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,37 @@ pub fn ec_recover_sub_a_b(
Ok(())
}

/* Implements Hint:
%{
from starkware.cairo.common.cairo_secp.secp_utils import pack
from starkware.python.math_utils import div_mod, safe_div
a = pack(ids.a, PRIME)
b = pack(ids.b, PRIME)
product = a * b
m = pack(ids.m, PRIME)
value = res = product % m
%}
*/
pub fn ec_recover_product_mod(
vm: &mut VirtualMachine,
exec_scopes: &mut ExecutionScopes,
ids_data: &HashMap<String, HintReference>,
ap_tracking: &ApTracking,
) -> Result<(), HintError> {
let a = bigint3_pack(BigInt3::from_var_name("a", vm, ids_data, ap_tracking)?);
let b = bigint3_pack(BigInt3::from_var_name("b", vm, ids_data, ap_tracking)?);
let m = bigint3_pack(BigInt3::from_var_name("m", vm, ids_data, ap_tracking)?);

let product = a * b;
exec_scopes.insert_value("product", product.clone());
let value = product.mod_floor(&m);
exec_scopes.insert_value("value", value.clone());
exec_scopes.insert_value("res", value);
Ok(())
}

#[cfg(test)]
mod tests {
use num_bigint::BigInt;
Expand Down Expand Up @@ -157,4 +188,46 @@ mod tests {
[("value", BigInt::from(75)), ("res", BigInt::from(75))]
);
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn run_ec_recover_product_mod_ok() {
let mut vm = vm!();
let mut exec_scopes = ExecutionScopes::new();

vm.run_context.fp = 8;
let ids_data = non_continuous_ids_data![("a", -8), ("b", -5), ("m", -2)];

vm.segments = segments![
//a
((1, 0), 60),
((1, 1), 0),
((1, 2), 0),
//b
((1, 3), 2),
((1, 4), 0),
((1, 5), 0),
//m
((1, 6), 100),
((1, 7), 0),
((1, 8), 0)
];

assert!(run_hint!(
vm,
ids_data,
hint_code::EC_RECOVER_PRODUCT_MOD,
&mut exec_scopes
)
.is_ok());

check_scope!(
&exec_scopes,
[
("value", BigInt::from(20)),
("res", BigInt::from(20)),
("product", BigInt::from(120))
]
);
}
}
8 changes: 8 additions & 0 deletions src/hint_processor/builtin_hint_processor/hint_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1035,6 +1035,14 @@ from starkware.python.math_utils import div_mod, safe_div
a = pack(ids.a, PRIME)
b = pack(ids.b, PRIME)
value = res = a - b"#;
pub const EC_RECOVER_PRODUCT_MOD: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import pack
from starkware.python.math_utils import div_mod, safe_div
a = pack(ids.a, PRIME)
b = pack(ids.b, PRIME)
product = a * b
m = pack(ids.m, PRIME)
value = res = product % m"#;
#[cfg(feature = "skip_next_instruction_hint")]
pub const SKIP_NEXT_INSTRUCTION: &str = "skip_next_instruction()";

0 comments on commit e0c3199

Please sign in to comment.