Skip to content

Commit

Permalink
nip49: encrypt before decrypt.
Browse files Browse the repository at this point in the history
  • Loading branch information
fiatjaf committed Jan 25, 2024
1 parent 84134f7 commit 58ff5f6
Showing 1 changed file with 44 additions and 44 deletions.
88 changes: 44 additions & 44 deletions nip49/nip49.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
}

0 comments on commit 58ff5f6

Please sign in to comment.