feat(example): add PointyCastle benchmark

This commit is contained in:
Hugo Pointcheval 2022-05-24 18:43:46 +02:00
parent 41354e3dc4
commit 6397e10c05
Signed by: hugo
GPG Key ID: A9E8E9615379254F
5 changed files with 102 additions and 39 deletions

View File

@ -1,12 +1,12 @@
buildscript {
ext.kotlin_version = '1.3.50'
ext.kotlin_version = "1.6.21"
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath 'com.android.tools.build:gradle:7.2.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

View File

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip

View File

@ -3,7 +3,7 @@
// -----
// File: benchmark_page.dart
// Created Date: 28/12/2021 15:12:39
// Last Modified: 28/12/2021 17:01:41
// Last Modified: 24/05/2022 17:23:33
// -----
// Copyright (c) 2021
@ -12,6 +12,7 @@ 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';
@ -23,37 +24,10 @@ class BenchmarkPage extends ConsumerWidget {
final Output keyContent = Output();
final Output benchmarkStatus = Output(large: true);
Future<void> _test(WidgetRef ref, Cipher cipher) async {
Session state = ref.read(sessionProvider.state).state;
if (state.secretKey.bytes.isEmpty) {
benchmarkStatus
.print('No SecretKey!\nGo in Key tab and generate or derive one.');
return;
}
int size = 64;
benchmarkStatus.print("Benchmark Test\n");
// Encryption
var before = DateTime.now();
var encryptedBigFile = await cipher.encrypt(Uint8List(size * 1000000));
var after = DateTime.now();
var benchmark =
after.millisecondsSinceEpoch - before.millisecondsSinceEpoch;
benchmarkStatus.append('[$size MB] Encryption took $benchmark ms\n');
// Decryption
var befored = DateTime.now();
await cipher.decrypt(encryptedBigFile);
var afterd = DateTime.now();
var benchmarkd =
afterd.millisecondsSinceEpoch - befored.millisecondsSinceEpoch;
benchmarkStatus.append('[$size MB] Decryption took $benchmarkd ms\n');
}
Future<void> _benchmark(WidgetRef ref, Cipher cipher) async {
Future<void> _benchmark(WidgetRef ref, Cipher cipher,
{bool usePc = false}) async {
Session state = ref.read(sessionProvider.state).state;
AesGcm pc = AesGcm();
if (state.secretKey.bytes.isEmpty) {
benchmarkStatus
@ -75,7 +49,13 @@ class BenchmarkPage extends ConsumerWidget {
// Encryption
var before = DateTime.now();
var encryptedBigFile = await cipher.encrypt(b.buffer.asUint8List());
Object encryptedBigFile;
if (usePc) {
encryptedBigFile =
pc.encrypt(b.buffer.asUint8List(), state.secretKey.bytes);
} else {
encryptedBigFile = await cipher.encrypt(b.buffer.asUint8List());
}
var after = DateTime.now();
var benchmark =
@ -87,7 +67,11 @@ class BenchmarkPage extends ConsumerWidget {
// Decryption
before = DateTime.now();
await cipher.decrypt(encryptedBigFile);
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;
@ -150,11 +134,11 @@ class BenchmarkPage extends ConsumerWidget {
children: [
Button(
() => _benchmark(ref, cipher),
"Launch benchmark",
"NativeCrypto",
),
Button(
() => _test(ref, cipher),
"Test benchmark",
() => _benchmark(ref, cipher, usePc: true),
"PointyCastle",
),
Button(
_clear,

View File

@ -0,0 +1,78 @@
// Author: Hugo Pointcheval
// Email: git@pcl.ovh
// -----
// File: aes_gcm.dart
// Created Date: 24/05/2022 16:34:54
// Last Modified: 24/05/2022 17:15:22
// -----
// Copyright (c) 2022
import 'dart:typed_data';
import 'package:pointycastle/export.dart';
import 'package:pointycastle/src/platform_check/platform_check.dart';
class AesGcm {
FortunaRandom? _secureRandom;
Uint8List encrypt(Uint8List data, Uint8List key) {
final iv = generateRandomBytes(12);
final gcm = GCMBlockCipher(AESEngine())
..init(
true,
AEADParameters(
KeyParameter(key),
16 * 8,
iv!,
Uint8List(0),
),
); // true=encrypt
final cipherText = gcm.process(data);
return Uint8List.fromList(
iv + cipherText,
);
}
Uint8List decrypt(Uint8List cipherText, Uint8List key) {
final iv = Uint8List.fromList(cipherText.sublist(0, 12));
final cipherTextWithoutIv = Uint8List.fromList(
cipherText.sublist(12),
);
final gcm = GCMBlockCipher(AESEngine())
..init(
false,
AEADParameters(
KeyParameter(key),
16 * 8,
iv,
Uint8List(0),
),
); // false=decrypt
// Decrypt the cipherText block-by-block
final paddedPlainText = gcm.process(cipherTextWithoutIv);
return paddedPlainText;
}
/// Generate random bytes to use as the Initialization Vector (IV).
Uint8List? generateRandomBytes(int numBytes) {
if (_secureRandom == null) {
// First invocation: create _secureRandom and seed it
_secureRandom = FortunaRandom();
_secureRandom!.seed(
KeyParameter(Platform.instance.platformEntropySource().getBytes(32)));
}
// Use it to generate the random bytes
final iv = _secureRandom!.nextBytes(numBytes);
return iv;
}
}

View File

@ -30,6 +30,7 @@ dependencies:
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
flutter_riverpod: ^1.0.3
pointycastle: ^3.6.0
dev_dependencies:
flutter_test: