Skip to content

Commit

Permalink
Implement IGE
Browse files Browse the repository at this point in the history
  • Loading branch information
dipu-bd committed Jul 15, 2024
1 parent b74fc05 commit 138fa42
Show file tree
Hide file tree
Showing 21 changed files with 946 additions and 292 deletions.
205 changes: 107 additions & 98 deletions BENCHMARK.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## 0.0.10
## 0.0.11

- `XOR` cipher.
- `Salsa20` cipher with `Poly1305` tag.
- `ChaCha20` cipher with `Poly1305` tag.
- `AES` in ECB, CBC, CTR, CFB, OFB, GCM, XTS, PCBC modes.
- `AES` in ECB, CBC, CTR, CFB, OFB, GCM, XTS, IGE, PCBC modes.
147 changes: 112 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Available modes for AES:
- `GCM` : Galois/Counter Mode
- `CFB` : Cipher Feedback
- `OFB` : Output Feedback
- `IGE` : Infinite Garble Extension
- `PCBC` : Propagating Cipher Block Chaining
- `XTS` : XEX (XOR-Encrypt-XOR) Tweakable Block Cipher with Ciphertext Stealing

Expand Down Expand Up @@ -71,6 +72,7 @@ void main() {
print(' CFB: ${toHex(AES(key).cfb(iv).encryptString(plain))}');
print(' OFB: ${toHex(AES(key).ofb(iv).encryptString(plain))}');
print(' XTS: ${toHex(AES(key).xts(iv).encryptString(plain))}');
print(' IGE: ${toHex(AES(key).ige(iv).encryptString(plain))}');
print(' PCBC: ${toHex(AES(key).pcbc(iv).encryptString(plain))}');
}
print('');
Expand Down Expand Up @@ -131,41 +133,116 @@ Libraries:
- **PointyCastle** : https://pub.dev/packages/pointycastle
- **Cryptography** : https://pub.dev/packages/cryptography

With 5MB message (10 iterations):

| Algorithms | `cipherlib` | `PointyCastle` | `cryptography` |
| ------------------------- | -------------- | ---------------------------- | ---------------------------- |
| XOR | **241MB/s** |||
| ChaCha20 | **107.60MB/s** | 30.48MB/s <br> `253% slower` ||
| ChaCha20/Poly1305 | **75.32MB/s** || 33.24MB/s <br> `127% slower` |
| ChaCha20/Poly1305(digest) | **247.47MB/s** |||
| Salsa20 | **107.24MB/s** | 27.91MB/s <br> `284% slower` ||
| Salsa20/Poly1305 | **76.42MB/s** |||
| Salsa20/Poly1305(digest) | **248.50MB/s** |||

With 1KB message (5000 iterations):

| Algorithms | `cipherlib` | `PointyCastle` | `cryptography` |
| ------------------------- | -------------- | ---------------------------- | ---------------------------- |
| XOR | **250.20MB/s** |||
| ChaCha20 | **108.38MB/s** | 30.87MB/s <br> `251% slower` ||
| ChaCha20/Poly1305 | **71.48MB/s** || 31.39MB/s <br> `128% slower` |
| ChaCha20/Poly1305(digest) | **213.58MB/s** |||
| Salsa20 | **108.21MB/s** | 29.29MB/s <br> `269% slower` ||
| Salsa20/Poly1305 | **72.17MB/s** |||
| Salsa20/Poly1305(digest) | **217.38MB/s** |||

With 10B message (100000 iterations):

| Algorithms | `cipherlib` | `PointyCastle` | `cryptography` |
| ------------------------- | -------------- | --------------------------- | --------------------------- |
| XOR | **185.62MB/s** |||
| ChaCha20 | **32.03MB/s** | 3.91MB/s <br> `719% slower` ||
| ChaCha20/Poly1305 | **9.71MB/s** || 4.14MB/s <br> `134% slower` |
| ChaCha20/Poly1305(digest) | **14.31MB/s** |||
| Salsa20 | **32.33MB/s** | 3.81MB/s <br> `748% slower` ||
| Salsa20/Poly1305 | **9.81MB/s** |||
| Salsa20/Poly1305(digest) | **14.25MB/s** |||
With 1MB message (10 iterations):

