From ad6260189472473a9596d5139a58ae1c18e2eb8f Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 27 Sep 2023 14:29:15 -0300 Subject: [PATCH 01/33] Add ExecutionResources struct --- pkg/runners/execution_resources.go | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 pkg/runners/execution_resources.go diff --git a/pkg/runners/execution_resources.go b/pkg/runners/execution_resources.go new file mode 100644 index 00000000..e3872021 --- /dev/null +++ b/pkg/runners/execution_resources.go @@ -0,0 +1,7 @@ +package runners + +type ExecutionResources struct { + NSteps uint + NMemoryHoles uint + BuiltinsInstanceCounter map[string]uint +} From 467621f798285ccd7825322daa1fe8fb4ac22599 Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 27 Sep 2023 14:45:58 -0300 Subject: [PATCH 02/33] Fix: Remove vm argument from CairoRunner methods --- pkg/runners/cairo_runner.go | 109 ++++++++++++++++++------------- pkg/runners/cairo_runner_test.go | 55 +++++++--------- pkg/vm/cairo_run/cairo_run.go | 6 +- 3 files changed, 89 insertions(+), 81 deletions(-) diff --git a/pkg/runners/cairo_runner.go b/pkg/runners/cairo_runner.go index e9baf5dc..27a2a67a 100644 --- a/pkg/runners/cairo_runner.go +++ b/pkg/runners/cairo_runner.go @@ -237,7 +237,7 @@ func (r *CairoRunner) RunUntilPC(end memory.Relocatable, hintProcessor vm.HintPr return nil } -func (runner *CairoRunner) EndRun(disableTracePadding bool, disableFinalizeAll bool, vm *vm.VirtualMachine, hintProcessor vm.HintProcessor) error { +func (runner *CairoRunner) EndRun(disableTracePadding bool, disableFinalizeAll bool, hintProcessor vm.HintProcessor) error { if runner.RunEnded { return ErrRunnerCalledTwice } @@ -245,7 +245,7 @@ func (runner *CairoRunner) EndRun(disableTracePadding bool, disableFinalizeAll b // TODO: This seems to have to do with temporary segments // vm.Segments.Memory.RelocateMemory() - err := vm.EndRun() + err := runner.Vm.EndRun() if err != nil { return err } @@ -254,15 +254,15 @@ func (runner *CairoRunner) EndRun(disableTracePadding bool, disableFinalizeAll b return nil } - vm.Segments.ComputeEffectiveSizes() + runner.Vm.Segments.ComputeEffectiveSizes() if runner.ProofMode && !disableTracePadding { - err := runner.RunUntilNextPowerOfTwo(vm, hintProcessor) + err := runner.RunUntilNextPowerOfTwo(hintProcessor) if err != nil { return err } for true { - err := runner.CheckUsedCells(vm) + err := runner.CheckUsedCells() if errors.Unwrap(err) == memory.ErrInsufficientAllocatedCells { } else if err != nil { return err @@ -270,12 +270,12 @@ func (runner *CairoRunner) EndRun(disableTracePadding bool, disableFinalizeAll b break } - err = runner.RunForSteps(1, vm, hintProcessor) + err = runner.RunForSteps(1, hintProcessor) if err != nil { return err } - err = runner.RunUntilNextPowerOfTwo(vm, hintProcessor) + err = runner.RunUntilNextPowerOfTwo(hintProcessor) if err != nil { return err } @@ -286,7 +286,7 @@ func (runner *CairoRunner) EndRun(disableTracePadding bool, disableFinalizeAll b return nil } -func (r *CairoRunner) FinalizeSegments(virtualMachine vm.VirtualMachine) error { +func (r *CairoRunner) FinalizeSegments() error { if r.SegmentsFinalized { return nil } @@ -304,7 +304,7 @@ func (r *CairoRunner) FinalizeSegments(virtualMachine vm.VirtualMachine) error { publicMemory = append(publicMemory, i) } - virtualMachine.Segments.Finalize(size, uint(r.ProgramBase.SegmentIndex), &publicMemory) + r.Vm.Segments.Finalize(size, uint(r.ProgramBase.SegmentIndex), &publicMemory) publicMemory = make([]uint, 0) execBase := r.executionBase @@ -316,9 +316,9 @@ func (r *CairoRunner) FinalizeSegments(virtualMachine vm.VirtualMachine) error { publicMemory = append(publicMemory, elem+execBase.Offset) } - virtualMachine.Segments.Finalize(nil, uint(execBase.SegmentIndex), &publicMemory) - for _, builtin := range virtualMachine.BuiltinRunners { - _, size, err := builtin.GetUsedCellsAndAllocatedSizes(&virtualMachine.Segments, virtualMachine.CurrentStep) + r.Vm.Segments.Finalize(nil, uint(execBase.SegmentIndex), &publicMemory) + for _, builtin := range r.Vm.BuiltinRunners { + _, size, err := builtin.GetUsedCellsAndAllocatedSizes(&r.Vm.Segments, r.Vm.CurrentStep) if err != nil { return err } @@ -329,9 +329,9 @@ func (r *CairoRunner) FinalizeSegments(virtualMachine vm.VirtualMachine) error { for i = 0; i < size; i++ { publicMemory = append(publicMemory, i) } - virtualMachine.Segments.Finalize(&size, uint(builtin.Base().SegmentIndex), &publicMemory) + r.Vm.Segments.Finalize(&size, uint(builtin.Base().SegmentIndex), &publicMemory) } else { - virtualMachine.Segments.Finalize(&size, uint(builtin.Base().SegmentIndex), nil) + r.Vm.Segments.Finalize(&size, uint(builtin.Base().SegmentIndex), nil) } } @@ -339,15 +339,15 @@ func (r *CairoRunner) FinalizeSegments(virtualMachine vm.VirtualMachine) error { return nil } -func (r *CairoRunner) ReadReturnValues(virtualMachine *vm.VirtualMachine) error { +func (r *CairoRunner) ReadReturnValues() error { if !r.RunEnded { return errors.New("Tried to read return values before run ended") } - pointer := virtualMachine.RunContext.Ap + pointer := r.Vm.RunContext.Ap - for i := len(virtualMachine.BuiltinRunners) - 1; i >= 0; i-- { - newPointer, err := virtualMachine.BuiltinRunners[i].FinalStack(&virtualMachine.Segments, pointer) + for i := len(r.Vm.BuiltinRunners) - 1; i >= 0; i-- { + newPointer, err := r.Vm.BuiltinRunners[i].FinalStack(&r.Vm.Segments, pointer) if err != nil { return err } @@ -363,7 +363,7 @@ func (r *CairoRunner) ReadReturnValues(virtualMachine *vm.VirtualMachine) error execBase := r.executionBase begin := pointer.Offset - execBase.Offset - ap := virtualMachine.RunContext.Ap + ap := r.Vm.RunContext.Ap end := ap.Offset - execBase.Offset var publicMemoryExtension []uint @@ -379,26 +379,26 @@ func (r *CairoRunner) ReadReturnValues(virtualMachine *vm.VirtualMachine) error } -func (runner *CairoRunner) CheckUsedCells(virtualMachine *vm.VirtualMachine) error { - for _, builtin := range virtualMachine.BuiltinRunners { +func (runner *CairoRunner) CheckUsedCells() error { + for _, builtin := range runner.Vm.BuiltinRunners { // I guess we call this just in case it errors out, even though later on we also call it? - _, _, err := builtin.GetUsedCellsAndAllocatedSizes(&virtualMachine.Segments, virtualMachine.CurrentStep) + _, _, err := builtin.GetUsedCellsAndAllocatedSizes(&runner.Vm.Segments, runner.Vm.CurrentStep) if err != nil { return err } } - err := runner.CheckRangeCheckUsage(virtualMachine) + err := runner.CheckRangeCheckUsage() if err != nil { return err } - err = runner.CheckMemoryUsage(virtualMachine) + err = runner.CheckMemoryUsage() if err != nil { return err } - err = runner.CheckDilutedCheckUsage(virtualMachine) + err = runner.CheckDilutedCheckUsage() if err != nil { return err } @@ -406,13 +406,13 @@ func (runner *CairoRunner) CheckUsedCells(virtualMachine *vm.VirtualMachine) err return nil } -func (runner *CairoRunner) CheckMemoryUsage(virtualMachine *vm.VirtualMachine) error { +func (runner *CairoRunner) CheckMemoryUsage() error { instance := runner.Layout var builtinsMemoryUnits uint = 0 - for _, builtin := range virtualMachine.BuiltinRunners { - result, err := builtin.GetAllocatedMemoryUnits(&virtualMachine.Segments, virtualMachine.CurrentStep) + for _, builtin := range runner.Vm.BuiltinRunners { + result, err := builtin.GetAllocatedMemoryUnits(&runner.Vm.Segments, runner.Vm.CurrentStep) if err != nil { return err } @@ -420,7 +420,7 @@ func (runner *CairoRunner) CheckMemoryUsage(virtualMachine *vm.VirtualMachine) e builtinsMemoryUnits += result } - totalMemoryUnits := instance.MemoryUnitsPerStep * virtualMachine.CurrentStep + totalMemoryUnits := instance.MemoryUnitsPerStep * runner.Vm.CurrentStep publicMemoryUnits := totalMemoryUnits / instance.PublicMemoryFraction remainder := totalMemoryUnits % instance.PublicMemoryFraction @@ -428,10 +428,10 @@ func (runner *CairoRunner) CheckMemoryUsage(virtualMachine *vm.VirtualMachine) e return errors.Errorf("Total Memory units was not divisible by the Public Memory Fraction. TotalMemoryUnits: %d PublicMemoryFraction: %d", totalMemoryUnits, instance.PublicMemoryFraction) } - instructionMemoryUnits := 4 * virtualMachine.CurrentStep + instructionMemoryUnits := 4 * runner.Vm.CurrentStep unusedMemoryUnits := totalMemoryUnits - (publicMemoryUnits + instructionMemoryUnits + builtinsMemoryUnits) - memoryAddressHoles, err := runner.GetMemoryHoles(virtualMachine) + memoryAddressHoles, err := runner.GetMemoryHoles() if err != nil { return err } @@ -443,11 +443,11 @@ func (runner *CairoRunner) CheckMemoryUsage(virtualMachine *vm.VirtualMachine) e return nil } -func (runner *CairoRunner) GetMemoryHoles(virtualMachine *vm.VirtualMachine) (uint, error) { - return virtualMachine.Segments.GetMemoryHoles(uint(len(virtualMachine.BuiltinRunners))) +func (runner *CairoRunner) GetMemoryHoles() (uint, error) { + return runner.Vm.Segments.GetMemoryHoles(uint(len(runner.Vm.BuiltinRunners))) } -func (runner *CairoRunner) CheckDilutedCheckUsage(virtualMachine *vm.VirtualMachine) error { +func (runner *CairoRunner) CheckDilutedCheckUsage() error { dilutedPoolInstance := runner.Layout.DilutedPoolInstance if dilutedPoolInstance == nil { return nil @@ -455,14 +455,14 @@ func (runner *CairoRunner) CheckDilutedCheckUsage(virtualMachine *vm.VirtualMach var usedUnitsByBuiltins uint = 0 - for _, builtin := range virtualMachine.BuiltinRunners { + for _, builtin := range runner.Vm.BuiltinRunners { usedUnits := builtin.GetUsedDilutedCheckUnits(dilutedPoolInstance.Spacing, dilutedPoolInstance.NBits) ratio := builtin.Ratio() if ratio == 0 { ratio = 1 } - multiplier, err := utils.SafeDiv(virtualMachine.CurrentStep, ratio) + multiplier, err := utils.SafeDiv(runner.Vm.CurrentStep, ratio) if err != nil { return err @@ -471,7 +471,7 @@ func (runner *CairoRunner) CheckDilutedCheckUsage(virtualMachine *vm.VirtualMach usedUnitsByBuiltins += usedUnits * multiplier } - var dilutedUnits uint = dilutedPoolInstance.UnitsPerStep * virtualMachine.CurrentStep + var dilutedUnits uint = dilutedPoolInstance.UnitsPerStep * runner.Vm.CurrentStep var unusedDilutedUnits uint = dilutedUnits - usedUnitsByBuiltins var dilutedUsageUpperBound uint = 1 << dilutedPoolInstance.NBits @@ -483,7 +483,7 @@ func (runner *CairoRunner) CheckDilutedCheckUsage(virtualMachine *vm.VirtualMach return nil } -func (runner *CairoRunner) CheckRangeCheckUsage(virtualMachine *vm.VirtualMachine) error { +func (runner *CairoRunner) CheckRangeCheckUsage() error { var rcMin, rcMax *uint for _, builtin := range runner.Vm.BuiltinRunners { @@ -513,7 +513,7 @@ func (runner *CairoRunner) CheckRangeCheckUsage(virtualMachine *vm.VirtualMachin var rcUnitsUsedByBuiltins uint = 0 for _, builtin := range runner.Vm.BuiltinRunners { - usedUnits, err := builtin.GetUsedPermRangeCheckLimits(&virtualMachine.Segments, virtualMachine.CurrentStep) + usedUnits, err := builtin.GetUsedPermRangeCheckLimits(&runner.Vm.Segments, runner.Vm.CurrentStep) if err != nil { return err } @@ -521,7 +521,7 @@ func (runner *CairoRunner) CheckRangeCheckUsage(virtualMachine *vm.VirtualMachin rcUnitsUsedByBuiltins += usedUnits } - unusedRcUnits := (runner.Layout.RcUnits-3)*virtualMachine.CurrentStep - uint(rcUnitsUsedByBuiltins) + unusedRcUnits := (runner.Layout.RcUnits-3)*runner.Vm.CurrentStep - uint(rcUnitsUsedByBuiltins) if unusedRcUnits < (*rcMax - *rcMin) { return memory.InsufficientAllocatedCellsError(unusedRcUnits, *rcMax-*rcMin) @@ -531,7 +531,7 @@ func (runner *CairoRunner) CheckRangeCheckUsage(virtualMachine *vm.VirtualMachin } // TODO: Add hint processor when it's done -func (runner *CairoRunner) RunForSteps(steps uint, virtualMachine *vm.VirtualMachine, hintProcessor vm.HintProcessor) error { +func (runner *CairoRunner) RunForSteps(steps uint, hintProcessor vm.HintProcessor) error { hintDataMap, err := runner.BuildHintDataMap(hintProcessor) if err != nil { return err @@ -539,11 +539,11 @@ func (runner *CairoRunner) RunForSteps(steps uint, virtualMachine *vm.VirtualMac constants := runner.Program.ExtractConstants() var remainingSteps int for remainingSteps = int(steps); remainingSteps > 0; remainingSteps-- { - if runner.finalPc != nil && *runner.finalPc == virtualMachine.RunContext.Pc { + if runner.finalPc != nil && *runner.finalPc == runner.Vm.RunContext.Pc { return &vm.VirtualMachineError{Msg: fmt.Sprintf("EndOfProgram: %d", remainingSteps)} } - err := virtualMachine.Step(hintProcessor, &hintDataMap, &constants, &runner.execScopes) + err := runner.Vm.Step(hintProcessor, &hintDataMap, &constants, &runner.execScopes) if err != nil { return err } @@ -553,11 +553,26 @@ func (runner *CairoRunner) RunForSteps(steps uint, virtualMachine *vm.VirtualMac } // TODO: Add hint processor when it's done -func (runner *CairoRunner) RunUntilSteps(steps uint, virtualMachine *vm.VirtualMachine, hintProcessor vm.HintProcessor) error { - return runner.RunForSteps(steps-virtualMachine.CurrentStep, virtualMachine, hintProcessor) +func (runner *CairoRunner) RunUntilSteps(steps uint, hintProcessor vm.HintProcessor) error { + return runner.RunForSteps(steps-runner.Vm.CurrentStep, hintProcessor) } // TODO: Add hint processor when it's done -func (runner *CairoRunner) RunUntilNextPowerOfTwo(virtualMachine *vm.VirtualMachine, hintProcessor vm.HintProcessor) error { - return runner.RunUntilSteps(utils.NextPowOf2(virtualMachine.CurrentStep), virtualMachine, hintProcessor) +func (runner *CairoRunner) RunUntilNextPowerOfTwo(hintProcessor vm.HintProcessor) error { + return runner.RunUntilSteps(utils.NextPowOf2(runner.Vm.CurrentStep), hintProcessor) +} + +func (runner *CairoRunner) GetExecutionResources() (ExecutionResources, error) { + nSteps := uint(len(runner.Vm.Trace)) + if nSteps == 0 { + nSteps = runner.Vm.CurrentStep + } + nMemoryHoles, err := runner.GetMemoryHoles() + if err != nil { + return ExecutionResources{}, err + } + return ExecutionResources{ + NSteps: nSteps, + NMemoryHoles: nMemoryHoles, + }, nil } diff --git a/pkg/runners/cairo_runner_test.go b/pkg/runners/cairo_runner_test.go index e19367d1..88e7e8ef 100644 --- a/pkg/runners/cairo_runner_test.go +++ b/pkg/runners/cairo_runner_test.go @@ -567,11 +567,10 @@ func TestCheckRangeCheckUsagePermRangeLimitsNone(t *testing.T) { if err != nil { t.Error("Could not initialize Cairo Runner") } - virtualMachine := vm.NewVirtualMachine() - virtualMachine.Trace = make([]vm.TraceEntry, 0) + runner.Vm.Trace = make([]vm.TraceEntry, 0) - err = runner.CheckRangeCheckUsage(virtualMachine) + err = runner.CheckRangeCheckUsage() if err != nil { t.Errorf("Check Range Usage Failed With Error %s", err) } @@ -584,18 +583,17 @@ func TestCheckRangeCheckUsageWithoutBuiltins(t *testing.T) { if err != nil { t.Error("Could not initialize Cairo Runner") } - virtualMachine := vm.NewVirtualMachine() - virtualMachine.Trace = make([]vm.TraceEntry, 0) - virtualMachine.CurrentStep = 1000 - virtualMachine.Segments.Memory.Insert( + runner.Vm.Trace = make([]vm.TraceEntry, 0) + runner.Vm.CurrentStep = 1000 + runner.Vm.Segments.Memory.Insert( memory.NewRelocatable(0, 0), memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromHex("0x80FF80000530")), ) - virtualMachine.Trace = make([]vm.TraceEntry, 1) - virtualMachine.Trace[0] = vm.TraceEntry{Pc: memory.NewRelocatable(0, 0), Ap: memory.NewRelocatable(0, 0), Fp: memory.NewRelocatable(0, 0)} - err = runner.CheckRangeCheckUsage(virtualMachine) + runner.Vm.Trace = make([]vm.TraceEntry, 1) + runner.Vm.Trace[0] = vm.TraceEntry{Pc: memory.NewRelocatable(0, 0), Ap: memory.NewRelocatable(0, 0), Fp: memory.NewRelocatable(0, 0)} + err = runner.CheckRangeCheckUsage() if err != nil { t.Errorf("Check Range Usage Failed With Error %s", err) } @@ -620,7 +618,7 @@ func TestCheckRangeUsageInsufficientAllocatedCells(t *testing.T) { runner.Vm.Trace = make([]vm.TraceEntry, 1) runner.Vm.Trace[0] = vm.TraceEntry{Pc: memory.NewRelocatable(0, 0), Ap: memory.NewRelocatable(0, 0), Fp: memory.NewRelocatable(0, 0)} runner.Vm.Segments.ComputeEffectiveSizes() - err = runner.CheckRangeCheckUsage(&runner.Vm) + err = runner.CheckRangeCheckUsage() if err == nil { t.Error("Check Range Usage Should Have Failed With Insufficient Allocated Cells Error") } @@ -633,11 +631,10 @@ func TestCheckDilutedCheckUsageWithoutPoolInstance(t *testing.T) { if err != nil { t.Error("Could not initialize Cairo Runner") } - virtualMachine := vm.NewVirtualMachine() runner.Layout.DilutedPoolInstance = nil - err = runner.CheckDilutedCheckUsage(virtualMachine) + err = runner.CheckDilutedCheckUsage() if err != nil { t.Errorf("Check Diluted Check Usage Failed With Error %s", err) } @@ -650,12 +647,11 @@ func TestCheckDilutedCheckUsageWithoutBuiltinRunners(t *testing.T) { if err != nil { t.Error("Could not initialize Cairo Runner") } - virtualMachine := vm.NewVirtualMachine() - virtualMachine.CurrentStep = 10000 - virtualMachine.BuiltinRunners = make([]builtins.BuiltinRunner, 0) + runner.Vm.CurrentStep = 10000 + runner.Vm.BuiltinRunners = make([]builtins.BuiltinRunner, 0) - err = runner.CheckDilutedCheckUsage(virtualMachine) + err = runner.CheckDilutedCheckUsage() if err != nil { t.Errorf("Check Diluted Check Usage Failed With Error %s", err) } @@ -668,12 +664,11 @@ func TestCheckDilutedCheckUsageInsufficientAllocatedCells(t *testing.T) { if err != nil { t.Error("Could not initialize Cairo Runner") } - virtualMachine := vm.NewVirtualMachine() - virtualMachine.CurrentStep = 100 - virtualMachine.BuiltinRunners = make([]builtins.BuiltinRunner, 0) + runner.Vm.CurrentStep = 100 + runner.Vm.BuiltinRunners = make([]builtins.BuiltinRunner, 0) - err = runner.CheckDilutedCheckUsage(virtualMachine) + err = runner.CheckDilutedCheckUsage() if err == nil { t.Errorf("Check Diluted Check Usage Should Have failed With Insufficient Allocated Cells Error") } @@ -686,13 +681,12 @@ func TestCheckDilutedCheckUsage(t *testing.T) { if err != nil { t.Error("Could not initialize Cairo Runner") } - virtualMachine := vm.NewVirtualMachine() - virtualMachine.CurrentStep = 8192 - virtualMachine.BuiltinRunners = make([]builtins.BuiltinRunner, 0) - virtualMachine.BuiltinRunners = append(virtualMachine.BuiltinRunners, builtins.NewBitwiseBuiltinRunner(256)) + runner.Vm.CurrentStep = 8192 + runner.Vm.BuiltinRunners = make([]builtins.BuiltinRunner, 0) + runner.Vm.BuiltinRunners = append(runner.Vm.BuiltinRunners, builtins.NewBitwiseBuiltinRunner(256)) - err = runner.CheckDilutedCheckUsage(virtualMachine) + err = runner.CheckDilutedCheckUsage() if err != nil { t.Errorf("Check Diluted Check Usage Failed With Error %s", err) } @@ -706,13 +700,12 @@ func TestCheckUsedCellsDilutedCheckUsageError(t *testing.T) { if err != nil { t.Error("Could not initialize Cairo Runner") } - virtualMachine := vm.NewVirtualMachine() - virtualMachine.Segments.SegmentUsedSizes = make(map[uint]uint) - virtualMachine.Segments.SegmentUsedSizes[0] = 4 - virtualMachine.Trace = []vm.TraceEntry{} + runner.Vm.Segments.SegmentUsedSizes = make(map[uint]uint) + runner.Vm.Segments.SegmentUsedSizes[0] = 4 + runner.Vm.Trace = []vm.TraceEntry{} - err = runner.CheckUsedCells(virtualMachine) + err = runner.CheckUsedCells() if err == nil { t.Errorf("Check Used Cells Should Have failed With Insufficient Allocated Cells Error") } diff --git a/pkg/vm/cairo_run/cairo_run.go b/pkg/vm/cairo_run/cairo_run.go index 678a658d..d54a1f99 100644 --- a/pkg/vm/cairo_run/cairo_run.go +++ b/pkg/vm/cairo_run/cairo_run.go @@ -53,18 +53,18 @@ func CairoRun(programPath string, cairoRunConfig CairoRunConfig) (*runners.Cairo if err != nil { return nil, err } - err = cairoRunner.EndRun(cairoRunConfig.DisableTracePadding, false, &cairoRunner.Vm, &hintProcessor) + err = cairoRunner.EndRun(cairoRunConfig.DisableTracePadding, false, &hintProcessor) if err != nil { return nil, err } - err = cairoRunner.ReadReturnValues(&cairoRunner.Vm) + err = cairoRunner.ReadReturnValues() if err != nil { return nil, err } if cairoRunConfig.ProofMode { - cairoRunner.FinalizeSegments(cairoRunner.Vm) + cairoRunner.FinalizeSegments() } err = cairoRunner.Vm.Relocate() From 8e2597a312d4db8d31365ec889cdaaf750a76994 Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 27 Sep 2023 14:50:13 -0300 Subject: [PATCH 03/33] Finish func + remove todos --- pkg/runners/cairo_runner.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/pkg/runners/cairo_runner.go b/pkg/runners/cairo_runner.go index 27a2a67a..4f069dea 100644 --- a/pkg/runners/cairo_runner.go +++ b/pkg/runners/cairo_runner.go @@ -530,7 +530,6 @@ func (runner *CairoRunner) CheckRangeCheckUsage() error { return nil } -// TODO: Add hint processor when it's done func (runner *CairoRunner) RunForSteps(steps uint, hintProcessor vm.HintProcessor) error { hintDataMap, err := runner.BuildHintDataMap(hintProcessor) if err != nil { @@ -552,12 +551,10 @@ func (runner *CairoRunner) RunForSteps(steps uint, hintProcessor vm.HintProcesso return nil } -// TODO: Add hint processor when it's done func (runner *CairoRunner) RunUntilSteps(steps uint, hintProcessor vm.HintProcessor) error { return runner.RunForSteps(steps-runner.Vm.CurrentStep, hintProcessor) } -// TODO: Add hint processor when it's done func (runner *CairoRunner) RunUntilNextPowerOfTwo(hintProcessor vm.HintProcessor) error { return runner.RunUntilSteps(utils.NextPowOf2(runner.Vm.CurrentStep), hintProcessor) } @@ -571,8 +568,16 @@ func (runner *CairoRunner) GetExecutionResources() (ExecutionResources, error) { if err != nil { return ExecutionResources{}, err } + builtinInstaceCounter := make(map[string]uint) + for i := 0; i < len(runner.Vm.BuiltinRunners); i++ { + builtinInstaceCounter[runner.Vm.BuiltinRunners[i].Name()], err = runner.Vm.BuiltinRunners[i].GetUsedInstances(&runner.Vm.Segments) + if err != nil { + return ExecutionResources{}, err + } + } return ExecutionResources{ - NSteps: nSteps, - NMemoryHoles: nMemoryHoles, + NSteps: nSteps, + NMemoryHoles: nMemoryHoles, + BuiltinsInstanceCounter: builtinInstaceCounter, }, nil } From 453846560afe2f2ed16c2c704106d2ca8b6a2f4f Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 27 Sep 2023 15:16:15 -0300 Subject: [PATCH 04/33] Add unit test --- pkg/runners/cairo_runner_test.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pkg/runners/cairo_runner_test.go b/pkg/runners/cairo_runner_test.go index 88e7e8ef..5f9fd2e2 100644 --- a/pkg/runners/cairo_runner_test.go +++ b/pkg/runners/cairo_runner_test.go @@ -710,3 +710,19 @@ func TestCheckUsedCellsDilutedCheckUsageError(t *testing.T) { t.Errorf("Check Used Cells Should Have failed With Insufficient Allocated Cells Error") } } + +func TestRunFibonacciGetExecutionResources(t *testing.T) { + cairoRunConfig := cairo_run.CairoRunConfig{Layout: "all_cairo", ProofMode: false} + runner, err := cairo_run.CairoRun("../../cairo_programs/fibonacci.json", cairoRunConfig) + if err != nil { + t.Errorf("Program execution failed with error: %s", err) + } + expectedExecutionResources := runners.ExecutionResources{ + NSteps: 80, + BuiltinsInstanceCounter: make(map[string]uint), + } + executionResources, _ := runner.GetExecutionResources() + if !reflect.DeepEqual(executionResources, expectedExecutionResources) { + t.Errorf("Wong ExecutionResources.\n Expected : %+v, got: %+v", expectedExecutionResources, executionResources) + } +} From 18b6255cf0340cfae3eaee2b92871f2c8aa86802 Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 27 Sep 2023 15:56:49 -0300 Subject: [PATCH 05/33] Implement GenArg --- pkg/vm/memory/segments.go | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/pkg/vm/memory/segments.go b/pkg/vm/memory/segments.go index 732ee0b7..e717034e 100644 --- a/pkg/vm/memory/segments.go +++ b/pkg/vm/memory/segments.go @@ -1,6 +1,8 @@ package memory import ( + "errors" + "github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks" ) @@ -186,3 +188,29 @@ func (m *MemorySegmentManager) GetFeltRange(start Relocatable, size uint) ([]lam } return feltRange, nil } + +/* +Converts a generic argument into a MaybeRelocatable +If the argument is a slice, it loads it into memory in a new segment and returns its base +Accepts MaybeRelocatable, []MaybeRelocatable, [][]MaybeRelocatable, etc +*/ +func (m *MemorySegmentManager) GenArg(arg any) (MaybeRelocatable, error) { + // Attempt to cast to MaybeRelocatable + a, ok := arg.(MaybeRelocatable) + if ok { + return a, nil + } + // Attempt to cast to []MaybeRelocatable + data, ok := arg.([]MaybeRelocatable) + if ok { + base := m.AddSegment() + _, err := m.LoadData(base, &data) + return *NewMaybeRelocatableRelocatable(base), err + } + // Attempt to cast to []any + arg, ok = arg.([]any) + if ok { + return m.GenArg(arg) + } + return *NewMaybeRelocatableFelt(lambdaworks.FeltZero()), errors.New("GenArg: found argument of invalid type.") +} From a82ec66ce230394495e06d01bdb4e72446a8d200 Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 27 Sep 2023 16:45:06 -0300 Subject: [PATCH 06/33] Remove recursive processing --- pkg/vm/memory/segments.go | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/pkg/vm/memory/segments.go b/pkg/vm/memory/segments.go index e717034e..32c5acda 100644 --- a/pkg/vm/memory/segments.go +++ b/pkg/vm/memory/segments.go @@ -192,7 +192,7 @@ func (m *MemorySegmentManager) GetFeltRange(start Relocatable, size uint) ([]lam /* Converts a generic argument into a MaybeRelocatable If the argument is a slice, it loads it into memory in a new segment and returns its base -Accepts MaybeRelocatable, []MaybeRelocatable, [][]MaybeRelocatable, etc +Accepts MaybeRelocatable, []MaybeRelocatable, [][]MaybeRelocatable */ func (m *MemorySegmentManager) GenArg(arg any) (MaybeRelocatable, error) { // Attempt to cast to MaybeRelocatable @@ -207,10 +207,20 @@ func (m *MemorySegmentManager) GenArg(arg any) (MaybeRelocatable, error) { _, err := m.LoadData(base, &data) return *NewMaybeRelocatableRelocatable(base), err } - // Attempt to cast to []any - arg, ok = arg.([]any) + // Attempt to cast to [][]MaybeRelocatable + datas, ok := arg.([][]MaybeRelocatable) if ok { - return m.GenArg(arg) + args := make([]MaybeRelocatable, 0) + for _, data = range datas { + dataBase, err := m.GenArg(data) + if err != nil { + return *NewMaybeRelocatableFelt(lambdaworks.FeltZero()), err + } + args = append(args, dataBase) + } + base := m.AddSegment() + _, err := m.LoadData(base, &args) + return *NewMaybeRelocatableRelocatable(base), err } return *NewMaybeRelocatableFelt(lambdaworks.FeltZero()), errors.New("GenArg: found argument of invalid type.") } From 13fa7c242c5bacdcfc67edb02622a257e05ff6ef Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 27 Sep 2023 16:45:23 -0300 Subject: [PATCH 07/33] Add unit tests --- pkg/vm/memory/segments_test.go | 49 ++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/pkg/vm/memory/segments_test.go b/pkg/vm/memory/segments_test.go index cdca3585..12fafa1a 100644 --- a/pkg/vm/memory/segments_test.go +++ b/pkg/vm/memory/segments_test.go @@ -310,3 +310,52 @@ func TestGetFeltRangeRelocatable(t *testing.T) { t.Errorf("GetFeltRange should have failed") } } + +func TestGenArgMaybeRelocatable(t *testing.T) { + segments := memory.NewMemorySegmentManager() + arg := any(*memory.NewMaybeRelocatableFelt(lambdaworks.FeltZero())) + expectedArg := *memory.NewMaybeRelocatableFelt(lambdaworks.FeltZero()) + genedArg, err := segments.GenArg(arg) + if err != nil || !reflect.DeepEqual(expectedArg, genedArg) { + t.Error("GenArg failed or returned wrong value") + } +} + +func TestGenArgSliceMaybeRelocatable(t *testing.T) { + segments := memory.NewMemorySegmentManager() + arg := any([]memory.MaybeRelocatable{*memory.NewMaybeRelocatableFelt(lambdaworks.FeltZero())}) + + expectedBase := memory.NewRelocatable(0, 0) + expectedArg := *memory.NewMaybeRelocatableRelocatable(expectedBase) + genedArg, err := segments.GenArg(arg) + if err != nil || !reflect.DeepEqual(expectedArg, genedArg) { + t.Error("GenArg failed or returned wrong value") + } + val, err := segments.Memory.GetFelt(expectedBase) + if err != nil || !val.IsZero() { + t.Error("GenArg inserted wrong value into memory") + } +} + +func TestGenArgSliceSliceMaybeRelocatable(t *testing.T) { + segments := memory.NewMemorySegmentManager() + arg := any([][]memory.MaybeRelocatable{{*memory.NewMaybeRelocatableFelt(lambdaworks.FeltZero())}}) + + expectedBaseA := memory.NewRelocatable(0, 0) + expectedBaseB := memory.NewRelocatable(1, 0) + expectedArg := *memory.NewMaybeRelocatableRelocatable(expectedBaseA) + genedArg, err := segments.GenArg(arg) + + if err != nil || !reflect.DeepEqual(expectedArg, genedArg) { + t.Error("GenArg failed or returned wrong value") + } + valA, err := segments.Memory.GetRelocatable(expectedBaseA) + if err != nil || valA != expectedBaseB { + t.Error("GenArg inserted wrong value into memory") + } + + valB, err := segments.Memory.GetFelt(expectedBaseB) + if err != nil || !valB.IsZero() { + t.Error("GenArg inserted wrong value into memory") + } +} From 623f8dc5dcd4ec4d0521ec77e2ad6647a8797d1c Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 27 Sep 2023 16:50:07 -0300 Subject: [PATCH 08/33] Fix test values --- pkg/vm/memory/segments_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/vm/memory/segments_test.go b/pkg/vm/memory/segments_test.go index 12fafa1a..e4604188 100644 --- a/pkg/vm/memory/segments_test.go +++ b/pkg/vm/memory/segments_test.go @@ -341,8 +341,8 @@ func TestGenArgSliceSliceMaybeRelocatable(t *testing.T) { segments := memory.NewMemorySegmentManager() arg := any([][]memory.MaybeRelocatable{{*memory.NewMaybeRelocatableFelt(lambdaworks.FeltZero())}}) - expectedBaseA := memory.NewRelocatable(0, 0) - expectedBaseB := memory.NewRelocatable(1, 0) + expectedBaseA := memory.NewRelocatable(1, 0) + expectedBaseB := memory.NewRelocatable(0, 0) expectedArg := *memory.NewMaybeRelocatableRelocatable(expectedBaseA) genedArg, err := segments.GenArg(arg) From 8fdb11ffd9f291406478637939eb61120e066839 Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 27 Sep 2023 16:52:47 -0300 Subject: [PATCH 09/33] Start fn --- pkg/runners/cairo_runner.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/runners/cairo_runner.go b/pkg/runners/cairo_runner.go index 4f069dea..8d8c16d8 100644 --- a/pkg/runners/cairo_runner.go +++ b/pkg/runners/cairo_runner.go @@ -581,3 +581,7 @@ func (runner *CairoRunner) GetExecutionResources() (ExecutionResources, error) { BuiltinsInstanceCounter: builtinInstaceCounter, }, nil } + +func (runner *CairoRunner) RunFromEntrypoint(entrypoint uint, args []any) error { + return nil +} From d07aeb1ad238d5056e9fadeeba00ee618538ae08 Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 27 Sep 2023 17:11:37 -0300 Subject: [PATCH 10/33] Add RunFromEntryPoint --- pkg/runners/cairo_runner.go | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/pkg/runners/cairo_runner.go b/pkg/runners/cairo_runner.go index 8d8c16d8..d75b1684 100644 --- a/pkg/runners/cairo_runner.go +++ b/pkg/runners/cairo_runner.go @@ -144,9 +144,9 @@ func (r *CairoRunner) initializeState(entrypoint uint, stack *[]memory.MaybeRelo // Initializes memory, initial register values & returns the end pointer (final pc) to run from a given pc offset // (entrypoint) -func (r *CairoRunner) initializeFunctionEntrypoint(entrypoint uint, stack *[]memory.MaybeRelocatable, return_fp memory.Relocatable) (memory.Relocatable, error) { +func (r *CairoRunner) initializeFunctionEntrypoint(entrypoint uint, stack *[]memory.MaybeRelocatable, return_fp memory.MaybeRelocatable) (memory.Relocatable, error) { end := r.Vm.Segments.AddSegment() - *stack = append(*stack, *memory.NewMaybeRelocatableRelocatable(return_fp), *memory.NewMaybeRelocatableRelocatable(end)) + *stack = append(*stack, return_fp, *memory.NewMaybeRelocatableRelocatable(end)) r.initialFp = r.executionBase r.initialFp.Offset += uint(len(*stack)) r.initialAp = r.initialFp @@ -188,7 +188,7 @@ func (r *CairoRunner) initializeMainEntrypoint() (memory.Relocatable, error) { return memory.NewRelocatable(r.ProgramBase.SegmentIndex, r.ProgramBase.Offset+r.Program.End), nil } - return_fp := r.Vm.Segments.AddSegment() + return_fp := *memory.NewMaybeRelocatableRelocatable(r.Vm.Segments.AddSegment()) return r.initializeFunctionEntrypoint(r.mainOffset, &stack, return_fp) } @@ -582,6 +582,34 @@ func (runner *CairoRunner) GetExecutionResources() (ExecutionResources, error) { }, nil } -func (runner *CairoRunner) RunFromEntrypoint(entrypoint uint, args []any) error { +// TODO: Add secure_run flag once its implemented +// Each arg can be either MaybeRelocatable, []MaybeRelocatable or [][]MaybeRelocatable +func (runner *CairoRunner) RunFromEntrypoint(entrypoint uint, args []any, hintProcessor vm.HintProcessor) error { + stack := make([]memory.MaybeRelocatable, 0) + for _, arg := range args { + val, err := runner.Vm.Segments.GenArg(arg) + if err != nil { + return err + } + stack = append(stack, val) + } + returnFp := *memory.NewMaybeRelocatableFelt(lambdaworks.FeltZero()) + end, err := runner.initializeFunctionEntrypoint(entrypoint, &stack, returnFp) + if err != nil { + return err + } + err = runner.initializeVM() + if err != nil { + return err + } + err = runner.RunUntilPC(end, hintProcessor) + if err != nil { + return err + } + err = runner.EndRun(false, false, hintProcessor) + if err != nil { + return err + } + // TODO: verifySecureRunner return nil } From 206ea73a768315ef797622d28d017504bb6e214f Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 27 Sep 2023 17:43:32 -0300 Subject: [PATCH 11/33] Add test for RunFromEntryPoint --- pkg/runners/cairo_runner.go | 8 ++++---- pkg/runners/cairo_runner_test.go | 33 ++++++++++++++++++++++++++++++++ pkg/vm/vm_core.go | 8 ++++++++ 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/pkg/runners/cairo_runner.go b/pkg/runners/cairo_runner.go index d75b1684..6c1dacc7 100644 --- a/pkg/runners/cairo_runner.go +++ b/pkg/runners/cairo_runner.go @@ -70,11 +70,11 @@ func NewCairoRunner(program vm.Program, layoutName string, proofMode bool) (*Cai // Performs the initialization step, returns the end pointer (pc upon which execution should stop) func (r *CairoRunner) Initialize() (memory.Relocatable, error) { - err := r.initializeBuiltins() + err := r.InitializeBuiltins() if err != nil { return memory.Relocatable{}, errors.New(err.Error()) } - r.initializeSegments() + r.InitializeSegments() end, err := r.initializeMainEntrypoint() if err == nil { err = r.initializeVM() @@ -84,7 +84,7 @@ func (r *CairoRunner) Initialize() (memory.Relocatable, error) { // Initializes builtin runners in accordance to the specified layout and // the builtins present in the running program. -func (r *CairoRunner) initializeBuiltins() error { +func (r *CairoRunner) InitializeBuiltins() error { var builtinRunners []builtins.BuiltinRunner programBuiltins := map[string]struct{}{} for _, builtin := range r.Program.Builtins { @@ -113,7 +113,7 @@ func (r *CairoRunner) initializeBuiltins() error { } // Creates program, execution and builtin segments -func (r *CairoRunner) initializeSegments() { +func (r *CairoRunner) InitializeSegments() { // Program Segment r.ProgramBase = r.Vm.Segments.AddSegment() // Execution Segment diff --git a/pkg/runners/cairo_runner_test.go b/pkg/runners/cairo_runner_test.go index 5f9fd2e2..1c5b7130 100644 --- a/pkg/runners/cairo_runner_test.go +++ b/pkg/runners/cairo_runner_test.go @@ -726,3 +726,36 @@ func TestRunFibonacciGetExecutionResources(t *testing.T) { t.Errorf("Wong ExecutionResources.\n Expected : %+v, got: %+v", expectedExecutionResources, executionResources) } } + +// This test will run the `fib` function in the fibonacci.json program +func TestRunFromEntryPointFibonacci(t *testing.T) { + compiledProgram, _ := parser.Parse("../../cairo_programs/fibonacci.json") + programJson := vm.DeserializeProgramJson(compiledProgram) + + entrypoint := programJson.Identifiers["__main__.fib"].PC + args := []any{ + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltOne()), + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltOne()), + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(10)), + } + runner, _ := runners.NewCairoRunner(programJson, "all_cairo", false) + hintProcessor := hints.CairoVmHintProcessor{} + + runner.InitializeBuiltins() + runner.InitializeSegments() + err := runner.RunFromEntrypoint(uint(entrypoint), args, &hintProcessor) + + if err != nil { + t.Errorf("Running fib entrypoint failed with error %s", err.Error()) + } + + // Check result + res, err := runner.Vm.GetReturnValues(1) + if err != nil { + t.Errorf("Failed to fetch return values from fib with error %s", err.Error()) + } + if len(res) != 1 || !reflect.DeepEqual(res[0], *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(144))) { + t.Errorf("Wrong value returned by fib entrypoint.\n Expected [144], got: %+v", res) + } + +} diff --git a/pkg/vm/vm_core.go b/pkg/vm/vm_core.go index b8aa1e2f..518b312d 100644 --- a/pkg/vm/vm_core.go +++ b/pkg/vm/vm_core.go @@ -642,3 +642,11 @@ func (vm *VirtualMachine) GetRangeCheckBound() (lambdaworks.Felt, error) { return rcBuiltin.Bound(), nil } + +func (vm *VirtualMachine) GetReturnValues(nRet uint) ([]memory.MaybeRelocatable, error) { + ptr, err := vm.RunContext.Ap.SubUint(nRet) + if err != nil { + return nil, err + } + return vm.Segments.Memory.GetRange(ptr, nRet) +} From 1230ee1725a2b625e2f0a1a68730a50580fb4ed0 Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 27 Sep 2023 17:49:18 -0300 Subject: [PATCH 12/33] Add unit tests --- pkg/vm/vm_test.go | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/pkg/vm/vm_test.go b/pkg/vm/vm_test.go index 8f3ab08c..1d537321 100644 --- a/pkg/vm/vm_test.go +++ b/pkg/vm/vm_test.go @@ -1088,3 +1088,31 @@ func TestGetFooBuiltinReturnsNilAndError(t *testing.T) { t.Error("Obtained a non existant builtin, or didn't raise an error") } } + +func TestReadReturnValuesOk(t *testing.T) { + vm := vm.NewVirtualMachine() + vm.Segments.AddSegment() + // Load data at ap and advance ap + data := []memory.MaybeRelocatable{ + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(1)), + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(2)), + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(3)), + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(4)), + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(5)), + } + vm.RunContext.Ap, _ = vm.Segments.LoadData(vm.RunContext.Ap, &data) + // Fetch 3 return values + expectedReturnValues := []memory.MaybeRelocatable{ + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(3)), + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(4)), + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(5)), + } + returnValues, err := vm.GetReturnValues(3) + if err != nil { + t.Errorf("GetReturnValues failed with error: %s", err.Error()) + } + + if !reflect.DeepEqual(expectedReturnValues, returnValues) { + t.Errorf("Wrong return values.\n Expected: %+v, got: %+v", expectedReturnValues, returnValues) + } +} From b7684cd2deac0b4ccd4b556693f18b0e033d470c Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 27 Sep 2023 17:53:46 -0300 Subject: [PATCH 13/33] Add comments --- pkg/runners/cairo_runner.go | 9 +++++++-- pkg/vm/vm_core.go | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/pkg/runners/cairo_runner.go b/pkg/runners/cairo_runner.go index 6c1dacc7..32cb37d4 100644 --- a/pkg/runners/cairo_runner.go +++ b/pkg/runners/cairo_runner.go @@ -582,8 +582,13 @@ func (runner *CairoRunner) GetExecutionResources() (ExecutionResources, error) { }, nil } -// TODO: Add secure_run flag once its implemented -// Each arg can be either MaybeRelocatable, []MaybeRelocatable or [][]MaybeRelocatable +// TODO: Add verifySecure once its implemented +/* +Runs a cairo program from a give entrypoint, indicated by its pc offset, with the given arguments. +If `verifySecure` is set to true, [verifySecureRunner] will be called to run extra verifications. +`programSegmentSize` is only used by the [verifySecureRunner] function and will be ignored if `verifySecure` is set to false. +Each arg can be either MaybeRelocatable, []MaybeRelocatable or [][]MaybeRelocatable +*/ func (runner *CairoRunner) RunFromEntrypoint(entrypoint uint, args []any, hintProcessor vm.HintProcessor) error { stack := make([]memory.MaybeRelocatable, 0) for _, arg := range args { diff --git a/pkg/vm/vm_core.go b/pkg/vm/vm_core.go index 518b312d..c5cb69b1 100644 --- a/pkg/vm/vm_core.go +++ b/pkg/vm/vm_core.go @@ -643,6 +643,7 @@ func (vm *VirtualMachine) GetRangeCheckBound() (lambdaworks.Felt, error) { return rcBuiltin.Bound(), nil } +// Gets `nRet` return values from memory func (vm *VirtualMachine) GetReturnValues(nRet uint) ([]memory.MaybeRelocatable, error) { ptr, err := vm.RunContext.Ap.SubUint(nRet) if err != nil { From 18d9553492a00b4170d9c67ace339e81e5584553 Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 27 Sep 2023 18:06:26 -0300 Subject: [PATCH 14/33] Add skeleton --- pkg/runners/security.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 pkg/runners/security.go diff --git a/pkg/runners/security.go b/pkg/runners/security.go new file mode 100644 index 00000000..79ef868b --- /dev/null +++ b/pkg/runners/security.go @@ -0,0 +1,18 @@ +package runners + +/* +Verify that the completed run in a runner is safe to be relocated and be +used by other Cairo programs. + +Checks include: + - (Only if `verifyBuiltins` is set to true) All accesses to the builtin segments must be within the range defined by + the builtins themselves. + - There must not be accesses to the program segment outside the program + data range. This check will use the `programSegmentSize` instead of the program data length if available. + - All addresses in memory must be real (not temporary) + +Note: Each builtin is responsible for checking its own segments' data. +*/ +func VerifySecureRunner(runner *CairoRunner, verifyBuiltins bool, programSegmentSize *uint) error { + return nil +} From 20d65ef2087a2061b5b295a2bdb889c287622d91 Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 27 Sep 2023 18:27:37 -0300 Subject: [PATCH 15/33] Implement GetMemoryAccesses for BuiltinRunner --- pkg/builtins/bitwise.go | 7 +++++++ pkg/builtins/builtin_runner.go | 2 +- pkg/builtins/ec_op.go | 7 +++++++ pkg/builtins/keccak.go | 7 +++++++ pkg/builtins/output.go | 7 +++++++ pkg/builtins/pedersen.go | 7 +++++++ pkg/builtins/poseidon.go | 7 +++++++ pkg/builtins/range_check.go | 7 +++++++ pkg/builtins/signature.go | 7 +++++++ pkg/runners/security.go | 11 +++++++++++ 10 files changed, 68 insertions(+), 1 deletion(-) diff --git a/pkg/builtins/bitwise.go b/pkg/builtins/bitwise.go index b2e26a34..f16ef148 100644 --- a/pkg/builtins/bitwise.go +++ b/pkg/builtins/bitwise.go @@ -253,3 +253,10 @@ func (r *BitwiseBuiltinRunner) GetUsedInstances(segments *memory.MemorySegmentMa return utils.DivCeil(usedCells, r.CellsPerInstance()), nil } + +func (b *BitwiseBuiltinRunner) GetMemorySegmentAddresses() (memory.Relocatable, memory.Relocatable, error) { + if b.StopPtr == nil { + return memory.Relocatable{}, memory.Relocatable{}, NewErrNoStopPointer(b.Name()) + } + return b.base, memory.NewRelocatable(b.base.SegmentIndex, *b.StopPtr), nil +} diff --git a/pkg/builtins/builtin_runner.go b/pkg/builtins/builtin_runner.go index 64148d7f..7a449e22 100644 --- a/pkg/builtins/builtin_runner.go +++ b/pkg/builtins/builtin_runner.go @@ -58,7 +58,7 @@ type BuiltinRunner interface { // // II. SECURITY (secure-run flag cairo-run || verify-secure flag run_from_entrypoint) // RunSecurityChecks(*vm.VirtualMachine) error // verify_secure_runner logic // // Returns the base & stop_ptr, stop_ptr can be nil - // GetMemorySegmentAddresses() (memory.Relocatable, *memory.Relocatable) //verify_secure_runner logic + GetMemorySegmentAddresses() (memory.Relocatable, memory.Relocatable, error) // // III. STARKNET-SPECIFIC GetUsedInstances(*memory.MemorySegmentManager) (uint, error) // // IV. GENERAL CASE (but not critical) diff --git a/pkg/builtins/ec_op.go b/pkg/builtins/ec_op.go index 0e973a0a..50f0027c 100644 --- a/pkg/builtins/ec_op.go +++ b/pkg/builtins/ec_op.go @@ -406,3 +406,10 @@ func (r *EcOpBuiltinRunner) GetUsedInstances(segments *memory.MemorySegmentManag return utils.DivCeil(usedCells, r.CellsPerInstance()), nil } + +func (b *EcOpBuiltinRunner) GetMemorySegmentAddresses() (memory.Relocatable, memory.Relocatable, error) { + if b.StopPtr == nil { + return memory.Relocatable{}, memory.Relocatable{}, NewErrNoStopPointer(b.Name()) + } + return b.base, memory.NewRelocatable(b.base.SegmentIndex, *b.StopPtr), nil +} diff --git a/pkg/builtins/keccak.go b/pkg/builtins/keccak.go index a5f9638e..773be886 100644 --- a/pkg/builtins/keccak.go +++ b/pkg/builtins/keccak.go @@ -676,3 +676,10 @@ func (r *KeccakBuiltinRunner) GetUsedInstances(segments *memory.MemorySegmentMan return utils.DivCeil(usedCells, r.CellsPerInstance()), nil } + +func (b *KeccakBuiltinRunner) GetMemorySegmentAddresses() (memory.Relocatable, memory.Relocatable, error) { + if b.StopPtr == nil { + return memory.Relocatable{}, memory.Relocatable{}, NewErrNoStopPointer(b.Name()) + } + return b.base, memory.NewRelocatable(b.base.SegmentIndex, *b.StopPtr), nil +} diff --git a/pkg/builtins/output.go b/pkg/builtins/output.go index 945a772b..30c5a060 100644 --- a/pkg/builtins/output.go +++ b/pkg/builtins/output.go @@ -133,3 +133,10 @@ func (r *OutputBuiltinRunner) GetUsedInstances(segments *memory.MemorySegmentMan return usedCells, nil } + +func (b *OutputBuiltinRunner) GetMemorySegmentAddresses() (memory.Relocatable, memory.Relocatable, error) { + if b.StopPtr == nil { + return memory.Relocatable{}, memory.Relocatable{}, NewErrNoStopPointer(b.Name()) + } + return b.base, memory.NewRelocatable(b.base.SegmentIndex, *b.StopPtr), nil +} diff --git a/pkg/builtins/pedersen.go b/pkg/builtins/pedersen.go index baa1d14c..e05cb4c9 100644 --- a/pkg/builtins/pedersen.go +++ b/pkg/builtins/pedersen.go @@ -228,3 +228,10 @@ func (r *PedersenBuiltinRunner) GetUsedInstances(segments *memory.MemorySegmentM return utils.DivCeil(usedCells, r.CellsPerInstance()), nil } + +func (b *PedersenBuiltinRunner) GetMemorySegmentAddresses() (memory.Relocatable, memory.Relocatable, error) { + if b.StopPtr == nil { + return memory.Relocatable{}, memory.Relocatable{}, NewErrNoStopPointer(b.Name()) + } + return b.base, memory.NewRelocatable(b.base.SegmentIndex, *b.StopPtr), nil +} diff --git a/pkg/builtins/poseidon.go b/pkg/builtins/poseidon.go index 9bb09e7e..f542d586 100644 --- a/pkg/builtins/poseidon.go +++ b/pkg/builtins/poseidon.go @@ -217,3 +217,10 @@ func (r *PoseidonBuiltinRunner) GetUsedInstances(segments *memory.MemorySegmentM return utils.DivCeil(usedCells, r.CellsPerInstance()), nil } + +func (b *PoseidonBuiltinRunner) GetMemorySegmentAddresses() (memory.Relocatable, memory.Relocatable, error) { + if b.StopPtr == nil { + return memory.Relocatable{}, memory.Relocatable{}, NewErrNoStopPointer(b.Name()) + } + return b.base, memory.NewRelocatable(b.base.SegmentIndex, *b.StopPtr), nil +} diff --git a/pkg/builtins/range_check.go b/pkg/builtins/range_check.go index 8ee6ae65..8be08b3a 100644 --- a/pkg/builtins/range_check.go +++ b/pkg/builtins/range_check.go @@ -280,3 +280,10 @@ func (r *RangeCheckBuiltinRunner) GetUsedInstances(segments *memory.MemorySegmen return usedCells, nil } + +func (b *RangeCheckBuiltinRunner) GetMemorySegmentAddresses() (memory.Relocatable, memory.Relocatable, error) { + if b.StopPtr == nil { + return memory.Relocatable{}, memory.Relocatable{}, NewErrNoStopPointer(b.Name()) + } + return b.base, memory.NewRelocatable(b.base.SegmentIndex, *b.StopPtr), nil +} diff --git a/pkg/builtins/signature.go b/pkg/builtins/signature.go index 5e577b61..71b3d36f 100644 --- a/pkg/builtins/signature.go +++ b/pkg/builtins/signature.go @@ -235,3 +235,10 @@ func (r *SignatureBuiltinRunner) GetUsedInstances(segments *memory.MemorySegment return utils.DivCeil(usedCells, r.CellsPerInstance()), nil } + +func (b *SignatureBuiltinRunner) GetMemorySegmentAddresses() (memory.Relocatable, memory.Relocatable, error) { + if b.StopPtr == nil { + return memory.Relocatable{}, memory.Relocatable{}, NewErrNoStopPointer(b.Name()) + } + return b.base, memory.NewRelocatable(b.base.SegmentIndex, *b.StopPtr), nil +} diff --git a/pkg/runners/security.go b/pkg/runners/security.go index 79ef868b..ce975a4e 100644 --- a/pkg/runners/security.go +++ b/pkg/runners/security.go @@ -14,5 +14,16 @@ Checks include: Note: Each builtin is responsible for checking its own segments' data. */ func VerifySecureRunner(runner *CairoRunner, verifyBuiltins bool, programSegmentSize *uint) error { + // programSize := uint(len(runner.Program.Data)) + // if programSegmentSize != nil { + // programSize = *programSegmentSize + // } + // builtinSegmentInfo := make(map[string]uint) + // if verifyBuiltins { + // for i := 0; i < len(runner.Vm.BuiltinRunners); i++ { + // info := runner.Vm.BuiltinRunners[i].GetSegmentInfo + // } + // } + return nil } From 2de8b4085c7fbdfc61e60b84ad285478ecc01606 Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 27 Sep 2023 19:11:45 -0300 Subject: [PATCH 16/33] Start implementing RunSecurityChecks --- pkg/builtins/bitwise.go | 51 +++++++++++++++++++++++++++++++++++++++++ pkg/builtins/output.go | 5 ++++ 2 files changed, 56 insertions(+) diff --git a/pkg/builtins/bitwise.go b/pkg/builtins/bitwise.go index f16ef148..775c5d4b 100644 --- a/pkg/builtins/bitwise.go +++ b/pkg/builtins/bitwise.go @@ -1,8 +1,11 @@ package builtins import ( + "sort" + "github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks" "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" @@ -260,3 +263,51 @@ func (b *BitwiseBuiltinRunner) GetMemorySegmentAddresses() (memory.Relocatable, } return b.base, memory.NewRelocatable(b.base.SegmentIndex, *b.StopPtr), nil } + +func (b *BitwiseBuiltinRunner) RunSecurityChecks(vm *vm.VirtualMachine) error { + cellsPerInstance := BITWISE_CELLS_PER_INSTANCE + nInputCells := BIWISE_INPUT_CELLS_PER_INSTANCE + builtinSegmentIndex := b.base.SegmentIndex + + offsets := make([]int, 0) + // Find the max offset for the builtin's segment + for addr, _ := range vm.Segments.Memory.Data { + if addr.SegmentIndex == builtinSegmentIndex { + offsets = append(offsets, int(addr.Offset)) + } + } + // Sort offsets for easier comparison + sort.Ints(offsets) + maxOffset := offsets[len(offsets)-1] + + n := utils.DivCeil(uint(maxOffset), uint(cellsPerInstance)+1) + //Verify that n is not too large to make sure the expectedOffsets list that is constructed below is not too large. + if n > utils.DivCeil(uint(len(offsets)), uint(nInputCells)) { + return errors.Errorf("Missing memory cells for %s", b.Name()) + } + + // Check that the two inputs (x and y) of each instance are set. + expectedOffsets := make([]int, 0) + for i := 0; i < int(n); i++ { + for j := 0; j < nInputCells; j++ { + expectedOffsets = append(expectedOffsets, cellsPerInstance*i+j) + } + } + if len(offsets) < len(expectedOffsets) { + // Find the missing offsets + j := 0 + missingOffsets := make([]int, 0) + for i := 0; i < len(expectedOffsets); i++ { + if expectedOffsets[i] < offsets[j] { + missingOffsets = append(missingOffsets, expectedOffsets[i]) + } else { + j++ + } + } + return errors.Errorf("Missing memory cells for builtin: %s: %v", b.Name(), missingOffsets) + } + + //To be continued... + + return nil +} diff --git a/pkg/builtins/output.go b/pkg/builtins/output.go index 30c5a060..57a27705 100644 --- a/pkg/builtins/output.go +++ b/pkg/builtins/output.go @@ -1,6 +1,7 @@ package builtins import ( + "github.com/lambdaclass/cairo-vm.go/pkg/vm" "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" ) @@ -140,3 +141,7 @@ func (b *OutputBuiltinRunner) GetMemorySegmentAddresses() (memory.Relocatable, m } return b.base, memory.NewRelocatable(b.base.SegmentIndex, *b.StopPtr), nil } + +func (b *OutputBuiltinRunner) RunSecurityChecks(*vm.VirtualMachine) error { + return nil +} From 85227d6f4f3faa688f8c7c86daf5ea218148babd Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 28 Sep 2023 10:51:05 -0300 Subject: [PATCH 17/33] Implement VerifyAutoDeductionsForAddr --- pkg/vm/vm_core.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pkg/vm/vm_core.go b/pkg/vm/vm_core.go index c5cb69b1..95999342 100644 --- a/pkg/vm/vm_core.go +++ b/pkg/vm/vm_core.go @@ -227,6 +227,26 @@ func (vm *VirtualMachine) VerifyAutoDeductions() error { return nil } +// Makes sure that the value at the given address is consistent with the auto deduction rules. +func (vm *VirtualMachine) VerifyAutoDeductionsForAddr(addr memory.Relocatable, builtin builtins.BuiltinRunner) error { + deducedVal, err := builtin.DeduceMemoryCell(addr, &vm.Segments.Memory) + if err != nil { + return err + } + if deducedVal == nil { + return nil + } + currentVal, err := vm.Segments.Memory.Get(addr) + if err != nil { + return nil + } + if *deducedVal != *currentVal { + return &VirtualMachineError{fmt.Sprintf("InconsistentAutoDeduction: %s", builtin.Name())} + } + + return nil +} + type Operands struct { Dst memory.MaybeRelocatable Res *memory.MaybeRelocatable From 3771c74e6011475355a9165a96123399d4cf6eae Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 28 Sep 2023 11:51:19 -0300 Subject: [PATCH 18/33] Finish func + remove import cycle --- pkg/builtins/bitwise.go | 25 +++++++++++++++++++------ pkg/builtins/builtin_runner.go | 2 +- pkg/vm/vm_core.go | 20 -------------------- 3 files changed, 20 insertions(+), 27 deletions(-) diff --git a/pkg/builtins/bitwise.go b/pkg/builtins/bitwise.go index 775c5d4b..502c0551 100644 --- a/pkg/builtins/bitwise.go +++ b/pkg/builtins/bitwise.go @@ -5,7 +5,6 @@ import ( "github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks" "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" @@ -264,20 +263,21 @@ func (b *BitwiseBuiltinRunner) GetMemorySegmentAddresses() (memory.Relocatable, return b.base, memory.NewRelocatable(b.base.SegmentIndex, *b.StopPtr), nil } -func (b *BitwiseBuiltinRunner) RunSecurityChecks(vm *vm.VirtualMachine) error { +func (b *BitwiseBuiltinRunner) RunSecurityChecks(segments *memory.MemorySegmentManager) error { cellsPerInstance := BITWISE_CELLS_PER_INSTANCE nInputCells := BIWISE_INPUT_CELLS_PER_INSTANCE builtinSegmentIndex := b.base.SegmentIndex offsets := make([]int, 0) - // Find the max offset for the builtin's segment - for addr, _ := range vm.Segments.Memory.Data { + // Collect the builtin segment's addres' offsets + for addr, _ := range segments.Memory.Data { if addr.SegmentIndex == builtinSegmentIndex { offsets = append(offsets, int(addr.Offset)) } } // Sort offsets for easier comparison sort.Ints(offsets) + // Obtain max offset maxOffset := offsets[len(offsets)-1] n := utils.DivCeil(uint(maxOffset), uint(cellsPerInstance)+1) @@ -306,8 +306,21 @@ func (b *BitwiseBuiltinRunner) RunSecurityChecks(vm *vm.VirtualMachine) error { } return errors.Errorf("Missing memory cells for builtin: %s: %v", b.Name(), missingOffsets) } - - //To be continued... + // Verify auto deduction rules for the unassigned output cells. + // Assigned output cells are checked as part of the call to VerifyAutoDeductions(). + for i := uint(0); i < n; i++ { + for j := uint(nInputCells); j < uint(cellsPerInstance); j++ { + addr := memory.NewRelocatable(builtinSegmentIndex, uint(cellsPerInstance)*i+j) + _, err := segments.Memory.Get(addr) + // Output cell not in memory + if err != nil { + _, err = b.DeduceMemoryCell(addr, &segments.Memory) + if err != nil { + return err + } + } + } + } return nil } diff --git a/pkg/builtins/builtin_runner.go b/pkg/builtins/builtin_runner.go index 7a449e22..f17f3508 100644 --- a/pkg/builtins/builtin_runner.go +++ b/pkg/builtins/builtin_runner.go @@ -56,7 +56,7 @@ type BuiltinRunner interface { GetUsedCellsAndAllocatedSizes(segments *memory.MemorySegmentManager, currentStep uint) (uint, uint, error) FinalStack(segments *memory.MemorySegmentManager, pointer memory.Relocatable) (memory.Relocatable, error) // // II. SECURITY (secure-run flag cairo-run || verify-secure flag run_from_entrypoint) - // RunSecurityChecks(*vm.VirtualMachine) error // verify_secure_runner logic + // RunSecurityChecks(*memory.MemorySegmentManager) error // verify_secure_runner logic // // Returns the base & stop_ptr, stop_ptr can be nil GetMemorySegmentAddresses() (memory.Relocatable, memory.Relocatable, error) // // III. STARKNET-SPECIFIC diff --git a/pkg/vm/vm_core.go b/pkg/vm/vm_core.go index 95999342..c5cb69b1 100644 --- a/pkg/vm/vm_core.go +++ b/pkg/vm/vm_core.go @@ -227,26 +227,6 @@ func (vm *VirtualMachine) VerifyAutoDeductions() error { return nil } -// Makes sure that the value at the given address is consistent with the auto deduction rules. -func (vm *VirtualMachine) VerifyAutoDeductionsForAddr(addr memory.Relocatable, builtin builtins.BuiltinRunner) error { - deducedVal, err := builtin.DeduceMemoryCell(addr, &vm.Segments.Memory) - if err != nil { - return err - } - if deducedVal == nil { - return nil - } - currentVal, err := vm.Segments.Memory.Get(addr) - if err != nil { - return nil - } - if *deducedVal != *currentVal { - return &VirtualMachineError{fmt.Sprintf("InconsistentAutoDeduction: %s", builtin.Name())} - } - - return nil -} - type Operands struct { Dst memory.MaybeRelocatable Res *memory.MaybeRelocatable From 7ee92b3450e59a348c7d51f8060647dfcf1bcf19 Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 28 Sep 2023 12:02:40 -0300 Subject: [PATCH 19/33] Add fix + unit test --- pkg/builtins/bitwise.go | 7 ++++++- pkg/builtins/bitwise_test.go | 9 +++++++++ pkg/builtins/output.go | 3 +-- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/pkg/builtins/bitwise.go b/pkg/builtins/bitwise.go index 502c0551..cbd61770 100644 --- a/pkg/builtins/bitwise.go +++ b/pkg/builtins/bitwise.go @@ -270,11 +270,16 @@ func (b *BitwiseBuiltinRunner) RunSecurityChecks(segments *memory.MemorySegmentM offsets := make([]int, 0) // Collect the builtin segment's addres' offsets - for addr, _ := range segments.Memory.Data { + for addr := range segments.Memory.Data { if addr.SegmentIndex == builtinSegmentIndex { offsets = append(offsets, int(addr.Offset)) } } + + if len(offsets) == 0 { + // No checks to run for empty segment + return nil + } // Sort offsets for easier comparison sort.Ints(offsets) // Obtain max offset diff --git a/pkg/builtins/bitwise_test.go b/pkg/builtins/bitwise_test.go index 5c798bc3..421b7b81 100644 --- a/pkg/builtins/bitwise_test.go +++ b/pkg/builtins/bitwise_test.go @@ -182,3 +182,12 @@ func TestGetUsedDilutedCheckUnitsC(t *testing.T) { t.Errorf("Wrong Value for GetUsedDilutedChecks, should be %d, got %d", expected, result) } } + +func TestRunSecurityChecksEmptyMemory(t *testing.T) { + builtin := builtins.NewBitwiseBuiltinRunner(256) + segments := memory.NewMemorySegmentManager() + err := builtin.RunSecurityChecks(&segments) + if err != nil { + t.Errorf("RunSecurityChecks failed with error: %s", err.Error()) + } +} diff --git a/pkg/builtins/output.go b/pkg/builtins/output.go index 57a27705..9f55080a 100644 --- a/pkg/builtins/output.go +++ b/pkg/builtins/output.go @@ -1,7 +1,6 @@ package builtins import ( - "github.com/lambdaclass/cairo-vm.go/pkg/vm" "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" ) @@ -142,6 +141,6 @@ func (b *OutputBuiltinRunner) GetMemorySegmentAddresses() (memory.Relocatable, m return b.base, memory.NewRelocatable(b.base.SegmentIndex, *b.StopPtr), nil } -func (b *OutputBuiltinRunner) RunSecurityChecks(*vm.VirtualMachine) error { +func (b *OutputBuiltinRunner) RunSecurityChecks(*memory.MemorySegmentManager) error { return nil } From fbfc94a2603c6fe6e76ebb468a6b37ad155ef5e9 Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 28 Sep 2023 12:15:39 -0300 Subject: [PATCH 20/33] Fix logic, add test --- pkg/builtins/bitwise.go | 21 +++++++++++---------- pkg/builtins/bitwise_test.go | 23 +++++++++++++++++++++++ 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/pkg/builtins/bitwise.go b/pkg/builtins/bitwise.go index cbd61770..2bdac057 100644 --- a/pkg/builtins/bitwise.go +++ b/pkg/builtins/bitwise.go @@ -298,19 +298,20 @@ func (b *BitwiseBuiltinRunner) RunSecurityChecks(segments *memory.MemorySegmentM expectedOffsets = append(expectedOffsets, cellsPerInstance*i+j) } } - if len(offsets) < len(expectedOffsets) { - // Find the missing offsets - j := 0 - missingOffsets := make([]int, 0) - for i := 0; i < len(expectedOffsets); i++ { - if expectedOffsets[i] < offsets[j] { - missingOffsets = append(missingOffsets, expectedOffsets[i]) - } else { - j++ - } + // Find the missing offsets + j := 0 + missingOffsets := make([]int, 0) + for i := 0; i < len(expectedOffsets); i++ { + if expectedOffsets[i] < offsets[j] { + missingOffsets = append(missingOffsets, expectedOffsets[i]) + } else { + j++ } + } + if len(missingOffsets) != 0 { return errors.Errorf("Missing memory cells for builtin: %s: %v", b.Name(), missingOffsets) } + // Verify auto deduction rules for the unassigned output cells. // Assigned output cells are checked as part of the call to VerifyAutoDeductions(). for i := uint(0); i < n; i++ { diff --git a/pkg/builtins/bitwise_test.go b/pkg/builtins/bitwise_test.go index 421b7b81..1264d2d2 100644 --- a/pkg/builtins/bitwise_test.go +++ b/pkg/builtins/bitwise_test.go @@ -191,3 +191,26 @@ func TestRunSecurityChecksEmptyMemory(t *testing.T) { t.Errorf("RunSecurityChecks failed with error: %s", err.Error()) } } + +func TestRunSecurityChecksMissingMemoryCells(t *testing.T) { + builtin := builtins.NewBitwiseBuiltinRunner(256) + segments := memory.NewMemorySegmentManager() + + builtin.InitializeSegments(&segments) + builtinBase := builtin.Base() + // A bitwise cell consists of 5 elements: 2 input cells & 3 output cells + // In this test we insert cells 4-5 and leave the first input cell empty + // This will fail the security checks, as the memory cell with offset 0 will be missing + builtinSegment := []memory.MaybeRelocatable{ + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(1)), + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(2)), + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(3)), + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(4)), + } + segments.LoadData(builtinBase.AddUint(1), &builtinSegment) + + err := builtin.RunSecurityChecks(&segments) + if err == nil { + t.Errorf("RunSecurityChecks should have failed") + } +} From 1f090a5020bbf4d4a13f6b18c5a27dab75daefd0 Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 28 Sep 2023 12:34:17 -0300 Subject: [PATCH 21/33] Fix logic --- pkg/builtins/bitwise.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/builtins/bitwise.go b/pkg/builtins/bitwise.go index 2bdac057..e4bc23a3 100644 --- a/pkg/builtins/bitwise.go +++ b/pkg/builtins/bitwise.go @@ -285,7 +285,7 @@ func (b *BitwiseBuiltinRunner) RunSecurityChecks(segments *memory.MemorySegmentM // Obtain max offset maxOffset := offsets[len(offsets)-1] - n := utils.DivCeil(uint(maxOffset), uint(cellsPerInstance)+1) + n := utils.DivCeil(uint(maxOffset), uint(cellsPerInstance)) + 1 //Verify that n is not too large to make sure the expectedOffsets list that is constructed below is not too large. if n > utils.DivCeil(uint(len(offsets)), uint(nInputCells)) { return errors.Errorf("Missing memory cells for %s", b.Name()) From c28f68672717d5a4422003977da30cf2f020d22e Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 28 Sep 2023 12:50:19 -0300 Subject: [PATCH 22/33] Fix logic --- pkg/builtins/bitwise.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pkg/builtins/bitwise.go b/pkg/builtins/bitwise.go index e4bc23a3..8f3a1551 100644 --- a/pkg/builtins/bitwise.go +++ b/pkg/builtins/bitwise.go @@ -298,15 +298,21 @@ func (b *BitwiseBuiltinRunner) RunSecurityChecks(segments *memory.MemorySegmentM expectedOffsets = append(expectedOffsets, cellsPerInstance*i+j) } } - // Find the missing offsets - j := 0 + // Find the missing offsets (offsets in expectedOffsets but not in offsets) missingOffsets := make([]int, 0) - for i := 0; i < len(expectedOffsets); i++ { + j := 0 + i := 0 + for i < len(expectedOffsets) && j < len(offsets) { if expectedOffsets[i] < offsets[j] { missingOffsets = append(missingOffsets, expectedOffsets[i]) } else { j++ } + i++ + } + for i < len(expectedOffsets) { + missingOffsets = append(missingOffsets, expectedOffsets[i]) + i++ } if len(missingOffsets) != 0 { return errors.Errorf("Missing memory cells for builtin: %s: %v", b.Name(), missingOffsets) From cd017a5fd49222c05ce3e4ecc226cf7e2f74255d Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 28 Sep 2023 12:57:37 -0300 Subject: [PATCH 23/33] Fix logic + add test --- pkg/builtins/bitwise.go | 8 ++++---- pkg/builtins/bitwise_test.go | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/pkg/builtins/bitwise.go b/pkg/builtins/bitwise.go index 8f3a1551..8d156add 100644 --- a/pkg/builtins/bitwise.go +++ b/pkg/builtins/bitwise.go @@ -285,15 +285,15 @@ func (b *BitwiseBuiltinRunner) RunSecurityChecks(segments *memory.MemorySegmentM // Obtain max offset maxOffset := offsets[len(offsets)-1] - n := utils.DivCeil(uint(maxOffset), uint(cellsPerInstance)) + 1 + n := (maxOffset / cellsPerInstance) + 1 //Verify that n is not too large to make sure the expectedOffsets list that is constructed below is not too large. - if n > utils.DivCeil(uint(len(offsets)), uint(nInputCells)) { + if n > len(offsets)/nInputCells { return errors.Errorf("Missing memory cells for %s", b.Name()) } // Check that the two inputs (x and y) of each instance are set. expectedOffsets := make([]int, 0) - for i := 0; i < int(n); i++ { + for i := 0; i < n; i++ { for j := 0; j < nInputCells; j++ { expectedOffsets = append(expectedOffsets, cellsPerInstance*i+j) } @@ -320,7 +320,7 @@ func (b *BitwiseBuiltinRunner) RunSecurityChecks(segments *memory.MemorySegmentM // Verify auto deduction rules for the unassigned output cells. // Assigned output cells are checked as part of the call to VerifyAutoDeductions(). - for i := uint(0); i < n; i++ { + for i := uint(0); i < uint(n); i++ { for j := uint(nInputCells); j < uint(cellsPerInstance); j++ { addr := memory.NewRelocatable(builtinSegmentIndex, uint(cellsPerInstance)*i+j) _, err := segments.Memory.Get(addr) diff --git a/pkg/builtins/bitwise_test.go b/pkg/builtins/bitwise_test.go index 1264d2d2..d727c472 100644 --- a/pkg/builtins/bitwise_test.go +++ b/pkg/builtins/bitwise_test.go @@ -214,3 +214,24 @@ func TestRunSecurityChecksMissingMemoryCells(t *testing.T) { t.Errorf("RunSecurityChecks should have failed") } } + +func TestRunSecurityChecksMissingMemoryCellsNCheck(t *testing.T) { + builtin := builtins.NewBitwiseBuiltinRunner(256) + segments := memory.NewMemorySegmentManager() + + builtin.InitializeSegments(&segments) + builtinBase := builtin.Base() + // n = max(offsets) // cellsPerInstance + 1 + // n = max[(0]) // 5 + 1 = 0 // 5 + 1 = 1 + // len(offsets) // inputCells = 1 // 2 + // This will fail the security checks, as n > len(offsets) // inputCells + builtinSegment := []memory.MaybeRelocatable{ + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(1)), + } + segments.LoadData(builtinBase, &builtinSegment) + + err := builtin.RunSecurityChecks(&segments) + if err == nil { + t.Errorf("RunSecurityChecks should have failed") + } +} From 6a53c1765647b340b2714a03f8427a677b169e7f Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 28 Sep 2023 13:09:08 -0300 Subject: [PATCH 24/33] Add unit tests --- pkg/builtins/bitwise_test.go | 43 ++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/pkg/builtins/bitwise_test.go b/pkg/builtins/bitwise_test.go index d727c472..e026cd1b 100644 --- a/pkg/builtins/bitwise_test.go +++ b/pkg/builtins/bitwise_test.go @@ -235,3 +235,46 @@ func TestRunSecurityChecksMissingMemoryCellsNCheck(t *testing.T) { t.Errorf("RunSecurityChecks should have failed") } } + +func TestRunSecurityChecksValidateOutputCellsNotDeducedOk(t *testing.T) { + builtin := builtins.NewBitwiseBuiltinRunner(256) + segments := memory.NewMemorySegmentManager() + + builtin.InitializeSegments(&segments) + builtinBase := builtin.Base() + // A bitwise cell consists of 5 elements: 2 input cells & 3 output cells + // In this test we insert the input cells (1-2), but not the output cells (3-5) + // This will cause the security checks to run the auto-deductions for those output cells + builtinSegment := []memory.MaybeRelocatable{ + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(1)), + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(2)), + } + segments.LoadData(builtinBase, &builtinSegment) + + err := builtin.RunSecurityChecks(&segments) + if err != nil { + t.Errorf("RunSecurityChecks failed with error: %s", err.Error()) + } +} + +func TestRunSecurityChecksValidateOutputCellsNotDeducedErr(t *testing.T) { + builtin := builtins.NewBitwiseBuiltinRunner(256) + segments := memory.NewMemorySegmentManager() + + builtin.InitializeSegments(&segments) + builtinBase := builtin.Base() + // A bitwise cell consists of 5 elements: 2 input cells & 3 output cells + // In this test we insert the input cells (1-2), but not the output cells (3-5) + // This will cause the security checks to run the auto-deductions for those output cells + // As we inserted an invalid value (PRIME -1) on the first input cell, this deduction will fail + builtinSegment := []memory.MaybeRelocatable{ + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromDecString("-1")), + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(2)), + } + segments.LoadData(builtinBase, &builtinSegment) + + err := builtin.RunSecurityChecks(&segments) + if err == nil { + t.Errorf("RunSecurityChecks should have failed") + } +} From eb863d903dada95b90b686e24a3ae74e8e47fe8b Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 28 Sep 2023 13:28:24 -0300 Subject: [PATCH 25/33] Move RunSecurityChecks to external func in builtins package --- pkg/builtins/bitwise.go | 80 ++------------------- pkg/builtins/bitwise_test.go | 96 ------------------------- pkg/builtins/builtin_runner.go | 83 ++++++++++++++++++++++ pkg/builtins/builtin_runner_test.go | 105 ++++++++++++++++++++++++++++ pkg/builtins/ec_op.go | 4 ++ pkg/builtins/keccak.go | 4 ++ pkg/builtins/output.go | 9 ++- pkg/builtins/pedersen.go | 4 ++ pkg/builtins/poseidon.go | 4 ++ pkg/builtins/range_check.go | 4 ++ pkg/builtins/signature.go | 4 ++ 11 files changed, 223 insertions(+), 174 deletions(-) create mode 100644 pkg/builtins/builtin_runner_test.go diff --git a/pkg/builtins/bitwise.go b/pkg/builtins/bitwise.go index 8d156add..39a9a44c 100644 --- a/pkg/builtins/bitwise.go +++ b/pkg/builtins/bitwise.go @@ -1,8 +1,6 @@ package builtins import ( - "sort" - "github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks" "github.com/lambdaclass/cairo-vm.go/pkg/utils" @@ -113,6 +111,10 @@ func (b *BitwiseBuiltinRunner) CellsPerInstance() uint { return BITWISE_CELLS_PER_INSTANCE } +func (b *BitwiseBuiltinRunner) InputCellsPerInstance() uint { + return BIWISE_INPUT_CELLS_PER_INSTANCE +} + func (b *BitwiseBuiltinRunner) GetAllocatedMemoryUnits(segments *memory.MemorySegmentManager, currentStep uint) (uint, error) { // This condition corresponds to an uninitialized ratio for the builtin, which should only // happen when layout is `dynamic` @@ -262,77 +264,3 @@ func (b *BitwiseBuiltinRunner) GetMemorySegmentAddresses() (memory.Relocatable, } return b.base, memory.NewRelocatable(b.base.SegmentIndex, *b.StopPtr), nil } - -func (b *BitwiseBuiltinRunner) RunSecurityChecks(segments *memory.MemorySegmentManager) error { - cellsPerInstance := BITWISE_CELLS_PER_INSTANCE - nInputCells := BIWISE_INPUT_CELLS_PER_INSTANCE - builtinSegmentIndex := b.base.SegmentIndex - - offsets := make([]int, 0) - // Collect the builtin segment's addres' offsets - for addr := range segments.Memory.Data { - if addr.SegmentIndex == builtinSegmentIndex { - offsets = append(offsets, int(addr.Offset)) - } - } - - if len(offsets) == 0 { - // No checks to run for empty segment - return nil - } - // Sort offsets for easier comparison - sort.Ints(offsets) - // Obtain max offset - maxOffset := offsets[len(offsets)-1] - - n := (maxOffset / cellsPerInstance) + 1 - //Verify that n is not too large to make sure the expectedOffsets list that is constructed below is not too large. - if n > len(offsets)/nInputCells { - return errors.Errorf("Missing memory cells for %s", b.Name()) - } - - // Check that the two inputs (x and y) of each instance are set. - expectedOffsets := make([]int, 0) - for i := 0; i < n; i++ { - for j := 0; j < nInputCells; j++ { - expectedOffsets = append(expectedOffsets, cellsPerInstance*i+j) - } - } - // Find the missing offsets (offsets in expectedOffsets but not in offsets) - missingOffsets := make([]int, 0) - j := 0 - i := 0 - for i < len(expectedOffsets) && j < len(offsets) { - if expectedOffsets[i] < offsets[j] { - missingOffsets = append(missingOffsets, expectedOffsets[i]) - } else { - j++ - } - i++ - } - for i < len(expectedOffsets) { - missingOffsets = append(missingOffsets, expectedOffsets[i]) - i++ - } - if len(missingOffsets) != 0 { - return errors.Errorf("Missing memory cells for builtin: %s: %v", b.Name(), missingOffsets) - } - - // Verify auto deduction rules for the unassigned output cells. - // Assigned output cells are checked as part of the call to VerifyAutoDeductions(). - for i := uint(0); i < uint(n); i++ { - for j := uint(nInputCells); j < uint(cellsPerInstance); j++ { - addr := memory.NewRelocatable(builtinSegmentIndex, uint(cellsPerInstance)*i+j) - _, err := segments.Memory.Get(addr) - // Output cell not in memory - if err != nil { - _, err = b.DeduceMemoryCell(addr, &segments.Memory) - if err != nil { - return err - } - } - } - } - - return nil -} diff --git a/pkg/builtins/bitwise_test.go b/pkg/builtins/bitwise_test.go index e026cd1b..5c798bc3 100644 --- a/pkg/builtins/bitwise_test.go +++ b/pkg/builtins/bitwise_test.go @@ -182,99 +182,3 @@ func TestGetUsedDilutedCheckUnitsC(t *testing.T) { t.Errorf("Wrong Value for GetUsedDilutedChecks, should be %d, got %d", expected, result) } } - -func TestRunSecurityChecksEmptyMemory(t *testing.T) { - builtin := builtins.NewBitwiseBuiltinRunner(256) - segments := memory.NewMemorySegmentManager() - err := builtin.RunSecurityChecks(&segments) - if err != nil { - t.Errorf("RunSecurityChecks failed with error: %s", err.Error()) - } -} - -func TestRunSecurityChecksMissingMemoryCells(t *testing.T) { - builtin := builtins.NewBitwiseBuiltinRunner(256) - segments := memory.NewMemorySegmentManager() - - builtin.InitializeSegments(&segments) - builtinBase := builtin.Base() - // A bitwise cell consists of 5 elements: 2 input cells & 3 output cells - // In this test we insert cells 4-5 and leave the first input cell empty - // This will fail the security checks, as the memory cell with offset 0 will be missing - builtinSegment := []memory.MaybeRelocatable{ - *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(1)), - *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(2)), - *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(3)), - *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(4)), - } - segments.LoadData(builtinBase.AddUint(1), &builtinSegment) - - err := builtin.RunSecurityChecks(&segments) - if err == nil { - t.Errorf("RunSecurityChecks should have failed") - } -} - -func TestRunSecurityChecksMissingMemoryCellsNCheck(t *testing.T) { - builtin := builtins.NewBitwiseBuiltinRunner(256) - segments := memory.NewMemorySegmentManager() - - builtin.InitializeSegments(&segments) - builtinBase := builtin.Base() - // n = max(offsets) // cellsPerInstance + 1 - // n = max[(0]) // 5 + 1 = 0 // 5 + 1 = 1 - // len(offsets) // inputCells = 1 // 2 - // This will fail the security checks, as n > len(offsets) // inputCells - builtinSegment := []memory.MaybeRelocatable{ - *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(1)), - } - segments.LoadData(builtinBase, &builtinSegment) - - err := builtin.RunSecurityChecks(&segments) - if err == nil { - t.Errorf("RunSecurityChecks should have failed") - } -} - -func TestRunSecurityChecksValidateOutputCellsNotDeducedOk(t *testing.T) { - builtin := builtins.NewBitwiseBuiltinRunner(256) - segments := memory.NewMemorySegmentManager() - - builtin.InitializeSegments(&segments) - builtinBase := builtin.Base() - // A bitwise cell consists of 5 elements: 2 input cells & 3 output cells - // In this test we insert the input cells (1-2), but not the output cells (3-5) - // This will cause the security checks to run the auto-deductions for those output cells - builtinSegment := []memory.MaybeRelocatable{ - *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(1)), - *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(2)), - } - segments.LoadData(builtinBase, &builtinSegment) - - err := builtin.RunSecurityChecks(&segments) - if err != nil { - t.Errorf("RunSecurityChecks failed with error: %s", err.Error()) - } -} - -func TestRunSecurityChecksValidateOutputCellsNotDeducedErr(t *testing.T) { - builtin := builtins.NewBitwiseBuiltinRunner(256) - segments := memory.NewMemorySegmentManager() - - builtin.InitializeSegments(&segments) - builtinBase := builtin.Base() - // A bitwise cell consists of 5 elements: 2 input cells & 3 output cells - // In this test we insert the input cells (1-2), but not the output cells (3-5) - // This will cause the security checks to run the auto-deductions for those output cells - // As we inserted an invalid value (PRIME -1) on the first input cell, this deduction will fail - builtinSegment := []memory.MaybeRelocatable{ - *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromDecString("-1")), - *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(2)), - } - segments.LoadData(builtinBase, &builtinSegment) - - err := builtin.RunSecurityChecks(&segments) - if err == nil { - t.Errorf("RunSecurityChecks should have failed") - } -} diff --git a/pkg/builtins/builtin_runner.go b/pkg/builtins/builtin_runner.go index f17f3508..6772cfe9 100644 --- a/pkg/builtins/builtin_runner.go +++ b/pkg/builtins/builtin_runner.go @@ -2,6 +2,7 @@ package builtins import ( "fmt" + "sort" "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" "github.com/pkg/errors" @@ -28,6 +29,10 @@ type BuiltinRunner interface { Base() memory.Relocatable // Returns the name of the builtin Name() string + // Cells per builtin instance + CellsPerInstance() uint + // Input cells per builtin instance + InputCellsPerInstance() uint // Creates a memory segment for the builtin and initializes its base InitializeSegments(*memory.MemorySegmentManager) // Returns the builtin's initial stack @@ -64,3 +69,81 @@ type BuiltinRunner interface { // // IV. GENERAL CASE (but not critical) // FinalStack(*memory.MemorySegmentManager, memory.Relocatable) (memory.Relocatable, error) // read_return_values } + +func RunSecurityChecksForBuiltin(builtin BuiltinRunner, segments *memory.MemorySegmentManager) error { + if builtin.Name() == OUTPUT_BUILTIN_NAME { + return nil + } + + cellsPerInstance := builtin.CellsPerInstance() + nInputCells := builtin.InputCellsPerInstance() + builtinSegmentIndex := builtin.Base().SegmentIndex + + offsets := make([]int, 0) + // Collect the builtin segment's addres' offsets + for addr := range segments.Memory.Data { + if addr.SegmentIndex == builtinSegmentIndex { + offsets = append(offsets, int(addr.Offset)) + } + } + + if len(offsets) == 0 { + // No checks to run for empty segment + return nil + } + // Sort offsets for easier comparison + sort.Ints(offsets) + // Obtain max offset + maxOffset := offsets[len(offsets)-1] + + n := (maxOffset / int(cellsPerInstance)) + 1 + //Verify that n is not too large to make sure the expectedOffsets list that is constructed below is not too large. + if n > len(offsets)/int(nInputCells) { + return errors.Errorf("Missing memory cells for %s", builtin.Name()) + } + + // Check that the two inputs (x and y) of each instance are set. + expectedOffsets := make([]int, 0) + for i := 0; i < n; i++ { + for j := 0; j < int(nInputCells); j++ { + expectedOffsets = append(expectedOffsets, int(cellsPerInstance)*i+j) + } + } + // Find the missing offsets (offsets in expectedOffsets but not in offsets) + missingOffsets := make([]int, 0) + j := 0 + i := 0 + for i < len(expectedOffsets) && j < len(offsets) { + if expectedOffsets[i] < offsets[j] { + missingOffsets = append(missingOffsets, expectedOffsets[i]) + } else { + j++ + } + i++ + } + for i < len(expectedOffsets) { + missingOffsets = append(missingOffsets, expectedOffsets[i]) + i++ + } + if len(missingOffsets) != 0 { + return errors.Errorf("Missing memory cells for builtin: %s: %v", builtin.Name(), missingOffsets) + } + + // Verify auto deduction rules for the unassigned output cells. + // Assigned output cells are checked as part of the call to VerifyAutoDeductions(). + for i := uint(0); i < uint(n); i++ { + for j := uint(nInputCells); j < cellsPerInstance; j++ { + addr := memory.NewRelocatable(builtinSegmentIndex, cellsPerInstance*i+j) + _, err := segments.Memory.Get(addr) + // Output cell not in memory + if err != nil { + _, err = builtin.DeduceMemoryCell(addr, &segments.Memory) + if err != nil { + return err + } + } + } + } + + return nil +} diff --git a/pkg/builtins/builtin_runner_test.go b/pkg/builtins/builtin_runner_test.go new file mode 100644 index 00000000..210b25a2 --- /dev/null +++ b/pkg/builtins/builtin_runner_test.go @@ -0,0 +1,105 @@ +package builtins_test + +import ( + "testing" + + "github.com/lambdaclass/cairo-vm.go/pkg/builtins" + "github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks" + "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" +) + +func TestRunSecurityChecksEmptyMemory(t *testing.T) { + builtin := builtins.NewBitwiseBuiltinRunner(256) + segments := memory.NewMemorySegmentManager() + err := builtins.RunSecurityChecksForBuiltin(builtin, &segments) + if err != nil { + t.Errorf("RunSecurityChecks failed with error: %s", err.Error()) + } +} + +func TestRunSecurityChecksMissingMemoryCells(t *testing.T) { + builtin := builtins.NewBitwiseBuiltinRunner(256) + segments := memory.NewMemorySegmentManager() + + builtin.InitializeSegments(&segments) + builtinBase := builtin.Base() + // A bitwise cell consists of 5 elements: 2 input cells & 3 output cells + // In this test we insert cells 4-5 and leave the first input cell empty + // This will fail the security checks, as the memory cell with offset 0 will be missing + builtinSegment := []memory.MaybeRelocatable{ + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(1)), + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(2)), + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(3)), + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(4)), + } + segments.LoadData(builtinBase.AddUint(1), &builtinSegment) + + err := builtins.RunSecurityChecksForBuiltin(builtin, &segments) + if err == nil { + t.Errorf("RunSecurityChecks should have failed") + } +} + +func TestRunSecurityChecksMissingMemoryCellsNCheck(t *testing.T) { + builtin := builtins.NewBitwiseBuiltinRunner(256) + segments := memory.NewMemorySegmentManager() + + builtin.InitializeSegments(&segments) + builtinBase := builtin.Base() + // n = max(offsets) // cellsPerInstance + 1 + // n = max[(0]) // 5 + 1 = 0 // 5 + 1 = 1 + // len(offsets) // inputCells = 1 // 2 + // This will fail the security checks, as n > len(offsets) // inputCells + builtinSegment := []memory.MaybeRelocatable{ + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(1)), + } + segments.LoadData(builtinBase, &builtinSegment) + + err := builtins.RunSecurityChecksForBuiltin(builtin, &segments) + if err == nil { + t.Errorf("RunSecurityChecks should have failed") + } +} + +func TestRunSecurityChecksValidateOutputCellsNotDeducedOk(t *testing.T) { + builtin := builtins.NewBitwiseBuiltinRunner(256) + segments := memory.NewMemorySegmentManager() + + builtin.InitializeSegments(&segments) + builtinBase := builtin.Base() + // A bitwise cell consists of 5 elements: 2 input cells & 3 output cells + // In this test we insert the input cells (1-2), but not the output cells (3-5) + // This will cause the security checks to run the auto-deductions for those output cells + builtinSegment := []memory.MaybeRelocatable{ + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(1)), + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(2)), + } + segments.LoadData(builtinBase, &builtinSegment) + + err := builtins.RunSecurityChecksForBuiltin(builtin, &segments) + if err != nil { + t.Errorf("RunSecurityChecks failed with error: %s", err.Error()) + } +} + +func TestRunSecurityChecksValidateOutputCellsNotDeducedErr(t *testing.T) { + builtin := builtins.NewBitwiseBuiltinRunner(256) + segments := memory.NewMemorySegmentManager() + + builtin.InitializeSegments(&segments) + builtinBase := builtin.Base() + // A bitwise cell consists of 5 elements: 2 input cells & 3 output cells + // In this test we insert the input cells (1-2), but not the output cells (3-5) + // This will cause the security checks to run the auto-deductions for those output cells + // As we inserted an invalid value (PRIME -1) on the first input cell, this deduction will fail + builtinSegment := []memory.MaybeRelocatable{ + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromDecString("-1")), + *memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(2)), + } + segments.LoadData(builtinBase, &builtinSegment) + + err := builtins.RunSecurityChecksForBuiltin(builtin, &segments) + if err == nil { + t.Errorf("RunSecurityChecks should have failed") + } +} diff --git a/pkg/builtins/ec_op.go b/pkg/builtins/ec_op.go index 50f0027c..ce05390d 100644 --- a/pkg/builtins/ec_op.go +++ b/pkg/builtins/ec_op.go @@ -148,6 +148,10 @@ func (r *EcOpBuiltinRunner) CellsPerInstance() uint { return CELLS_PER_EC_OP } +func (b *EcOpBuiltinRunner) InputCellsPerInstance() uint { + return INPUT_CELLS_PER_EC_OP +} + func (ec *EcOpBuiltinRunner) AddValidationRule(*memory.Memory) {} func (ec *EcOpBuiltinRunner) Base() memory.Relocatable { diff --git a/pkg/builtins/keccak.go b/pkg/builtins/keccak.go index 773be886..ac11ae37 100644 --- a/pkg/builtins/keccak.go +++ b/pkg/builtins/keccak.go @@ -539,6 +539,10 @@ func (k *KeccakBuiltinRunner) CellsPerInstance() uint { return KECCAK_CELLS_PER_INSTANCE } +func (b *KeccakBuiltinRunner) InputCellsPerInstance() uint { + return KECCAK_INPUT_CELLS_PER_INSTANCE +} + func (k *KeccakBuiltinRunner) GetAllocatedMemoryUnits(segments *memory.MemorySegmentManager, currentStep uint) (uint, error) { // This condition corresponds to an uninitialized ratio for the builtin, which should only // happen when layout is `dynamic` diff --git a/pkg/builtins/output.go b/pkg/builtins/output.go index 9f55080a..f445178b 100644 --- a/pkg/builtins/output.go +++ b/pkg/builtins/output.go @@ -5,6 +5,7 @@ import ( ) const OUTPUT_BUILTIN_NAME = "output" +const OUTPUT_CELLS_PER_INSTANCE = 1 type OutputBuiltinRunner struct { base memory.Relocatable @@ -141,6 +142,10 @@ func (b *OutputBuiltinRunner) GetMemorySegmentAddresses() (memory.Relocatable, m return b.base, memory.NewRelocatable(b.base.SegmentIndex, *b.StopPtr), nil } -func (b *OutputBuiltinRunner) RunSecurityChecks(*memory.MemorySegmentManager) error { - return nil +func (r *OutputBuiltinRunner) CellsPerInstance() uint { + return OUTPUT_CELLS_PER_INSTANCE +} + +func (b *OutputBuiltinRunner) InputCellsPerInstance() uint { + return OUTPUT_CELLS_PER_INSTANCE } diff --git a/pkg/builtins/pedersen.go b/pkg/builtins/pedersen.go index e05cb4c9..158ef68e 100644 --- a/pkg/builtins/pedersen.go +++ b/pkg/builtins/pedersen.go @@ -107,6 +107,10 @@ func (p *PedersenBuiltinRunner) CellsPerInstance() uint { return PEDERSEN_CELLS_PER_INSTANCE } +func (p *PedersenBuiltinRunner) InputCellsPerInstance() uint { + return PEDERSEN_INPUT_CELLS_PER_INSTANCE +} + func (p *PedersenBuiltinRunner) GetAllocatedMemoryUnits(segments *memory.MemorySegmentManager, currentStep uint) (uint, error) { // This condition corresponds to an uninitialized ratio for the builtin, which should only // happen when layout is `dynamic` diff --git a/pkg/builtins/poseidon.go b/pkg/builtins/poseidon.go index f542d586..81a9a8e0 100644 --- a/pkg/builtins/poseidon.go +++ b/pkg/builtins/poseidon.go @@ -96,6 +96,10 @@ func (p *PoseidonBuiltinRunner) CellsPerInstance() uint { return POSEIDON_CELLS_PER_INSTANCE } +func (p *PoseidonBuiltinRunner) InputCellsPerInstance() uint { + return POSEIDON_INPUT_CELLS_PER_INSTANCE +} + func (p *PoseidonBuiltinRunner) GetAllocatedMemoryUnits(segments *memory.MemorySegmentManager, currentStep uint) (uint, error) { // This condition corresponds to an uninitialized ratio for the builtin, which should only // happen when layout is `dynamic` diff --git a/pkg/builtins/range_check.go b/pkg/builtins/range_check.go index 8be08b3a..ee913b94 100644 --- a/pkg/builtins/range_check.go +++ b/pkg/builtins/range_check.go @@ -110,6 +110,10 @@ func (r *RangeCheckBuiltinRunner) CellsPerInstance() uint { return CELLS_PER_RANGE_CHECK } +func (b *RangeCheckBuiltinRunner) InputCellsPerInstance() uint { + return CELLS_PER_RANGE_CHECK +} + func (r *RangeCheckBuiltinRunner) GetAllocatedMemoryUnits(segments *memory.MemorySegmentManager, currentStep uint) (uint, error) { // This condition corresponds to an uninitialized ratio for the builtin, which should only // happen when layout is `dynamic` diff --git a/pkg/builtins/signature.go b/pkg/builtins/signature.go index 71b3d36f..ce6865bd 100644 --- a/pkg/builtins/signature.go +++ b/pkg/builtins/signature.go @@ -131,6 +131,10 @@ func (r *SignatureBuiltinRunner) CellsPerInstance() uint { return SIGNATURE_CELLS_PER_INSTANCE } +func (r *SignatureBuiltinRunner) InputCellsPerInstance() uint { + return SIGNATURE_CELLS_PER_INSTANCE +} + func (r *SignatureBuiltinRunner) GetRangeCheckUsage(memory *memory.Memory) (*uint, *uint) { return nil, nil } From 76e4c67b19d8ac463edf0fe8eb16cfeda450637c Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 28 Sep 2023 13:30:51 -0300 Subject: [PATCH 26/33] Remove todos from BuiltinRunner interface --- pkg/builtins/builtin_runner.go | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/pkg/builtins/builtin_runner.go b/pkg/builtins/builtin_runner.go index 6772cfe9..4ed7f46c 100644 --- a/pkg/builtins/builtin_runner.go +++ b/pkg/builtins/builtin_runner.go @@ -45,29 +45,21 @@ type BuiltinRunner interface { AddValidationRule(*memory.Memory) // Sets the inclusion of the Builtin Runner in the Cairo Runner Include(bool) - // TODO: Later additions -> Some of them could depend on a Default Implementation - // // Most of them depend on Layouts being implemented - // // Use cases: - // // I. PROOF_MODE // Returns the builtin's ratio, is zero if the layout is dynamic Ratio() uint // Returns the builtin's allocated memory units GetAllocatedMemoryUnits(segments *memory.MemorySegmentManager, currentStep uint) (uint, error) - // // Returns the list of memory addresses used by the builtin + // Returns the list of memory addresses used by the builtin GetMemoryAccesses(*memory.MemorySegmentManager) ([]memory.Relocatable, error) GetRangeCheckUsage(*memory.Memory) (*uint, *uint) GetUsedPermRangeCheckLimits(segments *memory.MemorySegmentManager, currentStep uint) (uint, error) GetUsedDilutedCheckUnits(dilutedSpacing uint, dilutedNBits uint) uint GetUsedCellsAndAllocatedSizes(segments *memory.MemorySegmentManager, currentStep uint) (uint, uint, error) FinalStack(segments *memory.MemorySegmentManager, pointer memory.Relocatable) (memory.Relocatable, error) - // // II. SECURITY (secure-run flag cairo-run || verify-secure flag run_from_entrypoint) - // RunSecurityChecks(*memory.MemorySegmentManager) error // verify_secure_runner logic - // // Returns the base & stop_ptr, stop_ptr can be nil + // Returns the base & stop_ptr GetMemorySegmentAddresses() (memory.Relocatable, memory.Relocatable, error) - // // III. STARKNET-SPECIFIC + // Amount of builtin instances used GetUsedInstances(*memory.MemorySegmentManager) (uint, error) - // // IV. GENERAL CASE (but not critical) - // FinalStack(*memory.MemorySegmentManager, memory.Relocatable) (memory.Relocatable, error) // read_return_values } func RunSecurityChecksForBuiltin(builtin BuiltinRunner, segments *memory.MemorySegmentManager) error { From 324fc1de978ac0960e37563fbadabc683ac99cb5 Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 28 Sep 2023 15:35:40 -0300 Subject: [PATCH 27/33] Finish verifySecureRunner --- pkg/runners/security.go | 59 ++++++++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/pkg/runners/security.go b/pkg/runners/security.go index ce975a4e..c8c5d4c9 100644 --- a/pkg/runners/security.go +++ b/pkg/runners/security.go @@ -1,5 +1,10 @@ package runners +import ( + "github.com/lambdaclass/cairo-vm.go/pkg/builtins" + "github.com/pkg/errors" +) + /* Verify that the completed run in a runner is safe to be relocated and be used by other Cairo programs. @@ -14,16 +19,50 @@ Checks include: Note: Each builtin is responsible for checking its own segments' data. */ func VerifySecureRunner(runner *CairoRunner, verifyBuiltins bool, programSegmentSize *uint) error { - // programSize := uint(len(runner.Program.Data)) - // if programSegmentSize != nil { - // programSize = *programSegmentSize - // } - // builtinSegmentInfo := make(map[string]uint) - // if verifyBuiltins { - // for i := 0; i < len(runner.Vm.BuiltinRunners); i++ { - // info := runner.Vm.BuiltinRunners[i].GetSegmentInfo - // } - // } + programSize := uint(len(runner.Program.Data)) + if programSegmentSize != nil { + programSize = *programSegmentSize + } + // Get builtin segment info + builtinNames := make(map[int]string) + builtinSizes := make(map[int]uint) + if verifyBuiltins { + for i := 0; i < len(runner.Vm.BuiltinRunners); i++ { + base, stopPtr, err := runner.Vm.BuiltinRunners[i].GetMemorySegmentAddresses() + if err != nil { + return err + } + builtinNames[base.SegmentIndex] = runner.Vm.BuiltinRunners[i].Name() + builtinSizes[base.SegmentIndex] = stopPtr.Offset + } + } + // Run memory checks + for addr, val := range runner.Vm.Segments.Memory.Data { + // Check out of bound accesses to builtin segment + size, ok := builtinSizes[addr.SegmentIndex] + if ok && addr.Offset >= size { + return errors.Errorf("Out of bounds access to builtin segment %s at %s", builtinNames[addr.SegmentIndex], addr.ToString()) + } + // Check out of bound accesses to program segment + if addr.SegmentIndex == runner.ProgramBase.SegmentIndex && addr.SegmentIndex >= int(programSize) { + return errors.Errorf("Out of bounds access to program segment at %s", addr.ToString()) + } + // Check non-relocated temporary addresses + if addr.SegmentIndex < 0 { + return errors.Errorf("Security Error: Invalid Memory Value: temporary address not relocated: %s", addr.ToString()) + } + relVal, isRel := val.GetRelocatable() + if isRel && relVal.SegmentIndex < 0 { + return errors.Errorf("Security Error: Invalid Memory Value: temporary address not relocated: %s", relVal.ToString()) + } + } + // Run builtin-specific checks + for i := 0; i < len(runner.Vm.BuiltinRunners); i++ { + err := builtins.RunSecurityChecksForBuiltin(runner.Vm.BuiltinRunners[i], &runner.Vm.Segments) + if err != nil { + return err + } + } return nil } From 22cfcfbcb5db636a50cfb0abdda7b37b903c2749 Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 28 Sep 2023 15:40:35 -0300 Subject: [PATCH 28/33] Add verifySecure to RunFromEntryPoint --- pkg/runners/cairo_runner.go | 7 ++++--- pkg/runners/cairo_runner_test.go | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pkg/runners/cairo_runner.go b/pkg/runners/cairo_runner.go index 32cb37d4..53354130 100644 --- a/pkg/runners/cairo_runner.go +++ b/pkg/runners/cairo_runner.go @@ -582,14 +582,13 @@ func (runner *CairoRunner) GetExecutionResources() (ExecutionResources, error) { }, nil } -// TODO: Add verifySecure once its implemented /* Runs a cairo program from a give entrypoint, indicated by its pc offset, with the given arguments. If `verifySecure` is set to true, [verifySecureRunner] will be called to run extra verifications. `programSegmentSize` is only used by the [verifySecureRunner] function and will be ignored if `verifySecure` is set to false. Each arg can be either MaybeRelocatable, []MaybeRelocatable or [][]MaybeRelocatable */ -func (runner *CairoRunner) RunFromEntrypoint(entrypoint uint, args []any, hintProcessor vm.HintProcessor) error { +func (runner *CairoRunner) RunFromEntrypoint(entrypoint uint, args []any, hintProcessor vm.HintProcessor, verifySecure bool, programSegmentSize *uint) error { stack := make([]memory.MaybeRelocatable, 0) for _, arg := range args { val, err := runner.Vm.Segments.GenArg(arg) @@ -615,6 +614,8 @@ func (runner *CairoRunner) RunFromEntrypoint(entrypoint uint, args []any, hintPr if err != nil { return err } - // TODO: verifySecureRunner + if verifySecure { + return VerifySecureRunner(runner, true, programSegmentSize) + } return nil } diff --git a/pkg/runners/cairo_runner_test.go b/pkg/runners/cairo_runner_test.go index 1c5b7130..0f5f34c6 100644 --- a/pkg/runners/cairo_runner_test.go +++ b/pkg/runners/cairo_runner_test.go @@ -743,7 +743,7 @@ func TestRunFromEntryPointFibonacci(t *testing.T) { runner.InitializeBuiltins() runner.InitializeSegments() - err := runner.RunFromEntrypoint(uint(entrypoint), args, &hintProcessor) + err := runner.RunFromEntrypoint(uint(entrypoint), args, &hintProcessor, true, nil) if err != nil { t.Errorf("Running fib entrypoint failed with error %s", err.Error()) From 01ecde92013fba2202c2aeae84096cc6ce9e3755 Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 28 Sep 2023 16:48:55 -0300 Subject: [PATCH 29/33] Add unit tests --- pkg/runners/security_test.go | 55 ++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 pkg/runners/security_test.go diff --git a/pkg/runners/security_test.go b/pkg/runners/security_test.go new file mode 100644 index 00000000..dd808ac7 --- /dev/null +++ b/pkg/runners/security_test.go @@ -0,0 +1,55 @@ +package runners_test + +import ( + "testing" + + "github.com/lambdaclass/cairo-vm.go/pkg/builtins" + . "github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks" + . "github.com/lambdaclass/cairo-vm.go/pkg/runners" + . "github.com/lambdaclass/cairo-vm.go/pkg/vm" + . "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" +) + +func TestVerifySecureRunnerEmptyMemory(t *testing.T) { + runner, _ := NewCairoRunner(Program{}, "all_cairo", false) + runner.Initialize() + err := VerifySecureRunner(runner, true, nil) + if err != nil { + t.Errorf("VerifySecureRunner failed with error: %s", err.Error()) + } +} + +func TestVerifySecureRunnerOutOfBoundsAccessProgram(t *testing.T) { + runner, _ := NewCairoRunner(Program{}, "all_cairo", false) + runner.Initialize() + // Insert an element into the program segment to trigger out of bounds access to program segment error + runner.Vm.Segments.Memory.Insert(runner.ProgramBase, NewMaybeRelocatableFelt(FeltOne())) + err := VerifySecureRunner(runner, true, nil) + if err == nil { + t.Errorf("VerifySecureRunner should have failed") + } +} + +func TestVerifySecureRunnerOutOfBoundsAccessBuiltin(t *testing.T) { + runner, _ := NewCairoRunner(Program{Builtins: []string{builtins.OUTPUT_BUILTIN_NAME}}, "all_cairo", false) + runner.Initialize() + stopPtr := uint(0) + runner.Vm.BuiltinRunners[0].(*builtins.OutputBuiltinRunner).StopPtr = &stopPtr + // Insert an element into the output segment to trigger out of bounds access to builtin segment error + runner.Vm.Segments.Memory.Insert(runner.Vm.BuiltinRunners[0].Base(), NewMaybeRelocatableFelt(FeltOne())) + err := VerifySecureRunner(runner, true, nil) + if err == nil { + t.Errorf("VerifySecureRunner should have failed") + } +} + +func TestVerifySecureRunnerTemporaryVal(t *testing.T) { + runner, _ := NewCairoRunner(Program{}, "all_cairo", false) + runner.Initialize() + // Insert a temporary address into memory + runner.Vm.Segments.Memory.Insert(NewRelocatable(1, 7), NewMaybeRelocatableRelocatable(NewRelocatable(-1, 0))) + err := VerifySecureRunner(runner, true, nil) + if err == nil { + t.Errorf("VerifySecureRunner should have failed") + } +} From e1dd296065906ce8e8c51d50c49d83baea097d6c Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 28 Sep 2023 17:01:59 -0300 Subject: [PATCH 30/33] Add secure_run flag --- cmd/cli/main.go | 14 +++++++++++++- pkg/vm/cairo_run/cairo_run.go | 8 ++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/cmd/cli/main.go b/cmd/cli/main.go index db77623b..e26d92f6 100644 --- a/cmd/cli/main.go +++ b/cmd/cli/main.go @@ -17,7 +17,14 @@ func handleCommands(ctx *cli.Context) error { layout = "plain" } - cairoRunConfig := cairo_run.CairoRunConfig{DisableTracePadding: false, ProofMode: ctx.Bool("proof_mode"), Layout: layout} + proofMode := ctx.Bool("proof_mode") + + secureRun := !proofMode + if ctx.Bool("secure_run") { + secureRun = true + } + + cairoRunConfig := cairo_run.CairoRunConfig{DisableTracePadding: false, ProofMode: proofMode, Layout: layout, SecureRun: secureRun} cairoRunner, err := cairo_run.CairoRun(programPath, cairoRunConfig) if err != nil { @@ -51,6 +58,11 @@ func main() { Aliases: []string{"p"}, Usage: "Run in proof mode", }, + &cli.BoolFlag{ + Name: "secure_run", + Aliases: []string{"p"}, + Usage: "Run security checks. Default: true unless proof_mode is true", + }, &cli.StringFlag{ Name: "layout", Aliases: []string{"l"}, diff --git a/pkg/vm/cairo_run/cairo_run.go b/pkg/vm/cairo_run/cairo_run.go index d54a1f99..db6b568a 100644 --- a/pkg/vm/cairo_run/cairo_run.go +++ b/pkg/vm/cairo_run/cairo_run.go @@ -24,6 +24,7 @@ type CairoRunConfig struct { DisableTracePadding bool ProofMode bool Layout string + SecureRun bool } func CairoRunError(err error) error { @@ -67,6 +68,13 @@ func CairoRun(programPath string, cairoRunConfig CairoRunConfig) (*runners.Cairo cairoRunner.FinalizeSegments() } + if cairoRunConfig.SecureRun { + err = runners.VerifySecureRunner(cairoRunner, true, nil) + if err != nil { + return nil, err + } + } + err = cairoRunner.Vm.Relocate() return cairoRunner, err } From 1cb8df453755768781c5e85d3249d648923bd1e4 Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 28 Sep 2023 17:06:48 -0300 Subject: [PATCH 31/33] Fix typo --- pkg/builtins/builtin_runner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/builtins/builtin_runner.go b/pkg/builtins/builtin_runner.go index 4ed7f46c..c9e9c7ad 100644 --- a/pkg/builtins/builtin_runner.go +++ b/pkg/builtins/builtin_runner.go @@ -72,7 +72,7 @@ func RunSecurityChecksForBuiltin(builtin BuiltinRunner, segments *memory.MemoryS builtinSegmentIndex := builtin.Base().SegmentIndex offsets := make([]int, 0) - // Collect the builtin segment's addres' offsets + // Collect the builtin segment's address' offsets for addr := range segments.Memory.Data { if addr.SegmentIndex == builtinSegmentIndex { offsets = append(offsets, int(addr.Offset)) From 67924a24a024f997c56b90632a1a24d79f2db8c5 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 2 Oct 2023 14:09:41 -0300 Subject: [PATCH 32/33] Fix alias for new flag --- cmd/cli/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/cli/main.go b/cmd/cli/main.go index e26d92f6..094facea 100644 --- a/cmd/cli/main.go +++ b/cmd/cli/main.go @@ -60,7 +60,7 @@ func main() { }, &cli.BoolFlag{ Name: "secure_run", - Aliases: []string{"p"}, + Aliases: []string{"s"}, Usage: "Run security checks. Default: true unless proof_mode is true", }, &cli.StringFlag{ From da1b2c5790508c092b1b3a8830f8bab61d404dce Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 3 Oct 2023 10:42:00 -0300 Subject: [PATCH 33/33] Set secure_run to true in testProgram --- pkg/vm/cairo_run/cairo_run_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/vm/cairo_run/cairo_run_test.go b/pkg/vm/cairo_run/cairo_run_test.go index 845a3076..33705cc8 100644 --- a/pkg/vm/cairo_run/cairo_run_test.go +++ b/pkg/vm/cairo_run/cairo_run_test.go @@ -8,7 +8,7 @@ import ( ) func testProgram(programName string, t *testing.T) { - cairoRunConfig := cairo_run.CairoRunConfig{DisableTracePadding: false, Layout: "all_cairo", ProofMode: false} + cairoRunConfig := cairo_run.CairoRunConfig{DisableTracePadding: false, Layout: "all_cairo", ProofMode: false, SecureRun: true} _, err := cairo_run.CairoRun("../../../cairo_programs/"+programName+".json", cairoRunConfig) if err != nil { t.Errorf("Program execution failed with error: %s", err)