Skip to content

Commit

Permalink
Add double assign hint (#287)
Browse files Browse the repository at this point in the history
* Add ec hints

* Implement hints

* Add the hints to the processor

* Test pack86 function

* Test hint

* Delete debug info, Test ec negative op

* Second hint test

* Test embedded hint

* Change to Camel case

* Implement slope hints

* Fix format

* Delete github conflict string

* Tests hints

* Tests hints slopes

* Rename misleading name function

* Fix function name

* Fix error in function call

* Delete debug info

* Delete unused import

* Secp hints

* Secpr21

* Add it to the hint processor

* Hints secp

* bigint3 nondet

* Zero verify

* Merge main

* Add hint to hint processor

* Add double assign hint

* Debug info

* Remove integration test

* Prints

* Add unit tests

* Test verify with unit test

* Debug unit test

* Test verify zero with debug

* Non det big 3 test

* Modify test to use ids manager

* debug info

* Fix broken test

* Move file from hints_utils and rename

* Delete debug

* Move integration test to cairo_run_test.go

* Return error of IdsData.Insert

* Change to camel case

* Add Integration test

---------

Co-authored-by: Milton <[email protected]>
Co-authored-by: mmsc2 <[email protected]>
Co-authored-by: Mariano A. Nicolini <[email protected]>
Co-authored-by: juan.mv <[email protected]>
Co-authored-by: Pedro Fontana <[email protected]>
  • Loading branch information
6 people authored Sep 29, 2023
1 parent 6d9bbf0 commit 51db1d4
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 2 deletions.
1 change: 1 addition & 0 deletions cairo_programs/cairo_keccak.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ func main{range_check_ptr: felt, bitwise_ptr: BitwiseBuiltin*}() {

return ();
}

32 changes: 32 additions & 0 deletions cairo_programs/ec_double_assign.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
%builtins range_check
from starkware.cairo.common.cairo_secp.bigint import BigInt3, nondet_bigint3
struct EcPoint {
x: BigInt3,
y: BigInt3,
}

func ec_double{range_check_ptr}(point: EcPoint, slope: BigInt3) -> (res: BigInt3) {
%{
from starkware.cairo.common.cairo_secp.secp_utils import pack
SECP_P = 2**255-19
slope = pack(ids.slope, PRIME)
x = pack(ids.point.x, PRIME)
y = pack(ids.point.y, PRIME)
value = new_x = (pow(slope, 2, SECP_P) - 2 * x) % SECP_P
%}

let (new_x: BigInt3) = nondet_bigint3();
return (res=new_x);
}

func main{range_check_ptr}() {
let p = EcPoint(BigInt3(1,2,3), BigInt3(4,5,6));
let s = BigInt3(7,8,9);
let (res) = ec_double(p, s);
assert res.d0 = 21935;
assert res.d1 = 12420;
assert res.d2 = 184;
return ();
}
43 changes: 43 additions & 0 deletions pkg/hints/ec_hint.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/lambdaclass/cairo-vm.go/pkg/builtins"
"github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_utils"
. "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_utils"
. "github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks"
"github.com/lambdaclass/cairo-vm.go/pkg/types"
. "github.com/lambdaclass/cairo-vm.go/pkg/types"
"github.com/lambdaclass/cairo-vm.go/pkg/vm"
Expand Down Expand Up @@ -184,6 +185,48 @@ func computeSlope(vm *VirtualMachine, execScopes ExecutionScopes, idsData IdsMan
return nil
}

// Implements hint:
// from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack
//
// slope = pack(ids.slope, PRIME)
// x = pack(ids.point.x, PRIME)
// y = pack(ids.point.y, PRIME)
//
// value = new_x = (pow(slope, 2, SECP_P) - 2 * x) % SECP_P
func ecDoubleAssignNewX(vm *VirtualMachine, execScopes ExecutionScopes, ids IdsManager, secpP big.Int) error {
execScopes.AssignOrUpdateVariable("SECP_P", secpP)

slope3, err := BigInt3FromVarName("slope", ids, vm)
if err != nil {
return err
}
packedSlope := slope3.Pack86()
slope := new(big.Int).Mod(&packedSlope, Prime())
point, err := EcPointFromVarName("point", vm, ids)
if err != nil {
return err
}

xPacked := point.X.Pack86()
x := new(big.Int).Mod(&xPacked, Prime())
yPacked := point.Y.Pack86()
y := new(big.Int).Mod(&yPacked, Prime())

value := new(big.Int).Mul(slope, slope)
value = value.Mod(value, &secpP)

value = value.Sub(value, x)
value = value.Sub(value, x)
value = value.Mod(value, &secpP)

execScopes.AssignOrUpdateVariable("slope", slope)
execScopes.AssignOrUpdateVariable("x", x)
execScopes.AssignOrUpdateVariable("y", y)
execScopes.AssignOrUpdateVariable("value", *value)
execScopes.AssignOrUpdateVariable("new_x", *value)
return nil
}

/*
Implements hint:
%{ from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_ALPHA as ALPHA %}
Expand Down
69 changes: 69 additions & 0 deletions pkg/hints/ec_hint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,75 @@ func TestRunComputeSlopeOk(t *testing.T) {
}
}

func TestEcDoubleAssignNewXOk(t *testing.T) {
vm := NewVirtualMachine()
vm.Segments.AddSegment()
idsManager := SetupIdsForTest(
map[string][]*MaybeRelocatable{
"slope": {
NewMaybeRelocatableFelt(FeltFromUint64(3)),
NewMaybeRelocatableFelt(FeltFromUint64(0)),
NewMaybeRelocatableFelt(FeltFromUint64(0)),
},
"point": {
// X
NewMaybeRelocatableFelt(FeltFromUint64(2)),
NewMaybeRelocatableFelt(FeltFromUint64(0)),
NewMaybeRelocatableFelt(FeltFromUint64(0)),
// Y
NewMaybeRelocatableFelt(FeltFromUint64(4)),
NewMaybeRelocatableFelt(FeltFromUint64(0)),
NewMaybeRelocatableFelt(FeltFromUint64(0)),
},
},
vm,
)

hintProcessor := CairoVmHintProcessor{}
hintData := any(HintData{
Ids: idsManager,
Code: EC_DOUBLE_ASSIGN_NEW_X_V1,
})

execScopes := types.NewExecutionScopes()
err := hintProcessor.ExecuteHint(vm, &hintData, nil, execScopes)

if err != nil {
t.Errorf("EC_DOUBLE_ASSIGN_NEW_X hint failed with error: %s", err)
}

slopeUncast, _ := execScopes.Get("slope")
slope := slopeUncast.(*big.Int)
xUncast, _ := execScopes.Get("x")
x := xUncast.(*big.Int)
yUncast, _ := execScopes.Get("y")
y := yUncast.(*big.Int)
valueUncast, _ := execScopes.Get("value")
value := valueUncast.(big.Int)
new_xUncast, _ := execScopes.Get("new_x")
new_x := new_xUncast.(big.Int)

if value.Cmp(&new_x) != 0 {
t.Errorf("EC_DOUBLE_ASSIGN_NEW_X hint failed: new_x != value. %v != %v", new_x, value)
}
expectedRes := big.NewInt(5)
if value.Cmp(expectedRes) != 0 {
t.Errorf("EC_DOUBLE_ASSIGN_NEW_X hint failed: expected value (%v) to be 6", value)
}
expectedSlope := big.NewInt(3)
if slope.Cmp(expectedSlope) != 0 {
t.Errorf("EC_DOUBLE_ASSIGN_NEW_X hint failed: expected slope (%v) to be 3", slope)
}
expectedX := big.NewInt(2)
if x.Cmp(expectedX) != 0 {
t.Errorf("EC_DOUBLE_ASSIGN_NEW_X hint failed: expected x (%v) to be 2", x)
}
expectedY := big.NewInt(4)
if y.Cmp(expectedY) != 0 {
t.Errorf("EC_DOUBLE_ASSIGN_NEW_X hint failed: expected y (%v) to be 4", y)
}
}

func TestRunComputeSlopeV2Ok(t *testing.T) {

vm := NewVirtualMachine()
Expand Down
33 changes: 31 additions & 2 deletions pkg/hints/hint_codes/ec_op_hints.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,39 @@ const EC_NEGATE = "from starkware.cairo.common.cairo_secp.secp_utils import SECP
const EC_NEGATE_EMBEDDED_SECP = "from starkware.cairo.common.cairo_secp.secp_utils import pack\nSECP_P = 2**255-19\n\ny = pack(ids.point.y, PRIME) % SECP_P\n# The modulo operation in python always returns a nonnegative number.\nvalue = (-y) % SECP_P"
const EC_DOUBLE_SLOPE_V1 = "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)"
const COMPUTE_SLOPE_V1 = "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)"
const EC_DOUBLE_SLOPE_EXTERNAL_CONSTS = "from starkware.cairo.common.cairo_secp.secp_utils import 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=ALPHA, p=SECP_P)"
const NONDET_BIGINT3_V1 = "from starkware.cairo.common.cairo_secp.secp_utils import split\n\nsegments.write_arg(ids.res.address_, split(value))"
const EC_DOUBLE_ASSIGN_NEW_X_V1 = `from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack
slope = pack(ids.slope, PRIME)
x = pack(ids.point.x, PRIME)
y = pack(ids.point.y, PRIME)
value = new_x = (pow(slope, 2, SECP_P) - 2 * x) % SECP_P`
const EC_DOUBLE_ASSIGN_NEW_X_V2 = `from starkware.cairo.common.cairo_secp.secp_utils import pack
slope = pack(ids.slope, PRIME)
x = pack(ids.point.x, PRIME)
y = pack(ids.point.y, PRIME)
value = new_x = (pow(slope, 2, SECP_P) - 2 * x) % SECP_P`
const EC_DOUBLE_ASSIGN_NEW_X_V3 = `from starkware.cairo.common.cairo_secp.secp_utils import pack
SECP_P = 2**255-19
slope = pack(ids.slope, PRIME)
x = pack(ids.point.x, PRIME)
y = pack(ids.point.y, PRIME)
value = new_x = (pow(slope, 2, SECP_P) - 2 * x) % SECP_P`
const EC_DOUBLE_ASSIGN_NEW_X_V4 = `from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack
slope = pack(ids.slope, PRIME)
x = pack(ids.pt.x, PRIME)
y = pack(ids.pt.y, PRIME)
value = new_x = (pow(slope, 2, SECP_P) - 2 * x) % SECP_P`
const COMPUTE_SLOPE_V2 = "from starkware.python.math_utils import line_slope\nfrom starkware.cairo.common.cairo_secp.secp_utils import pack\nSECP_P = 2**255-19\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)"
const COMPUTE_SLOPE_WHITELIST = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\nfrom starkware.python.math_utils import div_mod\n\n# Compute the slope.\nx0 = pack(ids.pt0.x, PRIME)\ny0 = pack(ids.pt0.y, PRIME)\nx1 = pack(ids.pt1.x, PRIME)\ny1 = pack(ids.pt1.y, PRIME)\nvalue = slope = div_mod(y0 - y1, x0 - x1, SECP_P)"
const EC_DOUBLE_SLOPE_EXTERNAL_CONSTS = "from starkware.cairo.common.cairo_secp.secp_utils import 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=ALPHA, p=SECP_P)"
const NONDET_BIGINT3_V1 = "from starkware.cairo.common.cairo_secp.secp_utils import split\n\nsegments.write_arg(ids.res.address_, split(value))"
const COMPUTE_SLOPE_SECP256R1 = "from starkware.cairo.common.cairo_secp.secp_utils import 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)"
const FAST_EC_ADD_ASSIGN_NEW_X = `"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack
Expand Down
2 changes: 2 additions & 0 deletions pkg/hints/hint_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any,
return ecNegateImportSecpP(vm, *execScopes, data.Ids)
case EC_NEGATE_EMBEDDED_SECP:
return ecNegateEmbeddedSecpP(vm, *execScopes, data.Ids)
case EC_DOUBLE_ASSIGN_NEW_X_V1, EC_DOUBLE_ASSIGN_NEW_X_V2, EC_DOUBLE_ASSIGN_NEW_X_V3, EC_DOUBLE_ASSIGN_NEW_X_V4:
return ecDoubleAssignNewX(vm, *execScopes, data.Ids, SECP_P_V2())
case POW:
return pow(data.Ids, vm)
case SQRT:
Expand Down
4 changes: 4 additions & 0 deletions pkg/vm/cairo_run/cairo_run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,10 @@ func TestSplitIntHintProofMode(t *testing.T) {
testProgramProof("split_int", t)
}

func TestEcDoubleAssign(t *testing.T) {
testProgram("ec_double_assign", t)
}

func TestIntegrationEcDoubleSlope(t *testing.T) {
testProgram("ec_double_slope", t)
}
Expand Down

0 comments on commit 51db1d4

Please sign in to comment.