| Algorithms | `cipherlib` | `PointyCastle` | `cryptography` |
| ----------------- | ------------- | ----------------------------- | -------------------------- |
| XOR | **5.74 Gbps** |
| ChaCha20 | **1.21 Gbps** | 264 Mbps <br> `4.6x slow` | |
| ChaCha20/Poly1305 | **765 Mbps** | 194 Mbps <br> `3.94x slow` | 289 Mbps <br> `2.65x slow` |
| Salsa20 | **1.23 Gbps** | 253 Mbps <br> `4.85x slow` | |
| Salsa20/Poly1305 | **771 Mbps** | | |
| AES-128/ECB | **944 Mbps** | 161 Mbps <br> `5.85x slow` | |
| AES-192/ECB | **853 Mbps** | 145 Mbps <br> `5.88x slow` | |
| AES-256/ECB | **776 Mbps** | 127 Mbps <br> `6.12x slow` | |
| AES-128/CBC | **964 Mbps** | 157 Mbps <br> `6.14x slow` | 859 Mbps <br> `1.12x slow` |
| AES-192/CBC | **872 Mbps** | 138 Mbps <br> `6.32x slow` | 783 Mbps <br> `1.11x slow` |
| AES-256/CBC | **793 Mbps** | 123 Mbps <br> `6.46x slow` | 712 Mbps <br> `1.11x slow` |
| AES-128/CTR | **944 Mbps** | 153 Mbps <br> `6.16x slow` | 497 Mbps <br> `1.9x slow` |
| AES-192/CTR | **858 Mbps** | 136 Mbps <br> `6.28x slow` | 473 Mbps <br> `1.81x slow` |
| AES-256/CTR | **781 Mbps** | 121 Mbps <br> `6.48x slow` | 449 Mbps <br> `1.74x slow` |
| AES-128/GCM | **143 Mbps** | 11.98 Mbps <br> `11.9x slow` | 129 Mbps <br> `1.1x slow` |
| AES-192/GCM | **141 Mbps** | 11.9 Mbps <br> `11.88x slow` | 129 Mbps <br> `1.09x slow` |
| AES-256/GCM | **139 Mbps** | 11.75 Mbps <br> `11.86x slow` | 126 Mbps <br> `1.11x slow` |
| AES-128/CFB | **453 Mbps** | 658 kbps <br> `688.39x slow` | |
| AES-192/CFB | **416 Mbps** | 661 kbps <br> `629.53x slow` | |
| AES-256/CFB | **378 Mbps** | 659 kbps <br> `573.25x slow` | |
| AES-128/OFB | **807 Mbps** | 155 Mbps <br> `5.19x slow` | |
| AES-192/OFB | **744 Mbps** | 139 Mbps <br> `5.34x slow` | |
| AES-256/OFB | **678 Mbps** | 124 Mbps <br> `5.47x slow` | |
| AES-128/XTS | **667 Mbps** | | |
| AES-192/XTS | **618 Mbps** | | |
| AES-256/XTS | **578 Mbps** | | |
| AES-128/IGE | **836 Mbps** | 150 Mbps <br> `5.56x slow` | |
| AES-192/IGE | **762 Mbps** | 131 Mbps <br> `5.8x slow` | |
| AES-256/IGE | **698 Mbps** | 117 Mbps <br> `5.96x slow` | |
| AES-128/PCBC | **835 Mbps** | | |
| AES-192/PCBC | **774 Mbps** | | |
| AES-256/PCBC | **700 Mbps** | | |

With 5KB message (5000 iterations):

