cipherlib
A pure-Dart symmetric cryptography library with modern stream ciphers, AEAD support, and a broad AES mode set.
cipherlib provides AES (multiple modes), ChaCha20/XChaCha20, Salsa20/XSalsa20, XOR, and Poly1305-based AEAD variants. The only runtime dependency is hashlib.
At a glance
- Pure Dart implementation with no native bindings.
- One-shot and stream APIs for common cipher workflows.
- Broad AES mode coverage, including GCM and XTS.
- Modern AEAD options: ChaCha20-Poly1305, XChaCha20-Poly1305, Salsa20-Poly1305, XSalsa20-Poly1305.
- Cross-library comparisons and benchmark data included.
Features
| Ciphers | Public class and methods | Source |
|---|---|---|
| AES | AES |
NIST.FIPS.197 |
| XOR | XOR, xor |
Wikipedia |
| ChaCha20 | ChaCha20, chacha20 |
RFC-8439 |
| ChaCha20/Poly1305 | ChaCha20Poly1305, chacha20poly1305 |
RFC-8439 |
| XChaCha20 | XChaCha20, xchacha20 |
libsodium |
| XChaCha20/Poly1305 | XChaCha20Poly1305, xchacha20poly1305 |
libsodium |
| Salsa20 | Salsa20, salsa20 |
Snuffle-2005 |
| Salsa20/Poly1305 | Salsa20Poly1305, salsa20poly1305 |
Snuffle-2005 |
| XSalsa20 | XSalsa20, xsalsa20 |
libsodium |
| XSalsa20/Poly1305 | XSalsa20Poly1305, xsalsa20poly1305 |
libsodium |
Every stream cipher is a StreamTransformer — pipe a Stream<List<int>>
through cipher.bind(...), or use the stream() extension method for
byte-by-byte Stream<int> processing.
Available modes for AES:
ECB: Electronic CodeblockCBC: Cipher Block ChainingCTR: CounterGCM: Galois/Counter ModeCCM: Counter with CBC-MACCFB: Cipher FeedbackOFB: Output FeedbackIGE: Infinite Garble ExtensionPCBC: Propagating Cipher Block ChainingXTS: XEX (XOR-Encrypt-XOR) Tweakable Block Cipher with Ciphertext Stealing
Getting started
The following import will give you access to all of the algorithms in this package.
import 'package:cipherlib/cipherlib.dart';
API docs: cipherlib library reference
Usage
Start with the full runnable examples in example folder.
import 'package:cipherlib/cipherlib.dart';
import 'package:cipherlib/codecs.dart';
import 'package:cipherlib/random.dart';
void main() {
aesGcmExample();
chacha20Poly1305Example();
xchacha20Poly1305Example();
tamperedMessageExample();
}
void aesGcmExample() {
print('----- AES-256-GCM (recommended for most apps) -----');
final plain = toUtf8('A practical message payload');
final key = randomBytes(32);
final nonce = randomBytes(12);
final aad = toUtf8('request-id=42');
final aes = AES(key).gcm(nonce, aad: aad);
final sealed = aes.encrypt(plain);
final opened = aes.decrypt(sealed);
print(' Key: ${toHex(key)}');
print(' Nonce: ${toHex(nonce)}');
print(' AAD: ${fromUtf8(aad)}');
print('Cipher: ${toHex(sealed)}');
print(' Plain: ${fromUtf8(opened)}');
print('');
}
void chacha20Poly1305Example() {
print('----- ChaCha20-Poly1305 (mobile/network friendly) -----');
final text = 'Hide me with ChaCha20';
final key = randomBytes(32);
final nonce = randomBytes(12);
final aad = toUtf8('content-type:text');
final sealed = chacha20poly1305(
toUtf8(text),
key,
nonce: nonce,
aad: aad,
);
final opened = chacha20poly1305(
sealed.data,
key,
nonce: nonce,
aad: aad,
mac: sealed.mac.bytes,
);
print(' Text: $text');
print(' Key: ${toHex(key)}');
print(' Nonce: ${toHex(nonce)}');
print('Cipher: ${toHex(sealed.data)}');
print(' Tag: ${sealed.mac.hex()}');
print(' Plain: ${fromUtf8(opened.data)}');
print('');
}
void xchacha20Poly1305Example() {
print('----- XChaCha20-Poly1305 (extended nonce) -----');
final text = 'Hide me!';
final key = randomBytes(32);
final nonce = randomBytes(24);
final sealed = xchacha20poly1305(
toUtf8(text),
key,
nonce: nonce,
aad: toUtf8('demo-aad'),
);
final opened = xchacha20poly1305(
sealed.data,
key,
nonce: nonce,
aad: toUtf8('demo-aad'),
mac: sealed.mac.bytes,
);
print(' Text: $text');
print(' Key: ${toHex(key)}');
print(' Nonce: ${toHex(nonce)}');
print('Cipher: ${toHex(sealed.data)}');
print(' Tag: ${sealed.mac.hex()}');
print(' Plain: ${fromUtf8(opened.data)}');
print('');
}
void tamperedMessageExample() {
print('----- Tamper detection -----');
final key = randomBytes(32);
final nonce = randomBytes(24);
final sealed = xchacha20poly1305(
toUtf8('integrity protected'),
key,
nonce: nonce,
);
final badTag = List<int>.from(sealed.mac.bytes)..[0] ^= 0xff;
try {
xchacha20poly1305(
sealed.data,
key,
nonce: nonce,
mac: badTag,
);
print('Unexpected: tampered message accepted');
} on StateError catch (e) {
print('Rejected tampered message: ${e.message}');
}
print('');
}
Benchmarks
Libraries:
- Cipherlib : https://pub.dev/packages/cipherlib
- PointyCastle : https://pub.dev/packages/pointycastle
- Cryptography : https://pub.dev/packages/cryptography
With 1MB message:
| Algorithms | cipherlib |
PointyCastle |
cryptography |
|---|---|---|---|
| XOR | 9.1 Gbps | ||
| Salsa20 | 2.16 Gbps | 356 Mbps 6.07x slow |
|
| Salsa20/Poly1305 | 2.16 Gbps | ||
| XSalsa20 | 2.16 Gbps | ||
| XSalsa20/Poly1305 | 2.15 Gbps | ||
| ChaCha20 | 2.01 Gbps | 359 Mbps 5.61x slow |
|
| ChaCha20/Poly1305 | 1.21 Gbps | 279 Mbps 4.33x slow |
283 Mbps 4.26x slow |
| XChaCha20 | 2.01 Gbps | ||
| XChaCha20/Poly1305 | 1.21 Gbps | ||
| AES-128/CBC | 1.47 Gbps | 234 Mbps 6.29x slow |
1.41 Gbps 1.05x slow |
| AES-192/CBC | 1.27 Gbps | 203 Mbps 6.28x slow |
1.22 Gbps 1.05x slow |
| AES-256/CBC | 1.12 Gbps | 181 Mbps 6.22x slow |
1.07 Gbps 1.05x slow |
| AES-128/CFB | 646 Mbps | 4.04 Mbps 159.66x slow |
|
| AES-192/CFB | 568 Mbps | 4.09 Mbps 138.91x slow |
|
| AES-256/CFB | 506 Mbps | 4.06 Mbps 124.59x slow |
|
| AES-128/CTR | 1.55 Gbps | 223 Mbps 6.96x slow |
746 Mbps 2.08x slow |
| AES-192/CTR | 1.34 Gbps | 195 Mbps 6.84x slow |
690 Mbps 1.94x slow |
| AES-256/CTR | 1.17 Gbps | 174 Mbps 6.73x slow |
642 Mbps 1.82x slow |
| AES-128/ECB | 1.5 Gbps | 250 Mbps 6.03x slow |
|
| AES-192/ECB | 1.29 Gbps | 215 Mbps 5.99x slow |
|
| AES-256/ECB | 1.12 Gbps | 189 Mbps 5.96x slow |
|
| AES-128/GCM | 232 Mbps | 12.7 Mbps 18.27x slow |
154 Mbps 1.51x slow |
| AES-192/GCM | 226 Mbps | 12.61 Mbps 17.95x slow |
154 Mbps 1.46x slow |
| AES-256/GCM | 221 Mbps | 12.49 Mbps 17.7x slow |
146 Mbps 1.51x slow |
| AES-128/IGE | 1.43 Gbps | 212 Mbps 6.74x slow |
|
| AES-192/IGE | 1.24 Gbps | 187 Mbps 6.63x slow |
|
| AES-256/IGE | 1.09 Gbps | 166 Mbps 6.55x slow |
|
| AES-128/OFB | 641 Mbps | 122 Mbps 5.25x slow |
|
| AES-192/OFB | 560 Mbps | 106 Mbps 5.31x slow |
|
| AES-256/OFB | 503 Mbps | 93.16 Mbps 5.4x slow |
|
| AES-128/PCBC | 1.47 Gbps | ||
| AES-192/PCBC | 1.27 Gbps | ||
| AES-256/PCBC | 1.12 Gbps | ||
| AES-128/XTS | 1.42 Gbps | ||
| AES-192/XTS | 1.24 Gbps | ||
| AES-256/XTS | 1.1 Gbps |
With 1KB message:
| Algorithms | cipherlib |
PointyCastle |
cryptography |
|---|---|---|---|
| XOR | 9.22 Gbps | ||
| Salsa20 | 2.15 Gbps | 348 Mbps 6.17x slow |
|
| Salsa20/Poly1305 | 2.03 Gbps | ||
| XSalsa20 | 2.01 Gbps | ||
| XSalsa20/Poly1305 | 1.9 Gbps | ||
| ChaCha20 | 2 Gbps | 353 Mbps 5.68x slow |
|
| ChaCha20/Poly1305 | 1.13 Gbps | 258 Mbps 4.38x slow |
261 Mbps 4.33x slow |
| XChaCha20 | 1.88 Gbps | ||
| XChaCha20/Poly1305 | 1.09 Gbps | ||
| AES-128/CBC | 1.34 Gbps | 206 Mbps 6.51x slow |
1.02 Gbps 1.31x slow |
| AES-192/CBC | 1.17 Gbps | 180 Mbps 6.49x slow |
893 Mbps 1.31x slow |
| AES-256/CBC | 1.03 Gbps | 160 Mbps 6.41x slow |
785 Mbps 1.31x slow |
| AES-128/CFB | 635 Mbps | 109 Mbps 5.85x slow |
|
| AES-192/CFB | 558 Mbps | 94.94 Mbps 5.88x slow |
|
| AES-256/CFB | 498 Mbps | 84.55 Mbps 5.89x slow |
|
| AES-128/CTR | 1.45 Gbps | 201 Mbps 7.21x slow |
594 Mbps 2.44x slow |
| AES-192/CTR | 1.25 Gbps | 175 Mbps 7.15x slow |
556 Mbps 2.25x slow |
| AES-256/CTR | 1.09 Gbps | 157 Mbps 6.95x slow |
517 Mbps 2.12x slow |
| AES-128/ECB | 1.36 Gbps | 219 Mbps 6.18x slow |
|
| AES-192/ECB | 1.18 Gbps | 190 Mbps 6.2x slow |
|
| AES-256/ECB | 1.04 Gbps | 168 Mbps 6.17x slow |
|
| AES-128/GCM | 364 Mbps | 15.14 Mbps 24.06x slow |
248 Mbps 1.47x slow |
| AES-192/GCM | 352 Mbps | 14.51 Mbps 24.27x slow |
242 Mbps 1.45x slow |
| AES-256/GCM | 335 Mbps | 14.51 Mbps 23.06x slow |
227 Mbps 1.47x slow |
| AES-128/IGE | 1.31 Gbps | 189 Mbps 6.94x slow |
|
| AES-192/IGE | 1.15 Gbps | 166 Mbps 6.89x slow |
|
| AES-256/IGE | 1.01 Gbps | 150 Mbps 6.71x slow |
|
| AES-128/OFB | 630 Mbps | 115 Mbps 5.48x slow |
|
| AES-192/OFB | 555 Mbps | 99.45 Mbps 5.58x slow |
|
| AES-256/OFB | 494 Mbps | 88.28 Mbps 5.59x slow |
|
| AES-128/PCBC | 1.35 Gbps | ||
| AES-192/PCBC | 1.18 Gbps | ||
| AES-256/PCBC | 1.04 Gbps | ||
| AES-128/XTS | 1.29 Gbps | ||
| AES-192/XTS | 1.13 Gbps | ||
| AES-256/XTS | 994 Mbps |
With 32B message:
| Algorithms | cipherlib |
PointyCastle |
cryptography |
|---|---|---|---|
| XOR | 7.99 Gbps | ||
| Salsa20 | 1.01 Gbps | 135 Mbps 7.49x slow |
|
| Salsa20/Poly1305 | 541 Mbps | ||
| XSalsa20 | 513 Mbps | ||
| XSalsa20/Poly1305 | 352 Mbps | ||
| ChaCha20 | 941 Mbps | 135 Mbps 6.95x slow |
|
| ChaCha20/Poly1305 | 322 Mbps | 116 Mbps 2.79x slow |
67.32 Mbps 4.79x slow |
| XChaCha20 | 489 Mbps | ||
| XChaCha20/Poly1305 | 243 Mbps | ||
| AES-128/CBC | 334 Mbps | 44.76 Mbps 7.47x slow |
107 Mbps 3.13x slow |
| AES-192/CBC | 307 Mbps | 39.74 Mbps 7.72x slow |
96.84 Mbps 3.17x slow |
| AES-256/CBC | 267 Mbps | 36.82 Mbps 7.25x slow |
87.24 Mbps 3.06x slow |
| AES-128/CFB | 416 Mbps | 42.35 Mbps 9.83x slow |
|
| AES-192/CFB | 390 Mbps | 36.98 Mbps 10.55x slow |
|
| AES-256/CFB | 334 Mbps | 34.58 Mbps 9.67x slow |
|
| AES-128/CTR | 456 Mbps | 48.93 Mbps 9.32x slow |
78.98 Mbps 5.77x slow |
| AES-192/CTR | 419 Mbps | 43.64 Mbps 9.6x slow |
79.12 Mbps 5.3x slow |
| AES-256/CTR | 358 Mbps | 40.93 Mbps 8.74x slow |
75.85 Mbps 4.72x slow |
| AES-128/ECB | 356 Mbps | 47.47 Mbps 7.5x slow |
|
| AES-192/ECB | 324 Mbps | 41.55 Mbps 7.81x slow |
|
| AES-256/ECB | 281 Mbps | 38.22 Mbps 7.36x slow |
|
| AES-128/GCM | 64.09 Mbps | 5.03 Mbps 12.75x slow |
50.56 Mbps 1.27x slow |
| AES-192/GCM | 62.52 Mbps | 4.9 Mbps 12.75x slow |
48.56 Mbps 1.29x slow |
| AES-256/GCM | 60.84 Mbps | 4.8 Mbps 12.66x slow |
45.88 Mbps 1.33x slow |
| AES-128/IGE | 363 Mbps | 43.78 Mbps 8.3x slow |
|
| AES-192/IGE | 331 Mbps | 38.58 Mbps 8.59x slow |
|
| AES-256/IGE | 284 Mbps | 36.19 Mbps 7.85x slow |
|
| AES-128/OFB | 428 Mbps | 43.09 Mbps 9.94x slow |
|
| AES-192/OFB | 406 Mbps | 37.56 Mbps 10.8x slow |
|
| AES-256/OFB | 345 Mbps | 34.85 Mbps 9.91x slow |
|
| AES-128/PCBC | 386 Mbps | ||
| AES-192/PCBC | 354 Mbps | ||
| AES-256/PCBC | 300 Mbps | ||
| AES-128/XTS | 329 Mbps | ||
| AES-192/XTS | 306 Mbps | ||
| AES-256/XTS | 254 Mbps |
All benchmarks are done on 36GB Apple M3 Pro using compiled exe
Dart SDK version: 3.8.1 (stable) (Wed May 28 00:47:25 2025 -0700) on "macos_arm64"