diff --git a/integration_tests/cairozero_test.go b/integration_tests/cairozero_test.go index f435badc2..5f5913d0d 100644 --- a/integration_tests/cairozero_test.go +++ b/integration_tests/cairozero_test.go @@ -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/") } diff --git a/pkg/hintrunner/zero/hintcode.go b/pkg/hintrunner/zero/hintcode.go index 12068ab1d..5dd6062b2 100644 --- a/pkg/hintrunner/zero/hintcode.go +++ b/pkg/hintrunner/zero/hintcode.go @@ -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)])" diff --git a/pkg/hintrunner/zero/zerohint.go b/pkg/hintrunner/zero/zerohint.go index 554fc668b..2dc52c9ab 100644 --- a/pkg/hintrunner/zero/zerohint.go +++ b/pkg/hintrunner/zero/zerohint.go @@ -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) diff --git a/pkg/hintrunner/zero/zerohint_signatures.go b/pkg/hintrunner/zero/zerohint_signatures.go new file mode 100644 index 000000000..18d1d6457 --- /dev/null +++ b/pkg/hintrunner/zero/zerohint_signatures.go @@ -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 +} diff --git a/pkg/hintrunner/zero/zerohint_signatures_test.go b/pkg/hintrunner/zero/zerohint_signatures_test.go new file mode 100644 index 000000000..0ddc007f3 --- /dev/null +++ b/pkg/hintrunner/zero/zerohint_signatures_test.go @@ -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) + }, + }, + }, + }) +}