| Algorithms | `cipherlib` | `PointyCastle` | `cryptography` |
| ----------------- | ------------- | ----------------------------- | -------------------------- |
| XOR | **6.74 Gbps** |
| ChaCha20 | **1.26 Gbps** | 277 Mbps <br> `4.55x slow` | |
| ChaCha20/Poly1305 | **765 Mbps** | 198 Mbps <br> `3.87x slow` | 280 Mbps <br> `2.73x slow` |
| Salsa20 | **1.25 Gbps** | 254 Mbps <br> `4.9x slow` | |
| Salsa20/Poly1305 | **761 Mbps** | | |
| AES-128/ECB | **953 Mbps** | 165 Mbps <br> `5.77x slow` | |
| AES-192/ECB | **866 Mbps** | 144 Mbps <br> `6.01x slow` | |
| AES-256/ECB | **790 Mbps** | 128 Mbps <br> `6.18x slow` | |
| AES-128/CBC | **973 Mbps** | 158 Mbps <br> `6.15x slow` | 854 Mbps <br> `1.14x slow` |
| AES-192/CBC | **879 Mbps** | 138 Mbps <br> `6.35x slow` | 774 Mbps <br> `1.14x slow` |
| AES-256/CBC | **798 Mbps** | 123 Mbps <br> `6.49x slow` | 708 Mbps <br> `1.13x slow` |
| AES-128/CTR | **950 Mbps** | 156 Mbps <br> `6.1x slow` | 503 Mbps <br> `1.89x slow` |
| AES-192/CTR | **866 Mbps** | 138 Mbps <br> `6.3x slow` | 475 Mbps <br> `1.82x slow` |
| AES-256/CTR | **780 Mbps** | 122 Mbps <br> `6.39x slow` | 450 Mbps <br> `1.73x slow` |
| AES-128/GCM | **145 Mbps** | 11.72 Mbps <br> `12.34x slow` | 131 Mbps <br> `1.11x slow` |
| AES-192/GCM | **144 Mbps** | 11.7 Mbps <br> `12.3x slow` | 128 Mbps <br> `1.12x slow` |
| AES-256/GCM | **141 Mbps** | 11.59 Mbps <br> `12.12x slow` | 128 Mbps <br> `1.1x slow` |
| AES-128/CFB | **453 Mbps** | 136 Mbps <br> `3.32x slow` | |
| AES-192/CFB | **419 Mbps** | 121 Mbps <br> `3.47x slow` | |
| AES-256/CFB | **381 Mbps** | 108 Mbps <br> `3.54x slow` | |
| AES-128/OFB | **760 Mbps** | 158 Mbps <br> `4.8x slow` | |
| AES-192/OFB | **747 Mbps** | 139 Mbps <br> `5.39x slow` | |
| AES-256/OFB | **689 Mbps** | 123 Mbps <br> `5.61x slow` | |
| AES-128/XTS | **688 Mbps** | | |
| AES-192/XTS | **634 Mbps** | | |
| AES-256/XTS | **595 Mbps** | | |
| AES-128/IGE | **843 Mbps** | 151 Mbps <br> `5.59x slow` | |
| AES-192/IGE | **770 Mbps** | 133 Mbps <br> `5.77x slow` | |
| AES-256/IGE | **710 Mbps** | 119 Mbps <br> `5.96x slow` | |
| AES-128/PCBC | **843 Mbps** | | |
| AES-192/PCBC | **778 Mbps** | | |
| AES-256/PCBC | **690 Mbps** | | |

With 16B message (100000 iterations):

