A pure-Dart cryptography library: modern stream ciphers, authenticated encryption, a full AES mode set, and post-quantum cryptography with no native bindings and a single dependency.
cipherlib is the top layer of a three-package family:
It reuses hashlib for the SHA-3/SHAKE, Poly1305, and secure-random
primitives it is built on, and that is its only runtime dependency.
- Runs on every platform: pure Dart with no native code or FFI, so the same library works everywhere Dart does: the VM, Flutter (Android, iOS, Windows, macOS, Linux), and the web (dart2js and dart2wasm).
- Authenticated by default: AES-GCM, AES-CCM, and a Poly1305 variant of every stream cipher, each with a constant-time tag check that rejects tampered messages.
- Broad AES coverage: ten modes, from ECB and CBC to GCM, CCM, and XTS.
- One-shot or streaming: encrypt a buffer in a single call, or pipe a
Stream<List<int>>through any cipher as aStreamTransformer. - Post-quantum ready: ML-KEM-512/768/1024 (FIPS 203) for quantum-resistant key exchange.
- Fast: consistently outruns
PointyCastleandcryptography, see in the benchmarks below.
dependencies:
cipherlib: ^0.7.1or run dart pub add cipherlib. A single import exposes every algorithm:
import 'package:cipherlib/cipherlib.dart';Two optional companions pair well with it — codecs for hex/UTF-8 conversion
(re-exported from hashlib) and random for secure key and nonce generation:
import 'package:cipherlib/codecs.dart'; // toHex, fromHex, toUtf8, fromUtf8
import 'package:cipherlib/random.dart'; // randomBytesFull API reference: cipherlib library.
AES-256-GCM is the recommended default for most applications: it encrypts and authenticates in one step, and decryption fails loudly if the ciphertext or the associated data bound to it was modified.
import 'package:cipherlib/cipherlib.dart';
import 'package:cipherlib/codecs.dart';
import 'package:cipherlib/random.dart';
void main() {
final key = randomBytes(32); // AES-256
final nonce = randomBytes(12); // Recommended IV size for GCM
final aad = toUtf8('order-id=INV-1001');
final plain = toUtf8('Ship 3 units to dock-7');
final aes = AES(key).gcm(nonce, aad: aad);
final sealed = aes.encrypt(plain);
final opened = aes.decrypt(sealed);
print('AES-256-GCM');
print('key : ${toHex(key)}');
print('nonce : ${toHex(nonce)}');
print('aad : ${fromUtf8(aad)}');
print('cipher: ${toHex(sealed)}');
print('plain : ${fromUtf8(opened)}');
}Every snippet in this README is also a runnable program in the example folder.
| Algorithm | Public class and methods | Source |
|---|---|---|
| AES | AES |
NIST.FIPS.197 |
| Blowfish | Blowfish |
Blowfish-1993 |
| Twofish | Twofish |
Twofish-1998 |
AES supports 10 modes:
ECB- Electronic CodebookCBC- Cipher Block ChainingCTR- CounterGCM- Galois/Counter Mode (authenticated)CCM- Counter with CBC-MAC (authenticated)CFB- Cipher FeedbackOFB- Output FeedbackIGE- Infinite Garble ExtensionPCBC- Propagating Cipher Block ChainingXTS- XEX Tweakable Block Cipher with Ciphertext Stealing
Blowfish and Twofish support 2 modes:
ECB- Electronic CodebookCBC- Cipher Block ChainingCTR- Counter
| Algorithm | Public class and methods | Source |
|---|---|---|
| XOR | XOR, xor |
Wikipedia |
| ChaCha20 | ChaCha20, chacha20 |
RFC-8439 |
| XChaCha20 | XChaCha20, xchacha20 |
libsodium |
| Salsa20 | Salsa20, salsa20 |
Snuffle-2005 |
| XSalsa20 | XSalsa20, xsalsa20 |
libsodium |
| Algorithm | Public class and methods | Source |
|---|---|---|
| ChaCha20/Poly1305 | ChaCha20Poly1305, chacha20poly1305 |
RFC-8439 |
| XChaCha20/Poly1305 | XChaCha20Poly1305, xchacha20poly1305 |
libsodium |
| Salsa20/Poly1305 | Salsa20Poly1305, salsa20poly1305 |
Snuffle-2005 |
| XSalsa20/Poly1305 | XSalsa20Poly1305, xsalsa20poly1305 |
libsodium |
AES adds authenticated encryption through its GCM and CCM modes.
| Algorithm | Public class and methods | Source |
|---|---|---|
| ML-KEM | MLKEM |
NIST.FIPS.203 |
MLKEM.kem512(), MLKEM.kem768(), and MLKEM.kem1024() provide key
generation, encapsulation, and decapsulation, with optional deterministic key
generation from a 64-byte seed.
- Never reuse a
(key, nonce)pair. For the stream ciphers and for AES-CTR/GCM/CCM, encrypting two messages under the same key and nonce destroys confidentiality — and for GCM/CCM it also lets an attacker forge tags. Use a fresh random nonce (or a strictly increasing counter) per message; XChaCha20/XSalsa20's 24-byte nonce is large enough to randomize safely. - AES is not constant-time. The pure-Dart AES uses table lookups, which are not guaranteed to run in constant time. Weigh the deployment environment before using it where cache-timing side channels matter.
- ML-KEM timing. The implementation follows the constant-time structure of the reference implementation, but Dart runtimes (JIT, AOT, dart2js) cannot guarantee constant-time execution. Consider the deployment environment before using ML-KEM in side-channel-sensitive settings.
A fast software AEAD, well suited to mobile and network protocols. The one-shot
function returns both the ciphertext (.data) and the tag (.mac); pass the
tag back on decryption and a mismatch throws.
import 'package:cipherlib/cipherlib.dart';
import 'package:cipherlib/codecs.dart';
import 'package:cipherlib/random.dart';
void main() {
final key = randomBytes(32);
final nonce = randomBytes(12);
final aad = toUtf8('content-type=application/json');
final message = toUtf8('{"event":"payment.settled","id":42}');
final sealed = chacha20poly1305(
message,
key,
nonce: nonce,
aad: aad,
);
final opened = chacha20poly1305(
sealed.data,
key,
nonce: nonce,
aad: aad,
mac: sealed.mac.bytes,
);
print('ChaCha20-Poly1305');
print('key : ${toHex(key)}');
print('nonce : ${toHex(nonce)}');
print('tag : ${sealed.mac.hex()}');
print('cipher: ${toHex(sealed.data)}');
print('plain : ${fromUtf8(opened.data)}');
}XChaCha20 widens the nonce to 24 bytes, so a random nonce per message is safe
without tracking a counter. Append poly1305 (xchacha20poly1305) for the
authenticated variant.
import 'package:cipherlib/cipherlib.dart';
import 'package:cipherlib/codecs.dart';
import 'package:cipherlib/random.dart';
void main() {
final key = randomBytes(32);
final nonce = randomBytes(24); // Extended nonce
final plain = toUtf8('XChaCha20 extended nonce payload');
final cipher = xchacha20(plain, key, nonce: nonce);
final opened = xchacha20(cipher, key, nonce: nonce);
print('XChaCha20');
print('key : ${toHex(key)}');
print('nonce : ${toHex(nonce)}');
print('cipher: ${toHex(cipher)}');
print('plain : ${fromUtf8(opened)}');
}For interoperability with systems that expect classic block modes. AES.pkcs7
adds and strips padding automatically, and encryptString/decrypt handle the
UTF-8 conversion.
import 'package:cipherlib/cipherlib.dart';
import 'package:cipherlib/codecs.dart';
import 'package:cipherlib/random.dart';
void main() {
final key = randomBytes(32);
final iv = randomBytes(16);
final plain = 'Confidential invoice payload';
// PKCS7 is the common padding choice for block modes like CBC.
final cbc = AES.pkcs7(key).cbc(iv);
final cipher = cbc.encryptString(plain);
final opened = cbc.decrypt(cipher);
print('AES-256-CBC + PKCS7');
print('key : ${toHex(key)}');
print('iv : ${toHex(iv)}');
print('cipher: ${toHex(cipher)}');
print('plain : ${fromUtf8(opened)}');
}Every stream cipher is a StreamTransformer<List<int>, Uint8List>, so a
Stream<List<int>> can be piped through cipher.bind(...) (or
stream.transform(cipher)) and processed chunk by chunk without buffering the
whole message in memory:
import 'package:cipherlib/cipherlib.dart';
import 'package:cipherlib/codecs.dart';
import 'package:cipherlib/random.dart';
Future<void> main() async {
final key = randomBytes(32);
final nonce = randomBytes(12);
final chacha = ChaCha20(key, nonce);
final plainChunks = Stream<List<int>>.fromIterable([
toUtf8('a streamed '),
toUtf8('message'),
]);
await for (final encrypted in chacha.bind(plainChunks)) {
print(toHex(encrypted));
}
}For byte-by-byte Stream<int> sources, use the stream() extension instead of
bind.
Authenticated ciphers reject modified input instead of returning garbage —
flipping a single bit of the tag makes decryption throw a StateError:
import 'package:cipherlib/cipherlib.dart';
import 'package:cipherlib/codecs.dart';
import 'package:cipherlib/random.dart';
void main() {
final key = randomBytes(32);
final nonce = randomBytes(24);
final sealed = xchacha20poly1305(
toUtf8('integrity protected'),
key,
nonce: nonce,
);
// Flip one bit of the tag to simulate tampering in transit.
final badTag = List<int>.from(sealed.mac.bytes)..[0] ^= 0xff;
try {
xchacha20poly1305(sealed.data, key, nonce: nonce, mac: badTag);
print('accepted (unexpected)');
} on StateError catch (e) {
print('rejected: ${e.message}');
}
}Two parties agree on a shared secret that stays safe even against an attacker with a quantum computer. Alice publishes her encapsulation key; Bob derives a shared secret and a ciphertext from it; Alice recovers the same secret from the ciphertext.
import 'package:cipherlib/cipherlib.dart';
import 'package:cipherlib/codecs.dart';
void main() {
final kem = MLKEM.kem768();
// Alice generates a key pair and publishes the encapsulation key
final alice = kem.keygen();
// Bob encapsulates a shared secret with Alice's public key and
// transmits the ciphertext back to Alice
final bob = kem.encaps(alice.encapsulationKey);
// Alice recovers the same shared secret from the ciphertext
final shared = kem.decaps(alice.decapsulationKey, bob.cipherText);
print(kem.name);
print('bob : ${bob.sharedSecret.hex()}');
print('alice : ${shared.hex()}');
print('match : ${shared.isEqual(bob.sharedSecret)}');
// A key pair can be stored as its 64-byte seed and re-derived later
final seed = List.generate(64, (i) => i);
final first = kem.keygen(seed: seed);
final again = kem.keygen(seed: seed);
final isSeeded =
toHex(first.encapsulationKey) == toHex(again.encapsulationKey);
print('seeded: $isSeeded');
}The shared secret is a HashDigest; compare it with isEqual (constant-time)
rather than ==, and derive symmetric keys from it with a KDF. A tampered
ciphertext does not throw — ML-KEM performs implicit rejection and returns a
deterministic but unrelated secret, so the two sides simply fail to agree.
- Cipherlib : https://pub.dev/packages/cipherlib
- PointyCastle : https://pub.dev/packages/pointycastle
- Cryptography : https://pub.dev/packages/cryptography
- PQCrypto : https://pub.dev/packages/pqcrypto
| Algorithm | Library | 1MB message | 1KB message | 32B message |
|---|---|---|---|---|
| XOR | cipherlib | ████████████████ 10.85 Gbps 🌟 |
████████████████ 11.1 Gbps 🌟 |
████████████████ 9.49 Gbps 🌟 |
| Salsa20 | cipherlib | ████████████████ 2.17 Gbps 🌟 |
████████████████ 2.13 Gbps 🌟 |
████████████████ 909 Mbps 🌟 |
| PointyCastle | ███░░░░░░░░░░░░░ 351 Mbps 🔻6.17x |
███░░░░░░░░░░░░░ 344 Mbps 🔻6.2x |
██░░░░░░░░░░░░░░ 133 Mbps 🔻6.84x |
|
| Salsa20 / Poly1305 | cipherlib | ████████████████ 2.16 Gbps 🌟 |
████████████████ 2.02 Gbps 🌟 |
████████████████ 509 Mbps 🌟 |
| XSalsa20 | cipherlib | ████████████████ 2.16 Gbps 🌟 |
████████████████ 2.01 Gbps 🌟 |
████████████████ 517 Mbps 🌟 |
| XSalsa20 / Poly1305 | cipherlib | ████████████████ 2.16 Gbps 🌟 |
████████████████ 1.92 Gbps 🌟 |
████████████████ 360 Mbps 🌟 |
| ChaCha20 | cipherlib | ████████████████ 2.02 Gbps 🌟 |
████████████████ 2 Gbps 🌟 |
████████████████ 856 Mbps 🌟 |
| PointyCastle | ███░░░░░░░░░░░░░ 354 Mbps 🔻5.69x |
███░░░░░░░░░░░░░ 348 Mbps 🔻5.74x |
███░░░░░░░░░░░░░ 135 Mbps 🔻6.33x |
|
| ChaCha20 / Poly1305 | cipherlib | ████████████████ 1.38 Gbps 🌟 |
████████████████ 1.26 Gbps 🌟 |
████████████████ 293 Mbps 🌟 |
| cryptography | ███░░░░░░░░░░░░░ 283 Mbps 🔻4.87x |
███░░░░░░░░░░░░░ 258 Mbps 🔻4.89x |
████░░░░░░░░░░░░ 66.66 Mbps 🔻4.4x |
|
| PointyCastle | ███░░░░░░░░░░░░░ 275 Mbps 🔻5.01x |
███░░░░░░░░░░░░░ 256 Mbps 🔻4.93x |
██████░░░░░░░░░░ 116 Mbps 🔻2.53x |
|
| XChaCha20 | cipherlib | ████████████████ 2.01 Gbps 🌟 |
████████████████ 1.88 Gbps 🌟 |
████████████████ 502 Mbps 🌟 |
| XChaCha20 / Poly1305 | cipherlib | ████████████████ 1.38 Gbps 🌟 |
████████████████ 1.25 Gbps 🌟 |
████████████████ 235 Mbps 🌟 |
| Algorithm | Library | 1MB message | 1KB message | 32B message |
|---|---|---|---|---|
| AES-128 / CBC | cipherlib | ████████████████ 1.46 Gbps 🌟 |
████████████████ 1.33 Gbps 🌟 |
████████████████ 338 Mbps 🌟 |
| cryptography | ███████████████░ 1.41 Gbps 🔻1.04x |
████████████░░░░ 1.02 Gbps 🔻1.31x |
█████░░░░░░░░░░░ 107 Mbps 🔻3.16x |
|
| PointyCastle | ███░░░░░░░░░░░░░ 231 Mbps 🔻6.3x |
██░░░░░░░░░░░░░░ 203 Mbps 🔻6.53x |
██░░░░░░░░░░░░░░ 44.35 Mbps 🔻7.61x |
|
| AES-192 / CBC | cipherlib | ████████████████ 1.26 Gbps 🌟 |
████████████████ 1.16 Gbps 🌟 |
████████████████ 310 Mbps 🌟 |
| cryptography | ███████████████░ 1.21 Gbps 🔻1.04x |
████████████░░░░ 889 Mbps 🔻1.31x |
█████░░░░░░░░░░░ 95.84 Mbps 🔻3.23x |
|
| PointyCastle | ███░░░░░░░░░░░░░ 201 Mbps 🔻6.27x |
██░░░░░░░░░░░░░░ 177 Mbps 🔻6.57x |
██░░░░░░░░░░░░░░ 39.48 Mbps 🔻7.84x |
|
| AES-256 / CBC | cipherlib | ████████████████ 1.11 Gbps 🌟 |
████████████████ 1.02 Gbps 🌟 |
████████████████ 269 Mbps 🌟 |
| cryptography | ███████████████░ 1.06 Gbps 🔻1.05x |
████████████░░░░ 783 Mbps 🔻1.3x |
█████░░░░░░░░░░░ 86.94 Mbps 🔻3.09x |
|
| PointyCastle | ███░░░░░░░░░░░░░ 178 Mbps 🔻6.22x |
██░░░░░░░░░░░░░░ 157 Mbps 🔻6.47x |
██░░░░░░░░░░░░░░ 36.37 Mbps 🔻7.39x |
|
| AES-128 / CCM | cipherlib | ████████████████ 554 Mbps 🌟 |
████████████████ 524 Mbps 🌟 |
████████████████ 201 Mbps 🌟 |
| PointyCastle | ███░░░░░░░░░░░░░ 112 Mbps 🔻4.96x |
███░░░░░░░░░░░░░ 97.2 Mbps 🔻5.39x |
██░░░░░░░░░░░░░░ 19.61 Mbps 🔻10.24x |
|
| AES-192 / CCM | cipherlib | ████████████████ 492 Mbps 🌟 |
████████████████ 468 Mbps 🌟 |
████████████████ 185 Mbps 🌟 |
| PointyCastle | ███░░░░░░░░░░░░░ 98.09 Mbps 🔻5.01x |
███░░░░░░░░░░░░░ 84.71 Mbps 🔻5.52x |
█░░░░░░░░░░░░░░░ 16.54 Mbps 🔻11.21x |
|
| AES-256 / CCM | cipherlib | ████████████████ 446 Mbps 🌟 |
████████████████ 423 Mbps 🌟 |
████████████████ 165 Mbps 🌟 |
| PointyCastle | ███░░░░░░░░░░░░░ 86.9 Mbps 🔻5.13x |
███░░░░░░░░░░░░░ 75.36 Mbps 🔻5.61x |
█░░░░░░░░░░░░░░░ 15.38 Mbps 🔻10.76x |
|
| AES-128 / CFB | cipherlib | ████████████████ 639 Mbps 🌟 |
████████████████ 629 Mbps 🌟 |
████████████████ 415 Mbps 🌟 |
| PointyCastle | █░░░░░░░░░░░░░░░ 3.66 Mbps 🔻174.44x |
███░░░░░░░░░░░░░ 107 Mbps 🔻5.9x |
██░░░░░░░░░░░░░░ 41.37 Mbps 🔻10.03x |
|
| AES-192 / CFB | cipherlib | ████████████████ 558 Mbps 🌟 |
████████████████ 546 Mbps 🌟 |
████████████████ 385 Mbps 🌟 |
| PointyCastle | █░░░░░░░░░░░░░░░ 3.64 Mbps 🔻153.4x |
███░░░░░░░░░░░░░ 92.26 Mbps 🔻5.92x |
██░░░░░░░░░░░░░░ 36.57 Mbps 🔻10.53x |
|
| AES-256 / CFB | cipherlib | ████████████████ 504 Mbps 🌟 |
████████████████ 494 Mbps 🌟 |
████████████████ 330 Mbps 🌟 |
| PointyCastle | █░░░░░░░░░░░░░░░ 3.61 Mbps 🔻139.45x |
███░░░░░░░░░░░░░ 82.72 Mbps 🔻5.97x |
██░░░░░░░░░░░░░░ 33.51 Mbps 🔻9.85x |
|
| AES-128 / CTR | cipherlib | ████████████████ 1.51 Gbps 🌟 |
████████████████ 1.46 Gbps 🌟 |
████████████████ 596 Mbps 🌟 |
| cryptography | ████████░░░░░░░░ 734 Mbps 🔻2.05x |
██████░░░░░░░░░░ 579 Mbps 🔻2.52x |
██░░░░░░░░░░░░░░ 77.12 Mbps 🔻7.73x |
|
| PointyCastle | ██░░░░░░░░░░░░░░ 219 Mbps 🔻6.88x |
██░░░░░░░░░░░░░░ 196 Mbps 🔻7.44x |
█░░░░░░░░░░░░░░░ 47.99 Mbps 🔻12.42x |
|
| AES-192 / CTR | cipherlib | ████████████████ 1.31 Gbps 🌟 |
████████████████ 1.27 Gbps 🌟 |
████████████████ 570 Mbps 🌟 |
| cryptography | ████████░░░░░░░░ 680 Mbps 🔻1.93x |
███████░░░░░░░░░ 545 Mbps 🔻2.34x |
██░░░░░░░░░░░░░░ 76.02 Mbps 🔻7.5x |
|
| PointyCastle | ██░░░░░░░░░░░░░░ 193 Mbps 🔻6.82x |
██░░░░░░░░░░░░░░ 172 Mbps 🔻7.41x |
█░░░░░░░░░░░░░░░ 42.99 Mbps 🔻13.26x |
|
| AES-256 / CTR | cipherlib | ████████████████ 1.15 Gbps 🌟 |
████████████████ 1.11 Gbps 🌟 |
████████████████ 489 Mbps 🌟 |
| cryptography | █████████░░░░░░░ 634 Mbps 🔻1.82x |
███████░░░░░░░░░ 513 Mbps 🔻2.17x |
██░░░░░░░░░░░░░░ 73.71 Mbps 🔻6.63x |
|
| PointyCastle | ██░░░░░░░░░░░░░░ 171 Mbps 🔻6.77x |
██░░░░░░░░░░░░░░ 154 Mbps 🔻7.22x |
█░░░░░░░░░░░░░░░ 40.13 Mbps 🔻12.17x |
|
| AES-128 / ECB | cipherlib | ████████████████ 1.49 Gbps 🌟 |
████████████████ 1.35 Gbps 🌟 |
████████████████ 350 Mbps 🌟 |
| PointyCastle | ███░░░░░░░░░░░░░ 249 Mbps 🔻5.97x |
███░░░░░░░░░░░░░ 217 Mbps 🔻6.2x |
██░░░░░░░░░░░░░░ 46.89 Mbps 🔻7.46x |
|
| AES-192 / ECB | cipherlib | ████████████████ 1.28 Gbps 🌟 |
████████████████ 1.17 Gbps 🌟 |
████████████████ 322 Mbps 🌟 |
| PointyCastle | ███░░░░░░░░░░░░░ 215 Mbps 🔻5.94x |
███░░░░░░░░░░░░░ 189 Mbps 🔻6.2x |
██░░░░░░░░░░░░░░ 41.35 Mbps 🔻7.79x |
|
| AES-256 / ECB | cipherlib | ████████████████ 1.12 Gbps 🌟 |
████████████████ 1.03 Gbps 🌟 |
████████████████ 278 Mbps 🌟 |
| PointyCastle | ███░░░░░░░░░░░░░ 189 Mbps 🔻5.96x |
███░░░░░░░░░░░░░ 167 Mbps 🔻6.17x |
██░░░░░░░░░░░░░░ 37.92 Mbps 🔻7.34x |
|
| AES-128 / GCM | cipherlib | ████████████████ 237 Mbps 🌟 |
████████████████ 352 Mbps 🌟 |
████████████████ 63.12 Mbps 🌟 |
| cryptography | ███████████░░░░░ 157 Mbps 🔻1.51x |
███████████░░░░░ 250 Mbps 🔻1.41x |
█████████████░░░ 49.76 Mbps 🔻1.27x |
|
| PointyCastle | █░░░░░░░░░░░░░░░ 12.67 Mbps 🔻18.71x |
█░░░░░░░░░░░░░░░ 15.58 Mbps 🔻22.57x |
█░░░░░░░░░░░░░░░ 5.09 Mbps 🔻12.39x |
|
| AES-192 / GCM | cipherlib | ████████████████ 233 Mbps 🌟 |
████████████████ 350 Mbps 🌟 |
████████████████ 61.76 Mbps 🌟 |
| cryptography | ███████████░░░░░ 158 Mbps 🔻1.47x |
███████████░░░░░ 244 Mbps 🔻1.43x |
████████████░░░░ 48.22 Mbps 🔻1.28x |
|
| PointyCastle | █░░░░░░░░░░░░░░░ 12.59 Mbps 🔻18.47x |
█░░░░░░░░░░░░░░░ 15.24 Mbps 🔻22.96x |
█░░░░░░░░░░░░░░░ 4.94 Mbps 🔻12.51x |
|
| AES-256 / GCM | cipherlib | ████████████████ 226 Mbps 🌟 |
████████████████ 333 Mbps 🌟 |
████████████████ 60.5 Mbps 🌟 |
| cryptography | ███████████░░░░░ 151 Mbps 🔻1.5x |
███████████░░░░░ 229 Mbps 🔻1.45x |
████████████░░░░ 45.65 Mbps 🔻1.33x |
|
| PointyCastle | █░░░░░░░░░░░░░░░ 12.45 Mbps 🔻18.18x |
█░░░░░░░░░░░░░░░ 15.25 Mbps 🔻21.83x |
█░░░░░░░░░░░░░░░ 4.95 Mbps 🔻12.23x |
|
| AES-128 / IGE | cipherlib | ████████████████ 1.41 Gbps 🌟 |
████████████████ 1.3 Gbps 🌟 |
████████████████ 356 Mbps 🌟 |
| PointyCastle | ██░░░░░░░░░░░░░░ 210 Mbps 🔻6.73x |
██░░░░░░░░░░░░░░ 186 Mbps 🔻6.99x |
██░░░░░░░░░░░░░░ 43.57 Mbps 🔻8.17x |
|
| AES-192 / IGE | cipherlib | ████████████████ 1.23 Gbps 🌟 |
████████████████ 1.14 Gbps 🌟 |
████████████████ 329 Mbps 🌟 |
| PointyCastle | ██░░░░░░░░░░░░░░ 184 Mbps 🔻6.65x |
██░░░░░░░░░░░░░░ 164 Mbps 🔻6.92x |
██░░░░░░░░░░░░░░ 38.67 Mbps 🔻8.51x |
|
| AES-256 / IGE | cipherlib | ████████████████ 1.08 Gbps 🌟 |
████████████████ 998 Mbps 🌟 |
████████████████ 286 Mbps 🌟 |
| PointyCastle | ██░░░░░░░░░░░░░░ 165 Mbps 🔻6.52x |
██░░░░░░░░░░░░░░ 148 Mbps 🔻6.76x |
██░░░░░░░░░░░░░░ 35.75 Mbps 🔻8x |
|
| AES-128 / OFB | cipherlib | ████████████████ 637 Mbps 🌟 |
████████████████ 628 Mbps 🌟 |
████████████████ 425 Mbps 🌟 |
| PointyCastle | ███░░░░░░░░░░░░░ 120 Mbps 🔻5.31x |
███░░░░░░░░░░░░░ 113 Mbps 🔻5.54x |
██░░░░░░░░░░░░░░ 42.35 Mbps 🔻10.03x |
|
| AES-192 / OFB | cipherlib | ████████████████ 550 Mbps 🌟 |
████████████████ 552 Mbps 🌟 |
████████████████ 396 Mbps 🌟 |
| PointyCastle | ███░░░░░░░░░░░░░ 104 Mbps 🔻5.3x |
███░░░░░░░░░░░░░ 97.81 Mbps 🔻5.64x |
██░░░░░░░░░░░░░░ 37.25 Mbps 🔻10.64x |
|
| AES-256 / OFB | cipherlib | ████████████████ 500 Mbps 🌟 |
████████████████ 494 Mbps 🌟 |
████████████████ 341 Mbps 🌟 |
| PointyCastle | ███░░░░░░░░░░░░░ 91.42 Mbps 🔻5.47x |
███░░░░░░░░░░░░░ 86.64 Mbps 🔻5.7x |
██░░░░░░░░░░░░░░ 34.42 Mbps 🔻9.92x |
|
| AES-128 / PCBC | cipherlib | ████████████████ 1.45 Gbps 🌟 |
████████████████ 1.34 Gbps 🌟 |
████████████████ 383 Mbps 🌟 |
| AES-192 / PCBC | cipherlib | ████████████████ 1.25 Gbps 🌟 |
████████████████ 1.17 Gbps 🌟 |
████████████████ 347 Mbps 🌟 |
| AES-256 / PCBC | cipherlib | ████████████████ 1.11 Gbps 🌟 |
████████████████ 1.03 Gbps 🌟 |
████████████████ 298 Mbps 🌟 |
| AES-128 / XTS | cipherlib | ████████████████ 1.42 Gbps 🌟 |
████████████████ 1.29 Gbps 🌟 |
████████████████ 333 Mbps 🌟 |
| AES-192 / XTS | cipherlib | ████████████████ 1.23 Gbps 🌟 |
████████████████ 1.13 Gbps 🌟 |
████████████████ 265 Mbps 🌟 |
| AES-256 / XTS | cipherlib | ████████████████ 1.09 Gbps 🌟 |
████████████████ 978 Mbps 🌟 |
████████████████ 256 Mbps 🌟 |
| Algorithm | Library | 1MB message | 1KB message | 32B message |
|---|---|---|---|---|
| Twofish-128 / ECB | cipherlib | ████████████████ 1.08 Gbps 🌟 |
████████████████ 638 Mbps 🌟 |
████████████████ 45.85 Mbps 🌟 |
| PointyCastle | █░░░░░░░░░░░░░░░ 1.84 Mbps 🔻585.2x |
█████████░░░░░░░ 339 Mbps 🔻1.88x |
███████████████░ 41.74 Mbps 🔻1.1x |
|
| Twofish-192 / ECB | cipherlib | ████████████████ 1.06 Gbps 🌟 |
████████████████ 567 Mbps 🌟 |
████████████████ 36.05 Mbps 🌟 |
| PointyCastle | █░░░░░░░░░░░░░░░ 1.8 Mbps 🔻590.1x |
█████████░░░░░░░ 321 Mbps 🔻1.76x |
███████████████░ 34.12 Mbps 🔻1.06x |
|
| Twofish-256 / ECB | cipherlib | ████████████████ 1.07 Gbps 🌟 |
████████████████ 499 Mbps 🌟 |
████████████████ 28.31 Mbps |
| PointyCastle | █░░░░░░░░░░░░░░░ 1.83 Mbps 🔻582.99x |
██████████░░░░░░ 304 Mbps 🔻1.64x |
████████████████ 28.97 Mbps 🔺1.02x |
|
| Twofish-128 / CBC | cipherlib | ████████████████ 1.06 Gbps 🌟 |
████████████████ 632 Mbps 🌟 |
████████████████ 46.42 Mbps 🌟 |
| PointyCastle | █░░░░░░░░░░░░░░░ 3.62 Mbps 🔻291.97x |
████████░░░░░░░░ 325 Mbps 🔻1.94x |
██████████████░░ 40.59 Mbps 🔻1.14x |
|
| Twofish-192 / CBC | cipherlib | ████████████████ 1.05 Gbps 🌟 |
████████████████ 560 Mbps 🌟 |
████████████████ 36.14 Mbps 🌟 |
| PointyCastle | █░░░░░░░░░░░░░░░ 3.6 Mbps 🔻291.63x |
█████████░░░░░░░ 307 Mbps 🔻1.82x |
███████████████░ 33.4 Mbps 🔻1.08x |
|
| Twofish-256 / CBC | cipherlib | ████████████████ 1.05 Gbps 🌟 |
████████████████ 496 Mbps 🌟 |
████████████████ 28.23 Mbps |
| PointyCastle | █░░░░░░░░░░░░░░░ 3.67 Mbps 🔻286.45x |
█████████░░░░░░░ 293 Mbps 🔻1.69x |
████████████████ 28.36 Mbps 🔺1x |
|
| Twofish-128 / CTR | cipherlib | ████████████████ 1.03 Gbps 🌟 |
████████████████ 619 Mbps 🌟 |
████████████████ 46.41 Mbps 🌟 |
| PointyCastle | ███████░░░░░░░░░ 422 Mbps 🔻2.43x |
████████░░░░░░░░ 328 Mbps 🔻1.89x |
██████████████░░ 40.26 Mbps 🔻1.15x |
|
| Twofish-192 / CTR | cipherlib | ████████████████ 1.03 Gbps 🌟 |
████████████████ 556 Mbps 🌟 |
████████████████ 35.99 Mbps 🌟 |
| PointyCastle | ███████░░░░░░░░░ 426 Mbps 🔻2.42x |
█████████░░░░░░░ 311 Mbps 🔻1.79x |
███████████████░ 33.26 Mbps 🔻1.08x |
|
| Twofish-256 / CTR | cipherlib | ████████████████ 1.04 Gbps 🌟 |
████████████████ 491 Mbps 🌟 |
████████████████ 28.32 Mbps 🌟 |
| PointyCastle | ███████░░░░░░░░░ 427 Mbps 🔻2.42x |
██████████░░░░░░ 295 Mbps 🔻1.66x |
████████████████ 28.15 Mbps 🔻1.01x |
|
| Blowfish-128 / ECB | cipherlib | ████████████████ 755 Mbps 🌟 |
████████████████ 77.07 Mbps 🌟 |
████████████████ 2.81 Mbps 🌟 |
| PointyCastle | █░░░░░░░░░░░░░░░ 1.82 Mbps 🔻414.53x |
█████████████░░░ 64.66 Mbps 🔻1.19x |
██████████████░░ 2.4 Mbps 🔻1.17x |
|
| Blowfish-256 / ECB | cipherlib | ████████████████ 760 Mbps 🌟 |
████████████████ 78.54 Mbps 🌟 |
████████████████ 2.62 Mbps 🌟 |
| PointyCastle | █░░░░░░░░░░░░░░░ 1.77 Mbps 🔻429.53x |
█████████████░░░ 63.87 Mbps 🔻1.23x |
███████████████░ 2.38 Mbps 🔻1.1x |
|
| Blowfish-448 / ECB | cipherlib | ████████████████ 707 Mbps 🌟 |
████████████████ 78.69 Mbps 🌟 |
████████████████ 2.74 Mbps 🌟 |
| PointyCastle | █░░░░░░░░░░░░░░░ 1.77 Mbps 🔻399.76x |
█████████████░░░ 64.31 Mbps 🔻1.22x |
██████████████░░ 2.34 Mbps 🔻1.17x |
|
| Blowfish-128 / CBC | cipherlib | ████████████████ 699 Mbps 🌟 |
████████████████ 76.81 Mbps 🌟 |
████████████████ 2.69 Mbps 🌟 |
| PointyCastle | █░░░░░░░░░░░░░░░ 3.45 Mbps 🔻202.76x |
█████████████░░░ 62.03 Mbps 🔻1.24x |
██████████████░░ 2.3 Mbps 🔻1.17x |
|
| Blowfish-256 / CBC | cipherlib | ████████████████ 689 Mbps 🌟 |
████████████████ 77.55 Mbps 🌟 |
████████████████ 2.72 Mbps 🌟 |
| PointyCastle | █░░░░░░░░░░░░░░░ 3.52 Mbps 🔻195.93x |
█████████████░░░ 61.94 Mbps 🔻1.25x |
██████████████░░ 2.34 Mbps 🔻1.16x |
|
| Blowfish-448 / CBC | cipherlib | ████████████████ 699 Mbps 🌟 |
████████████████ 79.48 Mbps 🌟 |
████████████████ 2.63 Mbps 🌟 |
| PointyCastle | █░░░░░░░░░░░░░░░ 3.48 Mbps 🔻200.51x |
█████████████░░░ 62.34 Mbps 🔻1.28x |
██████████████░░ 2.29 Mbps 🔻1.15x |
|
| Blowfish-128 / CTR | cipherlib | ████████████████ 763 Mbps 🌟 |
████████████████ 78.47 Mbps 🌟 |
████████████████ 2.79 Mbps 🌟 |
| PointyCastle | ████████░░░░░░░░ 403 Mbps 🔻1.9x |
█████████████░░░ 62.67 Mbps 🔻1.25x |
█████████████░░░ 2.33 Mbps 🔻1.2x |
|
| Blowfish-256 / CTR | cipherlib | ████████████████ 767 Mbps 🌟 |
████████████████ 78.86 Mbps 🌟 |
████████████████ 2.82 Mbps 🌟 |
| PointyCastle | ████████░░░░░░░░ 406 Mbps 🔻1.89x |
█████████████░░░ 64.4 Mbps 🔻1.22x |
██████████████░░ 2.39 Mbps 🔻1.18x |
|
| Blowfish-448 / CTR | cipherlib | ████████████████ 787 Mbps 🌟 |
████████████████ 81.16 Mbps 🌟 |
████████████████ 2.78 Mbps 🌟 |
| PointyCastle | ████████░░░░░░░░ 413 Mbps 🔻1.91x |
█████████████░░░ 64.71 Mbps 🔻1.25x |
██████████████░░ 2.37 Mbps 🔻1.17x |
| Algorithm | Library | Key Generation | Encapsulation | Decapsulation |
|---|---|---|---|---|
| ML-KEM-512 | cipherlib | ████████████████ 20.1 Mbps 🌟 |
████████████████ 204 Mbps 🌟 |
████████████████ 165 Mbps 🌟 |
| pqcrypto | ██░░░░░░░░░░░░░░ 2.29 Mbps 🔻8.77x |
██░░░░░░░░░░░░░░ 22.76 Mbps 🔻8.95x |
██░░░░░░░░░░░░░░ 20.18 Mbps 🔻8.17x |
|
| ML-KEM-768 | cipherlib | ████████████████ 12.4 Mbps 🌟 |
████████████████ 183 Mbps 🌟 |
████████████████ 153 Mbps 🌟 |
| pqcrypto | ██░░░░░░░░░░░░░░ 1.34 Mbps 🔻9.23x |
██░░░░░░░░░░░░░░ 19.13 Mbps 🔻9.59x |
██░░░░░░░░░░░░░░ 16.92 Mbps 🔻9.04x |
|
| ML-KEM-1024 | cipherlib | ████████████████ 8.11 Mbps 🌟 |
████████████████ 179 Mbps 🌟 |
████████████████ 152 Mbps 🌟 |
| pqcrypto | ██░░░░░░░░░░░░░░ 824 Kbps 🔻9.84x |
██░░░░░░░░░░░░░░ 17.7 Mbps 🔻10.11x |
██░░░░░░░░░░░░░░ 15.97 Mbps 🔻9.5x |
All benchmarks are done on 36GB Apple M3 Pro using compiled exe
Dart SDK version: 3.12.2 (stable) (Tue Jun 9 01:11:39 2026 -0700) on "macos_arm64"
BSD 3-Clause License. See the LICENSE file for details. Issues and contributions are welcome at github.com/bitanon/cipherlib.