nip49: encrypt before decrypt.

This commit is contained in:
fiatjaf 2024-01-25 10:43:40 -03:00
parent 84134f7d8e
commit 58ff5f6716
No known key found for this signature in database
GPG Key ID: BAD43C4BE5C1A3A1

View File

@ -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)
}