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.