33package nostr
44
55import (
6- "crypto/sha256"
76 "encoding/hex"
87 "fmt"
8+ "strings"
99
10- "github.com/btcsuite/btcd/btcec/v2 "
11- "github.com/btcsuite/btcd/btcec/v2/schnorr "
10+ "github.com/ethereum/go-ethereum/crypto "
11+ // "github.com/ethereum/go-ethereum/common/hexutil "
1212)
1313
1414// CheckSignature checks if the event signature is valid for the given event.
1515// It won't look at the ID field, instead it will recompute the id from the entire event body.
1616// If the signature is invalid bool will be false and err will be set.
1717func (evt Event ) CheckSignature () (bool , error ) {
1818 // read and check pubkey
19- pk , err := hex .DecodeString (evt .PubKey )
20- if err != nil {
21- return false , fmt .Errorf ("event pubkey '%s' is invalid hex: %w" , evt .PubKey , err )
22- }
23-
24- pubkey , err := schnorr .ParsePubKey (pk )
25- if err != nil {
26- return false , fmt .Errorf ("event has invalid pubkey '%s': %w" , evt .PubKey , err )
27- }
19+ address := "0x" + evt .PubKey
2820
2921 // read signature
30- s , err := hex .DecodeString (evt .Sig )
22+ //sig, err := hexutil.Decode(evt.Sig)
23+ sig , err := hex .DecodeString (evt .Sig )
3124 if err != nil {
3225 return false , fmt .Errorf ("signature '%s' is invalid hex: %w" , evt .Sig , err )
3326 }
34- sig , err := schnorr .ParseSignature (s )
35- if err != nil {
36- return false , fmt .Errorf ("failed to parse signature: %w" , err )
27+ if sig [64 ] >= 27 {
28+ sig [64 ] -= 27
3729 }
3830
3931 // check signature
40- hash := sha256 .Sum256 (evt .Serialize ())
41- return sig .Verify (hash [:], pubkey ), nil
32+ message := evt .Serialize ()
33+ prefixedMessage := fmt .Sprintf ("\x19 Ethereum Signed Message:\n %d%s" , len (message ), message )
34+ hash := crypto .Keccak256Hash ([]byte (prefixedMessage ))
35+
36+ pubKey , err := crypto .SigToPub (hash .Bytes (), sig )
37+ if err != nil {
38+ return false , fmt .Errorf ("failed to recover public key: %w" , err )
39+ }
40+
41+ recoveredAddr := crypto .PubkeyToAddress (* pubKey ).Hex ()
42+
43+ return (recoveredAddr == address ), nil
4244}
4345
4446// Sign signs an event with a given privateKey.
4547// It sets the event's ID, PubKey, and Sig fields.
4648// Returns an error if the private key is invalid or if signing fails.
4749func (evt * Event ) Sign (secretKey string ) error {
48- s , err := hex . DecodeString (secretKey )
50+ s , err := crypto . HexToECDSA (secretKey )
4951 if err != nil {
5052 return fmt .Errorf ("Sign called with invalid secret key '%s': %w" , secretKey , err )
5153 }
@@ -54,18 +56,22 @@ func (evt *Event) Sign(secretKey string) error {
5456 evt .Tags = make (Tags , 0 )
5557 }
5658
57- sk , pk := btcec .PrivKeyFromBytes (s )
58- pkBytes := pk .SerializeCompressed ()
59- evt .PubKey = hex .EncodeToString (pkBytes [1 :])
59+ evt .PubKey = crypto .PubkeyToAddress (s .PublicKey ).Hex ()
60+ evt .PubKey = strings .TrimPrefix (crypto .PubkeyToAddress (s .PublicKey ).Hex (), "0x" )
61+
62+
63+ message := evt .Serialize ()
64+ prefixedMessage := fmt .Sprintf ("\x19 Ethereum Signed Message:\n %d%s" , len (message ), message )
65+ h := crypto .Keccak256Hash ([]byte (prefixedMessage ))
6066
61- h := sha256 .Sum256 (evt .Serialize ())
62- sig , err := schnorr .Sign (sk , h [:], schnorr .FastSign ())
67+ sig , err := crypto .Sign (h .Bytes (), s )
6368 if err != nil {
64- return err
69+ return fmt . Errorf ( "failed to sign: %w" , err )
6570 }
6671
67- evt .ID = hex .EncodeToString (h [:])
68- evt .Sig = hex .EncodeToString (sig .Serialize ())
72+ evt .ID = hex .EncodeToString (h .Bytes ())
73+ //evt.Sig = hexutil.Encode(sig)
74+ evt .Sig = hex .EncodeToString (sig )
6975
7076 return nil
7177}
0 commit comments