From 31e0645afe3b59dba852ab203820e19e7aa64a79 Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Wed, 29 May 2024 15:40:57 -0300 Subject: [PATCH] libsecp256k1: use a static global context and add verification tests. --- libsecp256k1/benchmark_test.go | 6 +----- libsecp256k1/bip340.go | 29 +++++++++++------------------ libsecp256k1/signverify_test.go | 20 ++++++++++++++++++++ libsecp256k1/verify.go | 4 ++-- 4 files changed, 34 insertions(+), 25 deletions(-) create mode 100644 libsecp256k1/signverify_test.go diff --git a/libsecp256k1/benchmark_test.go b/libsecp256k1/benchmark_test.go index f372313..d4e4ca5 100644 --- a/libsecp256k1/benchmark_test.go +++ b/libsecp256k1/benchmark_test.go @@ -25,13 +25,9 @@ func BenchmarkSignatureVerification(b *testing.B) { }) b.Run("libsecp256k1", func(b *testing.B) { - c, err := NewContext() - if err != nil { - panic(err) - } for i := 0; i < b.N; i++ { for _, evt := range events { - c.CheckSignature(evt) + CheckSignature(evt) } } }) diff --git a/libsecp256k1/bip340.go b/libsecp256k1/bip340.go index 122f1c0..26d3c6b 100644 --- a/libsecp256k1/bip340.go +++ b/libsecp256k1/bip340.go @@ -14,45 +14,38 @@ import ( "unsafe" ) -type Context struct { - ctx *C.secp256k1_context -} +var globalSecp256k1Context *C.secp256k1_context -func NewContext() (*Context, error) { - ctx := C.secp256k1_context_create(C.SECP256K1_CONTEXT_SIGN | C.SECP256K1_CONTEXT_VERIFY) - if ctx == nil { - return nil, errors.New("failed to create secp256k1 context") +func init() { + globalSecp256k1Context = C.secp256k1_context_create(C.SECP256K1_CONTEXT_SIGN | C.SECP256K1_CONTEXT_VERIFY) + if globalSecp256k1Context == nil { + panic("failed to create secp256k1 context") } - return &Context{ctx: ctx}, nil } -func (c *Context) Destroy() { - C.secp256k1_context_destroy(c.ctx) -} - -func (c *Context) Sign(msg [32]byte, sk [32]byte) ([64]byte, error) { +func Sign(msg [32]byte, sk [32]byte) ([64]byte, error) { var sig [64]byte var keypair C.secp256k1_keypair - if C.secp256k1_keypair_create(c.ctx, &keypair, (*C.uchar)(unsafe.Pointer(&sk[0]))) != 1 { + if C.secp256k1_keypair_create(globalSecp256k1Context, &keypair, (*C.uchar)(unsafe.Pointer(&sk[0]))) != 1 { return sig, errors.New("failed to parse private key") } var random [32]byte rand.Read(random[:]) - if C.secp256k1_schnorrsig_sign32(c.ctx, (*C.uchar)(unsafe.Pointer(&sig[0])), (*C.uchar)(unsafe.Pointer(&msg[0])), &keypair, (*C.uchar)(unsafe.Pointer(&random[0]))) != 1 { + if C.secp256k1_schnorrsig_sign32(globalSecp256k1Context, (*C.uchar)(unsafe.Pointer(&sig[0])), (*C.uchar)(unsafe.Pointer(&msg[0])), &keypair, (*C.uchar)(unsafe.Pointer(&random[0]))) != 1 { return sig, errors.New("failed to sign message") } return sig, nil } -func (c *Context) Verify(msg [32]byte, sig [64]byte, pk [32]byte) bool { +func Verify(msg [32]byte, sig [64]byte, pk [32]byte) bool { var xonly C.secp256k1_xonly_pubkey - if C.secp256k1_xonly_pubkey_parse(c.ctx, &xonly, (*C.uchar)(unsafe.Pointer(&pk[0]))) != 1 { + if C.secp256k1_xonly_pubkey_parse(globalSecp256k1Context, &xonly, (*C.uchar)(unsafe.Pointer(&pk[0]))) != 1 { return false } - return C.secp256k1_schnorrsig_verify(c.ctx, (*C.uchar)(unsafe.Pointer(&sig[0])), (*C.uchar)(unsafe.Pointer(&msg[0])), 32, &xonly) == 1 + return C.secp256k1_schnorrsig_verify(globalSecp256k1Context, (*C.uchar)(unsafe.Pointer(&sig[0])), (*C.uchar)(unsafe.Pointer(&msg[0])), 32, &xonly) == 1 } diff --git a/libsecp256k1/signverify_test.go b/libsecp256k1/signverify_test.go new file mode 100644 index 0000000..b6606c3 --- /dev/null +++ b/libsecp256k1/signverify_test.go @@ -0,0 +1,20 @@ +package libsecp256k1 + +import ( + "encoding/json" + "testing" + + "github.com/nbd-wtf/go-nostr" + "github.com/nbd-wtf/go-nostr/test_common" + "github.com/stretchr/testify/assert" +) + +func TestEventVerification(t *testing.T) { + for _, jevt := range test_common.NormalEvents { + evt := &nostr.Event{} + json.Unmarshal([]byte(jevt), evt) + ok, _ := CheckSignature(evt) + shouldBe, _ := evt.CheckSignature() + assert.Equal(t, ok, shouldBe, "%s signature must be %s", jevt, shouldBe) + } +} diff --git a/libsecp256k1/verify.go b/libsecp256k1/verify.go index 5c67406..43b8486 100644 --- a/libsecp256k1/verify.go +++ b/libsecp256k1/verify.go @@ -8,7 +8,7 @@ import ( "github.com/nbd-wtf/go-nostr" ) -func (c *Context) CheckSignature(evt *nostr.Event) (bool, error) { +func CheckSignature(evt *nostr.Event) (bool, error) { var pk [32]byte _, err := hex.Decode(pk[:], []byte(evt.PubKey)) if err != nil { @@ -22,5 +22,5 @@ func (c *Context) CheckSignature(evt *nostr.Event) (bool, error) { } msg := sha256.Sum256(evt.Serialize()) - return c.Verify(msg, sig, pk), nil + return Verify(msg, sig, pk), nil }