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