package chachapoly import ( "crypto/rand" "fmt" "io" coreerr "dappco.re/go/core/log" "golang.org/x/crypto/chacha20poly1305" ) // Encrypt encrypts data using ChaCha20-Poly1305. func Encrypt(plaintext []byte, key []byte) ([]byte, error) { aead, err := chacha20poly1305.NewX(key) if err != nil { return nil, err } nonce := make([]byte, aead.NonceSize(), aead.NonceSize()+len(plaintext)+aead.Overhead()) if _, err := io.ReadFull(rand.Reader, nonce); err != nil { return nil, err } return aead.Seal(nonce, nonce, plaintext, nil), nil } // Decrypt decrypts data using ChaCha20-Poly1305. func Decrypt(ciphertext []byte, key []byte) ([]byte, error) { const op = "chachapoly.Decrypt" aead, err := chacha20poly1305.NewX(key) if err != nil { return nil, coreerr.E(op, "failed to create cipher", err) } minLen := aead.NonceSize() + aead.Overhead() if len(ciphertext) < minLen { return nil, coreerr.E(op, fmt.Sprintf("ciphertext too short: got %d bytes, need at least %d bytes", len(ciphertext), minLen), nil) } nonce, ciphertext := ciphertext[:aead.NonceSize()], ciphertext[aead.NonceSize():] decrypted, err := aead.Open(nil, nonce, ciphertext, nil) if err != nil { return nil, coreerr.E(op, "decryption failed", err) } if len(decrypted) == 0 { return []byte{}, nil } return decrypted, nil }