AES-256-GCM Authenticated Encryption
Source: Custom
Topics: symmetric encryption, AEAD, AES-GCM, nonces
Problem
Implement authenticated encryption with AES-256-GCM — the symmetric AEAD scheme used to
encrypt secrets, tokens, and payloads at rest and in transit. GCM gives you confidentiality
and integrity: a tampered ciphertext fails to decrypt rather than returning garbage.
Requirements:
Encrypt(key, plaintext []byte) ([]byte, error) — AES-256-GCM. Generate a fresh random nonce
per call and return nonce || ciphertext || tag as a single blob. key must be 32 bytes.
Decrypt(key, data []byte) ([]byte, error) — split off the nonce, verify the auth tag, and
return the plaintext. Tampered data → ErrAuthentication.
- Errors:
ErrInvalidKeySize (key ≠ 32 bytes), ErrMalformed (data too short to hold a nonce),
ErrAuthentication (tag mismatch).
var (
ErrInvalidKeySize = errors.New("aesgcm: key must be 32 bytes")
ErrMalformed = errors.New("aesgcm: ciphertext too short")
ErrAuthentication = errors.New("aesgcm: authentication failed")
)
func Encrypt(key, plaintext []byte) ([]byte, error)
func Decrypt(key, data []byte) ([]byte, error)
Key concepts
- AEAD (Authenticated Encryption with Associated Data): GCM produces ciphertext plus an
authentication tag.
Open recomputes the tag and refuses to return plaintext if it doesn't
match — so an attacker can't flip bits undetected.
- Nonce uniqueness is critical: reusing a (key, nonce) pair in GCM is catastrophic — it leaks
the XOR of plaintexts and breaks authentication. Always generate a fresh random nonce per
message (
crypto/rand), and store it alongside the ciphertext (it's not secret).
cipher.NewGCM + Seal/Open: Seal(nonce, nonce, plaintext, nil) prepends the nonce to
the output; Open(nil, nonce, ciphertext, nil) reverses it. The 4th arg is associated data —
extra bytes authenticated but not encrypted (e.g. a header), omitted here.
- 256-bit key: AES-256 requires a 32-byte key;
aes.NewCipher picks the variant from the key
length, so enforcing 32 bytes is what makes this AES-256.
Run
go test -v ./challenges/crypto/aes-gcm/
Sign in to submit your solution.