authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2025-09-16 23:13:58+02:00
committergravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2025-09-16 23:13:58+02:00
logb1b2cd7ef8d1935479212d8eb21508b8b51111ad
tree748821581bd0cb13106d4bdee8d6d033c9c11129
parent5eb7610112f58ff5dc07fb4b3bdf539fecafc17f

Parallelize deriveKeys


1 files changed, 39 insertions(+), 46 deletions(-)

lib/std/crypto/aes_gcm_siv.zig+39-46
...@@ -49,54 +49,47 @@ fn AesGcmSiv(comptime Aes: anytype) type {...@@ -49,54 +49,47 @@ fn AesGcmSiv(comptime Aes: anytype) type {
4949
50 // Derive authentication and message keys per RFC 8452 Section 450 // Derive authentication and message keys per RFC 8452 Section 4
51 // Each encryption produces 16 bytes, but we only use first 8 bytes of each block51 // Each encryption produces 16 bytes, but we only use first 8 bytes of each block
52 var key_block: [16]u8 = undefined;52
53 var cipher_out: [16]u8 = undefined;
54
55 // Generate authentication key (128 bits = 2 * 8 bytes)
56 // Block 0: counter = 0 with nonce
57 mem.writeInt(u32, key_block[0..4], 0, .little);
58 key_block[4..16].* = nonce;
59 aes.encrypt(&cipher_out, &key_block);
60 @memcpy(auth_key[0..8], cipher_out[0..8]);
61
62 // Block 1: counter = 1 with nonce
63 mem.writeInt(u32, key_block[0..4], 1, .little);
64 aes.encrypt(&cipher_out, &key_block);
65 @memcpy(auth_key[8..16], cipher_out[0..8]);
66
67 // Generate message encryption key
68 if (key_length == 16) {53 if (key_length == 16) {
69 // AES-128-GCM-SIV: 128-bit message key = 2 * 8 bytes54 // AES-128-GCM-SIV: Process 4 blocks in parallel
70 // Block 2: counter = 2 with nonce55 var key_blocks: [4 * 16]u8 = undefined;
71 mem.writeInt(u32, key_block[0..4], 2, .little);56 var cipher_outs: [4 * 16]u8 = undefined;
72 aes.encrypt(&cipher_out, &key_block);57
73 @memcpy(message_key[0..8], cipher_out[0..8]);58 // Set up all 4 blocks with counters 0-3 and nonce
7459 inline for (0..4) |i| {
75 // Block 3: counter = 3 with nonce60 mem.writeInt(u32, key_blocks[i * 16 ..][0..4], @intCast(i), .little);
76 mem.writeInt(u32, key_block[0..4], 3, .little);61 key_blocks[i * 16 + 4 .. i * 16 + 16].* = nonce;
77 aes.encrypt(&cipher_out, &key_block);62 }
78 @memcpy(message_key[8..16], cipher_out[0..8]);63
64 // Encrypt all 4 blocks in parallel
65 aes.encryptWide(4, &cipher_outs, &key_blocks);
66
67 // Extract the key material (first 8 bytes of each block)
68 @memcpy(auth_key[0..8], cipher_outs[0..8]);
69 @memcpy(auth_key[8..16], cipher_outs[16..24]);
70 @memcpy(message_key[0..8], cipher_outs[32..40]);
71 @memcpy(message_key[8..16], cipher_outs[48..56]);
79 } else {72 } else {
80 // AES-256-GCM-SIV: 256-bit message key = 4 * 8 bytes73 // AES-256-GCM-SIV: Process 6 blocks in parallel
81 // Block 2: counter = 2 with nonce74 var key_blocks: [6 * 16]u8 = undefined;
82 mem.writeInt(u32, key_block[0..4], 2, .little);75 var cipher_outs: [6 * 16]u8 = undefined;
83 aes.encrypt(&cipher_out, &key_block);76
84 @memcpy(message_key[0..8], cipher_out[0..8]);77 // Set up all 6 blocks with counters 0-5 and nonce
8578 inline for (0..6) |i| {
86 // Block 3: counter = 3 with nonce79 mem.writeInt(u32, key_blocks[i * 16 ..][0..4], @intCast(i), .little);
87 mem.writeInt(u32, key_block[0..4], 3, .little);80 key_blocks[i * 16 + 4 .. i * 16 + 16].* = nonce;
88 aes.encrypt(&cipher_out, &key_block);81 }
89 @memcpy(message_key[8..16], cipher_out[0..8]);82
9083 // Encrypt all 6 blocks in parallel
91 // Block 4: counter = 4 with nonce84 aes.encryptWide(6, &cipher_outs, &key_blocks);
92 mem.writeInt(u32, key_block[0..4], 4, .little);85
93 aes.encrypt(&cipher_out, &key_block);86 // Extract the key material (first 8 bytes of each block)
94 @memcpy(message_key[16..24], cipher_out[0..8]);87 @memcpy(auth_key[0..8], cipher_outs[0..8]);
9588 @memcpy(auth_key[8..16], cipher_outs[16..24]);
96 // Block 5: counter = 5 with nonce89 @memcpy(message_key[0..8], cipher_outs[32..40]);
97 mem.writeInt(u32, key_block[0..4], 5, .little);90 @memcpy(message_key[8..16], cipher_outs[48..56]);
98 aes.encrypt(&cipher_out, &key_block);91 @memcpy(message_key[16..24], cipher_outs[64..72]);
99 @memcpy(message_key[24..32], cipher_out[0..8]);92 @memcpy(message_key[24..32], cipher_outs[80..88]);
100 }93 }
101 }94 }
10295