package crypto import ( "crypto/aes" "crypto/cipher" "crypto/rand" "errors" "fmt" "io" ) var ErrAuthenticationFailed = errors.New("cipher: message authentication failed") func GCMEncrypt(key []byte, plaintext []byte) ([]byte, error) { if len(key) != 32 { return nil, fmt.Errorf("key is not 32 bytes") } block, err := aes.NewCipher(key) if err != nil { return nil, err } gcm, err := cipher.NewGCM(block) if err != nil { return nil, err } nonce := make([]byte, gcm.NonceSize()) _, err = io.ReadFull(rand.Reader, nonce) if err != nil { return nil, err } return gcm.Seal(nonce, nonce, plaintext, nil), nil } func GCMDecrypt(key []byte, ciphertext []byte) ([]byte, error) { if len(key) != 32 { return nil, fmt.Errorf("key is not 32 bytes") } block, err := aes.NewCipher(key) if err != nil { return nil, err } gcm, err := cipher.NewGCM(block) if err != nil { return nil, err } if len(ciphertext) < gcm.NonceSize() { return nil, errors.New("malformed ciphertext") } return gcm.Open(nil, ciphertext[:gcm.NonceSize()], ciphertext[gcm.NonceSize():], nil, ) }