Skip to content

Commit

Permalink
Merge main
Browse files Browse the repository at this point in the history
  • Loading branch information
har777 committed Apr 19, 2024
2 parents 721c3bd + 7d292fa commit 2f44135
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 0 deletions.
11 changes: 11 additions & 0 deletions pkg/hintrunner/utils/math_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package utils

import (
"errors"
"fmt"
"math/big"

"github.com/consensys/gnark-crypto/ecc/stark-curve/fp"
Expand Down Expand Up @@ -107,3 +108,13 @@ func sign(n *big.Int) (int, big.Int) {
}
return 1, *new(big.Int).Set(n)
}

func SafeDiv(x, y *big.Int) (big.Int, error) {
if y.Cmp(big.NewInt(0)) == 0 {
return *big.NewInt(0), fmt.Errorf("Division by zero.")
}
if new(big.Int).Mod(x, y).Cmp(big.NewInt(0)) != 0 {
return *big.NewInt(0), fmt.Errorf("%v is not divisible by %v.", x, y)
}
return *new(big.Int).Div(x, y), nil
}
8 changes: 8 additions & 0 deletions pkg/hintrunner/utils/secp_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package utils

import (
"fmt"

"math/big"

"github.com/consensys/gnark-crypto/ecc/stark-curve/fp"
Expand Down Expand Up @@ -42,6 +43,13 @@ func GetBetaBig() big.Int {
return *big.NewInt(7)
}

func GetNBig() big.Int {
// https://github.com/starkware-libs/cairo-lang/blob/efa9648f57568aad8f8a13fbf027d2de7c63c2c0/src/starkware/cairo/common/cairo_secp/secp_utils.py#L9

NBig, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16)
return *NBig
}

