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.
91 lines
3.1 KiB
91 lines
3.1 KiB
|
2 days ago
|
// Timings of the primitives of stage 2, on the VM or compiled to JavaScript:
|
||
|
|
//
|
||
|
|
// dart run tool/bench.dart
|
||
|
|
// dart compile js -O2 -o /tmp/bench.js tool/bench.dart && node /tmp/bench.js
|
||
|
|
//
|
||
|
|
// `scrypt` takes the largest logN to time, 16 by default (spec §29.12);
|
||
|
|
// pass a smaller one where 64 MiB or the time is too much, and the result is
|
||
|
|
// extrapolated: scrypt is linear in N.
|
||
|
|
// ignore_for_file: avoid_print
|
||
|
|
library;
|
||
|
|
|
||
|
|
import 'dart:typed_data';
|
||
|
|
|
||
|
|
import 'package:datekeys/src/chacha20poly1305.dart';
|
||
|
|
import 'package:datekeys/src/curve25519.dart';
|
||
|
|
import 'package:datekeys/src/scrypt.dart';
|
||
|
|
import 'package:datekeys/src/sha256.dart';
|
||
|
|
|
||
|
|
/// The mean time of [f] in milliseconds, over at least [minRuns] runs and
|
||
|
|
/// about [budgetMs] milliseconds, after one run to warm up.
|
||
|
|
double time(void Function() f, {int minRuns = 3, int budgetMs = 2000}) {
|
||
|
|
f();
|
||
|
|
final sw = Stopwatch()..start();
|
||
|
|
var runs = 0;
|
||
|
|
while (runs < minRuns || sw.elapsedMilliseconds < budgetMs) {
|
||
|
|
f();
|
||
|
|
runs++;
|
||
|
|
}
|
||
|
|
return sw.elapsedMicroseconds / 1000 / runs;
|
||
|
|
}
|
||
|
|
|
||
|
|
String ms(double v) => '${v.toStringAsFixed(v < 10 ? 2 : 0)} ms';
|
||
|
|
|
||
|
|
void main(List<String> args) {
|
||
|
|
final maxLogN = args.isEmpty ? 16 : int.parse(args.first);
|
||
|
|
final scalar = Uint8List(32)..[0] = 7;
|
||
|
|
final u = x25519PublicKey(Uint8List(32)..[0] = 9);
|
||
|
|
print(
|
||
|
|
'X25519 (one key agreement): ${ms(time(() => x25519Agree(scalar, u)))}',
|
||
|
|
);
|
||
|
|
|
||
|
|
// A valid signature: R = [r]B and S = r + k·a computed elsewhere is not
|
||
|
|
// available here, so the timing uses a signature from the vectors of Go.
|
||
|
|
final pub = _hex(
|
||
|
|
'd75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a',
|
||
|
|
);
|
||
|
|
final sig = _hex(
|
||
|
|
'e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e06522490155'
|
||
|
|
'5fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b',
|
||
|
|
);
|
||
|
|
if (!verifyStrict(pub, Uint8List(0), sig)) throw StateError('bad vector');
|
||
|
|
print(
|
||
|
|
'Ed25519 verify (strict): ${ms(time(() => verifyStrict(pub, Uint8List(0), sig)))}',
|
||
|
|
);
|
||
|
|
|
||
|
|
final mib = Uint8List(1 << 20);
|
||
|
|
final key = Uint8List(32);
|
||
|
|
final nonce = Uint8List(12);
|
||
|
|
final sealed = chacha20Poly1305Seal(key, nonce, mib);
|
||
|
|
print(
|
||
|
|
'ChaCha20-Poly1305 seal, 1 MiB: ${ms(time(() => chacha20Poly1305Seal(key, nonce, mib)))}',
|
||
|
|
);
|
||
|
|
print(
|
||
|
|
'ChaCha20-Poly1305 open, 1 MiB: ${ms(time(() => chacha20Poly1305Open(key, nonce, sealed)))}',
|
||
|
|
);
|
||
|
|
|
||
|
|
final pw = 'perro luna casa verde tren mar'.codeUnits;
|
||
|
|
final salt = 'DateKeys llave de palabras v2|x|1000|y'.codeUnits;
|
||
|
|
print(
|
||
|
|
'PBKDF2-HMAC-SHA256, 600 000 iterations: '
|
||
|
|
'${ms(time(() => pbkdf2HmacSha256(pw, salt, 600000, 32), minRuns: 1, budgetMs: 0))}',
|
||
|
|
);
|
||
|
|
|
||
|
|
for (var logN = 10; logN <= maxLogN; logN += 2) {
|
||
|
|
final t = time(
|
||
|
|
() => scrypt([1, 2, 3], [4, 5, 6], 1 << logN, 8, 1, 32),
|
||
|
|
minRuns: 1,
|
||
|
|
budgetMs: 0,
|
||
|
|
);
|
||
|
|
final note = logN < 16
|
||
|
|
? ', so about ${ms(t * (1 << (16 - logN)))} at logN 16'
|
||
|
|
: '';
|
||
|
|
print('scrypt logN $logN, r 8, p 1: ${ms(t)}$note');
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
Uint8List _hex(String s) => Uint8List.fromList([
|
||
|
|
for (var i = 0; i < s.length; i += 2)
|
||
|
|
int.parse(s.substring(i, i + 2), radix: 16),
|
||
|
|
]);
|