Skip to content

Commit

Permalink
Implement cairo0 compute slope V1 hint (#377)
Browse files Browse the repository at this point in the history
* Implement cairo0 compute slope V1 hint

* corrected a comment

* style

* added link to LineSlope method

* changed the logic for the LineSlope function
  • Loading branch information
Tomi-3-0 committed May 3, 2024
1 parent 0bb268f commit 122eb02
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 0 deletions.
18 changes: 18 additions & 0 deletions pkg/hintrunner/utils/math_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,24 @@ func EcDoubleSlope(pointX, pointY, alpha, prime *big.Int) (big.Int, error) {
return Divmod(n, m, prime)
}

func LineSlope(point_aX, point_aY, point_bX, point_bY, prime *big.Int) (big.Int, error) {
// https://github.com/starkware-libs/cairo-lang/blob/efa9648f57568aad8f8a13fbf027d2de7c63c2c0/src/starkware/python/math_utils.py#L130

modValue := new(big.Int).Mod(new(big.Int).Sub(point_aX, point_bX), prime)

if modValue.Cmp(big.NewInt(0)) == 0 {
return *big.NewInt(0), errors.New("the slope of the line is invalid")
}

// Compute the difference of y-coordinates
n := new(big.Int).Sub(point_aY, point_bY)

// Compute the difference of x-coordinates
m := new(big.Int).Sub(point_aX, point_bX)

return Divmod(n, m, prime)
}

func AsInt(valueFelt *fp.Element) big.Int {
// https://github.com/starkware-libs/cairo-lang/blob/efa9648f57568aad8f8a13fbf027d2de7c63c2c0/src/starkware/cairo/common/math_utils.py#L8

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 @@ -66,6 +66,7 @@ const (
fastEcAddAssignNewYCode string = "value = new_y = (slope * (x0 - new_x) - y0) % SECP_P"
fastEcAddAssignNewXCode string = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\n\nslope = pack(ids.slope, PRIME)\nx0 = pack(ids.point0.x, PRIME)\nx1 = pack(ids.point1.x, PRIME)\ny0 = pack(ids.point0.y, PRIME)\n\nvalue = new_x = (pow(slope, 2, SECP_P) - x0 - x1) % SECP_P"
ecDoubleSlopeV1Code string = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\nfrom starkware.python.math_utils import ec_double_slope\n\n# Compute the slope.\nx = pack(ids.point.x, PRIME)\ny = pack(ids.point.y, PRIME)\nvalue = slope = ec_double_slope(point=(x, y), alpha=0, p=SECP_P)"
computeSlopeV1Code string = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\nfrom starkware.python.math_utils import line_slope\n\n# Compute the slope.\nx0 = pack(ids.point0.x, PRIME)\ny0 = pack(ids.point0.y, PRIME)\nx1 = pack(ids.point1.x, PRIME)\ny1 = pack(ids.point1.y, PRIME)\nvalue = slope = line_slope(point1=(x0, y0), point2=(x1, y1), p=SECP_P)"
ecDoubleAssignNewXV1 string = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\n\nslope = pack(ids.slope, PRIME)\nx = pack(ids.point.x, PRIME)\ny = pack(ids.point.y, PRIME)\n\nvalue = new_x = (pow(slope, 2, SECP_P) - 2 * x) % SECP_P"

// ------ Signature hints related code ------
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 @@ -131,6 +131,8 @@ func GetHintFromCode(program *zero.ZeroProgram, rawHint zero.Hint, hintPC uint64
return createFastEcAddAssignNewXHinter(resolver)
case ecDoubleSlopeV1Code:
return createEcDoubleSlopeV1Hinter(resolver)
case computeSlopeV1Code:
return createComputeSlopeV1Hinter(resolver)
case ecDoubleAssignNewXV1:
return createEcDoubleAssignNewXV1Hinter(resolver)
// Blake hints
Expand Down
125 changes: 125 additions & 0 deletions pkg/hintrunner/zero/zerohint_ec.go
Original file line number Diff line number Diff line change
Expand Up @@ -496,3 +496,128 @@ func createEcDoubleAssignNewXV1Hinter(resolver hintReferenceResolver) (hinter.Hi

return newEcDoubleAssignNewXV1Hint(slope, point), nil
}

func newComputeSlopeV1Hint(point0, point1 hinter.ResOperander) hinter.Hinter {
return &GenericZeroHinter{
Name: "ComputeSlopeV1",
Op: func(vm *VM.VirtualMachine, ctx *hinter.HintRunnerContext) error {
//> from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack
//> from starkware.python.math_utils import line_slope

//> # Compute the slope.
//> x0 = pack(ids.point0.x, PRIME)
//> y0 = pack(ids.point0.y, PRIME)
//> x1 = pack(ids.point1.x, PRIME)
//> y1 = pack(ids.point1.y, PRIME)
//> value = slope = line_slope(point1=(x0, y0), point2=(x1, y1), p=SECP_P)

point0Addr, err := point0.GetAddress(vm)
if err != nil {
return err
}
point0MemoryValues, err := hinter.GetConsecutiveValues(vm, point0Addr, int16(6))
if err != nil {
return err
}

point1Addr, err := point1.GetAddress(vm)
if err != nil {
return err
}
point1MemoryValues, err := hinter.GetConsecutiveValues(vm, point1Addr, int16(6))
if err != nil {
return err
}

// [x.d0, x.d1, x.d2]
var point0XValues [3]*fp.Element
// [y.d0, y.d1, y.d2]
var point0YValues [3]*fp.Element
// [x.d0, x.d1, x.d2]
var point1XValues [3]*fp.Element
// [y.d0, y.d1, y.d2]
var point1YValues [3]*fp.Element

for i := 0; i < 3; i++ {
point0XValue, err := point0MemoryValues[i].FieldElement()
if err != nil {
return err
}
point0XValues[i] = point0XValue

point1XValue, err := point1MemoryValues[i].FieldElement()
if err != nil {
return err
}
point1XValues[i] = point1XValue
}

for i := 3; i < 6; i++ {
point0YValue, err := point0MemoryValues[i].FieldElement()
if err != nil {
return err
}
point0YValues[i-3] = point0YValue

point1YValue, err := point1MemoryValues[i].FieldElement()
if err != nil {
return err
}
point1YValues[i-3] = point1YValue
}

//> x0 = pack(ids.point0.x, PRIME)
x0Big, err := secp_utils.SecPPacked(point0XValues)
if err != nil {
return err
}

//> x1 = pack(ids.point1.x, PRIME)
x1Big, err := secp_utils.SecPPacked(point1XValues)
if err != nil {
return err
}

//> y0 = pack(ids.point0.y, PRIME)
y0Big, err := secp_utils.SecPPacked(point0YValues)
if err != nil {
return err
}

//> y1 = pack(ids.point0.y, PRIME)
y1Big, err := secp_utils.SecPPacked(point1YValues)
if err != nil {
return err
}

secPBig, ok := secp_utils.GetSecPBig()
if !ok {
return fmt.Errorf("GetSecPBig failed")
}

// value = slope = line_slope(point1=(x0, y0), point2=(x1, y1), p=SECP_P)
slopeBig, err := secp_utils.LineSlope(&x0Big, &y0Big, &x1Big, &y1Big, &secPBig)
if err != nil {
return err
}

value := new(big.Int).Set(&slopeBig)

return ctx.ScopeManager.AssignVariables(map[string]any{"value": value, "slope": value})
},
}
}

func createComputeSlopeV1Hinter(resolver hintReferenceResolver) (hinter.Hinter, error) {
point0, err := resolver.GetResOperander("point0")
if err != nil {
return nil, err
}

point1, err := resolver.GetResOperander("point1")
if err != nil {
return nil, err
}

return newComputeSlopeV1Hint(point0, point1), nil
}
53 changes: 53 additions & 0 deletions pkg/hintrunner/zero/zerohint_ec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -675,5 +675,58 @@ func TestZeroHintEc(t *testing.T) {
}),
},
},
"ComputeSlopeV1": {
{
operanders: []*hintOperander{
{Name: "point0.x.d0", Kind: apRelative, Value: &utils.FeltZero},
{Name: "point0.x.d1", Kind: apRelative, Value: &utils.FeltZero},
{Name: "point0.x.d2", Kind: apRelative, Value: &utils.FeltZero},
{Name: "point0.y.d0", Kind: apRelative, Value: &utils.FeltZero},
{Name: "point0.y.d1", Kind: apRelative, Value: &utils.FeltZero},
{Name: "point0.y.d2", Kind: apRelative, Value: &utils.FeltZero},
{Name: "point1.x.d0", Kind: apRelative, Value: &utils.FeltZero},
{Name: "point1.x.d1", Kind: apRelative, Value: &utils.FeltZero},
{Name: "point1.x.d2", Kind: apRelative, Value: &utils.FeltZero},
{Name: "point1.y.d0", Kind: apRelative, Value: &utils.FeltZero},
{Name: "point1.y.d1", Kind: apRelative, Value: &utils.FeltZero},
{Name: "point1.y.d2", Kind: apRelative, Value: &utils.FeltZero},
},
ctxInit: func(ctx *hinter.HintRunnerContext) {
ctx.ScopeManager.EnterScope(map[string]any{})
},
makeHinter: func(ctx *hintTestContext) hinter.Hinter {
return newComputeSlopeV1Hint(ctx.operanders["point0.x.d0"], ctx.operanders["point1.x.d0"])
},
errCheck: errorTextContains("the slope of the line is invalid"),
},
{
operanders: []*hintOperander{
// random values
{Name: "point0.x.d0", Kind: apRelative, Value: feltInt64(134)},
{Name: "point0.x.d1", Kind: apRelative, Value: feltInt64(5123)},
{Name: "point0.x.d2", Kind: apRelative, Value: feltInt64(140)},
{Name: "point0.y.d0", Kind: apRelative, Value: feltInt64(1232)},
{Name: "point0.y.d1", Kind: apRelative, Value: feltInt64(4652)},
{Name: "point0.y.d2", Kind: apRelative, Value: feltInt64(720)},
{Name: "point1.x.d0", Kind: apRelative, Value: feltInt64(156)},
{Name: "point1.x.d1", Kind: apRelative, Value: feltInt64(6545)},
{Name: "point1.x.d2", Kind: apRelative, Value: feltInt64(100010)},
{Name: "point1.y.d0", Kind: apRelative, Value: feltInt64(1123)},
{Name: "point1.y.d1", Kind: apRelative, Value: feltInt64(1325)},
{Name: "point1.y.d2", Kind: apRelative, Value: feltInt64(910)},
},
ctxInit: func(ctx *hinter.HintRunnerContext) {
ctx.ScopeManager.EnterScope(map[string]any{})
},
makeHinter: func(ctx *hintTestContext) hinter.Hinter {

return newComputeSlopeV1Hint(ctx.operanders["point0.x.d0"], ctx.operanders["point1.x.d0"])
},
check: allVarValueInScopeEquals(map[string]any{
"slope": bigIntString("41419765295989780131385135514529906223027172305400087935755859001910844026631", 10),
"value": bigIntString("41419765295989780131385135514529906223027172305400087935755859001910844026631", 10),
}),
},
},
})
}

0 comments on commit 122eb02

Please sign in to comment.