mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
Add Kyber post-quantum key encapsulation mechanism (#14902)
Implementation of the IND-CCA2 post-quantum secure key encapsulation mechanism (KEM) CRYSTALS-Kyber, as submitted to the third round of the NIST Post-Quantum Cryptography (v3.02/"draft00"), and selected for standardisation. Co-authored-by: Frank Denis <124872+jedisct1@users.noreply.github.com>
This commit is contained in:
parent
e17998b396
commit
4414f9c46e
@ -68,6 +68,11 @@ pub const dh = struct {
|
|||||||
pub const X25519 = @import("crypto/25519/x25519.zig").X25519;
|
pub const X25519 = @import("crypto/25519/x25519.zig").X25519;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Key Encapsulation Mechanisms.
|
||||||
|
pub const kem = struct {
|
||||||
|
pub const kyber_d00 = @import("crypto/kyber_d00.zig");
|
||||||
|
};
|
||||||
|
|
||||||
/// Elliptic-curve arithmetic.
|
/// Elliptic-curve arithmetic.
|
||||||
pub const ecc = struct {
|
pub const ecc = struct {
|
||||||
pub const Curve25519 = @import("crypto/25519/curve25519.zig").Curve25519;
|
pub const Curve25519 = @import("crypto/25519/curve25519.zig").Curve25519;
|
||||||
@ -240,6 +245,8 @@ test {
|
|||||||
|
|
||||||
_ = dh.X25519;
|
_ = dh.X25519;
|
||||||
|
|
||||||
|
_ = kem.kyber_d00;
|
||||||
|
|
||||||
_ = ecc.Curve25519;
|
_ = ecc.Curve25519;
|
||||||
_ = ecc.Edwards25519;
|
_ = ecc.Edwards25519;
|
||||||
_ = ecc.P256;
|
_ = ecc.P256;
|
||||||
|
|||||||
@ -203,6 +203,72 @@ pub fn benchmarkBatchSignatureVerification(comptime Signature: anytype, comptime
|
|||||||
return throughput;
|
return throughput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const kems = [_]Crypto{
|
||||||
|
Crypto{ .ty = crypto.kem.kyber_d00.Kyber512, .name = "kyber512d00" },
|
||||||
|
Crypto{ .ty = crypto.kem.kyber_d00.Kyber768, .name = "kyber768d00" },
|
||||||
|
Crypto{ .ty = crypto.kem.kyber_d00.Kyber1024, .name = "kyber1024d00" },
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn benchmarkKem(comptime Kem: anytype, comptime kems_count: comptime_int) !u64 {
|
||||||
|
const key_pair = try Kem.KeyPair.create(null);
|
||||||
|
|
||||||
|
var timer = try Timer.start();
|
||||||
|
const start = timer.lap();
|
||||||
|
{
|
||||||
|
var i: usize = 0;
|
||||||
|
while (i < kems_count) : (i += 1) {
|
||||||
|
const e = key_pair.public_key.encaps(null);
|
||||||
|
mem.doNotOptimizeAway(&e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const end = timer.read();
|
||||||
|
|
||||||
|
const elapsed_s = @intToFloat(f64, end - start) / time.ns_per_s;
|
||||||
|
const throughput = @floatToInt(u64, kems_count / elapsed_s);
|
||||||
|
|
||||||
|
return throughput;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn benchmarkKemDecaps(comptime Kem: anytype, comptime kems_count: comptime_int) !u64 {
|
||||||
|
const key_pair = try Kem.KeyPair.create(null);
|
||||||
|
|
||||||
|
const e = key_pair.public_key.encaps(null);
|
||||||
|
|
||||||
|
var timer = try Timer.start();
|
||||||
|
const start = timer.lap();
|
||||||
|
{
|
||||||
|
var i: usize = 0;
|
||||||
|
while (i < kems_count) : (i += 1) {
|
||||||
|
const ss2 = try key_pair.secret_key.decaps(&e.ciphertext);
|
||||||
|
mem.doNotOptimizeAway(&ss2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const end = timer.read();
|
||||||
|
|
||||||
|
const elapsed_s = @intToFloat(f64, end - start) / time.ns_per_s;
|
||||||
|
const throughput = @floatToInt(u64, kems_count / elapsed_s);
|
||||||
|
|
||||||
|
return throughput;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn benchmarkKemKeyGen(comptime Kem: anytype, comptime kems_count: comptime_int) !u64 {
|
||||||
|
var timer = try Timer.start();
|
||||||
|
const start = timer.lap();
|
||||||
|
{
|
||||||
|
var i: usize = 0;
|
||||||
|
while (i < kems_count) : (i += 1) {
|
||||||
|
const key_pair = try Kem.KeyPair.create(null);
|
||||||
|
mem.doNotOptimizeAway(&key_pair);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const end = timer.read();
|
||||||
|
|
||||||
|
const elapsed_s = @intToFloat(f64, end - start) / time.ns_per_s;
|
||||||
|
const throughput = @floatToInt(u64, kems_count / elapsed_s);
|
||||||
|
|
||||||
|
return throughput;
|
||||||
|
}
|
||||||
|
|
||||||
const aeads = [_]Crypto{
|
const aeads = [_]Crypto{
|
||||||
Crypto{ .ty = crypto.aead.chacha_poly.ChaCha20Poly1305, .name = "chacha20Poly1305" },
|
Crypto{ .ty = crypto.aead.chacha_poly.ChaCha20Poly1305, .name = "chacha20Poly1305" },
|
||||||
Crypto{ .ty = crypto.aead.chacha_poly.XChaCha20Poly1305, .name = "xchacha20Poly1305" },
|
Crypto{ .ty = crypto.aead.chacha_poly.XChaCha20Poly1305, .name = "xchacha20Poly1305" },
|
||||||
@ -485,4 +551,25 @@ pub fn main() !void {
|
|||||||
try stdout.print("{s:>17}: {d:10.3} s/ops\n", .{ H.name, throughput });
|
try stdout.print("{s:>17}: {d:10.3} s/ops\n", .{ H.name, throughput });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline for (kems) |E| {
|
||||||
|
if (filter == null or std.mem.indexOf(u8, E.name, filter.?) != null) {
|
||||||
|
const throughput = try benchmarkKem(E.ty, mode(1000));
|
||||||
|
try stdout.print("{s:>17}: {:10} encaps/s\n", .{ E.name, throughput });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline for (kems) |E| {
|
||||||
|
if (filter == null or std.mem.indexOf(u8, E.name, filter.?) != null) {
|
||||||
|
const throughput = try benchmarkKemDecaps(E.ty, mode(25000));
|
||||||
|
try stdout.print("{s:>17}: {:10} decaps/s\n", .{ E.name, throughput });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline for (kems) |E| {
|
||||||
|
if (filter == null or std.mem.indexOf(u8, E.name, filter.?) != null) {
|
||||||
|
const throughput = try benchmarkKemKeyGen(E.ty, mode(25000));
|
||||||
|
try stdout.print("{s:>17}: {:10} keygen/s\n", .{ E.name, throughput });
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1780
lib/std/crypto/kyber_d00.zig
Normal file
1780
lib/std/crypto/kyber_d00.zig
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user