diff --git a/pkg/hints/hint_codes/secp_hint_codes.go b/pkg/hints/hint_codes/secp_hint_codes.go index 065aecab..77bc3237 100644 --- a/pkg/hints/hint_codes/secp_hint_codes.go +++ b/pkg/hints/hint_codes/secp_hint_codes.go @@ -50,3 +50,8 @@ x = pack(ids.x, PRIME) % SECP_P` const IS_ZERO_PACK_V2 = `from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack x = pack(ids.x, PRIME) % SECP_P` + +const IS_ZERO_ASSIGN_SCOPE_VARS = `from starkware.cairo.common.cairo_secp.secp_utils import SECP_P +from starkware.python.math_utils import div_mod + +value = x_inv = div_mod(1, x, SECP_P)` diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index 08511bea..93d6ff17 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -227,6 +227,8 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, return isZeroNondet(data.Ids, vm) case IS_ZERO_PACK_V1, IS_ZERO_PACK_V2: return isZeroPack(data.Ids, vm, execScopes) + case IS_ZERO_ASSIGN_SCOPE_VARS: + return isZeroAssignScopeVars(execScopes) default: return errors.Errorf("Unknown Hint: %s", data.Code) } diff --git a/pkg/hints/secp_hints.go b/pkg/hints/secp_hints.go index 1767d864..2ed14744 100644 --- a/pkg/hints/secp_hints.go +++ b/pkg/hints/secp_hints.go @@ -6,6 +6,7 @@ import ( . "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_utils" "github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks" . "github.com/lambdaclass/cairo-vm.go/pkg/types" + "github.com/lambdaclass/cairo-vm.go/pkg/utils" . "github.com/lambdaclass/cairo-vm.go/pkg/vm" "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" "github.com/pkg/errors" @@ -106,3 +107,19 @@ func isZeroPack(ids IdsManager, vm *VirtualMachine, scopes *ExecutionScopes) err scopes.AssignOrUpdateVariable("x", *xModP) return nil } + +func isZeroAssignScopeVars(scopes *ExecutionScopes) error { + secpP := SECP_P() + scopes.AssignOrUpdateVariable("SECP_P", secpP) + x, err := FetchScopeVar[big.Int]("x", scopes) + if err != nil { + return err + } + value, err := utils.DivMod(big.NewInt(1), &x, &secpP) + if err != nil { + return err + } + scopes.AssignOrUpdateVariable("value", *value) + scopes.AssignOrUpdateVariable("x_inv", *value) + return nil +} diff --git a/pkg/hints/secp_hints_test.go b/pkg/hints/secp_hints_test.go index ae7355ac..1e8ebc30 100644 --- a/pkg/hints/secp_hints_test.go +++ b/pkg/hints/secp_hints_test.go @@ -344,3 +344,29 @@ func TestIsZeroPack(t *testing.T) { xUnpacked := Uint384{Limbs: []Felt{FeltFromUint(6), FeltFromUint(6), FeltFromUint(6)}} CheckScopeVar[big.Int]("x", xUnpacked.Pack86(), scopes, t) } + +func TestIsZeroAssignScopeVars(t *testing.T) { + vm := NewVirtualMachine() + vm.Segments.AddSegment() + idsManager := SetupIdsForTest(map[string][]*MaybeRelocatable{}, vm) + + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: IS_ZERO_ASSIGN_SCOPE_VARS, + }) + scopes := NewExecutionScopes() + x, _ := new(big.Int).SetString("52621538839140286024584685587354966255185961783273479086367", 10) + scopes.AssignOrUpdateVariable("x", *x) + + err := hintProcessor.ExecuteHint(vm, &hintData, nil, scopes) + if err != nil { + t.Errorf("IS_ZERO_ASSIGN_SCOPE_VARS hint failed with error %s", err) + } + // Check scope vars + CheckScopeVar[big.Int]("SECP_P", SECP_P(), scopes, t) + + value, _ := new(big.Int).SetString("19429627790501903254364315669614485084365347064625983303617500144471999752609", 10) + CheckScopeVar[big.Int]("value", *value, scopes, t) + CheckScopeVar[big.Int]("x_inv", *value, scopes, t) +}