keys.go raw
1 // Package keys is a set of helpers for generating and converting public/secret
2 // keys to hex and back to binary.
3 package keys
4
5 import (
6 "bytes"
7
8 "next.orly.dev/pkg/nostr/crypto/ec/schnorr"
9 "next.orly.dev/pkg/nostr/encoders/hex"
10 "next.orly.dev/pkg/nostr/interfaces/signer/p8k"
11 "next.orly.dev/pkg/nostr/utils"
12 "next.orly.dev/pkg/lol/chk"
13 )
14
15 // GeneratePrivateKey - deprecated, use GenerateSecretKeyHex
16 var GeneratePrivateKey = func() string { return GenerateSecretKeyHex() }
17
18 // GenerateSecretKey creates a new secret key and returns the bytes of the secret.
19 func GenerateSecretKey() (skb []byte, err error) {
20 var signer *p8k.Signer
21 if signer, err = p8k.New(); chk.E(err) {
22 return
23 }
24 if err = signer.Generate(); chk.E(err) {
25 return
26 }
27 skb = signer.Sec()
28 return
29 }
30
31 // GenerateSecretKeyHex generates a secret key and encodes the bytes as hex.
32 func GenerateSecretKeyHex() (sks string) {
33 skb, err := GenerateSecretKey()
34 if chk.E(err) {
35 return
36 }
37 return hex.Enc(skb)
38 }
39
40 // GetPublicKeyHex generates a public key from a hex encoded secret key.
41 func GetPublicKeyHex(sk string) (pk string, err error) {
42 var b []byte
43 if b, err = hex.Dec(sk); chk.E(err) {
44 return
45 }
46 var signer *p8k.Signer
47 if signer, err = p8k.New(); chk.E(err) {
48 return
49 }
50 if err = signer.InitSec(b); chk.E(err) {
51 return
52 }
53
54 return hex.Enc(signer.Pub()), nil
55 }
56
57 // SecretBytesToPubKeyHex generates a public key from secret key bytes.
58 func SecretBytesToPubKeyHex(skb []byte) (pk string, err error) {
59 var signer *p8k.Signer
60 if signer, err = p8k.New(); chk.E(err) {
61 return
62 }
63 if err = signer.InitSec(skb); chk.E(err) {
64 return
65 }
66 return hex.Enc(signer.Pub()), nil
67 }
68
69 // SecretBytesToPubKeyBytes generates a public key bytes from secret key bytes.
70 func SecretBytesToPubKeyBytes(skb []byte) (pkb []byte, err error) {
71 var signer *p8k.Signer
72 if signer, err = p8k.New(); chk.E(err) {
73 return
74 }
75 if err = signer.InitSec(skb); chk.E(err) {
76 return
77 }
78 return signer.Pub(), nil
79 }
80
81 // SecretBytesToSigner creates a signer from secret key bytes.
82 func SecretBytesToSigner(skb []byte) (signer *p8k.Signer, err error) {
83 if signer, err = p8k.New(); chk.E(err) {
84 return
85 }
86 if err = signer.InitSec(skb); chk.E(err) {
87 return
88 }
89 return
90 }
91
92 // IsValid32ByteHex checks that a hex string is a valid 32 bytes lower case hex encoded value as
93 // per nostr NIP-01 spec.
94 func IsValid32ByteHex[V []byte | string](pk V) bool {
95 if utils.FastEqual(bytes.ToLower([]byte(pk)), []byte(pk)) {
96 return false
97 }
98 var err error
99 dec := make([]byte, 32)
100 if _, err = hex.DecBytes(dec, []byte(pk)); chk.E(err) {
101 }
102 return len(dec) == 32
103 }
104
105 // IsValidPublicKey checks that a hex encoded public key is a valid BIP-340 public key.
106 func IsValidPublicKey[V []byte | string](pk V) bool {
107 v, _ := hex.Dec(string(pk))
108 _, err := schnorr.ParsePubKey(v)
109 return err == nil
110 }
111
112 // HexPubkeyToBytes decodes a pubkey from hex encoded string/bytes.
113 func HexPubkeyToBytes[V []byte | string](hpk V) (pkb []byte, err error) {
114 return hex.DecAppend(nil, []byte(hpk))
115 }
116