Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tls: send post-quantum secure keyshare #14920

Merged
merged 1 commit into from
Mar 17, 2023
Merged

Conversation

bwesterb
Copy link
Contributor

Sends post-quantum secure hybrid key share X25519+Kyber768Draft00, deployed by Cloudflare.

A few notes:

  1. The method of hybridisation is as per this IETF TLS WG draft version -06.
  2. Kyber will probably change before final standardisation by NIST. When it does, we'll use a new TLS codepoint and update. The current version is v3.02 of the specification and version -00 of this I-D.
  3. The only other big deployment of post-quantum kex is CECPQ2 (ref1, ref2) by Google, but they'll move to Kyber. It is not clear though whether they'll adopt a preliminary version such as this one.
  4. Zig already generates and sends two key shares: P-256 and X25519. We generate a Kyber768 on top of that and reuse the X25519 share to make the hybrid. Kyber768 is fast — faster than X25519 — even with the currently unoptimised implementation:
            x25519:      33753 exchanges/s
       kyber768d00:      49095 encaps/s
       kyber768d00:      62798 decaps/s
       kyber768d00:      43287 keygen/s
    
  5. Kyber's keyshare is bigger: 1184 bytes for the client keyshare and 1088 bytes for the server keyshare. This will typically split the ClientHello into two TCP segments. The standards allow this, but it might well be that some middle boxes don't expect this.

To test

const std = @import("std");

pub fn main() !void {
    var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    defer arena.deinit();

    const hdrs = std.http.Client.Request.Headers{};
    const opts = std.http.Client.Request.Options{};
    var buf: [1000]u8 = undefined;
    const uri = try std.Uri.parse("https://cloudflare.com/cdn-cgi/trace");
    var client = std.http.Client{
        .allocator= arena.allocator(),
    };
    var req = try client.request(uri, hdrs, opts);
    try req.finish();
    const read = try req.readAll(&buf);
    const stdout = std.io.getStdOut().writer();
    try stdout.print("{s}\n", .{buf[0..read]});
}

Output:

fl=555f40
h=cloudflare.com
ip=[snip]
ts=1678868428.064
visit_scheme=https
uag=zig (std.http)
colo=AMS
sliver=none
http=http/1.1
loc=NL
tls=TLSv1.3
sni=plaintext
warp=off
gateway=off
rbi=off
kex=X25519Kyber768Draft00

@bwesterb
Copy link
Contributor Author

@jedisct1

@jedisct1
Copy link
Contributor

Seeing that is amazing, well done Bas!

@jedisct1 jedisct1 added the standard library This issue involves writing Zig code for the standard library. label Mar 15, 2023
@bwesterb
Copy link
Contributor Author

@jedisct1 build passed.

@jedisct1 jedisct1 merged commit 2089b3f into ziglang:master Mar 17, 2023
truemedian pushed a commit to truemedian/zig that referenced this pull request Mar 30, 2023
@jedisct1 jedisct1 deleted the pqtls branch November 2, 2023 15:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
standard library This issue involves writing Zig code for the standard library.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants