190 lines
5.7 KiB
Dart
190 lines
5.7 KiB
Dart
// Author: Hugo Pointcheval
|
|
// Email: git@pcl.ovh
|
|
// -----
|
|
// File: benchmark_page.dart
|
|
// Created Date: 28/12/2021 15:12:39
|
|
// Last Modified: 25/05/2022 17:16:12
|
|
// -----
|
|
// Copyright (c) 2021
|
|
|
|
import 'dart:math';
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:native_crypto/native_crypto.dart';
|
|
import 'package:native_crypto_example/pointycastle/aes_gcm.dart';
|
|
import 'package:native_crypto_example/widgets/button.dart';
|
|
|
|
import '../session.dart';
|
|
import '../widgets/output.dart';
|
|
|
|
class BenchmarkPage extends ConsumerWidget {
|
|
BenchmarkPage({Key? key}) : super(key: key);
|
|
|
|
final Output keyContent = Output();
|
|
final Output benchmarkStatus = Output(large: true);
|
|
|
|
Future<void> _benchmark(
|
|
WidgetRef ref,
|
|
Cipher cipher, {
|
|
bool usePc = false,
|
|
bool encryptionOnly = false,
|
|
}) async {
|
|
Session state = ref.read(sessionProvider.state).state;
|
|
AesGcm pc = AesGcm();
|
|
|
|
if (state.secretKey.bytes.isEmpty) {
|
|
benchmarkStatus
|
|
.print('No SecretKey!\nGo in Key tab and generate or derive one.');
|
|
return;
|
|
}
|
|
|
|
List<int> testedSizes = [2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50];
|
|
int multiplier = pow(2, 20).toInt(); // MiB
|
|
|
|
benchmarkStatus.print("[Benchmark] Sizes: ${testedSizes.join('/')}MiB\n");
|
|
benchmarkStatus.appendln(
|
|
"[Benchmark] Engine: " + (usePc ? " PointyCastle" : " NativeCrypto"));
|
|
benchmarkStatus.appendln("[Benchmark] Test: " +
|
|
(encryptionOnly ? " Encryption Only" : " Encryption & Decryption"));
|
|
benchmarkStatus.appendln(
|
|
'[Benchmark] bytesCountPerChunk: ${Cipher.bytesCountPerChunk} bytes/chunk');
|
|
|
|
String csv = encryptionOnly
|
|
? "Run;Size (B);Encryption Time (ms)\n"
|
|
: "Run;Size (B);Encryption Time (ms);Decryption Time (ms)\n";
|
|
|
|
int run = 0;
|
|
var beforeBench = DateTime.now();
|
|
|
|
for (int size in testedSizes) {
|
|
run++;
|
|
final StringBuffer csvLine = StringBuffer();
|
|
final dummyBytes = Uint8List(size * multiplier);
|
|
csvLine.write('$run;${size * multiplier};');
|
|
|
|
// Encryption
|
|
Object encryptedBigFile;
|
|
var before = DateTime.now();
|
|
if (usePc) {
|
|
encryptedBigFile = pc.encrypt(dummyBytes, state.secretKey.bytes);
|
|
} else {
|
|
encryptedBigFile = await cipher.encrypt(dummyBytes);
|
|
}
|
|
var after = DateTime.now();
|
|
|
|
var benchmark =
|
|
after.millisecondsSinceEpoch - before.millisecondsSinceEpoch;
|
|
benchmarkStatus
|
|
.appendln('[Benchmark] ${size}MiB => Encryption took $benchmark ms');
|
|
csvLine.write('$benchmark');
|
|
|
|
if (!encryptionOnly) {
|
|
// Decryption
|
|
before = DateTime.now();
|
|
if (usePc) {
|
|
pc.decrypt(encryptedBigFile as Uint8List, state.secretKey.bytes);
|
|
} else {
|
|
await cipher.decrypt(encryptedBigFile as CipherText);
|
|
}
|
|
after = DateTime.now();
|
|
benchmark =
|
|
after.millisecondsSinceEpoch - before.millisecondsSinceEpoch;
|
|
benchmarkStatus
|
|
.appendln('[Benchmark] ${size}MiB => Decryption took $benchmark ms');
|
|
csvLine.write(';$benchmark');
|
|
}
|
|
csv += csvLine.toString() + '\n';
|
|
}
|
|
var afterBench = DateTime.now();
|
|
var benchmark =
|
|
afterBench.millisecondsSinceEpoch - beforeBench.millisecondsSinceEpoch;
|
|
var sum = testedSizes.reduce((a, b) => a + b);
|
|
benchmarkStatus
|
|
.appendln('[Benchmark] Finished: ${sum}MiB in $benchmark ms');
|
|
benchmarkStatus.appendln('[Benchmark] Check the console for csv data');
|
|
benchmarkStatus.appendln(csv);
|
|
print(csv);
|
|
}
|
|
|
|
void _clear() {
|
|
benchmarkStatus.clear();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
Session state = ref.read(sessionProvider.state).state;
|
|
if (state.secretKey.bytes.isEmpty) {
|
|
keyContent
|
|
.print('No SecretKey!\nGo in Key tab and generate or derive one.');
|
|
return SingleChildScrollView(
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(8.0),
|
|
child: Column(
|
|
children: [
|
|
const Align(
|
|
child: Text("Secret Key"),
|
|
alignment: Alignment.centerLeft,
|
|
),
|
|
keyContent,
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
keyContent.print(state.secretKey.bytes.toString());
|
|
|
|
AES cipher = AES(state.secretKey, AESMode.gcm);
|
|
|
|
return SingleChildScrollView(
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(8.0),
|
|
child: Column(
|
|
children: [
|
|
const Align(
|
|
child: Text("Secret Key"),
|
|
alignment: Alignment.centerLeft,
|
|
),
|
|
keyContent,
|
|
Wrap(
|
|
children: [
|
|
Button(
|
|
() => _benchmark(ref, cipher),
|
|
"NativeCrypto",
|
|
),
|
|
const SizedBox(width: 8),
|
|
Button(
|
|
() => _benchmark(ref, cipher, usePc: true),
|
|
"PointyCastle",
|
|
),
|
|
const SizedBox(width: 8),
|
|
Button(
|
|
() => _benchmark(ref, cipher, encryptionOnly: true),
|
|
"NC Encryption Only",
|
|
),
|
|
const SizedBox(width: 8),
|
|
Button(
|
|
() => _benchmark(
|
|
ref,
|
|
cipher,
|
|
usePc: true,
|
|
encryptionOnly: true,
|
|
),
|
|
"PC Encryption Only",
|
|
),
|
|
const SizedBox(width: 8),
|
|
Button(
|
|
_clear,
|
|
"Clear",
|
|
),
|
|
],
|
|
),
|
|
benchmarkStatus,
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|