Skip to content

Commit

Permalink
[WIP] EC_MUL_INNER hint
Browse files Browse the repository at this point in the history
  • Loading branch information
jrchatruc committed Sep 21, 2023
1 parent 1cdb017 commit 93cf966
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 0 deletions.
23 changes: 23 additions & 0 deletions cairo_programs/ec_mul_inner.cairo
Original file line number Diff line number Diff line change
@@ -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 ();
}
17 changes: 17 additions & 0 deletions pkg/hints/ec_hint.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
78 changes: 78 additions & 0 deletions pkg/hints/ec_hint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
1 change: 1 addition & 0 deletions pkg/hints/hint_codes/ec_op_hints.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
2 changes: 2 additions & 0 deletions pkg/hints/hint_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
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 @@ -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)
}

0 comments on commit 93cf966

Please sign in to comment.