Skip to content

Commit

Permalink
Merge branch 'main' into cairo0_hint_Uint256MulDivMod
Browse files Browse the repository at this point in the history
  • Loading branch information
MaksymMalicki authored Mar 20, 2024
2 parents 5c01ca5 + 9ddf3a6 commit 6b6ec59
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 25 deletions.
3 changes: 3 additions & 0 deletions pkg/hintrunner/zero/hintcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ const (
// split_felt() hints.
splitFeltCode string = "from starkware.cairo.common.math_utils import assert_integer\nassert ids.MAX_HIGH < 2**128 and ids.MAX_LOW < 2**128\nassert PRIME - 1 == ids.MAX_HIGH * 2**128 + ids.MAX_LOW\nassert_integer(ids.value)\nids.low = ids.value & ((1 << 128) - 1)\nids.high = ids.value >> 128"

// sqrt() hint
sqrtCode string = "from starkware.python.math_utils import isqrt\nvalue = ids.value % PRIME\nassert value < 2 ** 250, f\"value={value} is outside of the range [0, 2**250).\"\nassert 2 ** 250 < PRIME\nids.root = isqrt(value)"

// ------ Uint256 hints related code ------
uint256AddCode string = "sum_low = ids.a.low + ids.b.low\nids.carry_low = 1 if sum_low >= ids.SHIFT else 0\nsum_high = ids.a.high + ids.b.high + ids.carry_low\nids.carry_high = 1 if sum_high >= ids.SHIFT else 0"
uint256AddLowCode string = "sum_low = ids.a.low + ids.b.low\nids.carry_low = 1 if sum_low >= ids.SHIFT else 0"
Expand Down
2 changes: 2 additions & 0 deletions pkg/hintrunner/zero/zerohint.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ func GetHintFromCode(program *zero.ZeroProgram, rawHint zero.Hint, hintPC uint64
return createUint256SqrtHinter(resolver)
case uint256MulDivModCode:
return createUint256MulDivModHinter(resolver)
case sqrtCode:
return createSqrtHinter(resolver)
default:
return nil, fmt.Errorf("Not identified hint")
}
Expand Down
52 changes: 52 additions & 0 deletions pkg/hintrunner/zero/zerohint_math.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"fmt"
"math/big"

"github.com/holiman/uint256"

"github.com/NethermindEth/cairo-vm-go/pkg/hintrunner/core"
"github.com/NethermindEth/cairo-vm-go/pkg/hintrunner/hinter"
"github.com/NethermindEth/cairo-vm-go/pkg/utils"
Expand Down Expand Up @@ -581,3 +583,53 @@ func createSplitFeltHinter(resolver hintReferenceResolver) (hinter.Hinter, error

return newSplitFeltHint(low, high, value), nil
}

func newSqrtHint(root, value hinter.ResOperander) hinter.Hinter {
return &GenericZeroHinter{
Name: "Sqrt",
Op: func(vm *VM.VirtualMachine, _ *hinter.HintRunnerContext) error {
//> from starkware.python.math_utils import isqrt
// value = ids.value % PRIME
// assert value < 2 ** 250, f"value={value} is outside of the range [0, 2**250)."
// assert 2 ** 250 < PRIME
// ids.root = isqrt(value)

rootAddr, err := root.GetAddress(vm)
if err != nil {
return err
}

value, err := hinter.ResolveAsFelt(vm, value)
if err != nil {
return err
}

if !utils.FeltLt(value, &utils.FeltUpperBound) {
return fmt.Errorf("assertion failed: %v is outside of the range [0, 2**250)", value)
}

// Conversion needed to handle non-square values
valueU256 := uint256.Int(value.Bits())
valueU256.Sqrt(&valueU256)

result := fp.Element{}
result.SetBytes(valueU256.Bytes())

v := memory.MemoryValueFromFieldElement(&result)
return vm.Memory.WriteToAddress(&rootAddr, &v)
},
}
}

func createSqrtHinter(resolver hintReferenceResolver) (hinter.Hinter, error) {

root, err := resolver.GetResOperander("root")
if err != nil {
return nil, err
}
value, err := resolver.GetResOperander("value")
if err != nil {
return nil, err
}
return newSqrtHint(root, value), nil
}
43 changes: 43 additions & 0 deletions pkg/hintrunner/zero/zerohint_math_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -586,5 +586,48 @@ func TestZeroHintMath(t *testing.T) {
}),
},
},

"SqrtHint": {
{
operanders: []*hintOperander{
{Name: "root", Kind: uninitialized},
{Name: "value", Kind: fpRelative, Value: feltInt64(25)},
},
makeHinter: func(ctx *hintTestContext) hinter.Hinter {
return newSqrtHint(ctx.operanders["root"], ctx.operanders["value"])
},
check: varValueEquals("root", feltInt64(5)),
},
{
operanders: []*hintOperander{
{Name: "root", Kind: uninitialized},
{Name: "value", Kind: fpRelative, Value: feltInt64(0)},
},
makeHinter: func(ctx *hintTestContext) hinter.Hinter {
return newSqrtHint(ctx.operanders["root"], ctx.operanders["value"])
},
check: varValueEquals("root", feltInt64(0)),
},
{
operanders: []*hintOperander{
{Name: "root", Kind: uninitialized},
{Name: "value", Kind: fpRelative, Value: feltInt64(50)},
},
makeHinter: func(ctx *hintTestContext) hinter.Hinter {
return newSqrtHint(ctx.operanders["root"], ctx.operanders["value"])
},
check: varValueEquals("root", feltInt64(7)),
},
{
operanders: []*hintOperander{
{Name: "root", Kind: uninitialized},
{Name: "value", Kind: fpRelative, Value: feltInt64(-128)},
},
makeHinter: func(ctx *hintTestContext) hinter.Hinter {
return newSqrtHint(ctx.operanders["root"], ctx.operanders["value"])
},
errCheck: errorTextContains("outside of the range [0, 2**250)"),
},
},
})
}
3 changes: 1 addition & 2 deletions pkg/hintrunner/zero/zerohint_uint256.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,8 @@ func newUint256SignedNNHint(a hinter.ResOperander) hinter.Hinter {
return err
}
var v memory.MemoryValue
felt127 := new(fp.Element).SetBigInt(new(big.Int).Lsh(big.NewInt(1), 127))

