mirror of
https://github.com/nbd-wtf/go-nostr.git
synced 2025-05-29 17:19:16 +02:00
nip49: encrypt before decrypt.
This commit is contained in:
parent
84134f7d8e
commit
58ff5f6716
@ -19,6 +19,50 @@ const (
|
||||
ClientDoesNotTrackThisData KeySecurityByte = 0x02
|
||||
)
|
||||
|
||||
func Encrypt(secretKey string, password string, logn uint8, ksb KeySecurityByte) (b32code string, err error) {
|
||||
skb, err := hex.DecodeString(secretKey)
|
||||
if err != nil || len(skb) != 32 {
|
||||
return "", fmt.Errorf("invalid secret key")
|
||||
}
|
||||
return EncryptBytes(skb, password, logn, ksb)
|
||||
}
|
||||
|
||||
func EncryptBytes(secretKey []byte, password string, logn uint8, ksb KeySecurityByte) (b32code string, err error) {
|
||||
salt := make([]byte, 16)
|
||||
if _, err := rand.Read(salt); err != nil {
|
||||
return "", fmt.Errorf("failed to read salt: %w", err)
|
||||
}
|
||||
n := int(math.Pow(2, float64(int(logn))))
|
||||
key, err := scrypt.Key([]byte(password), salt, n, 8, 1, 32)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to compute key with scrypt: %w", err)
|
||||
}
|
||||
|
||||
concat := make([]byte, 91)
|
||||
concat[0] = 0x02
|
||||
concat[1] = byte(logn)
|
||||
copy(concat[2:2+16], salt)
|
||||
rand.Read(concat[2+16 : 2+16+24]) // nonce
|
||||
ad := []byte{byte(ksb)}
|
||||
copy(concat[2+16+24:2+16+24+1], ad)
|
||||
|
||||
c2p1, err := chacha20poly1305.NewX(key)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to start xchacha20poly1305: %w", err)
|
||||
}
|
||||
ciphertext := c2p1.Seal(nil, concat[2+16:2+16+24], secretKey, ad)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to encrypt: %w", err)
|
||||
}
|
||||
copy(concat[2+16+24+1:], ciphertext)
|
||||
|
||||
bits5, err := bech32.ConvertBits(concat, 8, 5, true)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return bech32.Encode("ncryptsec", bits5)
|
||||
}
|
||||
|
||||
func Decrypt(bech32string string, password string) (secretKey string, err error) {
|
||||
secb, err := DecryptToBytes(bech32string, password)
|
||||
return hex.EncodeToString(secb), err
|
||||
@ -63,47 +107,3 @@ func DecryptToBytes(bech32string string, password string) (secretKey []byte, err
|
||||
|
||||
return c2p1.Open(nil, nonce, encryptedKey, ad)
|
||||
}
|
||||
|
||||
func Encrypt(secretKey string, password string, logn uint8, ksb KeySecurityByte) (b32code string, err error) {
|
||||
skb, err := hex.DecodeString(secretKey)
|
||||
if err != nil || len(skb) != 32 {
|
||||
return "", fmt.Errorf("invalid secret key")
|
||||
}
|
||||
return EncryptBytes(skb, password, logn, ksb)
|
||||
}
|
||||
|
||||
func EncryptBytes(secretKey []byte, password string, logn uint8, ksb KeySecurityByte) (b32code string, err error) {
|
||||
salt := make([]byte, 16)
|
||||
if _, err := rand.Read(salt); err != nil {
|
||||
return "", fmt.Errorf("failed to read salt: %w", err)
|
||||
}
|
||||
n := int(math.Pow(2, float64(int(logn))))
|
||||
key, err := scrypt.Key([]byte(password), salt, n, 8, 1, 32)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to compute key with scrypt: %w", err)
|
||||
}
|
||||
|
||||
concat := make([]byte, 91)
|
||||
concat[0] = 0x02
|
||||
concat[1] = byte(logn)
|
||||
copy(concat[2:2+16], salt)
|
||||
rand.Read(concat[2+16 : 2+16+24]) // nonce
|
||||
ad := []byte{byte(ksb)}
|
||||
copy(concat[2+16+24:2+16+24+1], ad)
|
||||
|
||||
c2p1, err := chacha20poly1305.NewX(key)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to start xchacha20poly1305: %w", err)
|
||||
}
|
||||
ciphertext := c2p1.Seal(nil, concat[2+16:2+16+24], secretKey, ad)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to encrypt: %w", err)
|
||||
}
|
||||
copy(concat[2+16+24+1:], ciphertext)
|
||||
|
||||
bits5, err := bech32.ConvertBits(concat, 8, 5, true)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return bech32.Encode("ncryptsec", bits5)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user