| Algorithms | `cipherlib` | `PointyCastle` | `cryptography` |
| ----------------- | ------------- | ----------------------------- | -------------------------------- |
| XOR | **4.65 Gbps** |
| ChaCha20 | **420 Mbps** | 50.69 Mbps <br> `8.29x slow` | |
| ChaCha20/Poly1305 | **110 Mbps** | 41.08 Mbps <br> `2.68x slow` | 34.87 Mbps <br> `3.15x slow` |
| Salsa20 | **410 Mbps** | 48.25 Mbps <br> `8.51x slow` | |
| Salsa20/Poly1305 | **110 Mbps** | | |
| AES-128/ECB | **358 Mbps** | 54.07 Mbps <br> `6.61x slow` | |
| AES-192/ECB | **313 Mbps** | 49.44 Mbps <br> `6.33x slow` | |
| AES-256/ECB | **280 Mbps** | 45.83 Mbps <br> `6.12x slow` | |
| AES-128/CBC | **312 Mbps** | 50.29 Mbps <br> `6.2x slow` | 146 Mbps <br> `2.13x slow` |
| AES-192/CBC | **286 Mbps** | 47.28 Mbps <br> `6.04x slow` | 142 Mbps <br> `2.02x slow` |
| AES-256/CBC | **254 Mbps** | 44.26 Mbps <br> `5.74x slow` | 132 Mbps <br> `1.92x slow` |
| AES-128/CTR | **493 Mbps** | 50.47 Mbps <br> `9.78x slow` | 80.75 Mbps <br> `6.11x slow` |
| AES-192/CTR | **480 Mbps** | 46.99 Mbps <br> `10.22x slow` | 78.85 Mbps <br> `6.09x slow` |
| AES-256/CTR | **425 Mbps** | 43.79 Mbps <br> `9.7x slow` | 76 Mbps <br> `5.59x slow` |
| AES-128/GCM | 27.19 Mbps | 6.44 Mbps <br> `4.22x slow` | **41.33 Mbps** <br> `1.52x fast` |
| AES-192/GCM | 27.06 Mbps | 6.38 Mbps <br> `4.24x slow` | **40.41 Mbps** <br> `1.49x fast` |
| AES-256/GCM | 26.68 Mbps | 6.27 Mbps <br> `4.26x slow` | **39.05 Mbps** <br> `1.46x fast` |
| AES-128/CFB | **307 Mbps** | 50.4 Mbps <br> `6.1x slow` | |
| AES-192/CFB | **288 Mbps** | 46.91 Mbps <br> `6.13x slow` | |
| AES-256/CFB | **254 Mbps** | 43.66 Mbps <br> `5.81x slow` | |
| AES-128/OFB | **433 Mbps** | 51.04 Mbps <br> `8.48x slow` | |
| AES-192/OFB | **423 Mbps** | 47.07 Mbps <br> `8.99x slow` | |
| AES-256/OFB | **364 Mbps** | 44.54 Mbps <br> `8.18x slow` | |
| AES-128/XTS | **229 Mbps** | | |
| AES-192/XTS | **224 Mbps** | | |
| AES-256/XTS | **196 Mbps** | | |
| AES-128/IGE | **275 Mbps** | 49.15 Mbps <br> `5.6x slow` | |
| AES-192/IGE | **270 Mbps** | 45.42 Mbps <br> `5.94x slow` | |
| AES-256/IGE | **238 Mbps** | 42.69 Mbps <br> `5.58x slow` | |
| AES-128/PCBC | **303 Mbps** | | |
| AES-192/PCBC | **288 Mbps** | | |
| AES-256/PCBC | **248 Mbps** | | |

> All benchmarks are done on _AMD Ryzen 7 5800X_ processor and _3200MHz_ RAM using compiled _exe_
>
Expand Down
78 changes: 78 additions & 0 deletions benchmark/aes_ige.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright (c) 2023, Sudipto Chandra
// All rights reserved. Check LICENSE file for details.

import 'dart:math';
import 'dart:typed_data';

import 'package:cipherlib/cipherlib.dart';
import 'package:pointycastle/pointycastle.dart' as pc;

import 'base.dart';

Random random = Random();

class CipherlibBenchmark extends Benchmark {
final Uint8List key;
final Uint8List iv;

CipherlibBenchmark(int size, int iter, int keySize)
: key = Uint8List.fromList(List.filled(keySize, 0x9f)),
iv = Uint8List.fromList(List.filled(32, 0x87)),
super('cipherlib', size, iter);

@override
void run() {
AES(key).ige(iv).encrypt(input);
}
}

class PointyCastleBenchmark extends Benchmark {
final Uint8List key;
final Uint8List iv;

PointyCastleBenchmark(int size, int iter, int keySize)
: key = Uint8List.fromList(List.filled(keySize, 0x9f)),
iv = Uint8List.fromList(List.filled(32, 0x87)),
super('PointyCastle', size, iter);

@override
void run() {
var inp = Uint8List.fromList(input);
var out = Uint8List(inp.length);
var instance = pc.BlockCipher('AES/IGE');
instance.init(
true,
pc.ParametersWithIV(pc.KeyParameter(key), iv),
);
for (int i = 0; i < inp.length; i += 16) {
instance.processBlock(inp, i, out, i);
}
}
}

void main() async {
print('--------- AES/IGE ----------');
final conditions = [
[5 << 20, 10],
[1 << 10, 5000],
[16, 100000],
];
for (var condition in conditions) {
int size = condition[0];
int iter = condition[1];
print('---- message: ${formatSize(size)} | iterations: $iter ----');
print('[AES-128]');
await CipherlibBenchmark(size, iter, 16).measureDiff([
PointyCastleBenchmark(size, iter, 16),
]);
print('[AES-192]');
await CipherlibBenchmark(size, iter, 24).measureDiff([
PointyCastleBenchmark(size, iter, 24),
]);
print('[AES-256]');
await CipherlibBenchmark(size, iter, 32).measureDiff([
PointyCastleBenchmark(size, iter, 32),
]);
print('');
}
}
47 changes: 16 additions & 31 deletions benchmark/aes_keygen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,68 +15,53 @@ import 'base.dart';
Random random = Random();

class CipherlibBenchmark extends Benchmark {
final Uint8List key;
late final Uint8List key = Uint8List.fromList(input);

CipherlibBenchmark(int size, int iter, int keySize)
: key = Uint8List.fromList(List.filled(keySize, 0x9f)),
super('cipherlib', size, iter);
CipherlibBenchmark(int size, int iter) : super('cipherlib', size, iter);

@override
void run() {
var key32 = Uint32List.view(key.buffer);
AESCore.$expandEncryptionKey(key32);
AESCore.$expandDecryptionKey(Uint32List.view(key.buffer));
}
}

class PointyCastleBenchmark extends Benchmark {
final Uint8List key;
late final Uint8List key = Uint8List.fromList(input);

PointyCastleBenchmark(int size, int iter, int keySize)
: key = Uint8List.fromList(List.filled(keySize, 0x9f)),
super('PointyCastle', size, iter);
PointyCastleBenchmark(int size, int iter) : super('PointyCastle', size, iter);

@override
void run() {
var instance = aes.AESEngine();
instance.generateWorkingKey(true, pc.KeyParameter(key));
instance.generateWorkingKey(false, pc.KeyParameter(key));
}
}

class CryptographyBenchmark extends Benchmark {
final Uint8List key;
late final Uint8List key = Uint8List.fromList(input);

CryptographyBenchmark(int size, int iter, int keySize)
: key = Uint8List.fromList(List.filled(keySize, 0x9f)),
super('cryptography', size, iter);
CryptographyBenchmark(int size, int iter) : super('cryptography', size, iter);

@override
void run() {
aesExpandKeyForEncrypting(crypto.SecretKeyData(key));
aesExpandKeyForDecrypting(crypto.SecretKeyData(key));
}
}

void main() async {
print('--------- AES/ECB ----------');
final conditions = [
[5 << 20, 10],
[1 << 10, 5000],
[16, 100000],
[16, 100],
[24, 100],
[32, 100],
];
for (var condition in conditions) {
int size = condition[0];
int iter = condition[1];
print('---- message: ${formatSize(size)} | iterations: $iter ----');
await CipherlibBenchmark(size, iter, 16).measureDiff([
PointyCastleBenchmark(size, iter, 16),
CryptographyBenchmark(size, iter, 16),
]);
await CipherlibBenchmark(size, iter, 24).measureDiff([
PointyCastleBenchmark(size, iter, 24),
CryptographyBenchmark(size, iter, 24),
]);
await CipherlibBenchmark(size, iter, 32).measureDiff([
PointyCastleBenchmark(size, iter, 32),
CryptographyBenchmark(size, iter, 32),
print('---- keysize: $size iterations: $iter ----');
await CipherlibBenchmark(size, iter).measureDiff([
PointyCastleBenchmark(size, iter),
CryptographyBenchmark(size, iter),
]);
print('');
}
Expand Down
Loading

0 comments on commit 138fa42

Please sign in to comment.