Commit 047599928a

Frank Denis <github@pureftpd.org>
2020-10-19 23:08:38
Add a benchmark for signature verifications
1 parent 2d9befe
Changed files (1)
lib
std
lib/std/crypto/benchmark.zig
@@ -134,8 +134,8 @@ pub fn benchmarkSignature(comptime Signature: anytype, comptime signatures_count
     {
         var i: usize = 0;
         while (i < signatures_count) : (i += 1) {
-            const s = try Signature.sign(&msg, key_pair, null);
-            mem.doNotOptimizeAway(&s);
+            const sig = try Signature.sign(&msg, key_pair, null);
+            mem.doNotOptimizeAway(&sig);
         }
     }
     const end = timer.read();
@@ -146,6 +146,65 @@ pub fn benchmarkSignature(comptime Signature: anytype, comptime signatures_count
     return throughput;
 }
 
+const signature_verifications = [_]Crypto{Crypto{ .ty = crypto.sign.Ed25519, .name = "ed25519" }};
+
+pub fn benchmarkSignatureVerification(comptime Signature: anytype, comptime signatures_count: comptime_int) !u64 {
+    var seed: [Signature.seed_length]u8 = undefined;
+    prng.random.bytes(seed[0..]);
+    const msg = [_]u8{0} ** 64;
+    const key_pair = try Signature.createKeyPair(seed);
+    const public_key = Signature.publicKey(key_pair);
+    const sig = try Signature.sign(&msg, key_pair, null);
+
+    var timer = try Timer.start();
+    const start = timer.lap();
+    {
+        var i: usize = 0;
+        while (i < signatures_count) : (i += 1) {
+            try Signature.verify(sig, &msg, public_key);
+            mem.doNotOptimizeAway(&sig);
+        }
+    }
+    const end = timer.read();
+
+    const elapsed_s = @intToFloat(f64, end - start) / time.ns_per_s;
+    const throughput = @floatToInt(u64, signatures_count / elapsed_s);
+
+    return throughput;
+}
+
+const batch_signature_verifications = [_]Crypto{Crypto{ .ty = crypto.sign.Ed25519, .name = "ed25519" }};
+
+pub fn benchmarkBatchSignatureVerification(comptime Signature: anytype, comptime signatures_count: comptime_int) !u64 {
+    var seed: [Signature.seed_length]u8 = undefined;
+    prng.random.bytes(seed[0..]);
+    const msg = [_]u8{0} ** 64;
+    const key_pair = try Signature.createKeyPair(seed);
+    const public_key = Signature.publicKey(key_pair);
+    const sig = try Signature.sign(&msg, key_pair, null);
+
+    var batch: [64]Signature.BatchElement = undefined;
+    for (batch) |*element| {
+        element.* = Signature.BatchElement{ .sig = sig, .msg = &msg, .public_key = public_key };
+    }
+
+    var timer = try Timer.start();
+    const start = timer.lap();
+    {
+        var i: usize = 0;
+        while (i < signatures_count) : (i += 1) {
+            try Signature.verifyBatch(batch.len, batch);
+            mem.doNotOptimizeAway(&sig);
+        }
+    }
+    const end = timer.read();
+
+    const elapsed_s = @intToFloat(f64, end - start) / time.ns_per_s;
+    const throughput = batch.len * @floatToInt(u64, signatures_count / elapsed_s);
+
+    return throughput;
+}
+
 const aeads = [_]Crypto{
     Crypto{ .ty = crypto.aead.ChaCha20Poly1305, .name = "chacha20Poly1305" },
     Crypto{ .ty = crypto.aead.XChaCha20Poly1305, .name = "xchacha20Poly1305" },
@@ -326,6 +385,20 @@ pub fn main() !void {
         }
     }
 
+    inline for (signature_verifications) |E| {
+        if (filter == null or std.mem.indexOf(u8, E.name, filter.?) != null) {
+            const throughput = try benchmarkSignatureVerification(E.ty, mode(1000));
+            try stdout.print("{:>17}: {:10} verifications/s\n", .{ E.name, throughput });
+        }
+    }
+
+    inline for (batch_signature_verifications) |E| {
+        if (filter == null or std.mem.indexOf(u8, E.name, filter.?) != null) {
+            const throughput = try benchmarkBatchSignatureVerification(E.ty, mode(1000));
+            try stdout.print("{:>17}: {:10} verifications/s (batch)\n", .{ E.name, throughput });
+        }
+    }
+
     inline for (aeads) |E| {
         if (filter == null or std.mem.indexOf(u8, E.name, filter.?) != null) {
             const throughput = try benchmarkAead(E.ty, mode(128 * MiB));