func SecPSplit(num *big.Int) ([]big.Int, error) {
// https://github.com/starkware-libs/cairo-lang/blob/efa9648f57568aad8f8a13fbf027d2de7c63c2c0/src/starkware/cairo/common/cairo_secp/secp_utils.py#L14

Expand Down
1 change: 1 addition & 0 deletions pkg/hintrunner/zero/hintcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ const (
// ------ Signature hints related code ------
verifyECDSASignatureCode string = "ecdsa_builtin.add_signature(ids.ecdsa_ptr.address_, (ids.signature_r, ids.signature_s))"
getPointFromXCode string = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\nx_cube_int = pack(ids.x_cube, PRIME) % SECP_P\ny_square_int = (x_cube_int + ids.BETA) % SECP_P\ny = pow(y_square_int, (SECP_P + 1) // 4, SECP_P)\nif ids.v % 2 == y % 2:\nvalue = y\nelse:\nvalue = (-y) % SECP_P"
divModNSafeDivCode string = "value = k = safe_div(res * b - a, N)"
importSecp256R1PCode string = "from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_P as SECP_P"
verifyZeroCode string = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\n\nq, r = divmod(pack(ids.val, PRIME), SECP_P)\nassert r == 0, f\"verify_zero: Invalid input {ids.val.d0, ids.val.d1, ids.val.d2}.\"\nids.q = q % PRIME"

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 @@ -112,6 +112,8 @@ func GetHintFromCode(program *zero.ZeroProgram, rawHint zero.Hint, hintPC uint64
return createVerifyECDSASignatureHinter(resolver)
case getPointFromXCode:
return createGetPointFromXHinter(resolver)
case divModNSafeDivCode:
return createDivModSafeDivHinter()
case importSecp256R1PCode:
return createImportSecp256R1PHinter()
case verifyZeroCode:
Expand Down
41 changes: 41 additions & 0 deletions pkg/hintrunner/zero/zerohint_signature.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,44 @@ func newImportSecp256R1PHinter() hinter.Hinter {
func createImportSecp256R1PHinter() (hinter.Hinter, error) {
return newImportSecp256R1PHinter(), nil
}

func newDivModSafeDivHinter() hinter.Hinter {
return &GenericZeroHinter{
Name: "DivModSafeDivHinter",
Op: func(vm *VM.VirtualMachine, ctx *hinter.HintRunnerContext) error {
//> value = k = safe_div(res * b - a, N)

res, err := ctx.ScopeManager.GetVariableValueAsBigInt("res")
if err != nil {
return err
}
a, err := ctx.ScopeManager.GetVariableValueAsBigInt("a")
if err != nil {
return err
}
b, err := ctx.ScopeManager.GetVariableValueAsBigInt("b")
if err != nil {
return err
}
N, err := ctx.ScopeManager.GetVariableValueAsBigInt("N")
if err != nil {
return err
}
divisor := new(big.Int).Sub(new(big.Int).Mul(res, b), a)
value, err := secp_utils.SafeDiv(divisor, N)
if err != nil {
return err
}
k := new(big.Int).Set(&value)
err = ctx.ScopeManager.AssignVariable("k", k)
if err != nil {
return err
}
return ctx.ScopeManager.AssignVariable("value", &value)
},
}
}

func createDivModSafeDivHinter() (hinter.Hinter, error) {
return newDivModSafeDivHinter(), nil
}
71 changes: 71 additions & 0 deletions pkg/hintrunner/zero/zerohint_signature_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,5 +128,76 @@ func TestVerifyZeroHint(t *testing.T) {
check: varValueInScopeEquals("SECP_P", bigIntString("115792089210356248762697446949407573530086143415290314195533631308867097853951", 10)),
},
},
"DivModNSafeDivHint": {
{
// zero quotient
operanders: []*hintOperander{},
ctxInit: func(ctx *hinter.HintRunnerContext) {
ctx.ScopeManager.EnterScope(map[string]any{})
err := ctx.ScopeManager.AssignVariables(map[string]any{
"res": bigIntString("0", 10),
"a": bigIntString("0", 10),
"b": bigIntString("0", 10),
"N": bigIntString("1", 10),
})
if err != nil {
t.Fatal(err)
}
},
makeHinter: func(ctx *hintTestContext) hinter.Hinter {
return newDivModSafeDivHinter()
},
check: varListInScopeEquals(map[string]any{
"value": bigIntString("0", 10),
"k": bigIntString("0", 10),
}),
},
{
// negative quotient
operanders: []*hintOperander{},
ctxInit: func(ctx *hinter.HintRunnerContext) {
ctx.ScopeManager.EnterScope(map[string]any{})
err := ctx.ScopeManager.AssignVariables(map[string]any{
"res": bigIntString("1", 10),
"a": bigIntString("2", 10),
"b": bigIntString("1", 10),
"N": bigIntString("1", 10),
})
if err != nil {
t.Fatal(err)
}
},
makeHinter: func(ctx *hintTestContext) hinter.Hinter {
return newDivModSafeDivHinter()
},
check: varListInScopeEquals(map[string]any{
"value": bigIntString("-1", 10),
"k": bigIntString("-1", 10),
}),
},
{
// positive quotient
operanders: []*hintOperander{},
ctxInit: func(ctx *hinter.HintRunnerContext) {
ctx.ScopeManager.EnterScope(map[string]any{})
err := ctx.ScopeManager.AssignVariables(map[string]any{
"res": bigIntString("10", 10),
"a": bigIntString("20", 10),
"b": bigIntString("30", 10),
"N": bigIntString("2", 10),
})
if err != nil {
t.Fatal(err)
}
},
makeHinter: func(ctx *hintTestContext) hinter.Hinter {
return newDivModSafeDivHinter()
},
check: varListInScopeEquals(map[string]any{
"value": bigIntString("140", 10),
"k": bigIntString("140", 10),
}),
},
},
})
}
8 changes: 8 additions & 0 deletions pkg/hintrunner/zero/zerohint_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,11 @@ func errorIsNil(t *testing.T, ctx *hintTestContext, err error) {
t.Fatalf("expected a nil error, got: %v", err)
}
}

func varListInScopeEquals(expectedValues map[string]any) func(t *testing.T, ctx *hintTestContext) {
return func(t *testing.T, ctx *hintTestContext) {
for varName, expected := range expectedValues {
varValueInScopeEquals(varName, expected)(t, ctx)
}
}
}

0 comments on commit 2f44135

Please sign in to comment.