keys.mx raw
1 package bech32encoding
2
3 import (
4 "bytes"
5
6 "crypto/ec/bech32"
7 "crypto/secp256k1"
8 "git.smesh.lol/nostr/pkg/hex"
9 "git.smesh.lol/nostr/pkg/lol/chk"
10 "git.smesh.lol/nostr/pkg/lol/log"
11 )
12
13 const (
14 MinKeyStringLen = 56
15 HexKeyLen = 64
16 Bech32HRPLen = 4
17 )
18
19 var (
20 SecHRP []byte
21 PubHRP []byte
22 )
23
24 func init() {
25 SecHRP = []byte("nsec")
26 PubHRP = []byte("npub")
27 NoteHRP = []byte("note")
28 NsecHRP = []byte("nsec")
29 NpubHRP = []byte("npub")
30 NprofileHRP = []byte("nprofile")
31 NeventHRP = []byte("nevent")
32 NentityHRP = []byte("naddr")
33 }
34
35 func ConvertForBech32(b8 []byte) (b5 []byte, err error) {
36 return bech32.ConvertBits(b8, 8, 5, true)
37 }
38
39 func ConvertFromBech32(b5 []byte) (b8 []byte, err error) {
40 return bech32.ConvertBits(b5, 5, 8, true)
41 }
42
43 func NsecToBytes(encoded []byte) (sk []byte, err error) {
44 var b5, hrp []byte
45 if hrp, b5, err = bech32.Decode(encoded); chk.E(err) {
46 return
47 }
48 if !bytes.Equal(hrp, SecHRP) {
49 err = log.E.Err([]byte("wrong human readable part, got '%s' want '%s'"), hrp, SecHRP)
50 return
51 }
52 if sk, err = ConvertFromBech32(b5); chk.E(err) {
53 return
54 }
55 sk = sk[:secp256k1.PubKeyBytesLen]
56 return
57 }
58
59 func NpubToBytes(encoded []byte) (pk []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, PubHRP) {
65 err = log.E.Err([]byte("wrong human readable part, got '%s' want '%s'"), hrp, PubHRP)
66 return
67 }
68 if pk, err = ConvertFromBech32(b5); chk.E(err) {
69 return
70 }
71 pk = pk[:secp256k1.PubKeyBytesLen]
72 return
73 }
74
75 func HexToNpub(publicKeyHex []byte) (s []byte, err error) {
76 b := []byte{:secp256k1.PubKeyBytesLen}
77 if _, err = hex.DecBytes(b, publicKeyHex); chk.D(err) {
78 return
79 }
80 var bits5 []byte
81 if bits5, err = bech32.ConvertBits(b, 8, 5, true); chk.D(err) {
82 return
83 }
84 return bech32.Encode(NpubHRP, bits5)
85 }
86
87 func BinToNpub(b []byte) (s []byte, err error) {
88 var bits5 []byte
89 if bits5, err = bech32.ConvertBits(b, 8, 5, true); chk.D(err) {
90 return
91 }
92 return bech32.Encode(NpubHRP, bits5)
93 }
94
95 func BinToNsec(sk []byte) (nsec []byte, err error) {
96 var b5 []byte
97 if b5, err = ConvertForBech32(sk); chk.E(err) {
98 return
99 }
100 return bech32.Encode(SecHRP, b5)
101 }
102
103 func HexToNsec(sk []byte) (nsec []byte, err error) {
104 if len(sk) != HexKeyLen {
105 err = log.E.Err([]byte("secret key is %d bytes, must be %d"), len(sk), HexKeyLen)
106 return
107 }
108 pb := []byte{:secp256k1.PubKeyBytesLen}
109 if _, err = hex.DecBytes(pb, sk); chk.D(err) {
110 return
111 }
112 return BinToNsec(pb)
113 }
114
115 func NsecToHex(nsec []byte) (hexSec []byte, err error) {
116 var sk []byte
117 if sk, err = NsecToBytes(nsec); chk.E(err) {
118 return
119 }
120 return hex.EncAppend(nil, sk), nil
121 }
122