signatures.go raw
1 package event
2
3 import (
4 "next.orly.dev/pkg/nostr/interfaces/signer"
5 "next.orly.dev/pkg/nostr/interfaces/signer/p8k"
6 "next.orly.dev/pkg/nostr/utils"
7 "next.orly.dev/pkg/lol/chk"
8 "next.orly.dev/pkg/lol/errorf"
9 "next.orly.dev/pkg/lol/log"
10 )
11
12 // Sign the event using the signer.I. Uses github.com/bitcoin-core/secp256k1 if
13 // available for much faster signatures.
14 //
15 // Note that this only populates the Pubkey, ID and Sig. The caller must
16 // set the CreatedAt timestamp as intended.
17 func (ev *E) Sign(keys signer.I) (err error) {
18 // Copy Pub() and Sign() results — signers may return internal buffers
19 // that are reused on subsequent calls (e.g. P256K1Signer.sigBuf).
20 pub := keys.Pub()
21 ev.Pubkey = make([]byte, len(pub))
22 copy(ev.Pubkey, pub)
23 ev.ID = ev.GetIDBytes()
24 var sig []byte
25 if sig, err = keys.Sign(ev.ID); chk.E(err) {
26 return
27 }
28 ev.Sig = make([]byte, len(sig))
29 copy(ev.Sig, sig)
30 return
31 }
32
33 // Verify an event is signed by the pubkey it contains. Uses
34 // github.com/bitcoin-core/secp256k1 if available for faster verification.
35 func (ev *E) Verify() (valid bool, err error) {
36 var keys *p8k.Signer
37 if keys, err = p8k.New(); chk.E(err) {
38 return
39 }
40 if err = keys.InitPub(ev.Pubkey); chk.E(err) {
41 return
42 }
43 if valid, err = keys.Verify(ev.ID, ev.Sig); chk.T(err) {
44 // check that this isn't because of a bogus ID
45 id := ev.GetIDBytes()
46 if !utils.FastEqual(id, ev.ID) {
47 log.E.Ln("event Subscription incorrect")
48 ev.ID = id
49 err = nil
50 if valid, err = keys.Verify(ev.ID, ev.Sig); chk.E(err) {
51 return
52 }
53 err = errorf.W("event Subscription incorrect but signature is valid on correct Subscription")
54 }
55 return
56 }
57 return
58 }
59