Open
Description
Describe the bug
This simple cairo code
from starkware.cairo.common.cairo_builtins import UInt384, ModBuiltin
from starkware.cairo.common.modulo import run_mod_p_circuit
from starkware.cairo.lang.compiler.lib.registers import get_fp_and_pc
func add{range_check96_ptr: felt*, add_mod_ptr: ModBuiltin*, mul_mod_ptr: ModBuiltin*}(
x: UInt384*, y: UInt384*, p: UInt384*
) -> UInt384* {
let (_, pc) = get_fp_and_pc();
pc_label:
let add_mod_offsets_ptr = pc + (add_offsets - pc_label);
let mul_mod_offsets_ptr = pc + (mul_offsets - pc_label);
assert [range_check96_ptr + 0] = x.d0;
assert [range_check96_ptr + 1] = x.d1;
assert [range_check96_ptr + 2] = x.d2;
assert [range_check96_ptr + 3] = x.d3;
assert [range_check96_ptr + 4] = y.d0;
assert [range_check96_ptr + 5] = y.d1;
assert [range_check96_ptr + 6] = y.d2;
assert [range_check96_ptr + 7] = y.d3;
run_mod_p_circuit(
p=[p],
values_ptr=cast(range_check96_ptr, UInt384*),
add_mod_offsets_ptr=add_mod_offsets_ptr,
add_mod_n=1,
mul_mod_offsets_ptr=mul_mod_offsets_ptr,
mul_mod_n=0,
);
let range_check96_ptr = range_check96_ptr + 12;
return cast(range_check96_ptr - 4, UInt384*);
add_offsets:
dw 0;
dw 4;
dw 8;
mul_offsets:
}
will raise
Exception: /Users/clementwalter/Documents/sayajin-labs/keth/.venv/lib/python3.10/site-packages/starkware/cairo/common/modulo.cairo:98:5: Error at pc=0:41:
E Got an exception while executing a hint: Unknown memory cell at address 4:4
E %{
Address 4:4
is actually mul_mod_ptr:values_ptr
which is empty since no mul is to be performed.
Updating the above snippet to do only mul
and no add
will raise the same error but in segment 3:4
:
func mul{range_check96_ptr: felt*, add_mod_ptr: ModBuiltin*, mul_mod_ptr: ModBuiltin*}(
x: UInt384*, y: UInt384*, p: UInt384*
) -> UInt384* {
let (_, pc) = get_fp_and_pc();
pc_label:
let add_mod_offsets_ptr = pc + (add_offsets - pc_label);
let mul_mod_offsets_ptr = pc + (mul_offsets - pc_label);
assert [range_check96_ptr + 0] = x.d0;
assert [range_check96_ptr + 1] = x.d1;
assert [range_check96_ptr + 2] = x.d2;
assert [range_check96_ptr + 3] = x.d3;
assert [range_check96_ptr + 4] = y.d0;
assert [range_check96_ptr + 5] = y.d1;
assert [range_check96_ptr + 6] = y.d2;
assert [range_check96_ptr + 7] = y.d3;
run_mod_p_circuit(
p=[p],
values_ptr=cast(range_check96_ptr, UInt384*),
add_mod_offsets_ptr=add_mod_offsets_ptr,
add_mod_n=0,
mul_mod_offsets_ptr=mul_mod_offsets_ptr,
mul_mod_n=1,
);
let range_check96_ptr = range_check96_ptr + 12;
return cast(range_check96_ptr - 4, UInt384*);
add_offsets:
mul_offsets:
dw 0;
dw 4;
dw 8;
}
Putting both add
and mul
works
func inv{range_check96_ptr: felt*, add_mod_ptr: ModBuiltin*, mul_mod_ptr: ModBuiltin*}(
x: UInt384*, p: UInt384*
) -> UInt384* {
let (_, pc) = get_fp_and_pc();
pc_label:
let add_mod_offsets_ptr = pc + (add_offsets - pc_label);
let mul_mod_offsets_ptr = pc + (mul_offsets - pc_label);
assert [range_check96_ptr + 0] = 1;
assert [range_check96_ptr + 1] = 0;
assert [range_check96_ptr + 2] = 0;
assert [range_check96_ptr + 3] = 0;
assert [range_check96_ptr + 4] = 0;
assert [range_check96_ptr + 5] = 0;
assert [range_check96_ptr + 6] = 0;
assert [range_check96_ptr + 7] = 0;
assert [range_check96_ptr + 8] = x.d0;
assert [range_check96_ptr + 9] = x.d1;
assert [range_check96_ptr + 10] = x.d2;
assert [range_check96_ptr + 11] = x.d3;
run_mod_p_circuit(
p=[p],
values_ptr=cast(range_check96_ptr, UInt384*),
add_mod_offsets_ptr=add_mod_offsets_ptr,
add_mod_n=1,
mul_mod_offsets_ptr=mul_mod_offsets_ptr,
mul_mod_n=1,
);
let range_check96_ptr = range_check96_ptr + 20;
return cast(range_check96_ptr - 4, UInt384*);
add_offsets:
dw 4;
dw 0;
dw 12;
mul_offsets:
dw 16;
dw 8;
dw 12;
}
It's worth noticing that the test program at
cairo-vm/cairo_programs/mod_builtin_feature/common/modulo.cairo
Lines 93 to 124 in df12864
slightly differs from the run_mod_p_circuit
from the core lib because the assert
are not being a if
, see https://github.com/starkware-libs/cairo-lang/blob/8276ac35830148a397e1143389f23253c8b80e93/src/starkware/cairo/common/modulo.cairo#L12-L47