Skip to content

Commit

Permalink
Cairo0 verify ecdsa signature (#336)
Browse files Browse the repository at this point in the history
* Implement VerifyECDSASignature hint

* Fixed retrieving memory with signature via pointer

* Scooped out the deref from double deref in test cases

* Removed verify_ecdsa_sig integration test, modified ecdsa builtin integration test
  • Loading branch information
MaksymMalicki committed Apr 8, 2024
1 parent 22d4264 commit 0d4b740
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 3 deletions.
3 changes: 1 addition & 2 deletions integration_tests/cairozero_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,7 @@ func TestECDSA(t *testing.T) {
require.NoError(t, err)

_, _, _, err = runVm(compiledOutput)
//Note: This fails because no addSiganture hint
require.Error(t, err)
require.NoError(t, err)

clean("./builtin_tests/")
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/hintrunner/zero/hintcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const (
fastEcAddAssignNewXCode string = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\n\nslope = pack(ids.slope, PRIME)\nx0 = pack(ids.point0.x, PRIME)\nx1 = pack(ids.point1.x, PRIME)\ny0 = pack(ids.point0.y, PRIME)\n\nvalue = new_x = (pow(slope, 2, SECP_P) - x0 - x1) % SECP_P"

// ------ Signature hints related code ------

verifyECDSASignatureCode string = "ecdsa_builtin.add_signature(ids.ecdsa_ptr.address_, (ids.signature_r, ids.signature_s))"
// ------ Blake Hash hints related code ------
blake2sAddUint256BigendCode string = "B = 32\nMASK = 2 ** 32 - 1\nsegments.write_arg(ids.data, [(ids.high >> (B * (3 - i))) & MASK for i in range(4)])\nsegments.write_arg(ids.data + 4, [(ids.low >> (B * (3 - i))) & MASK for i in range(4)])"
blake2sAddUint256Code string = "B = 32\nMASK = 2 ** 32 - 1\nsegments.write_arg(ids.data, [(ids.low >> (B * i)) & MASK for i in range(4)])\nsegments.write_arg(ids.data + 4, [(ids.high >> (B * i)) & MASK for i in range(4)])"
Expand Down
3 changes: 3 additions & 0 deletions pkg/hintrunner/zero/zerohint.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ func GetHintFromCode(program *zero.ZeroProgram, rawHint zero.Hint, hintPC uint64
return createUint256SqrtHinter(resolver)
case uint256MulDivModCode:
return createUint256MulDivModHinter(resolver)
// Signature hints
case verifyECDSASignatureCode:
return createVerifyECDSASignatureHinter(resolver)
// EC hints
case ecNegateCode:
return createEcNegateHinter(resolver)
Expand Down
52 changes: 52 additions & 0 deletions pkg/hintrunner/zero/zerohint_signatures.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package zero

import (
"fmt"

"github.com/NethermindEth/cairo-vm-go/pkg/hintrunner/hinter"
VM "github.com/NethermindEth/cairo-vm-go/pkg/vm"
"github.com/NethermindEth/cairo-vm-go/pkg/vm/builtins"
)

func newVerifyECDSASignatureHinter(ecdsaPtr, signature_r, signature_s hinter.ResOperander) hinter.Hinter {
return &GenericZeroHinter{
Name: "VerifyECDSASignature",
Op: func(vm *VM.VirtualMachine, _ *hinter.HintRunnerContext) error {
//> ecdsa_builtin.add_signature(ids.ecdsa_ptr.address_, (ids.signature_r, ids.signature_s))
ecdsaPtrAddr, err := hinter.ResolveAsAddress(vm, ecdsaPtr)
if err != nil {
return err
}
signature_rFelt, err := hinter.ResolveAsFelt(vm, signature_r)
if err != nil {
return err
}
signature_sFelt, err := hinter.ResolveAsFelt(vm, signature_s)
if err != nil {
return err
}
ECDSA_segment, ok := vm.Memory.FindSegmentWithBuiltin(builtins.ECDSAName)
if !ok {
return fmt.Errorf("ECDSA segment not found")
}
ECDSA_builtinRunner := (ECDSA_segment.BuiltinRunner).(*builtins.ECDSA)
return ECDSA_builtinRunner.AddSignature(ecdsaPtrAddr.Offset, signature_rFelt, signature_sFelt)
},
}
}

func createVerifyECDSASignatureHinter(resolver hintReferenceResolver) (hinter.Hinter, error) {
ecdsaPtr, err := resolver.GetResOperander("ecdsa_ptr")
if err != nil {
return nil, err
}
signature_r, err := resolver.GetResOperander("signature_r")
if err != nil {
return nil, err
}
signature_s, err := resolver.GetResOperander("signature_s")
if err != nil {
return nil, err
}
return newVerifyECDSASignatureHinter(ecdsaPtr, signature_r, signature_s), nil
}
30 changes: 30 additions & 0 deletions pkg/hintrunner/zero/zerohint_signatures_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package zero

import (
"testing"

"github.com/NethermindEth/cairo-vm-go/pkg/hintrunner/hinter"
"github.com/NethermindEth/cairo-vm-go/pkg/parsers/starknet"
"github.com/stretchr/testify/require"
)

func TestSignatures(t *testing.T) {
runHinterTests(t, map[string][]hintTestCase{
"VerifyECDSASignature": {
{
operanders: []*hintOperander{
{Name: "ecdsaPtr", Kind: reference, Value: addrBuiltin(starknet.ECDSA, 0)},
{Name: "signature_r", Kind: apRelative, Value: feltString("3086480810278599376317923499561306189851900463386393948998357832163236918254")},
{Name: "signature_s", Kind: apRelative, Value: feltString("598673427589502599949712887611119751108407514580626464031881322743364689811")},
},
makeHinter: func(ctx *hintTestContext) hinter.Hinter {
ecdsaPtr := ctx.operanders["ecdsaPtr"].(*hinter.DoubleDeref).Deref
return newVerifyECDSASignatureHinter(ecdsaPtr, ctx.operanders["signature_r"], ctx.operanders["signature_s"])
},
errCheck: func(t *testing.T, ctx *hintTestContext, err error) {
require.NoError(t, err)
},
},
},
})
}

0 comments on commit 0d4b740

Please sign in to comment.