Skip to content

Commit

Permalink
Signature Hint (#209)
Browse files Browse the repository at this point in the history
* Merge and add basic builtin

* WIP

* Initial version

* Remove unused comments

* Add signature program

* Fix parser

* Merge

* Replace test file

* Fix signature builtin name

* Remove value from writeable address

* Add segment

* Remove unused import

* Fix test name

* fix fmt

---------

Co-authored-by: Javier Chatruc <[email protected]>
Co-authored-by: Federica <[email protected]>
Co-authored-by: fmoletta <[email protected]>
  • Loading branch information
4 people authored Sep 19, 2023
1 parent 3ab71d9 commit e6ab48a
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 6 deletions.
13 changes: 13 additions & 0 deletions cairo_programs/common_signature.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
%builtins ecdsa
from starkware.cairo.common.cairo_builtins import SignatureBuiltin
from starkware.cairo.common.signature import verify_ecdsa_signature

func main{ecdsa_ptr: SignatureBuiltin*}() {
verify_ecdsa_signature(
2718,
1735102664668487605176656616876767369909409133946409161569774794110049207117,
3086480810278599376317923499561306189851900463386393948998357832163236918254,
598673427589502599949712887611119751108407514580626464031881322743364689811,
);
return ();
}
7 changes: 3 additions & 4 deletions pkg/builtins/signature.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"github.com/pkg/errors"
)

const SIGNATURE_BUILTIN_NAME = "signature"
const SIGNATURE_BUILTIN_NAME = "ecdsa"

// Notice changing this to any other number breaks the code
const SIGNATURE_CELLS_PER_INSTANCE = 2
Expand Down Expand Up @@ -166,12 +166,11 @@ func (r *SignatureBuiltinRunner) AddValidationRule(mem *memory.Memory) {
}

