keys.mx raw
1 package bech32encoding
2
3 import (
4 "bytes"
5
6 "smesh.lol/pkg/nostr/ec/bech32"
7 "smesh.lol/pkg/nostr/ec/schnorr"
8 "smesh.lol/pkg/nostr/ec/secp256k1"
9 "smesh.lol/pkg/nostr/hex"
10 "smesh.lol/pkg/lol/chk"
11 "smesh.lol/pkg/lol/log"
12 )
13
14 const (
15 MinKeyStringLen = 56
16 HexKeyLen = 64
17 Bech32HRPLen = 4
18 )
19
20 var (
21 SecHRP = []byte("nsec")
22 PubHRP = []byte("npub")
23 )
24
25 func ConvertForBech32(b8 []byte) (b5 []byte, err error) {
26 return bech32.ConvertBits(b8, 8, 5, true)
27 }
28
29 func ConvertFromBech32(b5 []byte) (b8 []byte, err error) {
30 return bech32.ConvertBits(b5, 5, 8, true)
31 }
32
33 func SecretKeyToNsec(sk *secp256k1.SecretKey) (encoded []byte, err error) {
34 var b5 []byte
35 if b5, err = ConvertForBech32(sk.Serialize()); chk.E(err) {
36 return
37 }
38 return bech32.Encode(SecHRP, b5)
39 }
40
41 func PublicKeyToNpub(pk *secp256k1.PublicKey) (encoded []byte, err error) {
42 var bits5 []byte
43 pubKeyBytes := schnorr.SerializePubKey(pk)
44 if bits5, err = ConvertForBech32(pubKeyBytes); chk.E(err) {
45 return
46 }
47 return bech32.Encode(PubHRP, bits5)
48 }
49
50 func NsecToSecretKey(encoded []byte) (sk *secp256k1.SecretKey, err error) {
51 var b8 []byte
52 if b8, err = NsecToBytes(encoded); chk.E(err) {
53 return
54 }
55 sk = secp256k1.SecKeyFromBytes(b8)
56 return
57 }
58
59 func NsecToBytes(encoded []byte) (sk []byte, err error) {
60 var b5, hrp []byte
61 if hrp, b5, err = bech32.Decode(encoded); chk.E(err) {
62 return
63 }
64 if !bytes.Equal(hrp, SecHRP) {
65 err = log.E.Err([]byte("wrong human readable part, got '%s' want '%s'"), hrp, SecHRP)
66 return
67 }
68 if sk, err = ConvertFromBech32(b5); chk.E(err) {
69 return
70 }
71 sk = sk[:secp256k1.SecKeyBytesLen]
72 return
73 }
74
75 func NpubToBytes(encoded []byte) (pk []byte, err error) {
76 var b5, hrp []byte
77 if hrp, b5, err = bech32.Decode(encoded); chk.E(err) {
78 return
79 }
80 if !bytes.Equal(hrp, PubHRP) {
81 err = log.E.Err([]byte("wrong human readable part, got '%s' want '%s'"), hrp, PubHRP)
82 return
83 }
84 if pk, err = ConvertFromBech32(b5); chk.E(err) {
85 return
86 }
87 pk = pk[:schnorr.PubKeyBytesLen]
88 return
89 }
90
91 func NpubToPublicKey(encoded []byte) (pk *secp256k1.PublicKey, err error) {
92 var b5, b8, hrp []byte
93 if hrp, b5, err = bech32.Decode(encoded); chk.E(err) {
94 return
95 }
96 if !bytes.Equal(hrp, PubHRP) {
97 err = log.E.Err([]byte("wrong human readable part, got '%s' want '%s'"), hrp, PubHRP)
98 return
99 }
100 if b8, err = ConvertFromBech32(b5); chk.E(err) {
101 return
102 }
103 return schnorr.ParsePubKey(b8[:schnorr.PubKeyBytesLen])
104 }
105
106 func HexToPublicKey(pk []byte) (p *secp256k1.PublicKey, err error) {
107 if len(pk) != HexKeyLen {
108 err = log.E.Err([]byte("key is %d bytes, must be %d"), len(pk), HexKeyLen)
109 return
110 }
111 var pb []byte
112 if pb, err = hex.Dec(string(pk)); chk.D(err) {
113 return
114 }
115 return schnorr.ParsePubKey(pb)
116 }
117
118 func HexToNpub(publicKeyHex []byte) (s []byte, err error) {
119 b := []byte{:schnorr.PubKeyBytesLen}
120 if _, err = hex.DecBytes(b, publicKeyHex); chk.D(err) {
121 return
122 }
123 var bits5 []byte
124 if bits5, err = bech32.ConvertBits(b, 8, 5, true); chk.D(err) {
125 return
126 }
127 return bech32.Encode(NpubHRP, bits5)
128 }
129
130 func BinToNpub(b []byte) (s []byte, err error) {
131 var bits5 []byte
132 if bits5, err = bech32.ConvertBits(b, 8, 5, true); chk.D(err) {
133 return
134 }
135 return bech32.Encode(NpubHRP, bits5)
136 }
137
138 func HexToSecretKey(sk []byte) (s *secp256k1.SecretKey, err error) {
139 if len(sk) != HexKeyLen {
140 err = log.E.Err([]byte("secret key is %d bytes, must be %d"), len(sk), HexKeyLen)
141 return
142 }
143 pb := []byte{:schnorr.PubKeyBytesLen}
144 if _, err = hex.DecBytes(pb, sk); chk.D(err) {
145 return
146 }
147 s = secp256k1.SecKeyFromBytes(pb)
148 return
149 }
150
151 func HexToNsec(sk []byte) (nsec []byte, err error) {
152 var s *secp256k1.SecretKey
153 if s, err = HexToSecretKey(sk); chk.E(err) {
154 return
155 }
156 return SecretKeyToNsec(s)
157 }
158
159 func BinToNsec(sk []byte) (nsec []byte, err error) {
160 s := secp256k1.SecKeyFromBytes(sk)
161 return SecretKeyToNsec(s)
162 }
163
164 func SecretKeyToHex(sk *secp256k1.SecretKey) (hexSec []byte) {
165 return hex.EncAppend(nil, sk.Serialize())
166 }
167
168 func NsecToHex(nsec []byte) (hexSec []byte, err error) {
169 var sk *secp256k1.SecretKey
170 if sk, err = NsecToSecretKey(nsec); chk.E(err) {
171 return
172 }
173 return SecretKeyToHex(sk), nil
174 }
175