diff --git a/pkg/hintrunner/zero/zerohint_blake.go b/pkg/hintrunner/zero/zerohint_blake.go index aa7b0c8d..362a60af 100644 --- a/pkg/hintrunner/zero/zerohint_blake.go +++ b/pkg/hintrunner/zero/zerohint_blake.go @@ -1,14 +1,24 @@ package zero import ( + "math" + "math/big" + "github.com/NethermindEth/cairo-vm-go/pkg/hintrunner/hinter" VM "github.com/NethermindEth/cairo-vm-go/pkg/vm" mem "github.com/NethermindEth/cairo-vm-go/pkg/vm/memory" "github.com/consensys/gnark-crypto/ecc/stark-curve/fp" - "math" - "math/big" ) +// Blake2sAddUint256 hint serializes a `uint256` number in a Blake2s compatible way +// +// `newBlake2sAddUint256Hint` takes 3 operanders as arguments +// `low` and `high` are the low and high parts of a `uint256` variable, +// each of them being a `felt` interpreted as a `uint128` +// `data` is a pointer to the starting address in memory where to write the result of the hint +// +// `newBlake2sAddUint256Hint` splits each part of the `uint256` in 4 `u32` and writes the result in memory +// This hint is available in Big-Endian or Little-Endian representation func newBlake2sAddUint256Hint(low, high, data hinter.ResOperander, bigend bool) hinter.Hinter { name := "Blake2sAddUint256" if bigend { @@ -92,10 +102,12 @@ func createBlake2sAddUint256Hinter(resolver hintReferenceResolver, bigend bool) if err != nil { return nil, err } + high, err := resolver.GetResOperander("high") if err != nil { return nil, err } + data, err := resolver.GetResOperander("data") if err != nil { return nil, err diff --git a/pkg/hintrunner/zero/zerohint_ec.go b/pkg/hintrunner/zero/zerohint_ec.go index d0c66f8d..69a529f4 100644 --- a/pkg/hintrunner/zero/zerohint_ec.go +++ b/pkg/hintrunner/zero/zerohint_ec.go @@ -11,6 +11,12 @@ import ( "github.com/consensys/gnark-crypto/ecc/stark-curve/fp" ) +// EcNegate hint negates the y-coordinate of a point on an elliptic curve modulo SECP_P +// +// `newEcNegateHint` takes 1 operander as argument +// `point` is the point on an elliptic curve to operate on +// +// `newEcNegateHint` assigns the result as `value` in the current scope func newEcNegateHint(point hinter.ResOperander) hinter.Hinter { return &GenericZeroHinter{ Name: "EcNegate", @@ -57,7 +63,7 @@ func newEcNegateHint(point hinter.ResOperander) hinter.Hinter { yBig.Neg(&yBig) yBig.Mod(&yBig, &secPBig) - return ctx.ScopeManager.AssignVariables(map[string]any{"value": &yBig, "SECP_P": &secPBig}) + return ctx.ScopeManager.AssignVariables(map[string]any{"value": &yBig}) }, } } @@ -71,6 +77,12 @@ func createEcNegateHinter(resolver hintReferenceResolver) (hinter.Hinter, error) return newEcNegateHint(point), nil } +// NondetBigint3V1 hint writes a value to a specified segment of memory +// +// `newNondetBigint3V1Hint` takes 1 operander as argument +// `res` is the location in memory where to write the result +// +// `newNondetBigint3V1Hint` uses `SecPSplit` to split the value in 3 felts and writes the result in memory func newNondetBigint3V1Hint(res hinter.ResOperander) hinter.Hinter { return &GenericZeroHinter{ Name: "NondetBigint3V1", @@ -124,6 +136,13 @@ func createNondetBigint3V1Hinter(resolver hintReferenceResolver) (hinter.Hinter, return newNondetBigint3V1Hint(res), nil } +// FastEcAddAssignNewY hint computes a new y-coordinate for fast elliptic curve addition +// +// `newFastEcAddAssignNewYHint` doesn't take any operander as argument +// This hint follows the execution of `FastEcAddAssignNewX` hint when computing the addition of two given points +// This is why all variables are already accessible in the current scope +// +// `newFastEcAddAssignNewYHint` assigns the new y-coordinate as `value` in the current scope func newFastEcAddAssignNewYHint() hinter.Hinter { return &GenericZeroHinter{ Name: "FastEcAddAssignNewY", @@ -160,7 +179,7 @@ func newFastEcAddAssignNewYHint() hinter.Hinter { valueBig := new(big.Int) valueBig.Set(new_yBig) - return ctx.ScopeManager.AssignVariables(map[string]any{"new_y": new_yBig, "value": valueBig}) + return ctx.ScopeManager.AssignVariables(map[string]any{"value": valueBig}) }, } } @@ -169,6 +188,15 @@ func createFastEcAddAssignNewYHinter() (hinter.Hinter, error) { return newFastEcAddAssignNewYHint(), nil } +// FastEcAddAssignNewX hint computes a new x-coordinate for fast elliptic curve addition +// +// `newFastEcAddAssignNewXHint` takes 3 operanders as arguments +// `slope` is the slope of the line connecting `point0` and `point1` +// `point0` and `point1` are 2 points on an elliptic curve +// +// `newFastEcAddAssignNewXHint` assigns the new x-coordinate as `value` in the current scope +// It also assigns `slope`, `x0`, `y0` and `new_x` in the current scope +// so that they are available in the current scope for FastEcAddAssignNewY hint func newFastEcAddAssignNewXHint(slope, point0, point1 hinter.ResOperander) hinter.Hinter { return &GenericZeroHinter{ Name: "FastEcAddAssignNewX", @@ -285,7 +313,7 @@ func newFastEcAddAssignNewXHint(slope, point0, point1 hinter.ResOperander) hinte valueBig := new(big.Int) valueBig.Set(new_xBig) - return ctx.ScopeManager.AssignVariables(map[string]any{"slope": &slopeBig, "x0": &x0Big, "x1": &x1Big, "y0": &y0Big, "new_x": new_xBig, "value": valueBig}) + return ctx.ScopeManager.AssignVariables(map[string]any{"slope": &slopeBig, "x0": &x0Big, "y0": &y0Big, "new_x": new_xBig, "value": valueBig}) }, } } @@ -307,6 +335,12 @@ func createFastEcAddAssignNewXHinter(resolver hintReferenceResolver) (hinter.Hin return newFastEcAddAssignNewXHint(slope, point0, point1), nil } +// EcDoubleSlopeV1 hint computes the slope for doubling a point on an elliptic curve +// +// `newEcDoubleSlopeV1Hint` takes 1 operander as argument +// `point` is the point on an elliptic curve to operate on +// +// `newEcDoubleSlopeV1Hint` assigns the `slope` result as `value` in the current scope func newEcDoubleSlopeV1Hint(point hinter.ResOperander) hinter.Hinter { return &GenericZeroHinter{ Name: "EcDoubleSlopeV1", @@ -371,9 +405,7 @@ func newEcDoubleSlopeV1Hint(point hinter.ResOperander) hinter.Hinter { return err } - slopeBig := new(big.Int).Set(&valueBig) - - return ctx.ScopeManager.AssignVariables(map[string]any{"x": &xBig, "y": &yBig, "value": &valueBig, "slope": slopeBig}) + return ctx.ScopeManager.AssignVariables(map[string]any{"value": &valueBig}) }, } } @@ -387,6 +419,15 @@ func createEcDoubleSlopeV1Hinter(resolver hintReferenceResolver) (hinter.Hinter, return newEcDoubleSlopeV1Hint(point), nil } +// EcDoubleAssignNewXV1 hint computes a new x-coordinate for a point being doubled on an elliptic curve +// +// `newEcDoubleAssignNewXV1Hint` takes 2 operanders as arguments +// `slope` is the slope for doubling a point, computed with EcDoubleSlopeV1 hint +// `point` is the point on an elliptic curve to operate on +// +// `newEcDoubleAssignNewXV1Hint` assigns the `new_x` result as `value` in the current scope +// It also assigns `slope`, `x`, `y` and `new_x` in the current scope +// so that they are available in the current scope for EcDoubleAssignNewYV1 hint func newEcDoubleAssignNewXV1Hint(slope, point hinter.ResOperander) hinter.Hinter { return &GenericZeroHinter{ Name: "EcDoubleAssignNewXV1", @@ -497,6 +538,13 @@ func createEcDoubleAssignNewXV1Hinter(resolver hintReferenceResolver) (hinter.Hi return newEcDoubleAssignNewXV1Hint(slope, point), nil } +// ComputeSlopeV1Hint hint computes the slope between two points on an elliptic curve +// +// `newComputeSlopeV1Hint` takes 2 operanders as arguments +// `point0` is the first point on an elliptic curve to operate on +// `point1` is the second point on an elliptic curve to operate on +// +// `newComputeSlopeV1Hint` assigns the `slope` result as `value` in the current scope func newComputeSlopeV1Hint(point0, point1 hinter.ResOperander) hinter.Hinter { return &GenericZeroHinter{ Name: "ComputeSlopeV1", @@ -603,7 +651,7 @@ func newComputeSlopeV1Hint(point0, point1 hinter.ResOperander) hinter.Hinter { value := new(big.Int).Set(&slopeBig) - return ctx.ScopeManager.AssignVariables(map[string]any{"value": value, "slope": value}) + return ctx.ScopeManager.AssignVariables(map[string]any{"value": value}) }, } } diff --git a/pkg/hintrunner/zero/zerohint_ec_test.go b/pkg/hintrunner/zero/zerohint_ec_test.go index 5a7b1c5c..2fa60bc5 100644 --- a/pkg/hintrunner/zero/zerohint_ec_test.go +++ b/pkg/hintrunner/zero/zerohint_ec_test.go @@ -364,7 +364,6 @@ func TestZeroHintEc(t *testing.T) { return newFastEcAddAssignNewYHint() }, check: allVarValueInScopeEquals(map[string]any{ - "new_y": big.NewInt(990), "value": big.NewInt(990), }), }, @@ -386,7 +385,6 @@ func TestZeroHintEc(t *testing.T) { return newFastEcAddAssignNewYHint() }, check: allVarValueInScopeEquals(map[string]any{ - "new_y": bigIntString("115792089237316195423570985008687907853269984665640564039457584007908834671653", 10), "value": bigIntString("115792089237316195423570985008687907853269984665640564039457584007908834671653", 10), }), }, @@ -409,7 +407,6 @@ func TestZeroHintEc(t *testing.T) { return newFastEcAddAssignNewYHint() }, check: allVarValueInScopeEquals(map[string]any{ - "new_y": big.NewInt(0), "value": big.NewInt(0), }), }, @@ -440,7 +437,6 @@ func TestZeroHintEc(t *testing.T) { check: allVarValueInScopeEquals(map[string]any{ "slope": bigIntString("99065496658741969395000079476826955370154683653966841736214499259699304892273", 10), "x0": bigIntString("3799719333936312867907730225219317480871818784521830610814991", 10), - "x1": bigIntString("1283798249446970358602040710287144628881017552091260500619997", 10), "y0": bigIntString("5395443952678709065478416501711989224759665054189740766553850", 10), "value": bigIntString("53863685200989733811273896838983614723181733288322685009664997422229669431265", 10), "new_x": bigIntString("53863685200989733811273896838983614723181733288322685009664997422229669431265", 10), @@ -470,7 +466,6 @@ func TestZeroHintEc(t *testing.T) { check: allVarValueInScopeEquals(map[string]any{ "slope": bigIntString("0", 10), "x0": bigIntString("0", 10), - "x1": bigIntString("0", 10), "y0": bigIntString("0", 10), "value": bigIntString("0", 10), "new_x": bigIntString("0", 10), @@ -501,7 +496,6 @@ func TestZeroHintEc(t *testing.T) { check: allVarValueInScopeEquals(map[string]any{ "slope": bigIntString("-20441714640463444415550039378657358828977094550744864608392924301285287608509921726516187492362679433566942659569", 10), "x0": bigIntString("-20441714640463444415550039378657358828977094550744864608392924301285287608509921726516187492362679433566942659569", 10), - "x1": bigIntString("-20441714640463444415550039378657358828977094550744864608392924301285287608509921726516187492362679433566942659569", 10), "y0": bigIntString("-20441714640463444415550039378657358828977094550744864608392924301285287608509921726516187492362679433566942659569", 10), "value": bigIntString("30230181511926491618309110200401529297651013854327841200453332701540948849717", 10), "new_x": bigIntString("30230181511926491618309110200401529297651013854327841200453332701540948849717", 10), @@ -537,10 +531,7 @@ func TestZeroHintEc(t *testing.T) { return newEcDoubleSlopeV1Hint(ctx.operanders["point.x.d0"]) }, check: allVarValueInScopeEquals(map[string]any{ - "x": bigIntString("27324902462242089002202715756360945650502697953428275540292323343", 10), - "y": bigIntString("7911836854973739773537612350570845963794165335703809150610926758199350552314", 10), "value": bigIntString("8532480558268366897328020348259450788170980412191993744326748439943456131995", 10), - "slope": bigIntString("8532480558268366897328020348259450788170980412191993744326748439943456131995", 10), }), }, { @@ -558,10 +549,7 @@ func TestZeroHintEc(t *testing.T) { return newEcDoubleSlopeV1Hint(ctx.operanders["point.x.d0"]) }, check: allVarValueInScopeEquals(map[string]any{ - "x": bigIntString("7237005577332262213973186656579099030007160806638365755234031873103428059136", 10), - "y": bigIntString("6582018229284824168619876815299993750165559328377972410848116736", 10), "value": bigIntString("154266052248863066452028362858593603519505739480817180031844352", 10), - "slope": bigIntString("154266052248863066452028362858593603519505739480817180031844352", 10), }), }, { @@ -577,10 +565,7 @@ func TestZeroHintEc(t *testing.T) { return newEcDoubleSlopeV1Hint(ctx.operanders["point.x.d0"]) }, check: allVarValueInScopeEquals(map[string]any{ - "x": bigIntString("11972621413014756705924586226983042952357666573254656", 10), - "y": bigIntString("29931553532536891764811465683514486063898567204929539", 10), "value": bigIntString("35023503208535022533116513151423452638642669107476233313413226008091253006355", 10), - "slope": bigIntString("35023503208535022533116513151423452638642669107476233313413226008091253006355", 10), }), }, }, @@ -699,7 +684,6 @@ func TestZeroHintEc(t *testing.T) { 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), }), },