From 93cf966f66128145ce2fd5112d8ef28002c6ca6f Mon Sep 17 00:00:00 2001 From: Javier Chatruc Date: Thu, 21 Sep 2023 12:29:49 -0300 Subject: [PATCH] [WIP] EC_MUL_INNER hint --- cairo_programs/ec_mul_inner.cairo | 23 +++++++++ pkg/hints/ec_hint.go | 17 +++++++ pkg/hints/ec_hint_test.go | 78 +++++++++++++++++++++++++++++ pkg/hints/hint_codes/ec_op_hints.go | 1 + pkg/hints/hint_processor.go | 2 + pkg/vm/cairo_run/cairo_run_test.go | 4 ++ 6 files changed, 125 insertions(+) create mode 100644 cairo_programs/ec_mul_inner.cairo diff --git a/cairo_programs/ec_mul_inner.cairo b/cairo_programs/ec_mul_inner.cairo new file mode 100644 index 00000000..5a65e3f8 --- /dev/null +++ b/cairo_programs/ec_mul_inner.cairo @@ -0,0 +1,23 @@ +%builtins range_check + +from starkware.cairo.common.cairo_secp.ec import ( + EcPoint, + ec_mul_inner, +) +from starkware.cairo.common.cairo_secp.bigint import BigInt3 + +func main{range_check_ptr: felt}() { + // ec_mul_inner + let (pow2, res) = ec_mul_inner( + EcPoint( + BigInt3(65162296, 359657, 04862662171381), BigInt3(-5166641367474701, -63029418, 793) + ), + 123, + 298, + ); + assert pow2 = EcPoint( + BigInt3(30016796425722798916160189, 75045389156830800234717485, 13862403786096360935413684), + BigInt3(43820690643633544357415586, 29808113745001228006676979, 15112469502208690731782390), + ); + return (); +} diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index 8c83ff07..e7c15154 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -114,3 +114,20 @@ func ecNegateEmbeddedSecpP(virtual_machine vm.VirtualMachine, exec_scopes types. secp_p.Sub(secp_p, big.NewInt(19)) return ecNegate(virtual_machine, exec_scopes, ids_data, *secp_p) } + +/* +Implements hint: +%{ memory[ap] = (ids.scalar % PRIME) % 2 %} +*/ +func ecMulInner(virtualMachine *vm.VirtualMachine, ids hint_utils.IdsManager) error { + scalar, err := ids.GetFelt("scalar", virtualMachine) + + if err != nil { + return err + } + + result := scalar.And(lambdaworks.FeltOne()) + virtualMachine.Segments.Memory.Insert(virtualMachine.RunContext.Ap, memory.NewMaybeRelocatableFelt(result)) + + return nil +} diff --git a/pkg/hints/ec_hint_test.go b/pkg/hints/ec_hint_test.go index 8cd486aa..22303c4a 100644 --- a/pkg/hints/ec_hint_test.go +++ b/pkg/hints/ec_hint_test.go @@ -128,3 +128,81 @@ func TestRunEcEmbeddedSecpOk(t *testing.T) { } } + +func TestEcMulInnerSuccessEven(t *testing.T) { + vm := NewVirtualMachine() + vm.Segments.AddSegment() + vm.Segments.AddSegment() + + scalar := NewMaybeRelocatableFelt(FeltFromUint64(89712)) + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "scalar": {scalar}, + }, + vm, + ) + + hintProcessor := CairoVmHintProcessor{} + + hintData := any(HintData{ + Ids: idsManager, + Code: EC_MUL_INNER, + }) + + vm.RunContext.Ap = NewRelocatable(1, 1) + + err := hintProcessor.ExecuteHint(vm, &hintData, nil, nil) + result, err := vm.Segments.Memory.Get(NewRelocatable(1, 1)) + + if err != nil { + t.Errorf("EC_MUL_INNER hint failed with error %s", err) + } + + resultFelt, ok := result.GetFelt() + if !ok { + t.Errorf("EC_MUL_INNER hint expected Felt value as result") + } + + if !resultFelt.IsZero() { + t.Errorf("EC_MUL_INNER should have returned 0 but got %v", resultFelt) + } +} + +func TestEcMulInnerSuccessOdd(t *testing.T) { + vm := NewVirtualMachine() + vm.Segments.AddSegment() + vm.Segments.AddSegment() + + scalar := NewMaybeRelocatableFelt(FeltFromUint64(89711)) + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "scalar": {scalar}, + }, + vm, + ) + + hintProcessor := CairoVmHintProcessor{} + + hintData := any(HintData{ + Ids: idsManager, + Code: EC_MUL_INNER, + }) + + vm.RunContext.Ap = NewRelocatable(1, 1) + + err := hintProcessor.ExecuteHint(vm, &hintData, nil, nil) + result, err := vm.Segments.Memory.Get(NewRelocatable(1, 1)) + + if err != nil { + t.Errorf("EC_MUL_INNER hint failed with error %s", err) + } + + resultFelt, ok := result.GetFelt() + if !ok { + t.Errorf("EC_MUL_INNER hint expected Felt value as result") + } + + if resultFelt.Cmp(FeltOne()) != 0 { + t.Errorf("EC_MUL_INNER should have returned 1 but got %v", resultFelt) + } +} diff --git a/pkg/hints/hint_codes/ec_op_hints.go b/pkg/hints/hint_codes/ec_op_hints.go index c2092a7f..cfe1f9a5 100644 --- a/pkg/hints/hint_codes/ec_op_hints.go +++ b/pkg/hints/hint_codes/ec_op_hints.go @@ -2,3 +2,4 @@ package hint_codes const EC_NEGATE = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\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_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_MUL_INNER = "memory[ap] = (ids.scalar % PRIME) % 2" diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index 75cbc952..606cda0a 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -138,6 +138,8 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, return splitInt(data.Ids, vm) case SPLIT_INT_ASSERT_RANGE: return splitIntAssertRange(data.Ids, vm) + case EC_MUL_INNER: + return ecMulInner(vm, data.Ids) default: return errors.Errorf("Unknown Hint: %s", data.Code) } diff --git a/pkg/vm/cairo_run/cairo_run_test.go b/pkg/vm/cairo_run/cairo_run_test.go index aefaa7d0..b79cb921 100644 --- a/pkg/vm/cairo_run/cairo_run_test.go +++ b/pkg/vm/cairo_run/cairo_run_test.go @@ -197,3 +197,7 @@ func TestSplitIntHint(t *testing.T) { t.Errorf("Program execution failed with error: %s", err) } } + +func TestEcMulInner(t *testing.T) { + testProgram("ec_mul_inner", t) +}