if utils.FeltLt(aHigh, felt127) {
if utils.FeltLt(aHigh, &utils.Felt127) {
v = memory.MemoryValueFromFieldElement(&utils.FeltOne)
} else {
v = memory.MemoryValueFromFieldElement(&utils.FeltZero)
Expand Down
41 changes: 18 additions & 23 deletions pkg/hintrunner/zero/zerohint_uint256_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package zero

import (
"math/big"
"testing"

"github.com/NethermindEth/cairo-vm-go/pkg/hintrunner/hinter"
Expand All @@ -10,17 +9,13 @@ import (
)

func TestZeroHintUint256(t *testing.T) {
// Values used in the test cases
// 1 << 127
felt127 := new(fp.Element).SetBigInt(new(big.Int).Lsh(big.NewInt(1), 127))

runHinterTests(t, map[string][]hintTestCase{
"Uint256Add": {
{
operanders: []*hintOperander{
{Name: "a.low", Kind: fpRelative, Value: felt127},
{Name: "a.low", Kind: fpRelative, Value: &utils.Felt127},
{Name: "a.high", Kind: fpRelative, Value: feltUint64(0)},
{Name: "b.low", Kind: apRelative, Value: felt127},
{Name: "b.low", Kind: apRelative, Value: &utils.Felt127},
{Name: "b.high", Kind: apRelative, Value: feltUint64(0)},
{Name: "carry_low", Kind: uninitialized},
{Name: "carry_high", Kind: uninitialized},
Expand All @@ -35,10 +30,10 @@ func TestZeroHintUint256(t *testing.T) {
},
{
operanders: []*hintOperander{
{Name: "a.low", Kind: fpRelative, Value: felt127},
{Name: "a.high", Kind: fpRelative, Value: felt127},
{Name: "b.low", Kind: apRelative, Value: felt127},
{Name: "b.high", Kind: apRelative, Value: felt127},
{Name: "a.low", Kind: fpRelative, Value: &utils.Felt127},
{Name: "a.high", Kind: fpRelative, Value: &utils.Felt127},
{Name: "b.low", Kind: apRelative, Value: &utils.Felt127},
{Name: "b.high", Kind: apRelative, Value: &utils.Felt127},
{Name: "carry_low", Kind: uninitialized},
{Name: "carry_high", Kind: uninitialized},
},
Expand All @@ -53,9 +48,9 @@ func TestZeroHintUint256(t *testing.T) {
{
operanders: []*hintOperander{
{Name: "a.low", Kind: fpRelative, Value: feltUint64(0)},
{Name: "a.high", Kind: fpRelative, Value: felt127},
{Name: "a.high", Kind: fpRelative, Value: &utils.Felt127},
{Name: "b.low", Kind: apRelative, Value: feltUint64(0)},
{Name: "b.high", Kind: apRelative, Value: felt127},
{Name: "b.high", Kind: apRelative, Value: &utils.Felt127},
{Name: "carry_low", Kind: uninitialized},
{Name: "carry_high", Kind: uninitialized},
},
Expand All @@ -69,10 +64,10 @@ func TestZeroHintUint256(t *testing.T) {
},
{
operanders: []*hintOperander{
{Name: "a.low", Kind: fpRelative, Value: felt127},
{Name: "a.low", Kind: fpRelative, Value: &utils.Felt127},
{Name: "a.high", Kind: fpRelative, Value: feltUint64(0)},
{Name: "b.low", Kind: apRelative, Value: feltUint64(0)},
{Name: "b.high", Kind: apRelative, Value: felt127},
{Name: "b.high", Kind: apRelative, Value: &utils.Felt127},
{Name: "carry_low", Kind: uninitialized},
{Name: "carry_high", Kind: uninitialized},
},
Expand Down Expand Up @@ -104,7 +99,7 @@ func TestZeroHintUint256(t *testing.T) {
// `low` is zero
{
operanders: []*hintOperander{
{Name: "a", Kind: fpRelative, Value: felt127},
{Name: "a", Kind: fpRelative, Value: &utils.Felt127},
{Name: "low", Kind: uninitialized},
{Name: "high", Kind: uninitialized},
},
Expand Down Expand Up @@ -180,8 +175,8 @@ func TestZeroHintUint256(t *testing.T) {
},
{
operanders: []*hintOperander{
{Name: "n.low", Kind: fpRelative, Value: felt127},
{Name: "n.high", Kind: fpRelative, Value: felt127},
{Name: "n.low", Kind: fpRelative, Value: &utils.Felt127},
{Name: "n.high", Kind: fpRelative, Value: &utils.Felt127},
{Name: "root.low", Kind: uninitialized},
{Name: "root.high", Kind: uninitialized},
},
Expand All @@ -198,7 +193,7 @@ func TestZeroHintUint256(t *testing.T) {
{
operanders: []*hintOperander{
{Name: "a.low", Kind: fpRelative, Value: feltUint64(0)},
{Name: "a.high", Kind: fpRelative, Value: felt127},
{Name: "a.high", Kind: fpRelative, Value: &utils.Felt127},
},
makeHinter: func(ctx *hintTestContext) hinter.Hinter {
return newUint256SignedNNHint(ctx.operanders["a.low"])
Expand Down Expand Up @@ -240,9 +235,9 @@ func TestZeroHintUint256(t *testing.T) {
},
{
operanders: []*hintOperander{
{Name: "a.low", Kind: fpRelative, Value: felt127},
{Name: "a.low", Kind: fpRelative, Value: &utils.Felt127},
{Name: "a.high", Kind: fpRelative, Value: feltUint64(0)},
{Name: "div.low", Kind: fpRelative, Value: felt127},
{Name: "div.low", Kind: fpRelative, Value: &utils.Felt127},
{Name: "div.high", Kind: fpRelative, Value: feltUint64(0)},
{Name: "quotient.low", Kind: uninitialized},
{Name: "quotient.high", Kind: uninitialized},
Expand All @@ -262,9 +257,9 @@ func TestZeroHintUint256(t *testing.T) {
{
operanders: []*hintOperander{
{Name: "a.low", Kind: fpRelative, Value: feltUint64(5)},
{Name: "a.high", Kind: fpRelative, Value: felt127},
{Name: "a.high", Kind: fpRelative, Value: &utils.Felt127},
{Name: "div.low", Kind: fpRelative, Value: feltUint64(0)},
{Name: "div.high", Kind: fpRelative, Value: felt127},
{Name: "div.high", Kind: fpRelative, Value: &utils.Felt127},
{Name: "quotient.low", Kind: uninitialized},
{Name: "quotient.high", Kind: uninitialized},
{Name: "remainder.low", Kind: uninitialized},
Expand Down
4 changes: 4 additions & 0 deletions pkg/utils/constant.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ var FeltOne = fp.Element{
18446744073709551585, 18446744073709551615, 18446744073709551615, 576460752303422960,
}

// 1 << 127
// same as 2 ** 127
var Felt127 = fp.Element{18446744073704816641, 8703, 18446744073709551600, 576460752222928912}

// 1 << 128
// same as 2 ** 128
var FeltMax128 = fp.Element{18446744073700081665, 17407, 18446744073709551584, 576460752142434320}
Expand Down

0 comments on commit 6b6ec59

Please sign in to comment.