Skip to content

Commit

Permalink
Merge branch 'main' into feat/uint512-div-mod
Browse files Browse the repository at this point in the history
  • Loading branch information
rodrigo-pino committed Nov 20, 2023
2 parents 9f47b89 + ccef6dd commit b4b5fcd
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 45 deletions.
35 changes: 35 additions & 0 deletions pkg/hintrunner/hint.go
Original file line number Diff line number Diff line change
Expand Up @@ -1077,5 +1077,40 @@ func (hint Uint512DivModByUint256) Execute(vm *VM.VirtualMachine, _ *HintRunnerC
if err = vm.Memory.WriteToAddress(&remainder1Addr, &remainder1Val); err != nil {
return fmt.Errorf("write cell: %v", err)
}

return nil
}

type AllocConstantSize struct {
Size ResOperander
Dst CellRefer
}

func (hint *AllocConstantSize) String() string {
return "AllocConstantSize"
}

func (hint *AllocConstantSize) Execute(vm *VM.VirtualMachine, ctx *HintRunnerContext) error {
size, err := ResolveAsUint64(vm, hint.Size)
if err != nil {
return fmt.Errorf("size to big: %w", err)
}

if ctx.ConstantSizeSegment.Equal(&mem.UnknownAddress) {
ctx.ConstantSizeSegment = vm.Memory.AllocateEmptySegment()
}

dst, err := hint.Dst.Get(vm)
if err != nil {
return fmt.Errorf("get dst %w", err)
}

val := mem.MemoryValueFromMemoryAddress(&ctx.ConstantSizeSegment)
if err = vm.Memory.WriteToAddress(&dst, &val); err != nil {
return err
}

// todo(rodro): Is possible for this to overflow
ctx.ConstantSizeSegment.Offset += size
return nil
}
127 changes: 82 additions & 45 deletions pkg/hintrunner/hint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"testing"

VM "github.com/NethermindEth/cairo-vm-go/pkg/vm"
"github.com/NethermindEth/cairo-vm-go/pkg/vm/memory"
mem "github.com/NethermindEth/cairo-vm-go/pkg/vm/memory"
f "github.com/consensys/gnark-crypto/ecc/stark-curve/fp"
"github.com/holiman/uint256"
"github.com/stretchr/testify/require"
Expand All @@ -29,7 +29,7 @@ func TestAllocSegment(t *testing.T) {
require.Equal(t, 3, len(vm.Memory.Segments))
require.Equal(
t,
memory.MemoryValueFromSegmentAndOffset(2, 0),
mem.MemoryValueFromSegmentAndOffset(2, 0),
readFrom(vm, VM.ExecutionSegment, vm.Context.Ap+5),
)

Expand All @@ -38,7 +38,7 @@ func TestAllocSegment(t *testing.T) {
require.Equal(t, 4, len(vm.Memory.Segments))
require.Equal(
t,
memory.MemoryValueFromSegmentAndOffset(3, 0),
mem.MemoryValueFromSegmentAndOffset(3, 0),
readFrom(vm, VM.ExecutionSegment, vm.Context.Fp+9),
)

Expand All @@ -48,7 +48,7 @@ func TestTestLessThanTrue(t *testing.T) {
vm := defaultVirtualMachine()
vm.Context.Ap = 0
vm.Context.Fp = 0
writeTo(vm, VM.ExecutionSegment, 0, memory.MemoryValueFromInt(23))
writeTo(vm, VM.ExecutionSegment, 0, mem.MemoryValueFromInt(23))

var dst ApCellRef = 1
var rhsRef FpCellRef = 0
Expand All @@ -66,7 +66,7 @@ func TestTestLessThanTrue(t *testing.T) {
require.NoError(t, err)
require.Equal(
t,
memory.MemoryValueFromInt(1),
mem.MemoryValueFromInt(1),
readFrom(vm, VM.ExecutionSegment, 1),
"Expected the hint to evaluate to True when lhs is less than rhs",
)
Expand All @@ -85,7 +85,7 @@ func TestTestLessThanFalse(t *testing.T) {
vm := defaultVirtualMachine()
vm.Context.Ap = 0
vm.Context.Fp = 0
writeTo(vm, VM.ExecutionSegment, 0, memory.MemoryValueFromInt(17))
writeTo(vm, VM.ExecutionSegment, 0, mem.MemoryValueFromInt(17))

var dst ApCellRef = 1
var rhsRef FpCellRef = 0
Expand All @@ -102,7 +102,7 @@ func TestTestLessThanFalse(t *testing.T) {
require.NoError(t, err)
require.Equal(
t,
memory.EmptyMemoryValueAsFelt(),
mem.EmptyMemoryValueAsFelt(),
readFrom(vm, VM.ExecutionSegment, 1),
tc.expectedMsg,
)
Expand All @@ -124,7 +124,7 @@ func TestTestLessThanOrEqTrue(t *testing.T) {
vm := defaultVirtualMachine()
vm.Context.Ap = 0
vm.Context.Fp = 0
writeTo(vm, VM.ExecutionSegment, 0, memory.MemoryValueFromInt(23))
writeTo(vm, VM.ExecutionSegment, 0, mem.MemoryValueFromInt(23))

var dst ApCellRef = 1
var rhsRef FpCellRef = 0
Expand All @@ -141,7 +141,7 @@ func TestTestLessThanOrEqTrue(t *testing.T) {
require.NoError(t, err)
require.Equal(
t,
memory.MemoryValueFromInt(1),
mem.MemoryValueFromInt(1),
readFrom(vm, VM.ExecutionSegment, 1),
tc.expectedMsg,
)
Expand All @@ -153,7 +153,7 @@ func TestTestLessThanOrEqFalse(t *testing.T) {
vm := defaultVirtualMachine()
vm.Context.Ap = 0
vm.Context.Fp = 0
writeTo(vm, VM.ExecutionSegment, 0, memory.MemoryValueFromInt(17))
writeTo(vm, VM.ExecutionSegment, 0, mem.MemoryValueFromInt(17))

var dst ApCellRef = 1
var rhsRef FpCellRef = 0
Expand All @@ -171,7 +171,7 @@ func TestTestLessThanOrEqFalse(t *testing.T) {
require.NoError(t, err)
require.Equal(
t,
memory.EmptyMemoryValueAsFelt(),
mem.EmptyMemoryValueAsFelt(),
readFrom(vm, VM.ExecutionSegment, 1),
"Expected the hint to evaluate to False when lhs is larger",
)
Expand Down Expand Up @@ -199,9 +199,9 @@ func TestLinearSplit(t *testing.T) {
err := hint.Execute(vm, nil)
require.NoError(t, err)
xx := readFrom(vm, VM.ExecutionSegment, 0)
require.Equal(t, xx, memory.MemoryValueFromInt(223344))
require.Equal(t, xx, mem.MemoryValueFromInt(223344))
yy := readFrom(vm, VM.ExecutionSegment, 1)
require.Equal(t, yy, memory.MemoryValueFromInt(14))
require.Equal(t, yy, mem.MemoryValueFromInt(14))

vm = defaultVirtualMachine()
vm.Context.Ap = 0
Expand All @@ -220,9 +220,9 @@ func TestLinearSplit(t *testing.T) {
err = hint.Execute(vm, nil)
require.NoError(t, err)
xx = readFrom(vm, VM.ExecutionSegment, 0)
require.Equal(t, xx, memory.MemoryValueFromInt(223343))
require.Equal(t, xx, mem.MemoryValueFromInt(223343))
yy = readFrom(vm, VM.ExecutionSegment, 1)
require.Equal(t, yy, memory.MemoryValueFromInt(14+42))
require.Equal(t, yy, mem.MemoryValueFromInt(14+42))
}

func TestWideMul128(t *testing.T) {
Expand Down Expand Up @@ -257,12 +257,12 @@ func TestWideMul128(t *testing.T) {

require.Equal(
t,
memory.MemoryValueFromFieldElement(low),
mem.MemoryValueFromFieldElement(low),
readFrom(vm, VM.ExecutionSegment, 1),
)
require.Equal(
t,
memory.MemoryValueFromInt(1<<7),
mem.MemoryValueFromInt(1<<7),
readFrom(vm, VM.ExecutionSegment, 2),
)
}
Expand Down Expand Up @@ -303,11 +303,11 @@ func TestDebugPrint(t *testing.T) {
vm.Context.Ap = 0
vm.Context.Fp = 0

writeTo(vm, VM.ExecutionSegment, 0, memory.MemoryValueFromSegmentAndOffset(VM.ExecutionSegment, 2))
writeTo(vm, VM.ExecutionSegment, 1, memory.MemoryValueFromSegmentAndOffset(VM.ExecutionSegment, 5))
writeTo(vm, VM.ExecutionSegment, 2, memory.MemoryValueFromInt(10))
writeTo(vm, VM.ExecutionSegment, 3, memory.MemoryValueFromInt(20))
writeTo(vm, VM.ExecutionSegment, 4, memory.MemoryValueFromInt(30))
writeTo(vm, VM.ExecutionSegment, 0, mem.MemoryValueFromSegmentAndOffset(VM.ExecutionSegment, 2))
writeTo(vm, VM.ExecutionSegment, 1, mem.MemoryValueFromSegmentAndOffset(VM.ExecutionSegment, 5))
writeTo(vm, VM.ExecutionSegment, 2, mem.MemoryValueFromInt(10))
writeTo(vm, VM.ExecutionSegment, 3, mem.MemoryValueFromInt(20))
writeTo(vm, VM.ExecutionSegment, 4, mem.MemoryValueFromInt(30))

var starRef ApCellRef = 0
var endRef ApCellRef = 1
Expand Down Expand Up @@ -346,7 +346,7 @@ func TestSquareRoot(t *testing.T) {
require.NoError(t, err)
require.Equal(
t,
memory.MemoryValueFromInt(6),
mem.MemoryValueFromInt(6),
readFrom(vm, VM.ExecutionSegment, 1),
)

Expand All @@ -362,7 +362,7 @@ func TestSquareRoot(t *testing.T) {
require.NoError(t, err)
require.Equal(
t,
memory.MemoryValueFromInt(5),
mem.MemoryValueFromInt(5),
readFrom(vm, VM.ExecutionSegment, 2),
)
}
Expand Down Expand Up @@ -395,11 +395,11 @@ func TestUint256SquareRootLow(t *testing.T) {

require.NoError(t, err)

expectedSqrt0 := memory.MemoryValueFromInt(11)
expectedSqrt1 := memory.MemoryValueFromInt(0)
expectedRemainderLow := memory.MemoryValueFromInt(0)
expectedRemainderHigh := memory.MemoryValueFromInt(0)
expectedSqrtMul2MinusRemainderGeU128 := memory.MemoryValueFromInt(0)
expectedSqrt0 := mem.MemoryValueFromInt(11)
expectedSqrt1 := mem.MemoryValueFromInt(0)
expectedRemainderLow := mem.MemoryValueFromInt(0)
expectedRemainderHigh := mem.MemoryValueFromInt(0)
expectedSqrtMul2MinusRemainderGeU128 := mem.MemoryValueFromInt(0)

actualSqrt0 := readFrom(vm, VM.ExecutionSegment, 1)
actualSqrt1 := readFrom(vm, VM.ExecutionSegment, 2)
Expand Down Expand Up @@ -442,11 +442,11 @@ func TestUint256SquareRootHigh(t *testing.T) {

require.NoError(t, err)

expectedSqrt0 := memory.MemoryValueFromInt(0)
expectedSqrt1 := memory.MemoryValueFromInt(16)
expectedRemainderLow := memory.MemoryValueFromInt(0)
expectedRemainderHigh := memory.MemoryValueFromInt(0)
expectedSqrtMul2MinusRemainderGeU128 := memory.MemoryValueFromInt(0)
expectedSqrt0 := mem.MemoryValueFromInt(0)
expectedSqrt1 := mem.MemoryValueFromInt(16)
expectedRemainderLow := mem.MemoryValueFromInt(0)
expectedRemainderHigh := mem.MemoryValueFromInt(0)
expectedSqrtMul2MinusRemainderGeU128 := mem.MemoryValueFromInt(0)

actualSqrt0 := readFrom(vm, VM.ExecutionSegment, 1)
actualSqrt1 := readFrom(vm, VM.ExecutionSegment, 2)
Expand Down Expand Up @@ -489,11 +489,11 @@ func TestUint256SquareRoot(t *testing.T) {

require.NoError(t, err)

expectedSqrt0 := memory.MemoryValueFromInt(0)
expectedSqrt1 := memory.MemoryValueFromInt(32)
expectedRemainderLow := memory.MemoryValueFromInt(51)
expectedRemainderHigh := memory.MemoryValueFromInt(0)
expectedSqrtMul2MinusRemainderGeU128 := memory.MemoryValueFromInt(0)
expectedSqrt0 := mem.MemoryValueFromInt(0)
expectedSqrt1 := mem.MemoryValueFromInt(32)
expectedRemainderLow := mem.MemoryValueFromInt(51)
expectedRemainderHigh := mem.MemoryValueFromInt(0)
expectedSqrtMul2MinusRemainderGeU128 := mem.MemoryValueFromInt(0)

actualSqrt0 := readFrom(vm, VM.ExecutionSegment, 1)
actualSqrt1 := readFrom(vm, VM.ExecutionSegment, 2)
Expand Down Expand Up @@ -556,7 +556,7 @@ func TestUint512DivModByUint256(t *testing.T) {

require.Equal(
t,
memory.MemoryValueFromFieldElement(quotient0),
mem.MemoryValueFromFieldElement(quotient0),
readFrom(vm, VM.ExecutionSegment, 1),
)

Expand All @@ -566,7 +566,7 @@ func TestUint512DivModByUint256(t *testing.T) {

require.Equal(
t,
memory.MemoryValueFromFieldElement(quotient1),
mem.MemoryValueFromFieldElement(quotient1),
readFrom(vm, VM.ExecutionSegment, 2),
)

Expand All @@ -575,7 +575,7 @@ func TestUint512DivModByUint256(t *testing.T) {

require.Equal(
t,
memory.MemoryValueFromFieldElement(quotient2),
mem.MemoryValueFromFieldElement(quotient2),
readFrom(vm, VM.ExecutionSegment, 3),
)

Expand All @@ -584,7 +584,7 @@ func TestUint512DivModByUint256(t *testing.T) {

require.Equal(
t,
memory.MemoryValueFromFieldElement(quotient3),
mem.MemoryValueFromFieldElement(quotient3),
readFrom(vm, VM.ExecutionSegment, 4),
)

Expand All @@ -594,7 +594,7 @@ func TestUint512DivModByUint256(t *testing.T) {

require.Equal(
t,
memory.MemoryValueFromFieldElement(remainder0),
mem.MemoryValueFromFieldElement(remainder0),
readFrom(vm, VM.ExecutionSegment, 5),
)

Expand All @@ -603,7 +603,7 @@ func TestUint512DivModByUint256(t *testing.T) {

require.Equal(
t,
memory.MemoryValueFromFieldElement(remainder1),
mem.MemoryValueFromFieldElement(remainder1),
readFrom(vm, VM.ExecutionSegment, 6),
)
}
Expand Down Expand Up @@ -650,3 +650,40 @@ func TestUint512DivModByUint256DivisionByZero(t *testing.T) {
err = hint.Execute(vm, nil)
require.ErrorContains(t, err, "division by zero")
}

func TestAllocConstantSize(t *testing.T) {
vm := defaultVirtualMachine()

sizes := [3]Immediate{
Immediate(f.NewElement(15)),
Immediate(f.NewElement(13)),
Immediate(f.NewElement(2)),
}
expectedAddrs := [3]mem.MemoryAddress{
{SegmentIndex: 2, Offset: 0},
{SegmentIndex: 2, Offset: 15},
{SegmentIndex: 2, Offset: 28},
}

ctx := HintRunnerContext{
ConstantSizeSegment: mem.UnknownAddress,
}

for i := 0; i < len(sizes); i++ {
hint := AllocConstantSize{
Dst: ApCellRef(i),
Size: sizes[i],
}

err := hint.Execute(vm, &ctx)
require.NoError(t, err)

val := readFrom(vm, 1, uint64(i))
ptr, err := val.MemoryAddress()
require.NoError(t, err)

require.Equal(t, &expectedAddrs[i], ptr)
}

require.Equal(t, ctx.ConstantSizeSegment, mem.MemoryAddress{SegmentIndex: 2, Offset: 30})
}
3 changes: 3 additions & 0 deletions pkg/hintrunner/hintrunner.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ func (sdm *SquashedDictionaryManager) PopIndex() (uint64, error) {
type HintRunnerContext struct {
DictionaryManager DictionaryManager
SquashedDictionaryManager SquashedDictionaryManager
// points towards free memory of a segment
ConstantSizeSegment mem.MemoryAddress
}

type HintRunner struct {
Expand All @@ -201,6 +203,7 @@ func NewHintRunner(hints map[uint64]Hinter) HintRunner {
context: HintRunnerContext{
DictionaryManager{},
SquashedDictionaryManager{},
mem.UnknownAddress,
},
hints: hints,
}
Expand Down

0 comments on commit b4b5fcd

Please sign in to comment.