Source: aes_gcm.zigTests: aes_gcm.test.ts
Try it Live
Run AES-GCM examples in the interactive playground
Overview
AES-GCM is an authenticated encryption algorithm combining AES (Advanced Encryption Standard) in Galois/Counter Mode, providing both confidentiality and authenticity with a single key. Ethereum context: Not on Ethereum - Used for encrypted wallet storage (e.g., UTC/JSON keystore format) and secure messaging. Not part of Ethereum protocol. Key features:- Authenticated encryption: Confidentiality + integrity in one operation
- Performance: Hardware-accelerated on modern CPUs
- Parallelizable: Can encrypt/decrypt blocks in parallel
- Additional data: Authenticate without encrypting (AAD)
- Standards-compliant: NIST approved, widely used
- Key sizes: 128, 192, or 256 bits
- Implementations: Native Zig (16KB), NO WASM (not in browser crypto standard libs)
Quick Start
API Reference
Key Management
generateKey(bits: 128 | 256): Promise<CryptoKey>
Generates a cryptographically secure AES key.
Parameters:
bits- Key size (128 or 256 bits)- 128-bit: Faster, still very secure
- 256-bit: Maximum security, recommended for sensitive data
deriveKey(password: string | Uint8Array, salt: Uint8Array, iterations: number, bits: 128 | 256): Promise<CryptoKey>
Derives key from password using PBKDF2-HMAC-SHA256.
Parameters:
password- User password (string or bytes)salt- Salt for key derivation (≥16 bytes recommended)iterations- PBKDF2 iterations (≥100,000 recommended)bits- Key size (128 or 256)
importKey(keyData: Uint8Array): Promise<CryptoKey>
Imports raw key bytes as CryptoKey.
exportKey(key: CryptoKey): Promise<Uint8Array>
Exports CryptoKey to raw bytes.
Encryption/Decryption
encrypt(plaintext: Uint8Array, key: CryptoKey, nonce: Uint8Array, additionalData?: Uint8Array): Promise<Uint8Array>
Encrypts data with AES-GCM, returns ciphertext with authentication tag appended.
Parameters:
plaintext- Data to encryptkey- AES key (fromgenerateKeyorderiveKey)nonce- 12-byte nonce/IV (must be unique per encryption)additionalData- Optional AAD (authenticated but not encrypted)
decrypt(ciphertext: Uint8Array, key: CryptoKey, nonce: Uint8Array, additionalData?: Uint8Array): Promise<Uint8Array>
Decrypts AES-GCM ciphertext, verifies authentication tag.
Parameters:
ciphertext- Encrypted data with tagkey- Same key used for encryptionnonce- Same nonce used for encryptionadditionalData- Same AAD used for encryption (if any)
InvalidNonceError- Nonce not 12 bytesDecryptionError- Authentication tag verification fails (data tampered), wrong key/nonce/AAD used, or corrupted ciphertext
Nonce Generation
generateNonce(): Uint8Array
Generates cryptographically secure 12-byte nonce.
Constants
Nonce Management
Critical: Never reuse a nonce with the same key!Safe Nonce Usage
Storage Format
Store nonce with ciphertext (nonce is not secret):Nonce Collision Risk
With random nonces (12 bytes), collision probability:- After 2³² encryptions: ~0.005% chance
- After 2⁴⁸ encryptions: 50% chance (birthday paradox)
- Random nonces: Safe for up to ~2³² encryptions per key
- Counter-based: Increment counter for each encryption (no collisions)
- Key rotation: Generate new key periodically to reset nonce space
Additional Authenticated Data (AAD)
AAD is authenticated but not encrypted - useful for metadata:- Protocol version numbers
- Timestamps
- User IDs
- Packet headers
- Database row IDs
- AAD is authenticated (tampering detected)
- AAD is NOT encrypted (readable by anyone)
- Must provide same AAD for decryption
Password-Based Encryption
Derive key from user password using PBKDF2:Key Storage
Secure Storage Patterns
1. Environment variables (server-side)Security
Critical Warnings
1. Never reuse nonce with same keyBest Practices
1. Key size: Use 256-bit keys for sensitive dataCommon Attacks
Nonce Reuse Attack:- Same nonce + key reveals XOR of plaintexts
- Protection: Always generate new nonce
- Too many encryptions with same key increases collision risk
- Protection: Rotate keys periodically
- Brute-force PBKDF2-derived keys
- Protection: Strong passwords + high iteration count
- Constant-time operations in WebCrypto API
- Protection: Use native crypto.subtle (not hand-rolled crypto)
- Not applicable to GCM (no padding)
- GCM uses stream cipher mode
Performance
Benchmarks (typical)
Encryption speed (AES-256-GCM):- Modern CPU with AES-NI: 1-5 GB/s
- Without hardware acceleration: 50-200 MB/s
- 100,000 iterations: ~50-100ms
- 600,000 iterations: ~300-600ms
Optimization Tips
1. Batch operations when possibleUse Cases
File Encryption
Database Field Encryption
Secure Messaging
Error Handling
All AesGcm functions throw typed errors that extendCryptoError:
| Error | Code | When |
|---|---|---|
InvalidKeyError | INVALID_KEY | Key not 16 or 32 bytes on import |
InvalidNonceError | INVALID_NONCE | Nonce not 12 bytes |
DecryptionError | DECRYPTION_FAILED | Auth tag verification fails, wrong key/nonce/AAD, or ciphertext too short |
AesGcmError | AES_GCM_ERROR | Generic encryption failure |
name- Error class name (e.g.,"DecryptionError")code- Machine-readable error codemessage- Human-readable descriptiondocsPath- Link to relevant documentation
Implementation Notes
- Uses native WebCrypto API (
crypto.subtle) - Hardware-accelerated on modern CPUs (AES-NI)
- Constant-time operations (timing attack resistant)
- NIST SP 800-38D compliant
- 128-bit authentication tag (maximum security)
- 96-bit nonce (12 bytes, standard for GCM)

