You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
dateKeys-dart/tool/age_writer_bench.dart

90 lines
3.1 KiB

// Times the age writer of datekeys-dart, stage 6a, on the VM and compiled
// to JavaScript: the throughput of a large PAYLOAD_AGE encrypted in
// streaming, in pieces of 1 MiB, 64 MiB on the VM and 16 MiB in Node.js; and
// the header of each file of a capsule: PAYLOAD_AGE for one X25519
// recipient, INNER_ACCESS_AGE for 16 and a control of 103 bytes,
// OUTER_TIME_AGE for the tlock recipient, and the file of an author key, a
// scrypt recipient with logN 16. Each is the median of a few runs. The
// random values come from the CSPRNG of the platform, as in production.
//
// dart run tool/age_writer_bench.dart
//
// dart compile js -O2 -o age_writer_bench.js tool/age_writer_bench.dart
// node -e "globalThis.self = globalThis; require('./age_writer_bench.js')"
//
// ignore_for_file: avoid_print
import 'dart:typed_data';
import 'package:datekeys/datekeys.dart' show quicknet;
import 'package:datekeys/src/age_writer.dart';
import 'package:datekeys/src/random.dart';
import 'package:datekeys/src/recipient.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);
}
void main() {
final id = generateX25519Identity();
final payload = X25519Recipient.of(id);
final slots = [
for (var i = 0; i < 16; i++) X25519Recipient.of(generateX25519Identity()),
];
final tlock = TimeRecipient(quicknet(), 1000);
final scrypt = ScryptRecipient('a passphrase', workFactor: 16);
final control = Uint8List(103);
print('age writer, ${isWeb ? 'Node.js' : 'VM'}');
print(
'PAYLOAD_AGE header, one X25519 stanza: '
'${time(15, () => AgeEncryptor([payload]).close()).toStringAsFixed(2)} ms',
);
print(
'INNER_ACCESS_AGE, 16 X25519 stanzas, 103 bytes: '
'${time(7, () => ageEncrypt(control, slots)).toStringAsFixed(1)} ms',
);
print(
'OUTER_TIME_AGE, the tlock stanza of round 1000, 2128 bytes: '
'${time(5, () => ageEncrypt(Uint8List(1773), [tlock])).toStringAsFixed(0)} ms',
);
print(
'an author key file, scrypt with logN 16: '
'${time(3, () => ageEncrypt(Uint8List(120), [scrypt])).toStringAsFixed(0)} ms',
);
// The throughput in streaming, in pieces of 1 MiB.
final mib = isWeb ? 16 : 64;
final piece = Uint8List(1 << 20);
for (var i = 0; i < piece.length; i++) {
piece[i] = (31 * i + 7) & 0xff;
}
final ms = time(3, () {
final e = AgeEncryptor([payload], random: secureRandom);
var n = e.header.length + e.nonce.length;
for (var i = 0; i < mib; i++) {
for (final c in e.add(piece)) {
n += c.length;
}
}
n += e.close().length;
if (n != ageFileLength([x25519StanzaLength], mib << 20)) {
throw StateError('$n bytes');
}
});
print(
'$mib MiB in streaming: ${(ms / 1000).toStringAsFixed(2)} s, '
'${(mib / ms * 1000).toStringAsFixed(1)} MiB/s',
);
}

Powered by TurnKey Linux.