// Helper function to AddSignature
func AddSignature(
signatureBuiltin *SignatureBuiltinRunner,
func (r *SignatureBuiltinRunner) AddSignature(
address memory.Relocatable,
signature Signature,
) {
signatureBuiltin.signatures[address] = signature
r.signatures[address] = signature
}

func (runner *SignatureBuiltinRunner) GetMemoryAccesses(manager *memory.MemorySegmentManager) ([]memory.Relocatable, error) {
Expand Down
2 changes: 2 additions & 0 deletions pkg/hints/hint_codes/math_hint_codes.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package hint_codes

const ASSERT_NN = "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.a)\nassert 0 <= ids.a % PRIME < range_check_builtin.bound, f'a = {ids.a} is out of range.'"

const VERIFY_ECDSA_SIGNATURE = "ecdsa_builtin.add_signature(ids.ecdsa_ptr.address_, (ids.signature_r, ids.signature_s))"

const IS_POSITIVE = "from starkware.cairo.common.math_utils import is_positive\nids.is_positive = 1 if is_positive(\n value=ids.value, prime=PRIME, rc_bound=range_check_builtin.bound) else 0"

const ASSERT_NOT_ZERO = "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.value)\nassert ids.value % PRIME != 0, f'assert_not_zero failed: {ids.value} = 0.'"
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 @@ -44,6 +44,8 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any,
return add_segment(vm)
case ASSERT_NN:
return assert_nn(data.Ids, vm)
case VERIFY_ECDSA_SIGNATURE:
return verify_ecdsa_signature(data.Ids, vm)
case IS_POSITIVE:
return is_positive(data.Ids, vm)
case ASSERT_NOT_ZERO:
Expand Down
32 changes: 32 additions & 0 deletions pkg/hints/math_hints.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func is_positive(ids IdsManager, vm *VirtualMachine) error {
// assert ids.value % PRIME != 0, f'assert_not_zero failed: {ids.value} = 0.'
//
// %}

func assert_not_zero(ids IdsManager, vm *VirtualMachine) error {
value, err := ids.GetFelt("value", vm)
if err != nil {
Expand All @@ -66,6 +67,37 @@ func assert_not_zero(ids IdsManager, vm *VirtualMachine) error {
return nil
}

func verify_ecdsa_signature(ids IdsManager, vm *VirtualMachine) error {
r, err_get_r := ids.GetFelt("signature_r", vm)
if err_get_r != nil {
return err_get_r
}

s, err_get_s := ids.GetFelt("signature_s", vm)
if err_get_s != nil {
return err_get_s
}

ecdsa_ptr, err_get_ecdsa := ids.GetAddr("ecdsa_ptr", vm)
if err_get_ecdsa != nil {
return err_get_ecdsa
}

signature_builtin_interface, err_get_builtin := vm.GetBuiltinRunner(builtins.SIGNATURE_BUILTIN_NAME)
if err_get_builtin != nil {
return err_get_builtin
}

signature_builtin := (*signature_builtin_interface).(*builtins.SignatureBuiltinRunner)

signature := builtins.Signature{
R: r,
S: s,
}
signature_builtin.AddSignature(ecdsa_ptr, signature)
return nil
}

// Implements hint:from starkware.cairo.common.math.cairo
//
// %{
Expand Down
76 changes: 76 additions & 0 deletions pkg/hints/math_hints_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ package hints_test
import (
"testing"

"github.com/lambdaclass/cairo-vm.go/pkg/builtins"
. "github.com/lambdaclass/cairo-vm.go/pkg/hints"
. "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_codes"
. "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/lambdaworks"
. "github.com/lambdaclass/cairo-vm.go/pkg/vm"
"github.com/lambdaclass/cairo-vm.go/pkg/vm/memory"
. "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory"
)

Expand Down Expand Up @@ -164,6 +166,80 @@ func TestAssertNotZeroHintFail(t *testing.T) {
}
}

func TestVerifyValidSignature(t *testing.T) {
vm := NewVirtualMachine()
vm.Segments.AddSegment()
signature_builtin := builtins.NewSignatureBuiltinRunner(2048)
vm.BuiltinRunners = append(vm.BuiltinRunners, signature_builtin)

hintProcessor := CairoVmHintProcessor{}
vm.Segments.AddSegment()

r_felt := lambdaworks.FeltFromDecString("3086480810278599376317923499561306189851900463386393948998357832163236918254")
s_felt := lambdaworks.FeltFromDecString("598673427589502599949712887611119751108407514580626464031881322743364689811")
r := memory.NewMaybeRelocatableFelt(r_felt)
s := memory.NewMaybeRelocatableFelt(s_felt)

vm.RunContext.Fp = memory.NewRelocatable(1, 3)

idsManager := SetupIdsForTest(
map[string][]*MaybeRelocatable{
"ecdsa_ptr": {nil},
"signature_r": {r},
"signature_s": {s},
},
vm,
)

hintData := any(HintData{
Ids: idsManager,
Code: VERIFY_ECDSA_SIGNATURE,
})

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

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

func TestVerifySignatureInvalidEcdsaPointer(t *testing.T) {
vm := NewVirtualMachine()
signature_builtin := builtins.NewSignatureBuiltinRunner(2048)
vm.BuiltinRunners = append(vm.BuiltinRunners, signature_builtin)

hintProcessor := CairoVmHintProcessor{}
vm.Segments.AddSegment()

r_felt := lambdaworks.FeltFromDecString("3086480810278599376317923499561306189851900463386393948998357832163236918254")
s_felt := lambdaworks.FeltFromDecString("598673427589502599949712887611119751108407514580626464031881322743364689811")
three := memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromUint64(3))
r := memory.NewMaybeRelocatableFelt(r_felt)
s := memory.NewMaybeRelocatableFelt(s_felt)

vm.RunContext.Fp = memory.NewRelocatable(1, 3)

idsManager := SetupIdsForTest(
map[string][]*MaybeRelocatable{
"ecdsa_ptr": {three},
"signature_r": {r},
"signature_s": {s},
},
vm,
)

hintData := any(HintData{
Ids: idsManager,
Code: VERIFY_ECDSA_SIGNATURE,
})

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

if err == nil {
t.Errorf("Verified a signature with an invalid pointer")
}
}

func TestAssertNotEqualHintNonComparableDiffType(t *testing.T) {
vm := NewVirtualMachine()
vm.Segments.AddSegment()
Expand Down
2 changes: 1 addition & 1 deletion pkg/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ type HintParams struct {
}

type CompiledJson struct {
Attributes []string `json:"attributes"`
Attributes interface{} `json:"attributes"`
Builtins []string `json:"builtins"`
CompilerVersion string `json:"compiler_version"`
Data []string `json:"data"`
Expand Down
7 changes: 7 additions & 0 deletions pkg/vm/cairo_run/cairo_run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,13 @@ func TestAbsValue(t *testing.T) {
t.Errorf("Program execution failed with error: %s", err)
}
}
func TestCommonSignature(t *testing.T) {
cairoRunConfig := cairo_run.CairoRunConfig{DisableTracePadding: false, ProofMode: false, Layout: "all_cairo"}
_, err := cairo_run.CairoRun("../../../cairo_programs/common_signature.json", cairoRunConfig)
if err != nil {
t.Errorf("Program execution failed with error: %s", err)
}
}
func TestAssertNotZeroHint(t *testing.T) {
cairoRunConfig := cairo_run.CairoRunConfig{DisableTracePadding: false, ProofMode: false, Layout: "all_cairo"}
_, err := cairo_run.CairoRun("../../../cairo_programs/assert_not_zero.json", cairoRunConfig)
Expand Down
2 changes: 1 addition & 1 deletion pkg/vm/memory/memory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ func TestValidateMemoryForValidSignature(t *testing.T) {
S: signature_s_felt,
}

builtins.AddSignature(signature_builtin, signature_address, signature)
signature_builtin.AddSignature(signature_address, signature)

pub_key_address := memory.NewRelocatable(1, 0)
message_hash_address := memory.NewRelocatable(1, 1)
Expand Down

0 comments on commit e6ab48a

Please sign in to comment.