Skip to content

Commit

Permalink
Merge branch 'main' into execution-resources
Browse files Browse the repository at this point in the history
  • Loading branch information
pefontana authored Sep 29, 2023
2 parents 3802a3e + 8c01a73 commit d00239a
Show file tree
Hide file tree
Showing 15 changed files with 1,685 additions and 11 deletions.
894 changes: 885 additions & 9 deletions README.md

Large diffs are not rendered by default.

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 ();
}
1 change: 1 addition & 0 deletions cairo_programs/proof_programs/usort.cairo
22 changes: 22 additions & 0 deletions cairo_programs/usort.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
%builtins range_check
from starkware.cairo.common.usort import usort
from starkware.cairo.common.alloc import alloc

func main{range_check_ptr}() -> () {
alloc_locals;
let (input_array: felt*) = alloc();
assert input_array[0] = 2;
assert input_array[1] = 1;
assert input_array[2] = 0;

let (output_len, output, multiplicities) = usort(input_len=3, input=input_array);

assert output_len = 3;
assert output[0] = 0;
assert output[1] = 1;
assert output[2] = 2;
assert multiplicities[0] = 1;
assert multiplicities[1] = 1;
assert multiplicities[2] = 1;
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
32 changes: 32 additions & 0 deletions pkg/hints/hint_codes/usort_hint_codes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package hint_codes

const USORT_ENTER_SCOPE = "vm_enter_scope(dict(__usort_max_size = globals().get('__usort_max_size')))"

const USORT_BODY = `from collections import defaultdict
input_ptr = ids.input
input_len = int(ids.input_len)
if __usort_max_size is not None:
assert input_len <= __usort_max_size, (
f"usort() can only be used with input_len<={__usort_max_size}. "
f"Got: input_len={input_len}."
)
positions_dict = defaultdict(list)
for i in range(input_len):
val = memory[input_ptr + i]
positions_dict[val].append(i)
output = sorted(positions_dict.keys())
ids.output_len = len(output)
ids.output = segments.gen_arg(output)
ids.multiplicities = segments.gen_arg([len(positions_dict[k]) for k in output])`

const USORT_VERIFY = `last_pos = 0
positions = positions_dict[ids.value][::-1]`

const USORT_VERIFY_MULTIPLICITY_ASSERT = "assert len(positions) == 0"

const USORT_VERIFY_MULTIPLICITY_BODY = `current_pos = positions.pop()
ids.next_item_index = current_pos - last_pos
last_pos = current_pos + 1`
12 changes: 12 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 All @@ -106,6 +108,16 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any,
return memset_step_loop(data.Ids, vm, execScopes, "continue_loop")
case VM_ENTER_SCOPE:
return vm_enter_scope(execScopes)
case USORT_ENTER_SCOPE:
return usortEnterScope(execScopes)
case USORT_BODY:
return usortBody(data.Ids, execScopes, vm)
case USORT_VERIFY:
return usortVerify(data.Ids, execScopes, vm)
case USORT_VERIFY_MULTIPLICITY_ASSERT:
return usortVerifyMultiplicityAssert(execScopes)
case USORT_VERIFY_MULTIPLICITY_BODY:
return usortVerifyMultiplicityBody(data.Ids, execScopes, vm)
case SET_ADD:
return setAdd(data.Ids, vm)
case FIND_ELEMENT:
Expand Down
Loading

0 comments on commit d00239a

Please sign in to comment.