Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signature Hint #209

Merged
merged 21 commits into from
Sep 19, 2023
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,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
2 changes: 2 additions & 0 deletions pkg/hints/math_hint_codes.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package hints

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
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
77 changes: 77 additions & 0 deletions pkg/hints/math_hints_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ 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_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 @@ -162,6 +165,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