tool/authorkey_bench.dart times on the VM and compiled to JavaScript the generation of an author key, its Ed25519 signature of 99 bytes and of 1 MiB, the strict verification for comparison, its file encrypted with scrypt of logN 16 and read again, sealLocator for round 1000 and newEnvelope of a .dkc of 1 MiB. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>v0.11
parent
fe5b759e29
commit
ecc11be74d
@ -0,0 +1,77 @@
|
|||||||
|
// Times stage 7b of datekeys-dart on the VM and compiled to JavaScript: an
|
||||||
|
// author key, generated, its Ed25519 signature of AUTHOR_MESSAGE (99 bytes)
|
||||||
|
// and of 1 MiB, its file encrypted with scrypt of logN 16 and read again;
|
||||||
|
// and the sealing of a locator of round 1000 and the envelope of a .dkc of
|
||||||
|
// 1 MiB. Each is the median of a few runs. The random values come from the
|
||||||
|
// CSPRNG of the platform, as in production.
|
||||||
|
//
|
||||||
|
// dart run tool/authorkey_bench.dart
|
||||||
|
//
|
||||||
|
// dart compile js -O2 -o authorkey_bench.js tool/authorkey_bench.dart
|
||||||
|
// node -e "globalThis.self = globalThis; require('./authorkey_bench.js')"
|
||||||
|
//
|
||||||
|
// ignore_for_file: avoid_print
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:datekeys/datekeys.dart' show quicknet;
|
||||||
|
import 'package:datekeys/src/authorkey.dart';
|
||||||
|
import 'package:datekeys/src/curve25519.dart' show verifyStrict;
|
||||||
|
import 'package:datekeys/src/locator.dart';
|
||||||
|
import 'package:datekeys/src/locator_seal.dart';
|
||||||
|
|
||||||
|
const isWeb = identical(0, 0.0);
|
||||||
|
|
||||||
|
double median(List<double> xs) => (xs..sort())[xs.length ~/ 2];
|
||||||
|
|
||||||
|
/// The median time of [f], in milliseconds, over [runs] runs.
|
||||||
|
double time(int runs, void Function() f) {
|
||||||
|
final times = <double>[];
|
||||||
|
for (var i = 0; i < runs; i++) {
|
||||||
|
final sw = Stopwatch()..start();
|
||||||
|
f();
|
||||||
|
times.add(sw.elapsedMicroseconds / 1000);
|
||||||
|
}
|
||||||
|
return median(times);
|
||||||
|
}
|
||||||
|
|
||||||
|
String ms(double t) => t < 10 ? t.toStringAsFixed(2) : t.toStringAsFixed(0);
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
print('stage 7b, ${isWeb ? 'Node.js' : 'VM'}');
|
||||||
|
final key = AuthorKey.generate();
|
||||||
|
final msg = Uint8List(99);
|
||||||
|
final big = Uint8List(1 << 20);
|
||||||
|
// Warm up.
|
||||||
|
for (var i = 0; i < 20; i++) {
|
||||||
|
key.sign(msg);
|
||||||
|
}
|
||||||
|
print('AuthorKey.generate: ${ms(time(15, AuthorKey.generate))} ms');
|
||||||
|
print('Ed25519 sign, 99 bytes: ${ms(time(31, () => key.sign(msg)))} ms');
|
||||||
|
final sig = key.sign(msg);
|
||||||
|
print(
|
||||||
|
'Ed25519 verifyStrict, 99 bytes: '
|
||||||
|
'${ms(time(31, () => verifyStrict(key.publicKey, msg, sig)))} ms',
|
||||||
|
);
|
||||||
|
print('Ed25519 sign, 1 MiB: ${ms(time(7, () => key.sign(big)))} ms');
|
||||||
|
late Uint8List file;
|
||||||
|
print(
|
||||||
|
'encryptAuthorKey, scrypt logN 16: '
|
||||||
|
'${ms(time(5, () => file = encryptAuthorKey(key, 'a passphrase')))} ms',
|
||||||
|
);
|
||||||
|
print(
|
||||||
|
'readAuthorKey, scrypt logN 16: '
|
||||||
|
'${ms(time(5, () => readAuthorKey(file, passphrase: 'a passphrase')))} ms',
|
||||||
|
);
|
||||||
|
final e = newEnvelope(Uint8List(100));
|
||||||
|
final loc = e.locator.withAddresses([
|
||||||
|
LocatorAddress('https://example.com/rest'),
|
||||||
|
]);
|
||||||
|
print(
|
||||||
|
'sealLocator, round 1000: '
|
||||||
|
'${ms(time(5, () => sealLocator(quicknet(), 1000, loc)))} ms',
|
||||||
|
);
|
||||||
|
print(
|
||||||
|
'newEnvelope, a .dkc of 1 MiB: '
|
||||||
|
'${ms(time(5, () => newEnvelope(big)))} ms',
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
Reference in new issue