diff --git a/lib/std/crypto.zig b/lib/std/crypto.zig index 858869e5e3..0f6fa48d0a 100644 --- a/lib/std/crypto.zig +++ b/lib/std/crypto.zig @@ -11,10 +11,10 @@ pub const aead = struct { pub const Gimli = @import("crypto/gimli.zig").Aead; pub const ChaCha20Poly1305 = chacha20.Chacha20Poly1305; pub const XChaCha20Poly1305 = chacha20.XChacha20Poly1305; - pub const AEGIS128L = @import("crypto/aegis.zig").AEGIS128L; - pub const AEGIS256 = @import("crypto/aegis.zig").AEGIS256; - pub const AES128GCM = @import("crypto/aes_gcm.zig").AES128GCM; - pub const AES256GCM = @import("crypto/aes_gcm.zig").AES256GCM; + pub const Aegis128L = @import("crypto/aegis.zig").Aegis128L; + pub const Aegis256 = @import("crypto/aegis.zig").Aegis256; + pub const Aes128Gcm = @import("crypto/aes_gcm.zig").Aes128Gcm; + pub const Aes256Gcm = @import("crypto/aes_gcm.zig").Aes256Gcm; }; /// Authentication (MAC) functions. @@ -156,8 +156,11 @@ test "issue #4532: no index out of bounds" { hash.sha3.Sha3_256, hash.sha3.Sha3_384, hash.sha3.Sha3_512, + hash.blake2.Blake2s128, hash.blake2.Blake2s224, hash.blake2.Blake2s256, + hash.blake2.Blake2b128, + hash.blake2.Blake2b256, hash.blake2.Blake2b384, hash.blake2.Blake2b512, hash.Gimli, @@ -170,11 +173,11 @@ test "issue #4532: no index out of bounds" { const h0 = Hasher.init(.{}); var h = h0; h.update(block[0..]); - h.final(out1[0..]); + h.final(&out1); h = h0; h.update(block[0..1]); h.update(block[1..]); - h.final(out2[0..]); + h.final(&out2); std.testing.expectEqual(out1, out2); } diff --git a/lib/std/crypto/25519/x25519.zig b/lib/std/crypto/25519/x25519.zig index 913140657d..dc1bd5a5ef 100644 --- a/lib/std/crypto/25519/x25519.zig +++ b/lib/std/crypto/25519/x25519.zig @@ -14,12 +14,12 @@ pub const X25519 = struct { /// Length (in bytes) of a secret key. pub const secret_length = 32; /// Length (in bytes) of the output of the DH function. - pub const minimum_key_length = 32; + pub const key_length = 32; /// Compute the public key for a given private key. pub fn createPublicKey(public_key: []u8, private_key: []const u8) bool { - std.debug.assert(private_key.len >= minimum_key_length); - std.debug.assert(public_key.len >= minimum_key_length); + std.debug.assert(private_key.len >= key_length); + std.debug.assert(public_key.len >= key_length); var s: [32]u8 = undefined; mem.copy(u8, &s, private_key[0..32]); if (Curve.basePoint.clampedMul(s)) |q| { @@ -35,8 +35,8 @@ pub const X25519 = struct { /// hashing it first. pub fn create(out: []u8, private_key: []const u8, public_key: []const u8) bool { std.debug.assert(out.len >= secret_length); - std.debug.assert(private_key.len >= minimum_key_length); - std.debug.assert(public_key.len >= minimum_key_length); + std.debug.assert(private_key.len >= key_length); + std.debug.assert(public_key.len >= key_length); var s: [32]u8 = undefined; var b: [32]u8 = undefined; mem.copy(u8, &s, private_key[0..32]); diff --git a/lib/std/crypto/aegis.zig b/lib/std/crypto/aegis.zig index cb9e4cabe9..f91c13a06c 100644 --- a/lib/std/crypto/aegis.zig +++ b/lib/std/crypto/aegis.zig @@ -1,17 +1,17 @@ const std = @import("std"); const mem = std.mem; const assert = std.debug.assert; -const AESBlock = std.crypto.core.aes.Block; +const AesBlock = std.crypto.core.aes.Block; const State128L = struct { - blocks: [8]AESBlock, + blocks: [8]AesBlock, fn init(key: [16]u8, nonce: [16]u8) State128L { - const c1 = AESBlock.fromBytes(&[16]u8{ 0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, 0x2f, 0xf1, 0x20, 0x11, 0x31, 0x42, 0x73, 0xb5, 0x28, 0xdd }); - const c2 = AESBlock.fromBytes(&[16]u8{ 0x0, 0x1, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0d, 0x15, 0x22, 0x37, 0x59, 0x90, 0xe9, 0x79, 0x62 }); - const key_block = AESBlock.fromBytes(&key); - const nonce_block = AESBlock.fromBytes(&nonce); - const blocks = [8]AESBlock{ + const c1 = AesBlock.fromBytes(&[16]u8{ 0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, 0x2f, 0xf1, 0x20, 0x11, 0x31, 0x42, 0x73, 0xb5, 0x28, 0xdd }); + const c2 = AesBlock.fromBytes(&[16]u8{ 0x0, 0x1, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0d, 0x15, 0x22, 0x37, 0x59, 0x90, 0xe9, 0x79, 0x62 }); + const key_block = AesBlock.fromBytes(&key); + const nonce_block = AesBlock.fromBytes(&nonce); + const blocks = [8]AesBlock{ key_block.xorBlocks(nonce_block), c1, c2, @@ -29,7 +29,7 @@ const State128L = struct { return state; } - inline fn update(state: *State128L, d1: AESBlock, d2: AESBlock) void { + inline fn update(state: *State128L, d1: AesBlock, d2: AesBlock) void { const blocks = &state.blocks; const tmp = blocks[7]; comptime var i: usize = 7; @@ -43,8 +43,8 @@ const State128L = struct { fn enc(state: *State128L, dst: *[32]u8, src: *const [32]u8) void { const blocks = &state.blocks; - const msg0 = AESBlock.fromBytes(src[0..16]); - const msg1 = AESBlock.fromBytes(src[16..32]); + const msg0 = AesBlock.fromBytes(src[0..16]); + const msg1 = AesBlock.fromBytes(src[16..32]); var tmp0 = msg0.xorBlocks(blocks[6]).xorBlocks(blocks[1]); var tmp1 = msg1.xorBlocks(blocks[2]).xorBlocks(blocks[5]); tmp0 = tmp0.xorBlocks(blocks[2].andBlocks(blocks[3])); @@ -56,8 +56,8 @@ const State128L = struct { fn dec(state: *State128L, dst: *[32]u8, src: *const [32]u8) void { const blocks = &state.blocks; - var msg0 = AESBlock.fromBytes(src[0..16]).xorBlocks(blocks[6]).xorBlocks(blocks[1]); - var msg1 = AESBlock.fromBytes(src[16..32]).xorBlocks(blocks[2]).xorBlocks(blocks[5]); + var msg0 = AesBlock.fromBytes(src[0..16]).xorBlocks(blocks[6]).xorBlocks(blocks[1]); + var msg1 = AesBlock.fromBytes(src[16..32]).xorBlocks(blocks[2]).xorBlocks(blocks[5]); msg0 = msg0.xorBlocks(blocks[2].andBlocks(blocks[3])); msg1 = msg1.xorBlocks(blocks[6].andBlocks(blocks[7])); dst[0..16].* = msg0.toBytes(); @@ -70,7 +70,7 @@ const State128L = struct { var sizes: [16]u8 = undefined; mem.writeIntLittle(u64, sizes[0..8], adlen * 8); mem.writeIntLittle(u64, sizes[8..16], mlen * 8); - const tmp = AESBlock.fromBytes(&sizes).xorBlocks(blocks[2]); + const tmp = AesBlock.fromBytes(&sizes).xorBlocks(blocks[2]); var i: usize = 0; while (i < 7) : (i += 1) { state.update(tmp, tmp); @@ -86,7 +86,7 @@ const State128L = struct { /// It was designed to fully exploit the parallelism and built-in AES support of recent Intel and ARM CPUs. /// /// https://competitions.cr.yp.to/round3/aegisv11.pdf -pub const AEGIS128L = struct { +pub const Aegis128L = struct { pub const tag_length = 16; pub const nonce_length = 16; pub const key_length = 16; @@ -155,8 +155,8 @@ pub const AEGIS128L = struct { mem.copy(u8, m[i .. i + m.len % 32], dst[0 .. m.len % 32]); mem.set(u8, dst[0 .. m.len % 32], 0); const blocks = &state.blocks; - blocks[0] = blocks[0].xorBlocks(AESBlock.fromBytes(dst[0..16])); - blocks[4] = blocks[4].xorBlocks(AESBlock.fromBytes(dst[16..32])); + blocks[0] = blocks[0].xorBlocks(AesBlock.fromBytes(dst[0..16])); + blocks[4] = blocks[4].xorBlocks(AesBlock.fromBytes(dst[16..32])); } const computed_tag = state.mac(ad.len, m.len); var acc: u8 = 0; @@ -171,18 +171,18 @@ pub const AEGIS128L = struct { }; const State256 = struct { - blocks: [6]AESBlock, + blocks: [6]AesBlock, fn init(key: [32]u8, nonce: [32]u8) State256 { - const c1 = AESBlock.fromBytes(&[16]u8{ 0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, 0x2f, 0xf1, 0x20, 0x11, 0x31, 0x42, 0x73, 0xb5, 0x28, 0xdd }); - const c2 = AESBlock.fromBytes(&[16]u8{ 0x0, 0x1, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0d, 0x15, 0x22, 0x37, 0x59, 0x90, 0xe9, 0x79, 0x62 }); - const key_block1 = AESBlock.fromBytes(key[0..16]); - const key_block2 = AESBlock.fromBytes(key[16..32]); - const nonce_block1 = AESBlock.fromBytes(nonce[0..16]); - const nonce_block2 = AESBlock.fromBytes(nonce[16..32]); + const c1 = AesBlock.fromBytes(&[16]u8{ 0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, 0x2f, 0xf1, 0x20, 0x11, 0x31, 0x42, 0x73, 0xb5, 0x28, 0xdd }); + const c2 = AesBlock.fromBytes(&[16]u8{ 0x0, 0x1, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0d, 0x15, 0x22, 0x37, 0x59, 0x90, 0xe9, 0x79, 0x62 }); + const key_block1 = AesBlock.fromBytes(key[0..16]); + const key_block2 = AesBlock.fromBytes(key[16..32]); + const nonce_block1 = AesBlock.fromBytes(nonce[0..16]); + const nonce_block2 = AesBlock.fromBytes(nonce[16..32]); const kxn1 = key_block1.xorBlocks(nonce_block1); const kxn2 = key_block2.xorBlocks(nonce_block2); - const blocks = [6]AESBlock{ + const blocks = [6]AesBlock{ kxn1, kxn2, c1, @@ -201,7 +201,7 @@ const State256 = struct { return state; } - inline fn update(state: *State256, d: AESBlock) void { + inline fn update(state: *State256, d: AesBlock) void { const blocks = &state.blocks; const tmp = blocks[5].encrypt(blocks[0]); comptime var i: usize = 5; @@ -213,7 +213,7 @@ const State256 = struct { fn enc(state: *State256, dst: *[16]u8, src: *const [16]u8) void { const blocks = &state.blocks; - const msg = AESBlock.fromBytes(src); + const msg = AesBlock.fromBytes(src); var tmp = msg.xorBlocks(blocks[5]).xorBlocks(blocks[4]).xorBlocks(blocks[1]); tmp = tmp.xorBlocks(blocks[2].andBlocks(blocks[3])); dst.* = tmp.toBytes(); @@ -222,7 +222,7 @@ const State256 = struct { fn dec(state: *State256, dst: *[16]u8, src: *const [16]u8) void { const blocks = &state.blocks; - var msg = AESBlock.fromBytes(src).xorBlocks(blocks[5]).xorBlocks(blocks[4]).xorBlocks(blocks[1]); + var msg = AesBlock.fromBytes(src).xorBlocks(blocks[5]).xorBlocks(blocks[4]).xorBlocks(blocks[1]); msg = msg.xorBlocks(blocks[2].andBlocks(blocks[3])); dst.* = msg.toBytes(); state.update(msg); @@ -233,7 +233,7 @@ const State256 = struct { var sizes: [16]u8 = undefined; mem.writeIntLittle(u64, sizes[0..8], adlen * 8); mem.writeIntLittle(u64, sizes[8..16], mlen * 8); - const tmp = AESBlock.fromBytes(&sizes).xorBlocks(blocks[3]); + const tmp = AesBlock.fromBytes(&sizes).xorBlocks(blocks[3]); var i: usize = 0; while (i < 7) : (i += 1) { state.update(tmp); @@ -248,7 +248,7 @@ const State256 = struct { /// The 256 bit variant of AEGIS has a 256 bit key, a 256 bit nonce, and processes 128 bit message blocks. /// /// https://competitions.cr.yp.to/round3/aegisv11.pdf -pub const AEGIS256 = struct { +pub const Aegis256 = struct { pub const tag_length = 16; pub const nonce_length = 32; pub const key_length = 32; @@ -317,7 +317,7 @@ pub const AEGIS256 = struct { mem.copy(u8, m[i .. i + m.len % 16], dst[0 .. m.len % 16]); mem.set(u8, dst[0 .. m.len % 16], 0); const blocks = &state.blocks; - blocks[0] = blocks[0].xorBlocks(AESBlock.fromBytes(&dst)); + blocks[0] = blocks[0].xorBlocks(AesBlock.fromBytes(&dst)); } const computed_tag = state.mac(ad.len, m.len); var acc: u8 = 0; @@ -334,113 +334,113 @@ pub const AEGIS256 = struct { const htest = @import("test.zig"); const testing = std.testing; -test "AEGIS128L test vector 1" { - const key: [AEGIS128L.key_length]u8 = [_]u8{ 0x10, 0x01 } ++ [_]u8{0x00} ** 14; - const nonce: [AEGIS128L.nonce_length]u8 = [_]u8{ 0x10, 0x00, 0x02 } ++ [_]u8{0x00} ** 13; +test "Aegis128L test vector 1" { + const key: [Aegis128L.key_length]u8 = [_]u8{ 0x10, 0x01 } ++ [_]u8{0x00} ** 14; + const nonce: [Aegis128L.nonce_length]u8 = [_]u8{ 0x10, 0x00, 0x02 } ++ [_]u8{0x00} ** 13; const ad = [8]u8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }; const m = [32]u8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }; var c: [m.len]u8 = undefined; var m2: [m.len]u8 = undefined; - var tag: [AEGIS128L.tag_length]u8 = undefined; + var tag: [Aegis128L.tag_length]u8 = undefined; - AEGIS128L.encrypt(&c, &tag, &m, &ad, nonce, key); - try AEGIS128L.decrypt(&m2, &c, tag, &ad, nonce, key); + Aegis128L.encrypt(&c, &tag, &m, &ad, nonce, key); + try Aegis128L.decrypt(&m2, &c, tag, &ad, nonce, key); testing.expectEqualSlices(u8, &m, &m2); htest.assertEqual("79d94593d8c2119d7e8fd9b8fc77845c5c077a05b2528b6ac54b563aed8efe84", &c); htest.assertEqual("cc6f3372f6aa1bb82388d695c3962d9a", &tag); c[0] +%= 1; - testing.expectError(error.AuthenticationFailed, AEGIS128L.decrypt(&m2, &c, tag, &ad, nonce, key)); + testing.expectError(error.AuthenticationFailed, Aegis128L.decrypt(&m2, &c, tag, &ad, nonce, key)); c[0] -%= 1; tag[0] +%= 1; - testing.expectError(error.AuthenticationFailed, AEGIS128L.decrypt(&m2, &c, tag, &ad, nonce, key)); + testing.expectError(error.AuthenticationFailed, Aegis128L.decrypt(&m2, &c, tag, &ad, nonce, key)); } -test "AEGIS128L test vector 2" { - const key: [AEGIS128L.key_length]u8 = [_]u8{0x00} ** 16; - const nonce: [AEGIS128L.nonce_length]u8 = [_]u8{0x00} ** 16; +test "Aegis128L test vector 2" { + const key: [Aegis128L.key_length]u8 = [_]u8{0x00} ** 16; + const nonce: [Aegis128L.nonce_length]u8 = [_]u8{0x00} ** 16; const ad = [_]u8{}; const m = [_]u8{0x00} ** 16; var c: [m.len]u8 = undefined; var m2: [m.len]u8 = undefined; - var tag: [AEGIS128L.tag_length]u8 = undefined; + var tag: [Aegis128L.tag_length]u8 = undefined; - AEGIS128L.encrypt(&c, &tag, &m, &ad, nonce, key); - try AEGIS128L.decrypt(&m2, &c, tag, &ad, nonce, key); + Aegis128L.encrypt(&c, &tag, &m, &ad, nonce, key); + try Aegis128L.decrypt(&m2, &c, tag, &ad, nonce, key); testing.expectEqualSlices(u8, &m, &m2); htest.assertEqual("41de9000a7b5e40e2d68bb64d99ebb19", &c); htest.assertEqual("f4d997cc9b94227ada4fe4165422b1c8", &tag); } -test "AEGIS128L test vector 3" { - const key: [AEGIS128L.key_length]u8 = [_]u8{0x00} ** 16; - const nonce: [AEGIS128L.nonce_length]u8 = [_]u8{0x00} ** 16; +test "Aegis128L test vector 3" { + const key: [Aegis128L.key_length]u8 = [_]u8{0x00} ** 16; + const nonce: [Aegis128L.nonce_length]u8 = [_]u8{0x00} ** 16; const ad = [_]u8{}; const m = [_]u8{}; var c: [m.len]u8 = undefined; var m2: [m.len]u8 = undefined; - var tag: [AEGIS128L.tag_length]u8 = undefined; + var tag: [Aegis128L.tag_length]u8 = undefined; - AEGIS128L.encrypt(&c, &tag, &m, &ad, nonce, key); - try AEGIS128L.decrypt(&m2, &c, tag, &ad, nonce, key); + Aegis128L.encrypt(&c, &tag, &m, &ad, nonce, key); + try Aegis128L.decrypt(&m2, &c, tag, &ad, nonce, key); testing.expectEqualSlices(u8, &m, &m2); htest.assertEqual("83cc600dc4e3e7e62d4055826174f149", &tag); } -test "AEGIS256 test vector 1" { - const key: [AEGIS256.key_length]u8 = [_]u8{ 0x10, 0x01 } ++ [_]u8{0x00} ** 30; - const nonce: [AEGIS256.nonce_length]u8 = [_]u8{ 0x10, 0x00, 0x02 } ++ [_]u8{0x00} ** 29; +test "Aegis256 test vector 1" { + const key: [Aegis256.key_length]u8 = [_]u8{ 0x10, 0x01 } ++ [_]u8{0x00} ** 30; + const nonce: [Aegis256.nonce_length]u8 = [_]u8{ 0x10, 0x00, 0x02 } ++ [_]u8{0x00} ** 29; const ad = [8]u8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }; const m = [32]u8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }; var c: [m.len]u8 = undefined; var m2: [m.len]u8 = undefined; - var tag: [AEGIS256.tag_length]u8 = undefined; + var tag: [Aegis256.tag_length]u8 = undefined; - AEGIS256.encrypt(&c, &tag, &m, &ad, nonce, key); - try AEGIS256.decrypt(&m2, &c, tag, &ad, nonce, key); + Aegis256.encrypt(&c, &tag, &m, &ad, nonce, key); + try Aegis256.decrypt(&m2, &c, tag, &ad, nonce, key); testing.expectEqualSlices(u8, &m, &m2); htest.assertEqual("f373079ed84b2709faee373584585d60accd191db310ef5d8b11833df9dec711", &c); htest.assertEqual("8d86f91ee606e9ff26a01b64ccbdd91d", &tag); c[0] +%= 1; - testing.expectError(error.AuthenticationFailed, AEGIS256.decrypt(&m2, &c, tag, &ad, nonce, key)); + testing.expectError(error.AuthenticationFailed, Aegis256.decrypt(&m2, &c, tag, &ad, nonce, key)); c[0] -%= 1; tag[0] +%= 1; - testing.expectError(error.AuthenticationFailed, AEGIS256.decrypt(&m2, &c, tag, &ad, nonce, key)); + testing.expectError(error.AuthenticationFailed, Aegis256.decrypt(&m2, &c, tag, &ad, nonce, key)); } -test "AEGIS256 test vector 2" { - const key: [AEGIS256.key_length]u8 = [_]u8{0x00} ** 32; - const nonce: [AEGIS256.nonce_length]u8 = [_]u8{0x00} ** 32; +test "Aegis256 test vector 2" { + const key: [Aegis256.key_length]u8 = [_]u8{0x00} ** 32; + const nonce: [Aegis256.nonce_length]u8 = [_]u8{0x00} ** 32; const ad = [_]u8{}; const m = [_]u8{0x00} ** 16; var c: [m.len]u8 = undefined; var m2: [m.len]u8 = undefined; - var tag: [AEGIS256.tag_length]u8 = undefined; + var tag: [Aegis256.tag_length]u8 = undefined; - AEGIS256.encrypt(&c, &tag, &m, &ad, nonce, key); - try AEGIS256.decrypt(&m2, &c, tag, &ad, nonce, key); + Aegis256.encrypt(&c, &tag, &m, &ad, nonce, key); + try Aegis256.decrypt(&m2, &c, tag, &ad, nonce, key); testing.expectEqualSlices(u8, &m, &m2); htest.assertEqual("b98f03a947807713d75a4fff9fc277a6", &c); htest.assertEqual("478f3b50dc478ef7d5cf2d0f7cc13180", &tag); } -test "AEGIS256 test vector 3" { - const key: [AEGIS256.key_length]u8 = [_]u8{0x00} ** 32; - const nonce: [AEGIS256.nonce_length]u8 = [_]u8{0x00} ** 32; +test "Aegis256 test vector 3" { + const key: [Aegis256.key_length]u8 = [_]u8{0x00} ** 32; + const nonce: [Aegis256.nonce_length]u8 = [_]u8{0x00} ** 32; const ad = [_]u8{}; const m = [_]u8{}; var c: [m.len]u8 = undefined; var m2: [m.len]u8 = undefined; - var tag: [AEGIS256.tag_length]u8 = undefined; + var tag: [Aegis256.tag_length]u8 = undefined; - AEGIS256.encrypt(&c, &tag, &m, &ad, nonce, key); - try AEGIS256.decrypt(&m2, &c, tag, &ad, nonce, key); + Aegis256.encrypt(&c, &tag, &m, &ad, nonce, key); + try Aegis256.decrypt(&m2, &c, tag, &ad, nonce, key); testing.expectEqualSlices(u8, &m, &m2); htest.assertEqual("f7a0878f68bd083e8065354071fc27c3", &tag); diff --git a/lib/std/crypto/aes.zig b/lib/std/crypto/aes.zig index 9040524939..ada55fa975 100644 --- a/lib/std/crypto/aes.zig +++ b/lib/std/crypto/aes.zig @@ -21,10 +21,10 @@ impl: { }; pub const Block = impl.Block; -pub const AESEncryptCtx = impl.AESEncryptCtx; -pub const AESDecryptCtx = impl.AESDecryptCtx; -pub const AES128 = impl.AES128; -pub const AES256 = impl.AES256; +pub const AesEncryptCtx = impl.AesEncryptCtx; +pub const AesDecryptCtx = impl.AesDecryptCtx; +pub const Aes128 = impl.Aes128; +pub const Aes256 = impl.Aes256; test "ctr" { // NIST SP 800-38A pp 55-58 @@ -46,8 +46,8 @@ test "ctr" { }; var out: [exp_out.len]u8 = undefined; - var ctx = AES128.initEnc(key); - ctr(AESEncryptCtx(AES128), ctx, out[0..], in[0..], iv, builtin.Endian.Big); + var ctx = Aes128.initEnc(key); + ctr(AesEncryptCtx(Aes128), ctx, out[0..], in[0..], iv, builtin.Endian.Big); testing.expectEqualSlices(u8, exp_out[0..], out[0..]); } @@ -59,7 +59,7 @@ test "encrypt" { const exp_out = [_]u8{ 0x39, 0x25, 0x84, 0x1d, 0x02, 0xdc, 0x09, 0xfb, 0xdc, 0x11, 0x85, 0x97, 0x19, 0x6a, 0x0b, 0x32 }; var out: [exp_out.len]u8 = undefined; - var ctx = AES128.initEnc(key); + var ctx = Aes128.initEnc(key); ctx.encrypt(out[0..], in[0..]); testing.expectEqualSlices(u8, exp_out[0..], out[0..]); } @@ -74,7 +74,7 @@ test "encrypt" { const exp_out = [_]u8{ 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }; var out: [exp_out.len]u8 = undefined; - var ctx = AES256.initEnc(key); + var ctx = Aes256.initEnc(key); ctx.encrypt(out[0..], in[0..]); testing.expectEqualSlices(u8, exp_out[0..], out[0..]); } @@ -88,7 +88,7 @@ test "decrypt" { const exp_out = [_]u8{ 0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34 }; var out: [exp_out.len]u8 = undefined; - var ctx = AES128.initDec(key); + var ctx = Aes128.initDec(key); ctx.decrypt(out[0..], in[0..]); testing.expectEqualSlices(u8, exp_out[0..], out[0..]); } @@ -103,7 +103,7 @@ test "decrypt" { const exp_out = [_]u8{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; var out: [exp_out.len]u8 = undefined; - var ctx = AES256.initDec(key); + var ctx = Aes256.initDec(key); ctx.decrypt(out[0..], in[0..]); testing.expectEqualSlices(u8, exp_out[0..], out[0..]); } @@ -117,8 +117,8 @@ test "expand 128-bit key" { const exp_dec = [_]*const [32:0]u8{ "2b7e151628aed2a6abf7158809cf4f3c", "a0fafe1788542cb123a339392a6c7605", "f2c295f27a96b9435935807a7359f67f", "3d80477d4716fe3e1e237e446d7a883b", "ef44a541a8525b7fb671253bdb0bad00", "d4d1c6f87c839d87caf2b8bc11f915bc", "6d88a37a110b3efddbf98641ca0093fd", "4e54f70e5f5fc9f384a64fb24ea6dc4f", "ead27321b58dbad2312bf5607f8d292f", "ac7766f319fadc2128d12941575c006e", "d014f9a8c9ee2589e13f0cc8b6630ca6", }; - const enc = AES128.initEnc(key); - const dec = AES128.initDec(key); + const enc = Aes128.initEnc(key); + const dec = Aes128.initDec(key); var exp: [16]u8 = undefined; for (enc.key_schedule.round_keys) |round_key, i| { @@ -139,8 +139,8 @@ test "expand 256-bit key" { const exp_dec = [_]*const [32:0]u8{ "fe4890d1e6188d0b046df344706c631e", "ada23f4963e23b2455427c8a5c709104", "57c96cf6074f07c0706abb07137f9241", "b668b621ce40046d36a047ae0932ed8e", "34ad1e4450866b367725bcc763152946", "32526c367828b24cf8e043c33f92aa20", "c440b289642b757227a3d7f114309581", "d669a7334a7ade7a80c8f18fc772e9e3", "25ba3c22a06bc7fb4388a28333934270", "54fb808b9c137949cab22ff547ba186c", "6c3d632985d1fbd9e3e36578701be0f3", "4a7459f9c8e8f9c256a156bc8d083799", "42107758e9ec98f066329ea193f8858b", "8ec6bff6829ca03b9e49af7edba96125", "603deb1015ca71be2b73aef0857d7781", }; - const enc = AES256.initEnc(key); - const dec = AES256.initDec(key); + const enc = Aes256.initEnc(key); + const dec = Aes256.initDec(key); var exp: [16]u8 = undefined; for (enc.key_schedule.round_keys) |round_key, i| { diff --git a/lib/std/crypto/aes/aesni.zig b/lib/std/crypto/aes/aesni.zig index c1c077a988..8366a9785d 100644 --- a/lib/std/crypto/aes/aesni.zig +++ b/lib/std/crypto/aes/aesni.zig @@ -13,7 +13,7 @@ const BlockVec = Vector(2, u64); /// A single AES block. pub const Block = struct { - pub const block_size: usize = 16; + pub const block_length: usize = 16; /// Internal representation of a block. repr: BlockVec, @@ -165,9 +165,9 @@ pub const Block = struct { }; }; -fn KeySchedule(comptime AES: type) type { - std.debug.assert(AES.rounds == 10 or AES.rounds == 14); - const rounds = AES.rounds; +fn KeySchedule(comptime Aes: type) type { + std.debug.assert(Aes.rounds == 10 or Aes.rounds == 14); + const rounds = Aes.rounds; return struct { const Self = @This(); @@ -243,24 +243,24 @@ fn KeySchedule(comptime AES: type) type { } /// A context to perform encryption using the standard AES key schedule. -pub fn AESEncryptCtx(comptime AES: type) type { - std.debug.assert(AES.key_bits == 128 or AES.key_bits == 256); - const rounds = AES.rounds; +pub fn AesEncryptCtx(comptime Aes: type) type { + std.debug.assert(Aes.key_bits == 128 or Aes.key_bits == 256); + const rounds = Aes.rounds; return struct { const Self = @This(); - pub const block = AES.block; - pub const block_size = block.block_size; - key_schedule: KeySchedule(AES), + pub const block = Aes.block; + pub const block_length = block.block_length; + key_schedule: KeySchedule(Aes), /// Create a new encryption context with the given key. - pub fn init(key: [AES.key_bits / 8]u8) Self { + pub fn init(key: [Aes.key_bits / 8]u8) Self { var t1 = Block.fromBytes(key[0..16]); - const key_schedule = if (AES.key_bits == 128) ks: { - break :ks KeySchedule(AES).expand128(&t1); + const key_schedule = if (Aes.key_bits == 128) ks: { + break :ks KeySchedule(Aes).expand128(&t1); } else ks: { var t2 = Block.fromBytes(key[16..32]); - break :ks KeySchedule(AES).expand256(&t1, &t2); + break :ks KeySchedule(Aes).expand256(&t1, &t2); }; return Self{ .key_schedule = key_schedule, @@ -335,26 +335,26 @@ pub fn AESEncryptCtx(comptime AES: type) type { } /// A context to perform decryption using the standard AES key schedule. -pub fn AESDecryptCtx(comptime AES: type) type { - std.debug.assert(AES.key_bits == 128 or AES.key_bits == 256); - const rounds = AES.rounds; +pub fn AesDecryptCtx(comptime Aes: type) type { + std.debug.assert(Aes.key_bits == 128 or Aes.key_bits == 256); + const rounds = Aes.rounds; return struct { const Self = @This(); - pub const block = AES.block; - pub const block_size = block.block_size; - key_schedule: KeySchedule(AES), + pub const block = Aes.block; + pub const block_length = block.block_length; + key_schedule: KeySchedule(Aes), /// Create a decryption context from an existing encryption context. - pub fn initFromEnc(ctx: AESEncryptCtx(AES)) Self { + pub fn initFromEnc(ctx: AesEncryptCtx(Aes)) Self { return Self{ .key_schedule = ctx.key_schedule.invert(), }; } /// Create a new decryption context with the given key. - pub fn init(key: [AES.key_bits / 8]u8) Self { - const enc_ctx = AESEncryptCtx(AES).init(key); + pub fn init(key: [Aes.key_bits / 8]u8) Self { + const enc_ctx = AesEncryptCtx(Aes).init(key); return initFromEnc(enc_ctx); } @@ -395,35 +395,35 @@ pub fn AESDecryptCtx(comptime AES: type) type { } /// AES-128 with the standard key schedule. -pub const AES128 = struct { +pub const Aes128 = struct { pub const key_bits: usize = 128; pub const rounds = ((key_bits - 64) / 32 + 8); pub const block = Block; /// Create a new context for encryption. - pub fn initEnc(key: [key_bits / 8]u8) AESEncryptCtx(AES128) { - return AESEncryptCtx(AES128).init(key); + pub fn initEnc(key: [key_bits / 8]u8) AesEncryptCtx(Aes128) { + return AesEncryptCtx(Aes128).init(key); } /// Create a new context for decryption. - pub fn initDec(key: [key_bits / 8]u8) AESDecryptCtx(AES128) { - return AESDecryptCtx(AES128).init(key); + pub fn initDec(key: [key_bits / 8]u8) AesDecryptCtx(Aes128) { + return AesDecryptCtx(Aes128).init(key); } }; /// AES-256 with the standard key schedule. -pub const AES256 = struct { +pub const Aes256 = struct { pub const key_bits: usize = 256; pub const rounds = ((key_bits - 64) / 32 + 8); pub const block = Block; /// Create a new context for encryption. - pub fn initEnc(key: [key_bits / 8]u8) AESEncryptCtx(AES256) { - return AESEncryptCtx(AES256).init(key); + pub fn initEnc(key: [key_bits / 8]u8) AesEncryptCtx(Aes256) { + return AesEncryptCtx(Aes256).init(key); } /// Create a new context for decryption. - pub fn initDec(key: [key_bits / 8]u8) AESDecryptCtx(AES256) { - return AESDecryptCtx(AES256).init(key); + pub fn initDec(key: [key_bits / 8]u8) AesDecryptCtx(Aes256) { + return AesDecryptCtx(Aes256).init(key); } }; diff --git a/lib/std/crypto/aes/armcrypto.zig b/lib/std/crypto/aes/armcrypto.zig index b1d8252c94..a38d94de77 100644 --- a/lib/std/crypto/aes/armcrypto.zig +++ b/lib/std/crypto/aes/armcrypto.zig @@ -13,7 +13,7 @@ const BlockVec = Vector(2, u64); /// A single AES block. pub const Block = struct { - pub const block_size: usize = 16; + pub const block_length: usize = 16; /// Internal representation of a block. repr: BlockVec, @@ -181,9 +181,9 @@ pub const Block = struct { }; }; -fn KeySchedule(comptime AES: type) type { - std.debug.assert(AES.rounds == 10 or AES.rounds == 14); - const rounds = AES.rounds; +fn KeySchedule(comptime Aes: type) type { + std.debug.assert(Aes.rounds == 10 or Aes.rounds == 14); + const rounds = Aes.rounds; return struct { const Self = @This(); @@ -304,24 +304,24 @@ fn KeySchedule(comptime AES: type) type { } /// A context to perform encryption using the standard AES key schedule. -pub fn AESEncryptCtx(comptime AES: type) type { - std.debug.assert(AES.key_bits == 128 or AES.key_bits == 256); - const rounds = AES.rounds; +pub fn AesEncryptCtx(comptime Aes: type) type { + std.debug.assert(Aes.key_bits == 128 or Aes.key_bits == 256); + const rounds = Aes.rounds; return struct { const Self = @This(); - pub const block = AES.block; - pub const block_size = block.block_size; - key_schedule: KeySchedule(AES), + pub const block = Aes.block; + pub const block_length = block.block_length; + key_schedule: KeySchedule(Aes), /// Create a new encryption context with the given key. - pub fn init(key: [AES.key_bits / 8]u8) Self { + pub fn init(key: [Aes.key_bits / 8]u8) Self { var t1 = Block.fromBytes(key[0..16]); - const key_schedule = if (AES.key_bits == 128) ks: { - break :ks KeySchedule(AES).expand128(&t1); + const key_schedule = if (Aes.key_bits == 128) ks: { + break :ks KeySchedule(Aes).expand128(&t1); } else ks: { var t2 = Block.fromBytes(key[16..32]); - break :ks KeySchedule(AES).expand256(&t1, &t2); + break :ks KeySchedule(Aes).expand256(&t1, &t2); }; return Self{ .key_schedule = key_schedule, @@ -396,26 +396,26 @@ pub fn AESEncryptCtx(comptime AES: type) type { } /// A context to perform decryption using the standard AES key schedule. -pub fn AESDecryptCtx(comptime AES: type) type { - std.debug.assert(AES.key_bits == 128 or AES.key_bits == 256); - const rounds = AES.rounds; +pub fn AesDecryptCtx(comptime Aes: type) type { + std.debug.assert(Aes.key_bits == 128 or Aes.key_bits == 256); + const rounds = Aes.rounds; return struct { const Self = @This(); - pub const block = AES.block; - pub const block_size = block.block_size; - key_schedule: KeySchedule(AES), + pub const block = Aes.block; + pub const block_length = block.block_length; + key_schedule: KeySchedule(Aes), /// Create a decryption context from an existing encryption context. - pub fn initFromEnc(ctx: AESEncryptCtx(AES)) Self { + pub fn initFromEnc(ctx: AesEncryptCtx(Aes)) Self { return Self{ .key_schedule = ctx.key_schedule.invert(), }; } /// Create a new decryption context with the given key. - pub fn init(key: [AES.key_bits / 8]u8) Self { - const enc_ctx = AESEncryptCtx(AES).init(key); + pub fn init(key: [Aes.key_bits / 8]u8) Self { + const enc_ctx = AesEncryptCtx(Aes).init(key); return initFromEnc(enc_ctx); } @@ -456,35 +456,35 @@ pub fn AESDecryptCtx(comptime AES: type) type { } /// AES-128 with the standard key schedule. -pub const AES128 = struct { +pub const Aes128 = struct { pub const key_bits: usize = 128; pub const rounds = ((key_bits - 64) / 32 + 8); pub const block = Block; /// Create a new context for encryption. - pub fn initEnc(key: [key_bits / 8]u8) AESEncryptCtx(AES128) { - return AESEncryptCtx(AES128).init(key); + pub fn initEnc(key: [key_bits / 8]u8) AesEncryptCtx(Aes128) { + return AesEncryptCtx(Aes128).init(key); } /// Create a new context for decryption. - pub fn initDec(key: [key_bits / 8]u8) AESDecryptCtx(AES128) { - return AESDecryptCtx(AES128).init(key); + pub fn initDec(key: [key_bits / 8]u8) AesDecryptCtx(Aes128) { + return AesDecryptCtx(Aes128).init(key); } }; /// AES-256 with the standard key schedule. -pub const AES256 = struct { +pub const Aes256 = struct { pub const key_bits: usize = 256; pub const rounds = ((key_bits - 64) / 32 + 8); pub const block = Block; /// Create a new context for encryption. - pub fn initEnc(key: [key_bits / 8]u8) AESEncryptCtx(AES256) { - return AESEncryptCtx(AES256).init(key); + pub fn initEnc(key: [key_bits / 8]u8) AesEncryptCtx(Aes256) { + return AesEncryptCtx(Aes256).init(key); } /// Create a new context for decryption. - pub fn initDec(key: [key_bits / 8]u8) AESDecryptCtx(AES256) { - return AESDecryptCtx(AES256).init(key); + pub fn initDec(key: [key_bits / 8]u8) AesDecryptCtx(Aes256) { + return AesDecryptCtx(Aes256).init(key); } }; diff --git a/lib/std/crypto/aes/soft.zig b/lib/std/crypto/aes/soft.zig index 5f66f3499e..06f8134dec 100644 --- a/lib/std/crypto/aes/soft.zig +++ b/lib/std/crypto/aes/soft.zig @@ -12,7 +12,7 @@ const BlockVec = [4]u32; /// A single AES block. pub const Block = struct { - pub const block_size: usize = 16; + pub const block_length: usize = 16; /// Internal representation of a block. repr: BlockVec align(16), @@ -222,19 +222,19 @@ pub const Block = struct { }; }; -fn KeySchedule(comptime AES: type) type { - std.debug.assert(AES.rounds == 10 or AES.rounds == 14); - const key_size = AES.key_bits / 8; - const rounds = AES.rounds; +fn KeySchedule(comptime Aes: type) type { + std.debug.assert(Aes.rounds == 10 or Aes.rounds == 14); + const key_length = Aes.key_bits / 8; + const rounds = Aes.rounds; return struct { const Self = @This(); - const words_in_key = key_size / 4; + const words_in_key = key_length / 4; round_keys: [rounds + 1]Block, // Key expansion algorithm. See FIPS-197, Figure 11. - fn expandKey(key: [key_size]u8) Self { + fn expandKey(key: [key_length]u8) Self { const subw = struct { // Apply sbox0 to each byte in w. fn func(w: u32) u32 { @@ -282,19 +282,19 @@ fn KeySchedule(comptime AES: type) type { } /// A context to perform encryption using the standard AES key schedule. -pub fn AESEncryptCtx(comptime AES: type) type { - std.debug.assert(AES.key_bits == 128 or AES.key_bits == 256); - const rounds = AES.rounds; +pub fn AesEncryptCtx(comptime Aes: type) type { + std.debug.assert(Aes.key_bits == 128 or Aes.key_bits == 256); + const rounds = Aes.rounds; return struct { const Self = @This(); - pub const block = AES.block; - pub const block_size = block.block_size; - key_schedule: KeySchedule(AES), + pub const block = Aes.block; + pub const block_length = block.block_length; + key_schedule: KeySchedule(Aes), /// Create a new encryption context with the given key. - pub fn init(key: [AES.key_bits / 8]u8) Self { - const key_schedule = KeySchedule(AES).expandKey(key); + pub fn init(key: [Aes.key_bits / 8]u8) Self { + const key_schedule = KeySchedule(Aes).expandKey(key); return Self{ .key_schedule = key_schedule, }; @@ -343,26 +343,26 @@ pub fn AESEncryptCtx(comptime AES: type) type { } /// A context to perform decryption using the standard AES key schedule. -pub fn AESDecryptCtx(comptime AES: type) type { - std.debug.assert(AES.key_bits == 128 or AES.key_bits == 256); - const rounds = AES.rounds; +pub fn AesDecryptCtx(comptime Aes: type) type { + std.debug.assert(Aes.key_bits == 128 or Aes.key_bits == 256); + const rounds = Aes.rounds; return struct { const Self = @This(); - pub const block = AES.block; - pub const block_size = block.block_size; - key_schedule: KeySchedule(AES), + pub const block = Aes.block; + pub const block_length = block.block_length; + key_schedule: KeySchedule(Aes), /// Create a decryption context from an existing encryption context. - pub fn initFromEnc(ctx: AESEncryptCtx(AES)) Self { + pub fn initFromEnc(ctx: AesEncryptCtx(Aes)) Self { return Self{ .key_schedule = ctx.key_schedule.invert(), }; } /// Create a new decryption context with the given key. - pub fn init(key: [AES.key_bits / 8]u8) Self { - const enc_ctx = AESEncryptCtx(AES).init(key); + pub fn init(key: [Aes.key_bits / 8]u8) Self { + const enc_ctx = AesEncryptCtx(Aes).init(key); return initFromEnc(enc_ctx); } @@ -389,36 +389,36 @@ pub fn AESDecryptCtx(comptime AES: type) type { } /// AES-128 with the standard key schedule. -pub const AES128 = struct { +pub const Aes128 = struct { pub const key_bits: usize = 128; pub const rounds = ((key_bits - 64) / 32 + 8); pub const block = Block; /// Create a new context for encryption. - pub fn initEnc(key: [key_bits / 8]u8) AESEncryptCtx(AES128) { - return AESEncryptCtx(AES128).init(key); + pub fn initEnc(key: [key_bits / 8]u8) AesEncryptCtx(Aes128) { + return AesEncryptCtx(Aes128).init(key); } /// Create a new context for decryption. - pub fn initDec(key: [key_bits / 8]u8) AESDecryptCtx(AES128) { - return AESDecryptCtx(AES128).init(key); + pub fn initDec(key: [key_bits / 8]u8) AesDecryptCtx(Aes128) { + return AesDecryptCtx(Aes128).init(key); } }; /// AES-256 with the standard key schedule. -pub const AES256 = struct { +pub const Aes256 = struct { pub const key_bits: usize = 256; pub const rounds = ((key_bits - 64) / 32 + 8); pub const block = Block; /// Create a new context for encryption. - pub fn initEnc(key: [key_bits / 8]u8) AESEncryptCtx(AES256) { - return AESEncryptCtx(AES256).init(key); + pub fn initEnc(key: [key_bits / 8]u8) AesEncryptCtx(Aes256) { + return AesEncryptCtx(Aes256).init(key); } /// Create a new context for decryption. - pub fn initDec(key: [key_bits / 8]u8) AESDecryptCtx(AES256) { - return AESDecryptCtx(AES256).init(key); + pub fn initDec(key: [key_bits / 8]u8) AesDecryptCtx(Aes256) { + return AesDecryptCtx(Aes256).init(key); } }; diff --git a/lib/std/crypto/aes_gcm.zig b/lib/std/crypto/aes_gcm.zig index c7093a7593..ee88804388 100644 --- a/lib/std/crypto/aes_gcm.zig +++ b/lib/std/crypto/aes_gcm.zig @@ -7,16 +7,16 @@ const Ghash = std.crypto.onetimeauth.Ghash; const mem = std.mem; const modes = crypto.core.modes; -pub const AES128GCM = AESGCM(crypto.core.aes.AES128); -pub const AES256GCM = AESGCM(crypto.core.aes.AES256); +pub const Aes128Gcm = AesGcm(crypto.core.aes.Aes128); +pub const Aes256Gcm = AesGcm(crypto.core.aes.Aes256); -fn AESGCM(comptime AES: anytype) type { - debug.assert(AES.block.block_size == 16); +fn AesGcm(comptime Aes: anytype) type { + debug.assert(Aes.block.block_length == 16); return struct { pub const tag_length = 16; pub const nonce_length = 12; - pub const key_length = AES.key_bits / 8; + pub const key_length = Aes.key_bits / 8; const zeros = [_]u8{0} ** 16; @@ -24,7 +24,7 @@ fn AESGCM(comptime AES: anytype) type { debug.assert(c.len == m.len); debug.assert(m.len <= 16 * ((1 << 32) - 2)); - const aes = AES.initEnc(key); + const aes = Aes.initEnc(key); var h: [16]u8 = undefined; aes.encrypt(&h, &zeros); @@ -56,7 +56,7 @@ fn AESGCM(comptime AES: anytype) type { pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, key: [key_length]u8) !void { assert(c.len == m.len); - const aes = AES.initEnc(key); + const aes = Aes.initEnc(key); var h: [16]u8 = undefined; aes.encrypt(&h, &zeros); @@ -101,59 +101,59 @@ fn AESGCM(comptime AES: anytype) type { const htest = @import("test.zig"); const testing = std.testing; -test "AES256GCM - Empty message and no associated data" { - const key: [AES256GCM.key_length]u8 = [_]u8{0x69} ** AES256GCM.key_length; - const nonce: [AES256GCM.nonce_length]u8 = [_]u8{0x42} ** AES256GCM.nonce_length; +test "Aes256Gcm - Empty message and no associated data" { + const key: [Aes256Gcm.key_length]u8 = [_]u8{0x69} ** Aes256Gcm.key_length; + const nonce: [Aes256Gcm.nonce_length]u8 = [_]u8{0x42} ** Aes256Gcm.nonce_length; const ad = ""; const m = ""; var c: [m.len]u8 = undefined; var m2: [m.len]u8 = undefined; - var tag: [AES256GCM.tag_length]u8 = undefined; + var tag: [Aes256Gcm.tag_length]u8 = undefined; - AES256GCM.encrypt(&c, &tag, m, ad, nonce, key); + Aes256Gcm.encrypt(&c, &tag, m, ad, nonce, key); htest.assertEqual("6b6ff610a16fa4cd59f1fb7903154e92", &tag); } -test "AES256GCM - Associated data only" { - const key: [AES256GCM.key_length]u8 = [_]u8{0x69} ** AES256GCM.key_length; - const nonce: [AES256GCM.nonce_length]u8 = [_]u8{0x42} ** AES256GCM.nonce_length; +test "Aes256Gcm - Associated data only" { + const key: [Aes256Gcm.key_length]u8 = [_]u8{0x69} ** Aes256Gcm.key_length; + const nonce: [Aes256Gcm.nonce_length]u8 = [_]u8{0x42} ** Aes256Gcm.nonce_length; const m = ""; const ad = "Test with associated data"; var c: [m.len]u8 = undefined; - var tag: [AES256GCM.tag_length]u8 = undefined; + var tag: [Aes256Gcm.tag_length]u8 = undefined; - AES256GCM.encrypt(&c, &tag, m, ad, nonce, key); + Aes256Gcm.encrypt(&c, &tag, m, ad, nonce, key); htest.assertEqual("262ed164c2dfb26e080a9d108dd9dd4c", &tag); } -test "AES256GCM - Message only" { - const key: [AES256GCM.key_length]u8 = [_]u8{0x69} ** AES256GCM.key_length; - const nonce: [AES256GCM.nonce_length]u8 = [_]u8{0x42} ** AES256GCM.nonce_length; +test "Aes256Gcm - Message only" { + const key: [Aes256Gcm.key_length]u8 = [_]u8{0x69} ** Aes256Gcm.key_length; + const nonce: [Aes256Gcm.nonce_length]u8 = [_]u8{0x42} ** Aes256Gcm.nonce_length; const m = "Test with message only"; const ad = ""; var c: [m.len]u8 = undefined; var m2: [m.len]u8 = undefined; - var tag: [AES256GCM.tag_length]u8 = undefined; + var tag: [Aes256Gcm.tag_length]u8 = undefined; - AES256GCM.encrypt(&c, &tag, m, ad, nonce, key); - try AES256GCM.decrypt(&m2, &c, tag, ad, nonce, key); + Aes256Gcm.encrypt(&c, &tag, m, ad, nonce, key); + try Aes256Gcm.decrypt(&m2, &c, tag, ad, nonce, key); testing.expectEqualSlices(u8, m[0..], m2[0..]); htest.assertEqual("5ca1642d90009fea33d01f78cf6eefaf01d539472f7c", &c); htest.assertEqual("07cd7fc9103e2f9e9bf2dfaa319caff4", &tag); } -test "AES256GCM - Message and associated data" { - const key: [AES256GCM.key_length]u8 = [_]u8{0x69} ** AES256GCM.key_length; - const nonce: [AES256GCM.nonce_length]u8 = [_]u8{0x42} ** AES256GCM.nonce_length; +test "Aes256Gcm - Message and associated data" { + const key: [Aes256Gcm.key_length]u8 = [_]u8{0x69} ** Aes256Gcm.key_length; + const nonce: [Aes256Gcm.nonce_length]u8 = [_]u8{0x42} ** Aes256Gcm.nonce_length; const m = "Test with message"; const ad = "Test with associated data"; var c: [m.len]u8 = undefined; var m2: [m.len]u8 = undefined; - var tag: [AES256GCM.tag_length]u8 = undefined; + var tag: [Aes256Gcm.tag_length]u8 = undefined; - AES256GCM.encrypt(&c, &tag, m, ad, nonce, key); - try AES256GCM.decrypt(&m2, &c, tag, ad, nonce, key); + Aes256Gcm.encrypt(&c, &tag, m, ad, nonce, key); + try Aes256Gcm.decrypt(&m2, &c, tag, ad, nonce, key); testing.expectEqualSlices(u8, m[0..], m2[0..]); htest.assertEqual("5ca1642d90009fea33d01f78cf6eefaf01", &c); diff --git a/lib/std/crypto/benchmark.zig b/lib/std/crypto/benchmark.zig index 1db3a1e870..efd4a1ffc3 100644 --- a/lib/std/crypto/benchmark.zig +++ b/lib/std/crypto/benchmark.zig @@ -73,7 +73,7 @@ pub fn benchmarkMac(comptime Mac: anytype, comptime bytes: comptime_int) !u64 { var in: [512 * KiB]u8 = undefined; prng.random.bytes(in[0..]); - const key_length = if (Mac.minimum_key_length == 0) 32 else Mac.minimum_key_length; + const key_length = if (Mac.key_length == 0) 32 else Mac.key_length; var key: [key_length]u8 = undefined; prng.random.bytes(key[0..]); @@ -96,12 +96,12 @@ pub fn benchmarkMac(comptime Mac: anytype, comptime bytes: comptime_int) !u64 { const exchanges = [_]Crypto{Crypto{ .ty = crypto.dh.X25519, .name = "x25519" }}; pub fn benchmarkKeyExchange(comptime DhKeyExchange: anytype, comptime exchange_count: comptime_int) !u64 { - std.debug.assert(DhKeyExchange.minimum_key_length >= DhKeyExchange.secret_length); + std.debug.assert(DhKeyExchange.key_length >= DhKeyExchange.secret_length); - var in: [DhKeyExchange.minimum_key_length]u8 = undefined; + var in: [DhKeyExchange.key_length]u8 = undefined; prng.random.bytes(in[0..]); - var out: [DhKeyExchange.minimum_key_length]u8 = undefined; + var out: [DhKeyExchange.key_length]u8 = undefined; prng.random.bytes(out[0..]); var timer = try Timer.start(); @@ -150,10 +150,10 @@ const aeads = [_]Crypto{ Crypto{ .ty = crypto.aead.ChaCha20Poly1305, .name = "chacha20Poly1305" }, Crypto{ .ty = crypto.aead.XChaCha20Poly1305, .name = "xchacha20Poly1305" }, Crypto{ .ty = crypto.aead.Gimli, .name = "gimli-aead" }, - Crypto{ .ty = crypto.aead.AEGIS128L, .name = "aegis-128l" }, - Crypto{ .ty = crypto.aead.AEGIS256, .name = "aegis-256" }, - Crypto{ .ty = crypto.aead.AES128GCM, .name = "aes128-gcm" }, - Crypto{ .ty = crypto.aead.AES256GCM, .name = "aes256-gcm" }, + Crypto{ .ty = crypto.aead.Aegis128L, .name = "aegis-128l" }, + Crypto{ .ty = crypto.aead.Aegis256, .name = "aegis-256" }, + Crypto{ .ty = crypto.aead.Aes128Gcm, .name = "aes128-gcm" }, + Crypto{ .ty = crypto.aead.Aes256Gcm, .name = "aes256-gcm" }, }; pub fn benchmarkAead(comptime Aead: anytype, comptime bytes: comptime_int) !u64 { @@ -185,14 +185,14 @@ pub fn benchmarkAead(comptime Aead: anytype, comptime bytes: comptime_int) !u64 } const aes = [_]Crypto{ - Crypto{ .ty = crypto.core.aes.AES128, .name = "aes128-single" }, - Crypto{ .ty = crypto.core.aes.AES256, .name = "aes256-single" }, + Crypto{ .ty = crypto.core.aes.Aes128, .name = "aes128-single" }, + Crypto{ .ty = crypto.core.aes.Aes256, .name = "aes256-single" }, }; -pub fn benchmarkAES(comptime AES: anytype, comptime count: comptime_int) !u64 { - var key: [AES.key_bits / 8]u8 = undefined; +pub fn benchmarkAes(comptime Aes: anytype, comptime count: comptime_int) !u64 { + var key: [Aes.key_bits / 8]u8 = undefined; prng.random.bytes(key[0..]); - const ctx = AES.initEnc(key); + const ctx = Aes.initEnc(key); var in = [_]u8{0} ** 16; @@ -214,14 +214,14 @@ pub fn benchmarkAES(comptime AES: anytype, comptime count: comptime_int) !u64 { } const aes8 = [_]Crypto{ - Crypto{ .ty = crypto.core.aes.AES128, .name = "aes128-8" }, - Crypto{ .ty = crypto.core.aes.AES256, .name = "aes256-8" }, + Crypto{ .ty = crypto.core.aes.Aes128, .name = "aes128-8" }, + Crypto{ .ty = crypto.core.aes.Aes256, .name = "aes256-8" }, }; -pub fn benchmarkAES8(comptime AES: anytype, comptime count: comptime_int) !u64 { - var key: [AES.key_bits / 8]u8 = undefined; +pub fn benchmarkAes8(comptime Aes: anytype, comptime count: comptime_int) !u64 { + var key: [Aes.key_bits / 8]u8 = undefined; prng.random.bytes(key[0..]); - const ctx = AES.initEnc(key); + const ctx = Aes.initEnc(key); var in = [_]u8{0} ** (8 * 16); @@ -335,14 +335,14 @@ pub fn main() !void { inline for (aes) |E| { if (filter == null or std.mem.indexOf(u8, E.name, filter.?) != null) { - const throughput = try benchmarkAES(E.ty, mode(100000000)); + const throughput = try benchmarkAes(E.ty, mode(100000000)); try stdout.print("{:>17}: {:10} ops/s\n", .{ E.name, throughput }); } } inline for (aes8) |E| { if (filter == null or std.mem.indexOf(u8, E.name, filter.?) != null) { - const throughput = try benchmarkAES8(E.ty, mode(10000000)); + const throughput = try benchmarkAes8(E.ty, mode(10000000)); try stdout.print("{:>17}: {:10} ops/s\n", .{ E.name, throughput }); } } diff --git a/lib/std/crypto/blake2.zig b/lib/std/crypto/blake2.zig index 1599be3b25..4a32eb69ba 100644 --- a/lib/std/crypto/blake2.zig +++ b/lib/std/crypto/blake2.zig @@ -18,7 +18,7 @@ const RoundParam = struct { y: usize, }; -fn Rp(a: usize, b: usize, c: usize, d: usize, x: usize, y: usize) RoundParam { +fn roundParam(a: usize, b: usize, c: usize, d: usize, x: usize, y: usize) RoundParam { return RoundParam{ .a = a, .b = b, @@ -32,14 +32,18 @@ fn Rp(a: usize, b: usize, c: usize, d: usize, x: usize, y: usize) RoundParam { ///////////////////// // Blake2s +pub const Blake2s128 = Blake2s(128); pub const Blake2s224 = Blake2s(224); pub const Blake2s256 = Blake2s(256); -pub fn Blake2s(comptime out_len: usize) type { +pub fn Blake2s(comptime out_bits: usize) type { return struct { const Self = @This(); pub const block_length = 64; - pub const digest_length = out_len / 8; + pub const digest_length = out_bits / 8; + pub const key_length_min = 0; + pub const key_length_max = 32; + pub const key_length = 32; // recommended key length pub const Options = struct { key: ?[]const u8 = null, salt: ?[8]u8 = null, context: ?[8]u8 = null }; const iv = [8]u32{ @@ -73,14 +77,14 @@ pub fn Blake2s(comptime out_len: usize) type { buf_len: u8, pub fn init(options: Options) Self { - debug.assert(8 <= out_len and out_len <= 512); + debug.assert(8 <= out_bits and out_bits <= 256); var d: Self = undefined; mem.copy(u32, d.h[0..], iv[0..]); const key_len = if (options.key) |key| key.len else 0; // default parameters - d.h[0] ^= 0x01010000 ^ @truncate(u32, key_len << 8) ^ @intCast(u32, out_len >> 3); + d.h[0] ^= 0x01010000 ^ @truncate(u32, key_len << 8) ^ @intCast(u32, out_bits >> 3); d.t = 0; d.buf_len = 0; @@ -100,7 +104,7 @@ pub fn Blake2s(comptime out_len: usize) type { return d; } - pub fn hash(b: []const u8, out: []u8, options: Options) void { + pub fn hash(b: []const u8, out: *[digest_length]u8, options: Options) void { var d = Self.init(options); d.update(b); d.final(out); @@ -129,14 +133,12 @@ pub fn Blake2s(comptime out_len: usize) type { d.buf_len += @intCast(u8, b[off..].len); } - pub fn final(d: *Self, out: []u8) void { - debug.assert(out.len >= out_len / 8); - + pub fn final(d: *Self, out: *[digest_length]u8) void { mem.set(u8, d.buf[d.buf_len..], 0); d.t += d.buf_len; d.round(d.buf[0..], true); - const rr = d.h[0 .. out_len / 32]; + const rr = d.h[0 .. digest_length / 4]; for (rr) |s, j| { mem.writeIntSliceLittle(u32, out[4 * j ..], s); @@ -164,14 +166,14 @@ pub fn Blake2s(comptime out_len: usize) type { if (last) v[14] = ~v[14]; const rounds = comptime [_]RoundParam{ - Rp(0, 4, 8, 12, 0, 1), - Rp(1, 5, 9, 13, 2, 3), - Rp(2, 6, 10, 14, 4, 5), - Rp(3, 7, 11, 15, 6, 7), - Rp(0, 5, 10, 15, 8, 9), - Rp(1, 6, 11, 12, 10, 11), - Rp(2, 7, 8, 13, 12, 13), - Rp(3, 4, 9, 14, 14, 15), + roundParam(0, 4, 8, 12, 0, 1), + roundParam(1, 5, 9, 13, 2, 3), + roundParam(2, 6, 10, 14, 4, 5), + roundParam(3, 7, 11, 15, 6, 7), + roundParam(0, 5, 10, 15, 8, 9), + roundParam(1, 6, 11, 12, 10, 11), + roundParam(2, 7, 8, 13, 12, 13), + roundParam(3, 4, 9, 14, 14, 15), }; comptime var j: usize = 0; @@ -372,15 +374,19 @@ test "comptime blake2s256" { ///////////////////// // Blake2b +pub const Blake2b128 = Blake2b(128); pub const Blake2b256 = Blake2b(256); pub const Blake2b384 = Blake2b(384); pub const Blake2b512 = Blake2b(512); -pub fn Blake2b(comptime out_len: usize) type { +pub fn Blake2b(comptime out_bits: usize) type { return struct { const Self = @This(); pub const block_length = 128; - pub const digest_length = out_len / 8; + pub const digest_length = out_bits / 8; + pub const key_length_min = 0; + pub const key_length_max = 64; + pub const key_length = 32; // recommended key length pub const Options = struct { key: ?[]const u8 = null, salt: ?[16]u8 = null, context: ?[16]u8 = null }; const iv = [8]u64{ @@ -416,14 +422,14 @@ pub fn Blake2b(comptime out_len: usize) type { buf_len: u8, pub fn init(options: Options) Self { - debug.assert(8 <= out_len and out_len <= 512); + debug.assert(8 <= out_bits and out_bits <= 512); var d: Self = undefined; mem.copy(u64, d.h[0..], iv[0..]); const key_len = if (options.key) |key| key.len else 0; // default parameters - d.h[0] ^= 0x01010000 ^ (key_len << 8) ^ (out_len >> 3); + d.h[0] ^= 0x01010000 ^ (key_len << 8) ^ (out_bits >> 3); d.t = 0; d.buf_len = 0; @@ -443,7 +449,7 @@ pub fn Blake2b(comptime out_len: usize) type { return d; } - pub fn hash(b: []const u8, out: []u8, options: Options) void { + pub fn hash(b: []const u8, out: *[digest_length]u8, options: Options) void { var d = Self.init(options); d.update(b); d.final(out); @@ -472,12 +478,12 @@ pub fn Blake2b(comptime out_len: usize) type { d.buf_len += @intCast(u8, b[off..].len); } - pub fn final(d: *Self, out: []u8) void { + pub fn final(d: *Self, out: *[digest_length]u8) void { mem.set(u8, d.buf[d.buf_len..], 0); d.t += d.buf_len; d.round(d.buf[0..], true); - const rr = d.h[0 .. out_len / 64]; + const rr = d.h[0 .. digest_length / 8]; for (rr) |s, j| { mem.writeIntSliceLittle(u64, out[8 * j ..], s); @@ -505,14 +511,14 @@ pub fn Blake2b(comptime out_len: usize) type { if (last) v[14] = ~v[14]; const rounds = comptime [_]RoundParam{ - Rp(0, 4, 8, 12, 0, 1), - Rp(1, 5, 9, 13, 2, 3), - Rp(2, 6, 10, 14, 4, 5), - Rp(3, 7, 11, 15, 6, 7), - Rp(0, 5, 10, 15, 8, 9), - Rp(1, 6, 11, 12, 10, 11), - Rp(2, 7, 8, 13, 12, 13), - Rp(3, 4, 9, 14, 14, 15), + roundParam(0, 4, 8, 12, 0, 1), + roundParam(1, 5, 9, 13, 2, 3), + roundParam(2, 6, 10, 14, 4, 5), + roundParam(3, 7, 11, 15, 6, 7), + roundParam(0, 5, 10, 15, 8, 9), + roundParam(1, 6, 11, 12, 10, 11), + roundParam(2, 7, 8, 13, 12, 13), + roundParam(3, 4, 9, 14, 14, 15), }; comptime var j: usize = 0; diff --git a/lib/std/crypto/blake3.zig b/lib/std/crypto/blake3.zig index 163c91b358..601eefbb7c 100644 --- a/lib/std/crypto/blake3.zig +++ b/lib/std/crypto/blake3.zig @@ -124,11 +124,11 @@ fn compress( return state; } -fn first_8_words(words: [16]u32) [8]u32 { +fn first8Words(words: [16]u32) [8]u32 { return @ptrCast(*const [8]u32, &words).*; } -fn words_from_little_endian_bytes(words: []u32, bytes: []const u8) void { +fn wordsFromLittleEndianBytes(words: []u32, bytes: []const u8) void { var byte_slice = bytes; for (words) |*word| { word.* = mem.readIntSliceLittle(u32, byte_slice); @@ -146,8 +146,8 @@ const Output = struct { counter: u64, flags: u8, - fn chaining_value(self: *const Output) [8]u32 { - return first_8_words(compress( + fn chainingValue(self: *const Output) [8]u32 { + return first8Words(compress( self.input_chaining_value, self.block_words, self.block_len, @@ -156,7 +156,7 @@ const Output = struct { )); } - fn root_output_bytes(self: *const Output, output: []u8) void { + fn rootOutputBytes(self: *const Output, output: []u8) void { var out_block_it = ChunkIterator.init(output, 2 * OUT_LEN); var output_block_counter: usize = 0; while (out_block_it.next()) |out_block| { @@ -200,7 +200,7 @@ const ChunkState = struct { return BLOCK_LEN * @as(usize, self.blocks_compressed) + @as(usize, self.block_len); } - fn fill_block_buf(self: *ChunkState, input: []const u8) []const u8 { + fn fillBlockBuf(self: *ChunkState, input: []const u8) []const u8 { const want = BLOCK_LEN - self.block_len; const take = math.min(want, input.len); mem.copy(u8, self.block[self.block_len..][0..take], input[0..take]); @@ -208,7 +208,7 @@ const ChunkState = struct { return input[take..]; } - fn start_flag(self: *const ChunkState) u8 { + fn startFlag(self: *const ChunkState) u8 { return if (self.blocks_compressed == 0) CHUNK_START else 0; } @@ -219,13 +219,13 @@ const ChunkState = struct { // input is coming, so this compression is not CHUNK_END. if (self.block_len == BLOCK_LEN) { var block_words: [16]u32 = undefined; - words_from_little_endian_bytes(block_words[0..], self.block[0..]); - self.chaining_value = first_8_words(compress( + wordsFromLittleEndianBytes(block_words[0..], self.block[0..]); + self.chaining_value = first8Words(compress( self.chaining_value, block_words, BLOCK_LEN, self.chunk_counter, - self.flags | self.start_flag(), + self.flags | self.startFlag(), )); self.blocks_compressed += 1; self.block = [_]u8{0} ** BLOCK_LEN; @@ -233,24 +233,24 @@ const ChunkState = struct { } // Copy input bytes into the block buffer. - input = self.fill_block_buf(input); + input = self.fillBlockBuf(input); } } fn output(self: *const ChunkState) Output { var block_words: [16]u32 = undefined; - words_from_little_endian_bytes(block_words[0..], self.block[0..]); + wordsFromLittleEndianBytes(block_words[0..], self.block[0..]); return Output{ .input_chaining_value = self.chaining_value, .block_words = block_words, .block_len = self.block_len, .counter = self.chunk_counter, - .flags = self.flags | self.start_flag() | CHUNK_END, + .flags = self.flags | self.startFlag() | CHUNK_END, }; } }; -fn parent_output( +fn parentOutput( left_child_cv: [8]u32, right_child_cv: [8]u32, key: [8]u32, @@ -268,18 +268,18 @@ fn parent_output( }; } -fn parent_cv( +fn parentCv( left_child_cv: [8]u32, right_child_cv: [8]u32, key: [8]u32, flags: u8, ) [8]u32 { - return parent_output(left_child_cv, right_child_cv, key, flags).chaining_value(); + return parentOutput(left_child_cv, right_child_cv, key, flags).chainingValue(); } /// An incremental hasher that can accept any number of writes. pub const Blake3 = struct { - pub const Options = struct { key: ?[KEY_LEN]u8 = null }; + pub const Options = struct { key: ?[digest_length]u8 = null }; pub const KdfOptions = struct {}; chunk_state: ChunkState, @@ -288,8 +288,9 @@ pub const Blake3 = struct { cv_stack_len: u8 = 0, // 2^54 * CHUNK_LEN = 2^64 flags: u8, - pub const digest_length = OUT_LEN; pub const block_length = BLOCK_LEN; + pub const digest_length = OUT_LEN; + pub const key_length = KEY_LEN; fn init_internal(key: [8]u32, flags: u8) Blake3 { return Blake3{ @@ -303,7 +304,7 @@ pub const Blake3 = struct { pub fn init(options: Options) Blake3 { if (options.key) |key| { var key_words: [8]u32 = undefined; - words_from_little_endian_bytes(key_words[0..], key[0..]); + wordsFromLittleEndianBytes(key_words[0..], key[0..]); return Blake3.init_internal(key_words, KEYED_HASH); } else { return Blake3.init_internal(IV, 0); @@ -318,7 +319,7 @@ pub const Blake3 = struct { var context_key: [KEY_LEN]u8 = undefined; context_hasher.final(context_key[0..]); var context_key_words: [8]u32 = undefined; - words_from_little_endian_bytes(context_key_words[0..], context_key[0..]); + wordsFromLittleEndianBytes(context_key_words[0..], context_key[0..]); return Blake3.init_internal(context_key_words, DERIVE_KEY_MATERIAL); } @@ -328,18 +329,18 @@ pub const Blake3 = struct { hasher.final(out); } - fn push_cv(self: *Blake3, cv: [8]u32) void { + fn pushCv(self: *Blake3, cv: [8]u32) void { self.cv_stack[self.cv_stack_len] = cv; self.cv_stack_len += 1; } - fn pop_cv(self: *Blake3) [8]u32 { + fn popCv(self: *Blake3) [8]u32 { self.cv_stack_len -= 1; return self.cv_stack[self.cv_stack_len]; } // Section 5.1.2 of the BLAKE3 spec explains this algorithm in more detail. - fn add_chunk_chaining_value(self: *Blake3, first_cv: [8]u32, total_chunks: u64) void { + fn addChunkChainingValue(self: *Blake3, first_cv: [8]u32, total_chunks: u64) void { // This chunk might complete some subtrees. For each completed subtree, // its left child will be the current top entry in the CV stack, and // its right child will be the current value of `new_cv`. Pop each left @@ -350,10 +351,10 @@ pub const Blake3 = struct { var new_cv = first_cv; var chunk_counter = total_chunks; while (chunk_counter & 1 == 0) { - new_cv = parent_cv(self.pop_cv(), new_cv, self.key, self.flags); + new_cv = parentCv(self.popCv(), new_cv, self.key, self.flags); chunk_counter >>= 1; } - self.push_cv(new_cv); + self.pushCv(new_cv); } /// Add input to the hash state. This can be called any number of times. @@ -363,9 +364,9 @@ pub const Blake3 = struct { // If the current chunk is complete, finalize it and reset the // chunk state. More input is coming, so this chunk is not ROOT. if (self.chunk_state.len() == CHUNK_LEN) { - const chunk_cv = self.chunk_state.output().chaining_value(); + const chunk_cv = self.chunk_state.output().chainingValue(); const total_chunks = self.chunk_state.chunk_counter + 1; - self.add_chunk_chaining_value(chunk_cv, total_chunks); + self.addChunkChainingValue(chunk_cv, total_chunks); self.chunk_state = ChunkState.init(self.key, total_chunks, self.flags); } @@ -386,14 +387,14 @@ pub const Blake3 = struct { var parent_nodes_remaining: usize = self.cv_stack_len; while (parent_nodes_remaining > 0) { parent_nodes_remaining -= 1; - output = parent_output( + output = parentOutput( self.cv_stack[parent_nodes_remaining], - output.chaining_value(), + output.chainingValue(), self.key, self.flags, ); } - output.root_output_bytes(out_slice); + output.rootOutputBytes(out_slice); } }; @@ -561,7 +562,7 @@ const reference_test = ReferenceTest{ }, }; -fn test_blake3(hasher: *Blake3, input_len: usize, expected_hex: [262]u8) void { +fn testBlake3(hasher: *Blake3, input_len: usize, expected_hex: [262]u8) void { // Save initial state const initial_state = hasher.*; @@ -596,8 +597,8 @@ test "BLAKE3 reference test cases" { var derive_key = &Blake3.initKdf(reference_test.context_string, .{}); for (reference_test.cases) |t| { - test_blake3(hash, t.input_len, t.hash.*); - test_blake3(keyed_hash, t.input_len, t.keyed_hash.*); - test_blake3(derive_key, t.input_len, t.derive_key.*); + testBlake3(hash, t.input_len, t.hash.*); + testBlake3(keyed_hash, t.input_len, t.keyed_hash.*); + testBlake3(derive_key, t.input_len, t.derive_key.*); } } diff --git a/lib/std/crypto/chacha20.zig b/lib/std/crypto/chacha20.zig index 3b651bb2e4..ecf9abbef9 100644 --- a/lib/std/crypto/chacha20.zig +++ b/lib/std/crypto/chacha20.zig @@ -317,7 +317,7 @@ fn keyToWords(key: [32]u8) [8]u32 { /// counter, nonce, and key. pub const ChaCha20IETF = struct { pub fn xor(out: []u8, in: []const u8, counter: u32, key: [32]u8, nonce: [12]u8) void { - assert(in.len >= out.len); + assert(in.len == out.len); assert((in.len >> 6) + counter <= maxInt(u32)); var c: [4]u32 = undefined; @@ -334,7 +334,7 @@ pub const ChaCha20IETF = struct { /// exceed the 256 GiB limit of the 96-bit nonce version. pub const ChaCha20With64BitNonce = struct { pub fn xor(out: []u8, in: []const u8, counter: u64, key: [32]u8, nonce: [8]u8) void { - assert(in.len >= out.len); + assert(in.len == out.len); assert(counter +% (in.len >> 6) >= counter); var cursor: usize = 0; @@ -345,9 +345,9 @@ pub const ChaCha20With64BitNonce = struct { c[2] = mem.readIntLittle(u32, nonce[0..4]); c[3] = mem.readIntLittle(u32, nonce[4..8]); - const block_size = (1 << 6); + const block_length = (1 << 6); // The full block size is greater than the address space on a 32bit machine - const big_block = if (@sizeOf(usize) > 4) (block_size << 32) else maxInt(usize); + const big_block = if (@sizeOf(usize) > 4) (block_length << 32) else maxInt(usize); // first partial big block if (((@intCast(u64, maxInt(u32) - @truncate(u32, counter)) + 1) << 6) < in.len) { @@ -621,10 +621,10 @@ test "crypto.chacha20 test vector 5" { testing.expectEqualSlices(u8, &expected_result, &result); } -pub const chacha20poly1305_tag_size = 16; +pub const chacha20poly1305_tag_length = 16; -fn chacha20poly1305SealDetached(ciphertext: []u8, tag: *[chacha20poly1305_tag_size]u8, plaintext: []const u8, data: []const u8, key: [32]u8, nonce: [12]u8) void { - assert(ciphertext.len >= plaintext.len); +fn chacha20poly1305SealDetached(ciphertext: []u8, tag: *[chacha20poly1305_tag_length]u8, plaintext: []const u8, data: []const u8, key: [32]u8, nonce: [12]u8) void { + assert(ciphertext.len == plaintext.len); // derive poly1305 key var polyKey = [_]u8{0} ** 32; @@ -655,13 +655,13 @@ fn chacha20poly1305SealDetached(ciphertext: []u8, tag: *[chacha20poly1305_tag_si } fn chacha20poly1305Seal(ciphertextAndTag: []u8, plaintext: []const u8, data: []const u8, key: [32]u8, nonce: [12]u8) void { - return chacha20poly1305SealDetached(ciphertextAndTag[0..plaintext.len], ciphertextAndTag[plaintext.len..][0..chacha20poly1305_tag_size], plaintext, data, key, nonce); + return chacha20poly1305SealDetached(ciphertextAndTag[0..plaintext.len], ciphertextAndTag[plaintext.len..][0..chacha20poly1305_tag_length], plaintext, data, key, nonce); } /// Verifies and decrypts an authenticated message produced by chacha20poly1305SealDetached. -fn chacha20poly1305OpenDetached(dst: []u8, ciphertext: []const u8, tag: *const [chacha20poly1305_tag_size]u8, data: []const u8, key: [32]u8, nonce: [12]u8) !void { +fn chacha20poly1305OpenDetached(dst: []u8, ciphertext: []const u8, tag: *const [chacha20poly1305_tag_length]u8, data: []const u8, key: [32]u8, nonce: [12]u8) !void { // split ciphertext and tag - assert(dst.len >= ciphertext.len); + assert(dst.len == ciphertext.len); // derive poly1305 key var polyKey = [_]u8{0} ** 32; @@ -706,11 +706,11 @@ fn chacha20poly1305OpenDetached(dst: []u8, ciphertext: []const u8, tag: *const [ /// Verifies and decrypts an authenticated message produced by chacha20poly1305Seal. fn chacha20poly1305Open(dst: []u8, ciphertextAndTag: []const u8, data: []const u8, key: [32]u8, nonce: [12]u8) !void { - if (ciphertextAndTag.len < chacha20poly1305_tag_size) { + if (ciphertextAndTag.len < chacha20poly1305_tag_length) { return error.InvalidMessage; } - const ciphertextLen = ciphertextAndTag.len - chacha20poly1305_tag_size; - return try chacha20poly1305OpenDetached(dst, ciphertextAndTag[0..ciphertextLen], ciphertextAndTag[ciphertextLen..][0..chacha20poly1305_tag_size], data, key, nonce); + const ciphertextLen = ciphertextAndTag.len - chacha20poly1305_tag_length; + return try chacha20poly1305OpenDetached(dst, ciphertextAndTag[0..ciphertextLen], ciphertextAndTag[ciphertextLen..][0..chacha20poly1305_tag_length], data, key, nonce); } fn extend(key: [32]u8, nonce: [24]u8) struct { key: [32]u8, nonce: [12]u8 } { @@ -730,9 +730,9 @@ pub const XChaCha20IETF = struct { } }; -pub const xchacha20poly1305_tag_size = 16; +pub const xchacha20poly1305_tag_length = 16; -fn xchacha20poly1305SealDetached(ciphertext: []u8, tag: *[chacha20poly1305_tag_size]u8, plaintext: []const u8, data: []const u8, key: [32]u8, nonce: [24]u8) void { +fn xchacha20poly1305SealDetached(ciphertext: []u8, tag: *[chacha20poly1305_tag_length]u8, plaintext: []const u8, data: []const u8, key: [32]u8, nonce: [24]u8) void { const extended = extend(key, nonce); return chacha20poly1305SealDetached(ciphertext, tag, plaintext, data, extended.key, extended.nonce); } @@ -743,7 +743,7 @@ fn xchacha20poly1305Seal(ciphertextAndTag: []u8, plaintext: []const u8, data: [] } /// Verifies and decrypts an authenticated message produced by xchacha20poly1305SealDetached. -fn xchacha20poly1305OpenDetached(plaintext: []u8, ciphertext: []const u8, tag: *const [chacha20poly1305_tag_size]u8, data: []const u8, key: [32]u8, nonce: [24]u8) !void { +fn xchacha20poly1305OpenDetached(plaintext: []u8, ciphertext: []const u8, tag: *const [chacha20poly1305_tag_length]u8, data: []const u8, key: [32]u8, nonce: [24]u8) !void { const extended = extend(key, nonce); return try chacha20poly1305OpenDetached(plaintext, ciphertext, tag, data, extended.key, extended.nonce); } @@ -883,7 +883,7 @@ test "crypto.xchacha20" { } { const data = "Additional data"; - var ciphertext: [input.len + xchacha20poly1305_tag_size]u8 = undefined; + var ciphertext: [input.len + xchacha20poly1305_tag_length]u8 = undefined; xchacha20poly1305Seal(ciphertext[0..], input, data, key, nonce); var out: [input.len]u8 = undefined; try xchacha20poly1305Open(out[0..], ciphertext[0..], data, key, nonce); diff --git a/lib/std/crypto/ghash.zig b/lib/std/crypto/ghash.zig index 83446f280b..36ce7b2c88 100644 --- a/lib/std/crypto/ghash.zig +++ b/lib/std/crypto/ghash.zig @@ -18,9 +18,9 @@ const mem = std.mem; /// /// GHASH is typically used to compute the authentication tag in the AES-GCM construction. pub const Ghash = struct { - pub const block_size: usize = 16; + pub const block_length: usize = 16; pub const mac_length = 16; - pub const minimum_key_length = 16; + pub const key_length = 16; y0: u64 = 0, y1: u64 = 0, @@ -39,9 +39,9 @@ pub const Ghash = struct { hh2r: u64 = undefined, leftover: usize = 0, - buf: [block_size]u8 align(16) = undefined, + buf: [block_length]u8 align(16) = undefined, - pub fn init(key: *const [minimum_key_length]u8) Ghash { + pub fn init(key: *const [key_length]u8) Ghash { const h1 = mem.readIntBig(u64, key[0..8]); const h0 = mem.readIntBig(u64, key[8..16]); const h1r = @bitReverse(u64, h1); @@ -261,21 +261,21 @@ pub const Ghash = struct { var mb = m; if (st.leftover > 0) { - const want = math.min(block_size - st.leftover, mb.len); + const want = math.min(block_length - st.leftover, mb.len); const mc = mb[0..want]; for (mc) |x, i| { st.buf[st.leftover + i] = x; } mb = mb[want..]; st.leftover += want; - if (st.leftover < block_size) { + if (st.leftover < block_length) { return; } st.blocks(&st.buf); st.leftover = 0; } - if (mb.len >= block_size) { - const want = mb.len & ~(block_size - 1); + if (mb.len >= block_length) { + const want = mb.len & ~(block_length - 1); st.blocks(mb[0..want]); mb = mb[want..]; } @@ -293,7 +293,7 @@ pub const Ghash = struct { return; } var i = st.leftover; - while (i < block_size) : (i += 1) { + while (i < block_length) : (i += 1) { st.buf[i] = 0; } st.blocks(&st.buf); @@ -308,7 +308,7 @@ pub const Ghash = struct { mem.secureZero(u8, @ptrCast([*]u8, st)[0..@sizeOf(Ghash)]); } - pub fn create(out: *[mac_length]u8, msg: []const u8, key: *const [minimum_key_length]u8) void { + pub fn create(out: *[mac_length]u8, msg: []const u8, key: *const [key_length]u8) void { var st = Ghash.init(key); st.update(msg); st.final(out); diff --git a/lib/std/crypto/gimli.zig b/lib/std/crypto/gimli.zig index c68bd0abb5..42fd38d393 100644 --- a/lib/std/crypto/gimli.zig +++ b/lib/std/crypto/gimli.zig @@ -200,6 +200,7 @@ pub const Hash = struct { buf_off: usize, pub const block_length = State.RATE; + pub const digest_length = 32; pub const Options = struct {}; const Self = @This(); @@ -231,15 +232,13 @@ pub const Hash = struct { } } - pub const digest_length = 32; - /// Finish the current hashing operation, writing the hash to `out` /// /// From 4.9 "Application to hashing" /// By default, Gimli-Hash provides a fixed-length output of 32 bytes /// (the concatenation of two 16-byte blocks). However, Gimli-Hash can /// be used as an “extendable one-way function” (XOF). - pub fn final(self: *Self, out: []u8) void { + pub fn final(self: *Self, out: *[digest_length]u8) void { const buf = self.state.toSlice(); // XOR 1 into the next byte of the state @@ -251,7 +250,7 @@ pub const Hash = struct { } }; -pub fn hash(out: []u8, in: []const u8, options: Hash.Options) void { +pub fn hash(out: *[Hash.digest_length]u8, in: []const u8, options: Hash.Options) void { var st = Hash.init(options); st.update(in); st.final(out); diff --git a/lib/std/crypto/hmac.zig b/lib/std/crypto/hmac.zig index 5f10b77591..e0972ecb7e 100644 --- a/lib/std/crypto/hmac.zig +++ b/lib/std/crypto/hmac.zig @@ -22,14 +22,15 @@ pub fn Hmac(comptime Hash: type) type { return struct { const Self = @This(); pub const mac_length = Hash.digest_length; - pub const minimum_key_length = 0; + pub const key_length_min = 0; + pub const key_length = 32; // recommended key length o_key_pad: [Hash.block_length]u8, i_key_pad: [Hash.block_length]u8, scratch: [Hash.block_length]u8, hash: Hash, - // HMAC(k, m) = H(o_key_pad | H(i_key_pad | msg)) where | is concatenation + // HMAC(k, m) = H(o_key_pad || H(i_key_pad || msg)) where || is concatenation pub fn create(out: []u8, msg: []const u8, key: []const u8) void { var ctx = Self.init(key); ctx.update(msg); diff --git a/lib/std/crypto/md5.zig b/lib/std/crypto/md5.zig index 7ba78b5879..8b454c52a7 100644 --- a/lib/std/crypto/md5.zig +++ b/lib/std/crypto/md5.zig @@ -6,7 +6,6 @@ const std = @import("../std.zig"); const mem = std.mem; const math = std.math; -const debug = std.debug; const RoundParam = struct { a: usize, @@ -18,7 +17,7 @@ const RoundParam = struct { t: u32, }; -fn Rp(a: usize, b: usize, c: usize, d: usize, k: usize, s: u32, t: u32) RoundParam { +fn roundParam(a: usize, b: usize, c: usize, d: usize, k: usize, s: u32, t: u32) RoundParam { return RoundParam{ .a = a, .b = b, @@ -59,7 +58,7 @@ pub const Md5 = struct { }; } - pub fn hash(b: []const u8, out: []u8, options: Options) void { + pub fn hash(b: []const u8, out: *[digest_length]u8, options: Options) void { var d = Md5.init(options); d.update(b); d.final(out); @@ -73,13 +72,13 @@ pub const Md5 = struct { off += 64 - d.buf_len; mem.copy(u8, d.buf[d.buf_len..], b[0..off]); - d.round(d.buf[0..]); + d.round(&d.buf); d.buf_len = 0; } // Full middle blocks. while (off + 64 <= b.len) : (off += 64) { - d.round(b[off .. off + 64]); + d.round(b[off..][0..64]); } // Copy any remainder for next pass. @@ -90,9 +89,7 @@ pub const Md5 = struct { d.total_len +%= b.len; } - pub fn final(d: *Self, out: []u8) void { - debug.assert(out.len >= 16); - + pub fn final(d: *Self, out: *[digest_length]u8) void { // The buffer here will never be completely full. mem.set(u8, d.buf[d.buf_len..], 0); @@ -122,9 +119,7 @@ pub const Md5 = struct { } } - fn round(d: *Self, b: []const u8) void { - debug.assert(b.len == 64); - + fn round(d: *Self, b: *const [64]u8) void { var s: [16]u32 = undefined; var i: usize = 0; @@ -145,22 +140,22 @@ pub const Md5 = struct { }; const round0 = comptime [_]RoundParam{ - Rp(0, 1, 2, 3, 0, 7, 0xD76AA478), - Rp(3, 0, 1, 2, 1, 12, 0xE8C7B756), - Rp(2, 3, 0, 1, 2, 17, 0x242070DB), - Rp(1, 2, 3, 0, 3, 22, 0xC1BDCEEE), - Rp(0, 1, 2, 3, 4, 7, 0xF57C0FAF), - Rp(3, 0, 1, 2, 5, 12, 0x4787C62A), - Rp(2, 3, 0, 1, 6, 17, 0xA8304613), - Rp(1, 2, 3, 0, 7, 22, 0xFD469501), - Rp(0, 1, 2, 3, 8, 7, 0x698098D8), - Rp(3, 0, 1, 2, 9, 12, 0x8B44F7AF), - Rp(2, 3, 0, 1, 10, 17, 0xFFFF5BB1), - Rp(1, 2, 3, 0, 11, 22, 0x895CD7BE), - Rp(0, 1, 2, 3, 12, 7, 0x6B901122), - Rp(3, 0, 1, 2, 13, 12, 0xFD987193), - Rp(2, 3, 0, 1, 14, 17, 0xA679438E), - Rp(1, 2, 3, 0, 15, 22, 0x49B40821), + roundParam(0, 1, 2, 3, 0, 7, 0xD76AA478), + roundParam(3, 0, 1, 2, 1, 12, 0xE8C7B756), + roundParam(2, 3, 0, 1, 2, 17, 0x242070DB), + roundParam(1, 2, 3, 0, 3, 22, 0xC1BDCEEE), + roundParam(0, 1, 2, 3, 4, 7, 0xF57C0FAF), + roundParam(3, 0, 1, 2, 5, 12, 0x4787C62A), + roundParam(2, 3, 0, 1, 6, 17, 0xA8304613), + roundParam(1, 2, 3, 0, 7, 22, 0xFD469501), + roundParam(0, 1, 2, 3, 8, 7, 0x698098D8), + roundParam(3, 0, 1, 2, 9, 12, 0x8B44F7AF), + roundParam(2, 3, 0, 1, 10, 17, 0xFFFF5BB1), + roundParam(1, 2, 3, 0, 11, 22, 0x895CD7BE), + roundParam(0, 1, 2, 3, 12, 7, 0x6B901122), + roundParam(3, 0, 1, 2, 13, 12, 0xFD987193), + roundParam(2, 3, 0, 1, 14, 17, 0xA679438E), + roundParam(1, 2, 3, 0, 15, 22, 0x49B40821), }; inline for (round0) |r| { v[r.a] = v[r.a] +% (v[r.d] ^ (v[r.b] & (v[r.c] ^ v[r.d]))) +% r.t +% s[r.k]; @@ -168,22 +163,22 @@ pub const Md5 = struct { } const round1 = comptime [_]RoundParam{ - Rp(0, 1, 2, 3, 1, 5, 0xF61E2562), - Rp(3, 0, 1, 2, 6, 9, 0xC040B340), - Rp(2, 3, 0, 1, 11, 14, 0x265E5A51), - Rp(1, 2, 3, 0, 0, 20, 0xE9B6C7AA), - Rp(0, 1, 2, 3, 5, 5, 0xD62F105D), - Rp(3, 0, 1, 2, 10, 9, 0x02441453), - Rp(2, 3, 0, 1, 15, 14, 0xD8A1E681), - Rp(1, 2, 3, 0, 4, 20, 0xE7D3FBC8), - Rp(0, 1, 2, 3, 9, 5, 0x21E1CDE6), - Rp(3, 0, 1, 2, 14, 9, 0xC33707D6), - Rp(2, 3, 0, 1, 3, 14, 0xF4D50D87), - Rp(1, 2, 3, 0, 8, 20, 0x455A14ED), - Rp(0, 1, 2, 3, 13, 5, 0xA9E3E905), - Rp(3, 0, 1, 2, 2, 9, 0xFCEFA3F8), - Rp(2, 3, 0, 1, 7, 14, 0x676F02D9), - Rp(1, 2, 3, 0, 12, 20, 0x8D2A4C8A), + roundParam(0, 1, 2, 3, 1, 5, 0xF61E2562), + roundParam(3, 0, 1, 2, 6, 9, 0xC040B340), + roundParam(2, 3, 0, 1, 11, 14, 0x265E5A51), + roundParam(1, 2, 3, 0, 0, 20, 0xE9B6C7AA), + roundParam(0, 1, 2, 3, 5, 5, 0xD62F105D), + roundParam(3, 0, 1, 2, 10, 9, 0x02441453), + roundParam(2, 3, 0, 1, 15, 14, 0xD8A1E681), + roundParam(1, 2, 3, 0, 4, 20, 0xE7D3FBC8), + roundParam(0, 1, 2, 3, 9, 5, 0x21E1CDE6), + roundParam(3, 0, 1, 2, 14, 9, 0xC33707D6), + roundParam(2, 3, 0, 1, 3, 14, 0xF4D50D87), + roundParam(1, 2, 3, 0, 8, 20, 0x455A14ED), + roundParam(0, 1, 2, 3, 13, 5, 0xA9E3E905), + roundParam(3, 0, 1, 2, 2, 9, 0xFCEFA3F8), + roundParam(2, 3, 0, 1, 7, 14, 0x676F02D9), + roundParam(1, 2, 3, 0, 12, 20, 0x8D2A4C8A), }; inline for (round1) |r| { v[r.a] = v[r.a] +% (v[r.c] ^ (v[r.d] & (v[r.b] ^ v[r.c]))) +% r.t +% s[r.k]; @@ -191,22 +186,22 @@ pub const Md5 = struct { } const round2 = comptime [_]RoundParam{ - Rp(0, 1, 2, 3, 5, 4, 0xFFFA3942), - Rp(3, 0, 1, 2, 8, 11, 0x8771F681), - Rp(2, 3, 0, 1, 11, 16, 0x6D9D6122), - Rp(1, 2, 3, 0, 14, 23, 0xFDE5380C), - Rp(0, 1, 2, 3, 1, 4, 0xA4BEEA44), - Rp(3, 0, 1, 2, 4, 11, 0x4BDECFA9), - Rp(2, 3, 0, 1, 7, 16, 0xF6BB4B60), - Rp(1, 2, 3, 0, 10, 23, 0xBEBFBC70), - Rp(0, 1, 2, 3, 13, 4, 0x289B7EC6), - Rp(3, 0, 1, 2, 0, 11, 0xEAA127FA), - Rp(2, 3, 0, 1, 3, 16, 0xD4EF3085), - Rp(1, 2, 3, 0, 6, 23, 0x04881D05), - Rp(0, 1, 2, 3, 9, 4, 0xD9D4D039), - Rp(3, 0, 1, 2, 12, 11, 0xE6DB99E5), - Rp(2, 3, 0, 1, 15, 16, 0x1FA27CF8), - Rp(1, 2, 3, 0, 2, 23, 0xC4AC5665), + roundParam(0, 1, 2, 3, 5, 4, 0xFFFA3942), + roundParam(3, 0, 1, 2, 8, 11, 0x8771F681), + roundParam(2, 3, 0, 1, 11, 16, 0x6D9D6122), + roundParam(1, 2, 3, 0, 14, 23, 0xFDE5380C), + roundParam(0, 1, 2, 3, 1, 4, 0xA4BEEA44), + roundParam(3, 0, 1, 2, 4, 11, 0x4BDECFA9), + roundParam(2, 3, 0, 1, 7, 16, 0xF6BB4B60), + roundParam(1, 2, 3, 0, 10, 23, 0xBEBFBC70), + roundParam(0, 1, 2, 3, 13, 4, 0x289B7EC6), + roundParam(3, 0, 1, 2, 0, 11, 0xEAA127FA), + roundParam(2, 3, 0, 1, 3, 16, 0xD4EF3085), + roundParam(1, 2, 3, 0, 6, 23, 0x04881D05), + roundParam(0, 1, 2, 3, 9, 4, 0xD9D4D039), + roundParam(3, 0, 1, 2, 12, 11, 0xE6DB99E5), + roundParam(2, 3, 0, 1, 15, 16, 0x1FA27CF8), + roundParam(1, 2, 3, 0, 2, 23, 0xC4AC5665), }; inline for (round2) |r| { v[r.a] = v[r.a] +% (v[r.b] ^ v[r.c] ^ v[r.d]) +% r.t +% s[r.k]; @@ -214,22 +209,22 @@ pub const Md5 = struct { } const round3 = comptime [_]RoundParam{ - Rp(0, 1, 2, 3, 0, 6, 0xF4292244), - Rp(3, 0, 1, 2, 7, 10, 0x432AFF97), - Rp(2, 3, 0, 1, 14, 15, 0xAB9423A7), - Rp(1, 2, 3, 0, 5, 21, 0xFC93A039), - Rp(0, 1, 2, 3, 12, 6, 0x655B59C3), - Rp(3, 0, 1, 2, 3, 10, 0x8F0CCC92), - Rp(2, 3, 0, 1, 10, 15, 0xFFEFF47D), - Rp(1, 2, 3, 0, 1, 21, 0x85845DD1), - Rp(0, 1, 2, 3, 8, 6, 0x6FA87E4F), - Rp(3, 0, 1, 2, 15, 10, 0xFE2CE6E0), - Rp(2, 3, 0, 1, 6, 15, 0xA3014314), - Rp(1, 2, 3, 0, 13, 21, 0x4E0811A1), - Rp(0, 1, 2, 3, 4, 6, 0xF7537E82), - Rp(3, 0, 1, 2, 11, 10, 0xBD3AF235), - Rp(2, 3, 0, 1, 2, 15, 0x2AD7D2BB), - Rp(1, 2, 3, 0, 9, 21, 0xEB86D391), + roundParam(0, 1, 2, 3, 0, 6, 0xF4292244), + roundParam(3, 0, 1, 2, 7, 10, 0x432AFF97), + roundParam(2, 3, 0, 1, 14, 15, 0xAB9423A7), + roundParam(1, 2, 3, 0, 5, 21, 0xFC93A039), + roundParam(0, 1, 2, 3, 12, 6, 0x655B59C3), + roundParam(3, 0, 1, 2, 3, 10, 0x8F0CCC92), + roundParam(2, 3, 0, 1, 10, 15, 0xFFEFF47D), + roundParam(1, 2, 3, 0, 1, 21, 0x85845DD1), + roundParam(0, 1, 2, 3, 8, 6, 0x6FA87E4F), + roundParam(3, 0, 1, 2, 15, 10, 0xFE2CE6E0), + roundParam(2, 3, 0, 1, 6, 15, 0xA3014314), + roundParam(1, 2, 3, 0, 13, 21, 0x4E0811A1), + roundParam(0, 1, 2, 3, 4, 6, 0xF7537E82), + roundParam(3, 0, 1, 2, 11, 10, 0xBD3AF235), + roundParam(2, 3, 0, 1, 2, 15, 0x2AD7D2BB), + roundParam(1, 2, 3, 0, 9, 21, 0xEB86D391), }; inline for (round3) |r| { v[r.a] = v[r.a] +% (v[r.c] ^ (v[r.b] | ~v[r.d])) +% r.t +% s[r.k]; diff --git a/lib/std/crypto/modes.zig b/lib/std/crypto/modes.zig index 5c1fa4b2f3..a81d30e50f 100644 --- a/lib/std/crypto/modes.zig +++ b/lib/std/crypto/modes.zig @@ -16,34 +16,34 @@ const debug = std.debug; /// /// Important: the counter mode doesn't provide authenticated encryption: the ciphertext can be trivially modified without this being detected. /// As a result, applications should generally never use it directly, but only in a construction that includes a MAC. -pub fn ctr(comptime BlockCipher: anytype, block_cipher: BlockCipher, dst: []u8, src: []const u8, iv: [BlockCipher.block_size]u8, endian: comptime builtin.Endian) void { +pub fn ctr(comptime BlockCipher: anytype, block_cipher: BlockCipher, dst: []u8, src: []const u8, iv: [BlockCipher.block_length]u8, endian: comptime builtin.Endian) void { debug.assert(dst.len >= src.len); - const block_size = BlockCipher.block_size; - var counter: [BlockCipher.block_size]u8 = undefined; + const block_length = BlockCipher.block_length; + var counter: [BlockCipher.block_length]u8 = undefined; var counterInt = mem.readInt(u128, &iv, endian); var i: usize = 0; const parallel_count = BlockCipher.block.parallel.optimal_parallel_blocks; - const wide_block_size = parallel_count * 16; - if (src.len >= wide_block_size) { + const wide_block_length = parallel_count * 16; + if (src.len >= wide_block_length) { var counters: [parallel_count * 16]u8 = undefined; - while (i + wide_block_size <= src.len) : (i += wide_block_size) { + while (i + wide_block_length <= src.len) : (i += wide_block_length) { comptime var j = 0; inline while (j < parallel_count) : (j += 1) { mem.writeInt(u128, counters[j * 16 .. j * 16 + 16], counterInt, endian); counterInt +%= 1; } - block_cipher.xorWide(parallel_count, dst[i .. i + wide_block_size][0..wide_block_size], src[i .. i + wide_block_size][0..wide_block_size], counters); + block_cipher.xorWide(parallel_count, dst[i .. i + wide_block_length][0..wide_block_length], src[i .. i + wide_block_length][0..wide_block_length], counters); } } - while (i + block_size <= src.len) : (i += block_size) { + while (i + block_length <= src.len) : (i += block_length) { mem.writeInt(u128, &counter, counterInt, endian); counterInt +%= 1; - block_cipher.xor(dst[i .. i + block_size][0..block_size], src[i .. i + block_size][0..block_size], counter); + block_cipher.xor(dst[i .. i + block_length][0..block_length], src[i .. i + block_length][0..block_length], counter); } if (i < src.len) { mem.writeInt(u128, &counter, counterInt, endian); - var pad = [_]u8{0} ** block_size; + var pad = [_]u8{0} ** block_length; mem.copy(u8, &pad, src[i..]); block_cipher.xor(&pad, &pad, counter); mem.copy(u8, dst[i..], pad[0 .. src.len - i]); diff --git a/lib/std/crypto/poly1305.zig b/lib/std/crypto/poly1305.zig index c6613f64ba..5b1554b113 100644 --- a/lib/std/crypto/poly1305.zig +++ b/lib/std/crypto/poly1305.zig @@ -7,9 +7,9 @@ const std = @import("../std.zig"); const mem = std.mem; pub const Poly1305 = struct { - pub const block_size: usize = 16; + pub const block_length: usize = 16; pub const mac_length = 16; - pub const minimum_key_length = 32; + pub const key_length = 32; // constant multiplier (from the secret key) r: [3]u64, @@ -20,9 +20,9 @@ pub const Poly1305 = struct { // how many bytes are waiting to be processed in a partial block leftover: usize = 0, // partial block buffer - buf: [block_size]u8 align(16) = undefined, + buf: [block_length]u8 align(16) = undefined, - pub fn init(key: *const [minimum_key_length]u8) Poly1305 { + pub fn init(key: *const [key_length]u8) Poly1305 { const t0 = mem.readIntLittle(u64, key[0..8]); const t1 = mem.readIntLittle(u64, key[8..16]); return Poly1305{ @@ -49,7 +49,7 @@ pub const Poly1305 = struct { const s1 = r1 * (5 << 2); const s2 = r2 * (5 << 2); var i: usize = 0; - while (i + block_size <= m.len) : (i += block_size) { + while (i + block_length <= m.len) : (i += block_length) { // h += m[i] const t0 = mem.readIntLittle(u64, m[i..][0..8]); const t1 = mem.readIntLittle(u64, m[i + 8 ..][0..8]); @@ -84,14 +84,14 @@ pub const Poly1305 = struct { // handle leftover if (st.leftover > 0) { - const want = std.math.min(block_size - st.leftover, mb.len); + const want = std.math.min(block_length - st.leftover, mb.len); const mc = mb[0..want]; for (mc) |x, i| { st.buf[st.leftover + i] = x; } mb = mb[want..]; st.leftover += want; - if (st.leftover < block_size) { + if (st.leftover < block_length) { return; } st.blocks(&st.buf, false); @@ -99,8 +99,8 @@ pub const Poly1305 = struct { } // process full blocks - if (mb.len >= block_size) { - const want = mb.len & ~(block_size - 1); + if (mb.len >= block_length) { + const want = mb.len & ~(block_length - 1); st.blocks(mb[0..want], false); mb = mb[want..]; } @@ -120,7 +120,7 @@ pub const Poly1305 = struct { return; } var i = st.leftover; - while (i < block_size) : (i += 1) { + while (i < block_length) : (i += 1) { st.buf[i] = 0; } st.blocks(&st.buf); @@ -132,7 +132,7 @@ pub const Poly1305 = struct { var i = st.leftover; st.buf[i] = 1; i += 1; - while (i < block_size) : (i += 1) { + while (i < block_length) : (i += 1) { st.buf[i] = 0; } st.blocks(&st.buf, true); @@ -198,7 +198,7 @@ pub const Poly1305 = struct { std.mem.secureZero(u8, @ptrCast([*]u8, st)[0..@sizeOf(Poly1305)]); } - pub fn create(out: *[mac_length]u8, msg: []const u8, key: *const [minimum_key_length]u8) void { + pub fn create(out: *[mac_length]u8, msg: []const u8, key: *const [key_length]u8) void { var st = Poly1305.init(key); st.update(msg); st.final(out); diff --git a/lib/std/crypto/sha1.zig b/lib/std/crypto/sha1.zig index f4b380e4f1..c2ae0a6544 100644 --- a/lib/std/crypto/sha1.zig +++ b/lib/std/crypto/sha1.zig @@ -6,7 +6,6 @@ const std = @import("../std.zig"); const mem = std.mem; const math = std.math; -const debug = std.debug; const RoundParam = struct { a: usize, @@ -17,7 +16,7 @@ const RoundParam = struct { i: u32, }; -fn Rp(a: usize, b: usize, c: usize, d: usize, e: usize, i: u32) RoundParam { +fn roundParam(a: usize, b: usize, c: usize, d: usize, e: usize, i: u32) RoundParam { return RoundParam{ .a = a, .b = b, @@ -55,7 +54,7 @@ pub const Sha1 = struct { }; } - pub fn hash(b: []const u8, out: []u8, options: Options) void { + pub fn hash(b: []const u8, out: *[digest_length]u8, options: Options) void { var d = Sha1.init(options); d.update(b); d.final(out); @@ -75,7 +74,7 @@ pub const Sha1 = struct { // Full middle blocks. while (off + 64 <= b.len) : (off += 64) { - d.round(b[off .. off + 64]); + d.round(b[off..][0..64]); } // Copy any remainder for next pass. @@ -85,9 +84,7 @@ pub const Sha1 = struct { d.total_len += b.len; } - pub fn final(d: *Self, out: []u8) void { - debug.assert(out.len >= 20); - + pub fn final(d: *Self, out: *[digest_length]u8) void { // The buffer here will never be completely full. mem.set(u8, d.buf[d.buf_len..], 0); @@ -117,9 +114,7 @@ pub const Sha1 = struct { } } - fn round(d: *Self, b: []const u8) void { - debug.assert(b.len == 64); - + fn round(d: *Self, b: *const [64]u8) void { var s: [16]u32 = undefined; var v: [5]u32 = [_]u32{ @@ -131,22 +126,22 @@ pub const Sha1 = struct { }; const round0a = comptime [_]RoundParam{ - Rp(0, 1, 2, 3, 4, 0), - Rp(4, 0, 1, 2, 3, 1), - Rp(3, 4, 0, 1, 2, 2), - Rp(2, 3, 4, 0, 1, 3), - Rp(1, 2, 3, 4, 0, 4), - Rp(0, 1, 2, 3, 4, 5), - Rp(4, 0, 1, 2, 3, 6), - Rp(3, 4, 0, 1, 2, 7), - Rp(2, 3, 4, 0, 1, 8), - Rp(1, 2, 3, 4, 0, 9), - Rp(0, 1, 2, 3, 4, 10), - Rp(4, 0, 1, 2, 3, 11), - Rp(3, 4, 0, 1, 2, 12), - Rp(2, 3, 4, 0, 1, 13), - Rp(1, 2, 3, 4, 0, 14), - Rp(0, 1, 2, 3, 4, 15), + roundParam(0, 1, 2, 3, 4, 0), + roundParam(4, 0, 1, 2, 3, 1), + roundParam(3, 4, 0, 1, 2, 2), + roundParam(2, 3, 4, 0, 1, 3), + roundParam(1, 2, 3, 4, 0, 4), + roundParam(0, 1, 2, 3, 4, 5), + roundParam(4, 0, 1, 2, 3, 6), + roundParam(3, 4, 0, 1, 2, 7), + roundParam(2, 3, 4, 0, 1, 8), + roundParam(1, 2, 3, 4, 0, 9), + roundParam(0, 1, 2, 3, 4, 10), + roundParam(4, 0, 1, 2, 3, 11), + roundParam(3, 4, 0, 1, 2, 12), + roundParam(2, 3, 4, 0, 1, 13), + roundParam(1, 2, 3, 4, 0, 14), + roundParam(0, 1, 2, 3, 4, 15), }; inline for (round0a) |r| { s[r.i] = (@as(u32, b[r.i * 4 + 0]) << 24) | (@as(u32, b[r.i * 4 + 1]) << 16) | (@as(u32, b[r.i * 4 + 2]) << 8) | (@as(u32, b[r.i * 4 + 3]) << 0); @@ -156,10 +151,10 @@ pub const Sha1 = struct { } const round0b = comptime [_]RoundParam{ - Rp(4, 0, 1, 2, 3, 16), - Rp(3, 4, 0, 1, 2, 17), - Rp(2, 3, 4, 0, 1, 18), - Rp(1, 2, 3, 4, 0, 19), + roundParam(4, 0, 1, 2, 3, 16), + roundParam(3, 4, 0, 1, 2, 17), + roundParam(2, 3, 4, 0, 1, 18), + roundParam(1, 2, 3, 4, 0, 19), }; inline for (round0b) |r| { const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf]; @@ -170,26 +165,26 @@ pub const Sha1 = struct { } const round1 = comptime [_]RoundParam{ - Rp(0, 1, 2, 3, 4, 20), - Rp(4, 0, 1, 2, 3, 21), - Rp(3, 4, 0, 1, 2, 22), - Rp(2, 3, 4, 0, 1, 23), - Rp(1, 2, 3, 4, 0, 24), - Rp(0, 1, 2, 3, 4, 25), - Rp(4, 0, 1, 2, 3, 26), - Rp(3, 4, 0, 1, 2, 27), - Rp(2, 3, 4, 0, 1, 28), - Rp(1, 2, 3, 4, 0, 29), - Rp(0, 1, 2, 3, 4, 30), - Rp(4, 0, 1, 2, 3, 31), - Rp(3, 4, 0, 1, 2, 32), - Rp(2, 3, 4, 0, 1, 33), - Rp(1, 2, 3, 4, 0, 34), - Rp(0, 1, 2, 3, 4, 35), - Rp(4, 0, 1, 2, 3, 36), - Rp(3, 4, 0, 1, 2, 37), - Rp(2, 3, 4, 0, 1, 38), - Rp(1, 2, 3, 4, 0, 39), + roundParam(0, 1, 2, 3, 4, 20), + roundParam(4, 0, 1, 2, 3, 21), + roundParam(3, 4, 0, 1, 2, 22), + roundParam(2, 3, 4, 0, 1, 23), + roundParam(1, 2, 3, 4, 0, 24), + roundParam(0, 1, 2, 3, 4, 25), + roundParam(4, 0, 1, 2, 3, 26), + roundParam(3, 4, 0, 1, 2, 27), + roundParam(2, 3, 4, 0, 1, 28), + roundParam(1, 2, 3, 4, 0, 29), + roundParam(0, 1, 2, 3, 4, 30), + roundParam(4, 0, 1, 2, 3, 31), + roundParam(3, 4, 0, 1, 2, 32), + roundParam(2, 3, 4, 0, 1, 33), + roundParam(1, 2, 3, 4, 0, 34), + roundParam(0, 1, 2, 3, 4, 35), + roundParam(4, 0, 1, 2, 3, 36), + roundParam(3, 4, 0, 1, 2, 37), + roundParam(2, 3, 4, 0, 1, 38), + roundParam(1, 2, 3, 4, 0, 39), }; inline for (round1) |r| { const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf]; @@ -200,26 +195,26 @@ pub const Sha1 = struct { } const round2 = comptime [_]RoundParam{ - Rp(0, 1, 2, 3, 4, 40), - Rp(4, 0, 1, 2, 3, 41), - Rp(3, 4, 0, 1, 2, 42), - Rp(2, 3, 4, 0, 1, 43), - Rp(1, 2, 3, 4, 0, 44), - Rp(0, 1, 2, 3, 4, 45), - Rp(4, 0, 1, 2, 3, 46), - Rp(3, 4, 0, 1, 2, 47), - Rp(2, 3, 4, 0, 1, 48), - Rp(1, 2, 3, 4, 0, 49), - Rp(0, 1, 2, 3, 4, 50), - Rp(4, 0, 1, 2, 3, 51), - Rp(3, 4, 0, 1, 2, 52), - Rp(2, 3, 4, 0, 1, 53), - Rp(1, 2, 3, 4, 0, 54), - Rp(0, 1, 2, 3, 4, 55), - Rp(4, 0, 1, 2, 3, 56), - Rp(3, 4, 0, 1, 2, 57), - Rp(2, 3, 4, 0, 1, 58), - Rp(1, 2, 3, 4, 0, 59), + roundParam(0, 1, 2, 3, 4, 40), + roundParam(4, 0, 1, 2, 3, 41), + roundParam(3, 4, 0, 1, 2, 42), + roundParam(2, 3, 4, 0, 1, 43), + roundParam(1, 2, 3, 4, 0, 44), + roundParam(0, 1, 2, 3, 4, 45), + roundParam(4, 0, 1, 2, 3, 46), + roundParam(3, 4, 0, 1, 2, 47), + roundParam(2, 3, 4, 0, 1, 48), + roundParam(1, 2, 3, 4, 0, 49), + roundParam(0, 1, 2, 3, 4, 50), + roundParam(4, 0, 1, 2, 3, 51), + roundParam(3, 4, 0, 1, 2, 52), + roundParam(2, 3, 4, 0, 1, 53), + roundParam(1, 2, 3, 4, 0, 54), + roundParam(0, 1, 2, 3, 4, 55), + roundParam(4, 0, 1, 2, 3, 56), + roundParam(3, 4, 0, 1, 2, 57), + roundParam(2, 3, 4, 0, 1, 58), + roundParam(1, 2, 3, 4, 0, 59), }; inline for (round2) |r| { const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf]; @@ -230,26 +225,26 @@ pub const Sha1 = struct { } const round3 = comptime [_]RoundParam{ - Rp(0, 1, 2, 3, 4, 60), - Rp(4, 0, 1, 2, 3, 61), - Rp(3, 4, 0, 1, 2, 62), - Rp(2, 3, 4, 0, 1, 63), - Rp(1, 2, 3, 4, 0, 64), - Rp(0, 1, 2, 3, 4, 65), - Rp(4, 0, 1, 2, 3, 66), - Rp(3, 4, 0, 1, 2, 67), - Rp(2, 3, 4, 0, 1, 68), - Rp(1, 2, 3, 4, 0, 69), - Rp(0, 1, 2, 3, 4, 70), - Rp(4, 0, 1, 2, 3, 71), - Rp(3, 4, 0, 1, 2, 72), - Rp(2, 3, 4, 0, 1, 73), - Rp(1, 2, 3, 4, 0, 74), - Rp(0, 1, 2, 3, 4, 75), - Rp(4, 0, 1, 2, 3, 76), - Rp(3, 4, 0, 1, 2, 77), - Rp(2, 3, 4, 0, 1, 78), - Rp(1, 2, 3, 4, 0, 79), + roundParam(0, 1, 2, 3, 4, 60), + roundParam(4, 0, 1, 2, 3, 61), + roundParam(3, 4, 0, 1, 2, 62), + roundParam(2, 3, 4, 0, 1, 63), + roundParam(1, 2, 3, 4, 0, 64), + roundParam(0, 1, 2, 3, 4, 65), + roundParam(4, 0, 1, 2, 3, 66), + roundParam(3, 4, 0, 1, 2, 67), + roundParam(2, 3, 4, 0, 1, 68), + roundParam(1, 2, 3, 4, 0, 69), + roundParam(0, 1, 2, 3, 4, 70), + roundParam(4, 0, 1, 2, 3, 71), + roundParam(3, 4, 0, 1, 2, 72), + roundParam(2, 3, 4, 0, 1, 73), + roundParam(1, 2, 3, 4, 0, 74), + roundParam(0, 1, 2, 3, 4, 75), + roundParam(4, 0, 1, 2, 3, 76), + roundParam(3, 4, 0, 1, 2, 77), + roundParam(2, 3, 4, 0, 1, 78), + roundParam(1, 2, 3, 4, 0, 79), }; inline for (round3) |r| { const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf]; @@ -279,19 +274,19 @@ test "sha1 streaming" { var h = Sha1.init(.{}); var out: [20]u8 = undefined; - h.final(out[0..]); + h.final(&out); htest.assertEqual("da39a3ee5e6b4b0d3255bfef95601890afd80709", out[0..]); h = Sha1.init(.{}); h.update("abc"); - h.final(out[0..]); + h.final(&out); htest.assertEqual("a9993e364706816aba3e25717850c26c9cd0d89d", out[0..]); h = Sha1.init(.{}); h.update("a"); h.update("b"); h.update("c"); - h.final(out[0..]); + h.final(&out); htest.assertEqual("a9993e364706816aba3e25717850c26c9cd0d89d", out[0..]); } diff --git a/lib/std/crypto/sha2.zig b/lib/std/crypto/sha2.zig index 3e388f2e48..4e06a214dd 100644 --- a/lib/std/crypto/sha2.zig +++ b/lib/std/crypto/sha2.zig @@ -6,7 +6,6 @@ const std = @import("../std.zig"); const mem = std.mem; const math = std.math; -const debug = std.debug; const htest = @import("test.zig"); ///////////////////// @@ -25,7 +24,7 @@ const RoundParam256 = struct { k: u32, }; -fn Rp256(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize, h: usize, i: usize, k: u32) RoundParam256 { +fn roundParam256(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize, h: usize, i: usize, k: u32) RoundParam256 { return RoundParam256{ .a = a, .b = b, @@ -49,7 +48,7 @@ const Sha2Params32 = struct { iv5: u32, iv6: u32, iv7: u32, - out_len: usize, + digest_bits: usize, }; const Sha224Params = Sha2Params32{ @@ -61,7 +60,7 @@ const Sha224Params = Sha2Params32{ .iv5 = 0x68581511, .iv6 = 0x64F98FA7, .iv7 = 0xBEFA4FA4, - .out_len = 224, + .digest_bits = 224, }; const Sha256Params = Sha2Params32{ @@ -73,20 +72,20 @@ const Sha256Params = Sha2Params32{ .iv5 = 0x9B05688C, .iv6 = 0x1F83D9AB, .iv7 = 0x5BE0CD19, - .out_len = 256, + .digest_bits = 256, }; /// SHA-224 -pub const Sha224 = Sha2_32(Sha224Params); +pub const Sha224 = Sha2x32(Sha224Params); /// SHA-256 -pub const Sha256 = Sha2_32(Sha256Params); +pub const Sha256 = Sha2x32(Sha256Params); -fn Sha2_32(comptime params: Sha2Params32) type { +fn Sha2x32(comptime params: Sha2Params32) type { return struct { const Self = @This(); pub const block_length = 64; - pub const digest_length = params.out_len / 8; + pub const digest_length = params.digest_bits / 8; pub const Options = struct {}; s: [8]u32, @@ -110,7 +109,7 @@ fn Sha2_32(comptime params: Sha2Params32) type { }; } - pub fn hash(b: []const u8, out: []u8, options: Options) void { + pub fn hash(b: []const u8, out: *[digest_length]u8, options: Options) void { var d = Self.init(options); d.update(b); d.final(out); @@ -124,13 +123,13 @@ fn Sha2_32(comptime params: Sha2Params32) type { off += 64 - d.buf_len; mem.copy(u8, d.buf[d.buf_len..], b[0..off]); - d.round(d.buf[0..]); + d.round(&d.buf); d.buf_len = 0; } // Full middle blocks. while (off + 64 <= b.len) : (off += 64) { - d.round(b[off .. off + 64]); + d.round(b[off..][0..64]); } // Copy any remainder for next pass. @@ -140,9 +139,7 @@ fn Sha2_32(comptime params: Sha2Params32) type { d.total_len += b.len; } - pub fn final(d: *Self, out: []u8) void { - debug.assert(out.len >= params.out_len / 8); - + pub fn final(d: *Self, out: *[digest_length]u8) void { // The buffer here will never be completely full. mem.set(u8, d.buf[d.buf_len..], 0); @@ -152,7 +149,7 @@ fn Sha2_32(comptime params: Sha2Params32) type { // > 448 mod 512 so need to add an extra round to wrap around. if (64 - d.buf_len < 8) { - d.round(d.buf[0..]); + d.round(&d.buf); mem.set(u8, d.buf[0..], 0); } @@ -165,19 +162,17 @@ fn Sha2_32(comptime params: Sha2Params32) type { len >>= 8; } - d.round(d.buf[0..]); + d.round(&d.buf); // May truncate for possible 224 output - const rr = d.s[0 .. params.out_len / 32]; + const rr = d.s[0 .. params.digest_bits / 32]; for (rr) |s, j| { mem.writeIntBig(u32, out[4 * j ..][0..4], s); } } - fn round(d: *Self, b: []const u8) void { - debug.assert(b.len == 64); - + fn round(d: *Self, b: *const [64]u8) void { var s: [64]u32 = undefined; var i: usize = 0; @@ -204,70 +199,70 @@ fn Sha2_32(comptime params: Sha2Params32) type { }; const round0 = comptime [_]RoundParam256{ - Rp256(0, 1, 2, 3, 4, 5, 6, 7, 0, 0x428A2F98), - Rp256(7, 0, 1, 2, 3, 4, 5, 6, 1, 0x71374491), - Rp256(6, 7, 0, 1, 2, 3, 4, 5, 2, 0xB5C0FBCF), - Rp256(5, 6, 7, 0, 1, 2, 3, 4, 3, 0xE9B5DBA5), - Rp256(4, 5, 6, 7, 0, 1, 2, 3, 4, 0x3956C25B), - Rp256(3, 4, 5, 6, 7, 0, 1, 2, 5, 0x59F111F1), - Rp256(2, 3, 4, 5, 6, 7, 0, 1, 6, 0x923F82A4), - Rp256(1, 2, 3, 4, 5, 6, 7, 0, 7, 0xAB1C5ED5), - Rp256(0, 1, 2, 3, 4, 5, 6, 7, 8, 0xD807AA98), - Rp256(7, 0, 1, 2, 3, 4, 5, 6, 9, 0x12835B01), - Rp256(6, 7, 0, 1, 2, 3, 4, 5, 10, 0x243185BE), - Rp256(5, 6, 7, 0, 1, 2, 3, 4, 11, 0x550C7DC3), - Rp256(4, 5, 6, 7, 0, 1, 2, 3, 12, 0x72BE5D74), - Rp256(3, 4, 5, 6, 7, 0, 1, 2, 13, 0x80DEB1FE), - Rp256(2, 3, 4, 5, 6, 7, 0, 1, 14, 0x9BDC06A7), - Rp256(1, 2, 3, 4, 5, 6, 7, 0, 15, 0xC19BF174), - Rp256(0, 1, 2, 3, 4, 5, 6, 7, 16, 0xE49B69C1), - Rp256(7, 0, 1, 2, 3, 4, 5, 6, 17, 0xEFBE4786), - Rp256(6, 7, 0, 1, 2, 3, 4, 5, 18, 0x0FC19DC6), - Rp256(5, 6, 7, 0, 1, 2, 3, 4, 19, 0x240CA1CC), - Rp256(4, 5, 6, 7, 0, 1, 2, 3, 20, 0x2DE92C6F), - Rp256(3, 4, 5, 6, 7, 0, 1, 2, 21, 0x4A7484AA), - Rp256(2, 3, 4, 5, 6, 7, 0, 1, 22, 0x5CB0A9DC), - Rp256(1, 2, 3, 4, 5, 6, 7, 0, 23, 0x76F988DA), - Rp256(0, 1, 2, 3, 4, 5, 6, 7, 24, 0x983E5152), - Rp256(7, 0, 1, 2, 3, 4, 5, 6, 25, 0xA831C66D), - Rp256(6, 7, 0, 1, 2, 3, 4, 5, 26, 0xB00327C8), - Rp256(5, 6, 7, 0, 1, 2, 3, 4, 27, 0xBF597FC7), - Rp256(4, 5, 6, 7, 0, 1, 2, 3, 28, 0xC6E00BF3), - Rp256(3, 4, 5, 6, 7, 0, 1, 2, 29, 0xD5A79147), - Rp256(2, 3, 4, 5, 6, 7, 0, 1, 30, 0x06CA6351), - Rp256(1, 2, 3, 4, 5, 6, 7, 0, 31, 0x14292967), - Rp256(0, 1, 2, 3, 4, 5, 6, 7, 32, 0x27B70A85), - Rp256(7, 0, 1, 2, 3, 4, 5, 6, 33, 0x2E1B2138), - Rp256(6, 7, 0, 1, 2, 3, 4, 5, 34, 0x4D2C6DFC), - Rp256(5, 6, 7, 0, 1, 2, 3, 4, 35, 0x53380D13), - Rp256(4, 5, 6, 7, 0, 1, 2, 3, 36, 0x650A7354), - Rp256(3, 4, 5, 6, 7, 0, 1, 2, 37, 0x766A0ABB), - Rp256(2, 3, 4, 5, 6, 7, 0, 1, 38, 0x81C2C92E), - Rp256(1, 2, 3, 4, 5, 6, 7, 0, 39, 0x92722C85), - Rp256(0, 1, 2, 3, 4, 5, 6, 7, 40, 0xA2BFE8A1), - Rp256(7, 0, 1, 2, 3, 4, 5, 6, 41, 0xA81A664B), - Rp256(6, 7, 0, 1, 2, 3, 4, 5, 42, 0xC24B8B70), - Rp256(5, 6, 7, 0, 1, 2, 3, 4, 43, 0xC76C51A3), - Rp256(4, 5, 6, 7, 0, 1, 2, 3, 44, 0xD192E819), - Rp256(3, 4, 5, 6, 7, 0, 1, 2, 45, 0xD6990624), - Rp256(2, 3, 4, 5, 6, 7, 0, 1, 46, 0xF40E3585), - Rp256(1, 2, 3, 4, 5, 6, 7, 0, 47, 0x106AA070), - Rp256(0, 1, 2, 3, 4, 5, 6, 7, 48, 0x19A4C116), - Rp256(7, 0, 1, 2, 3, 4, 5, 6, 49, 0x1E376C08), - Rp256(6, 7, 0, 1, 2, 3, 4, 5, 50, 0x2748774C), - Rp256(5, 6, 7, 0, 1, 2, 3, 4, 51, 0x34B0BCB5), - Rp256(4, 5, 6, 7, 0, 1, 2, 3, 52, 0x391C0CB3), - Rp256(3, 4, 5, 6, 7, 0, 1, 2, 53, 0x4ED8AA4A), - Rp256(2, 3, 4, 5, 6, 7, 0, 1, 54, 0x5B9CCA4F), - Rp256(1, 2, 3, 4, 5, 6, 7, 0, 55, 0x682E6FF3), - Rp256(0, 1, 2, 3, 4, 5, 6, 7, 56, 0x748F82EE), - Rp256(7, 0, 1, 2, 3, 4, 5, 6, 57, 0x78A5636F), - Rp256(6, 7, 0, 1, 2, 3, 4, 5, 58, 0x84C87814), - Rp256(5, 6, 7, 0, 1, 2, 3, 4, 59, 0x8CC70208), - Rp256(4, 5, 6, 7, 0, 1, 2, 3, 60, 0x90BEFFFA), - Rp256(3, 4, 5, 6, 7, 0, 1, 2, 61, 0xA4506CEB), - Rp256(2, 3, 4, 5, 6, 7, 0, 1, 62, 0xBEF9A3F7), - Rp256(1, 2, 3, 4, 5, 6, 7, 0, 63, 0xC67178F2), + roundParam256(0, 1, 2, 3, 4, 5, 6, 7, 0, 0x428A2F98), + roundParam256(7, 0, 1, 2, 3, 4, 5, 6, 1, 0x71374491), + roundParam256(6, 7, 0, 1, 2, 3, 4, 5, 2, 0xB5C0FBCF), + roundParam256(5, 6, 7, 0, 1, 2, 3, 4, 3, 0xE9B5DBA5), + roundParam256(4, 5, 6, 7, 0, 1, 2, 3, 4, 0x3956C25B), + roundParam256(3, 4, 5, 6, 7, 0, 1, 2, 5, 0x59F111F1), + roundParam256(2, 3, 4, 5, 6, 7, 0, 1, 6, 0x923F82A4), + roundParam256(1, 2, 3, 4, 5, 6, 7, 0, 7, 0xAB1C5ED5), + roundParam256(0, 1, 2, 3, 4, 5, 6, 7, 8, 0xD807AA98), + roundParam256(7, 0, 1, 2, 3, 4, 5, 6, 9, 0x12835B01), + roundParam256(6, 7, 0, 1, 2, 3, 4, 5, 10, 0x243185BE), + roundParam256(5, 6, 7, 0, 1, 2, 3, 4, 11, 0x550C7DC3), + roundParam256(4, 5, 6, 7, 0, 1, 2, 3, 12, 0x72BE5D74), + roundParam256(3, 4, 5, 6, 7, 0, 1, 2, 13, 0x80DEB1FE), + roundParam256(2, 3, 4, 5, 6, 7, 0, 1, 14, 0x9BDC06A7), + roundParam256(1, 2, 3, 4, 5, 6, 7, 0, 15, 0xC19BF174), + roundParam256(0, 1, 2, 3, 4, 5, 6, 7, 16, 0xE49B69C1), + roundParam256(7, 0, 1, 2, 3, 4, 5, 6, 17, 0xEFBE4786), + roundParam256(6, 7, 0, 1, 2, 3, 4, 5, 18, 0x0FC19DC6), + roundParam256(5, 6, 7, 0, 1, 2, 3, 4, 19, 0x240CA1CC), + roundParam256(4, 5, 6, 7, 0, 1, 2, 3, 20, 0x2DE92C6F), + roundParam256(3, 4, 5, 6, 7, 0, 1, 2, 21, 0x4A7484AA), + roundParam256(2, 3, 4, 5, 6, 7, 0, 1, 22, 0x5CB0A9DC), + roundParam256(1, 2, 3, 4, 5, 6, 7, 0, 23, 0x76F988DA), + roundParam256(0, 1, 2, 3, 4, 5, 6, 7, 24, 0x983E5152), + roundParam256(7, 0, 1, 2, 3, 4, 5, 6, 25, 0xA831C66D), + roundParam256(6, 7, 0, 1, 2, 3, 4, 5, 26, 0xB00327C8), + roundParam256(5, 6, 7, 0, 1, 2, 3, 4, 27, 0xBF597FC7), + roundParam256(4, 5, 6, 7, 0, 1, 2, 3, 28, 0xC6E00BF3), + roundParam256(3, 4, 5, 6, 7, 0, 1, 2, 29, 0xD5A79147), + roundParam256(2, 3, 4, 5, 6, 7, 0, 1, 30, 0x06CA6351), + roundParam256(1, 2, 3, 4, 5, 6, 7, 0, 31, 0x14292967), + roundParam256(0, 1, 2, 3, 4, 5, 6, 7, 32, 0x27B70A85), + roundParam256(7, 0, 1, 2, 3, 4, 5, 6, 33, 0x2E1B2138), + roundParam256(6, 7, 0, 1, 2, 3, 4, 5, 34, 0x4D2C6DFC), + roundParam256(5, 6, 7, 0, 1, 2, 3, 4, 35, 0x53380D13), + roundParam256(4, 5, 6, 7, 0, 1, 2, 3, 36, 0x650A7354), + roundParam256(3, 4, 5, 6, 7, 0, 1, 2, 37, 0x766A0ABB), + roundParam256(2, 3, 4, 5, 6, 7, 0, 1, 38, 0x81C2C92E), + roundParam256(1, 2, 3, 4, 5, 6, 7, 0, 39, 0x92722C85), + roundParam256(0, 1, 2, 3, 4, 5, 6, 7, 40, 0xA2BFE8A1), + roundParam256(7, 0, 1, 2, 3, 4, 5, 6, 41, 0xA81A664B), + roundParam256(6, 7, 0, 1, 2, 3, 4, 5, 42, 0xC24B8B70), + roundParam256(5, 6, 7, 0, 1, 2, 3, 4, 43, 0xC76C51A3), + roundParam256(4, 5, 6, 7, 0, 1, 2, 3, 44, 0xD192E819), + roundParam256(3, 4, 5, 6, 7, 0, 1, 2, 45, 0xD6990624), + roundParam256(2, 3, 4, 5, 6, 7, 0, 1, 46, 0xF40E3585), + roundParam256(1, 2, 3, 4, 5, 6, 7, 0, 47, 0x106AA070), + roundParam256(0, 1, 2, 3, 4, 5, 6, 7, 48, 0x19A4C116), + roundParam256(7, 0, 1, 2, 3, 4, 5, 6, 49, 0x1E376C08), + roundParam256(6, 7, 0, 1, 2, 3, 4, 5, 50, 0x2748774C), + roundParam256(5, 6, 7, 0, 1, 2, 3, 4, 51, 0x34B0BCB5), + roundParam256(4, 5, 6, 7, 0, 1, 2, 3, 52, 0x391C0CB3), + roundParam256(3, 4, 5, 6, 7, 0, 1, 2, 53, 0x4ED8AA4A), + roundParam256(2, 3, 4, 5, 6, 7, 0, 1, 54, 0x5B9CCA4F), + roundParam256(1, 2, 3, 4, 5, 6, 7, 0, 55, 0x682E6FF3), + roundParam256(0, 1, 2, 3, 4, 5, 6, 7, 56, 0x748F82EE), + roundParam256(7, 0, 1, 2, 3, 4, 5, 6, 57, 0x78A5636F), + roundParam256(6, 7, 0, 1, 2, 3, 4, 5, 58, 0x84C87814), + roundParam256(5, 6, 7, 0, 1, 2, 3, 4, 59, 0x8CC70208), + roundParam256(4, 5, 6, 7, 0, 1, 2, 3, 60, 0x90BEFFFA), + roundParam256(3, 4, 5, 6, 7, 0, 1, 2, 61, 0xA4506CEB), + roundParam256(2, 3, 4, 5, 6, 7, 0, 1, 62, 0xBEF9A3F7), + roundParam256(1, 2, 3, 4, 5, 6, 7, 0, 63, 0xC67178F2), }; inline for (round0) |r| { v[r.h] = v[r.h] +% (math.rotr(u32, v[r.e], @as(u32, 6)) ^ math.rotr(u32, v[r.e], @as(u32, 11)) ^ math.rotr(u32, v[r.e], @as(u32, 25))) +% (v[r.g] ^ (v[r.e] & (v[r.f] ^ v[r.g]))) +% r.k +% s[r.i]; @@ -366,7 +361,7 @@ const RoundParam512 = struct { k: u64, }; -fn Rp512(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize, h: usize, i: usize, k: u64) RoundParam512 { +fn roundParam512(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize, h: usize, i: usize, k: u64) RoundParam512 { return RoundParam512{ .a = a, .b = b, @@ -390,7 +385,7 @@ const Sha2Params64 = struct { iv5: u64, iv6: u64, iv7: u64, - out_len: usize, + digest_bits: usize, }; const Sha384Params = Sha2Params64{ @@ -402,7 +397,7 @@ const Sha384Params = Sha2Params64{ .iv5 = 0x8EB44A8768581511, .iv6 = 0xDB0C2E0D64F98FA7, .iv7 = 0x47B5481DBEFA4FA4, - .out_len = 384, + .digest_bits = 384, }; const Sha512Params = Sha2Params64{ @@ -414,7 +409,7 @@ const Sha512Params = Sha2Params64{ .iv5 = 0x9B05688C2B3E6C1F, .iv6 = 0x1F83D9ABFB41BD6B, .iv7 = 0x5BE0CD19137E2179, - .out_len = 512, + .digest_bits = 512, }; const Sha512256Params = Sha2Params64{ @@ -426,7 +421,7 @@ const Sha512256Params = Sha2Params64{ .iv5 = 0xBE5E1E2553863992, .iv6 = 0x2B0199FC2C85B8AA, .iv7 = 0x0EB72DDC81C52CA2, - .out_len = 256, + .digest_bits = 256, }; const Sha512T256Params = Sha2Params64{ @@ -438,26 +433,26 @@ const Sha512T256Params = Sha2Params64{ .iv5 = 0x9B05688C2B3E6C1F, .iv6 = 0x1F83D9ABFB41BD6B, .iv7 = 0x5BE0CD19137E2179, - .out_len = 256, + .digest_bits = 256, }; /// SHA-384 -pub const Sha384 = Sha2_64(Sha384Params); +pub const Sha384 = Sha2x64(Sha384Params); /// SHA-512 -pub const Sha512 = Sha2_64(Sha512Params); +pub const Sha512 = Sha2x64(Sha512Params); /// SHA-512/256 -pub const Sha512256 = Sha2_64(Sha512256Params); +pub const Sha512256 = Sha2x64(Sha512256Params); /// Truncated SHA-512 -pub const Sha512T256 = Sha2_64(Sha512T256Params); +pub const Sha512T256 = Sha2x64(Sha512T256Params); -fn Sha2_64(comptime params: Sha2Params64) type { +fn Sha2x64(comptime params: Sha2Params64) type { return struct { const Self = @This(); pub const block_length = 128; - pub const digest_length = params.out_len / 8; + pub const digest_length = params.digest_bits / 8; pub const Options = struct {}; s: [8]u64, @@ -481,7 +476,7 @@ fn Sha2_64(comptime params: Sha2Params64) type { }; } - pub fn hash(b: []const u8, out: []u8, options: Options) void { + pub fn hash(b: []const u8, out: *[digest_length]u8, options: Options) void { var d = Self.init(options); d.update(b); d.final(out); @@ -495,13 +490,13 @@ fn Sha2_64(comptime params: Sha2Params64) type { off += 128 - d.buf_len; mem.copy(u8, d.buf[d.buf_len..], b[0..off]); - d.round(d.buf[0..]); + d.round(&d.buf); d.buf_len = 0; } // Full middle blocks. while (off + 128 <= b.len) : (off += 128) { - d.round(b[off .. off + 128]); + d.round(b[off..][0..128]); } // Copy any remainder for next pass. @@ -511,9 +506,7 @@ fn Sha2_64(comptime params: Sha2Params64) type { d.total_len += b.len; } - pub fn final(d: *Self, out: []u8) void { - debug.assert(out.len >= params.out_len / 8); - + pub fn final(d: *Self, out: *[digest_length]u8) void { // The buffer here will never be completely full. mem.set(u8, d.buf[d.buf_len..], 0); @@ -539,16 +532,14 @@ fn Sha2_64(comptime params: Sha2Params64) type { d.round(d.buf[0..]); // May truncate for possible 384 output - const rr = d.s[0 .. params.out_len / 64]; + const rr = d.s[0 .. params.digest_bits / 64]; for (rr) |s, j| { mem.writeIntBig(u64, out[8 * j ..][0..8], s); } } - fn round(d: *Self, b: []const u8) void { - debug.assert(b.len == 128); - + fn round(d: *Self, b: *const [128]u8) void { var s: [80]u64 = undefined; var i: usize = 0; @@ -581,86 +572,86 @@ fn Sha2_64(comptime params: Sha2Params64) type { }; const round0 = comptime [_]RoundParam512{ - Rp512(0, 1, 2, 3, 4, 5, 6, 7, 0, 0x428A2F98D728AE22), - Rp512(7, 0, 1, 2, 3, 4, 5, 6, 1, 0x7137449123EF65CD), - Rp512(6, 7, 0, 1, 2, 3, 4, 5, 2, 0xB5C0FBCFEC4D3B2F), - Rp512(5, 6, 7, 0, 1, 2, 3, 4, 3, 0xE9B5DBA58189DBBC), - Rp512(4, 5, 6, 7, 0, 1, 2, 3, 4, 0x3956C25BF348B538), - Rp512(3, 4, 5, 6, 7, 0, 1, 2, 5, 0x59F111F1B605D019), - Rp512(2, 3, 4, 5, 6, 7, 0, 1, 6, 0x923F82A4AF194F9B), - Rp512(1, 2, 3, 4, 5, 6, 7, 0, 7, 0xAB1C5ED5DA6D8118), - Rp512(0, 1, 2, 3, 4, 5, 6, 7, 8, 0xD807AA98A3030242), - Rp512(7, 0, 1, 2, 3, 4, 5, 6, 9, 0x12835B0145706FBE), - Rp512(6, 7, 0, 1, 2, 3, 4, 5, 10, 0x243185BE4EE4B28C), - Rp512(5, 6, 7, 0, 1, 2, 3, 4, 11, 0x550C7DC3D5FFB4E2), - Rp512(4, 5, 6, 7, 0, 1, 2, 3, 12, 0x72BE5D74F27B896F), - Rp512(3, 4, 5, 6, 7, 0, 1, 2, 13, 0x80DEB1FE3B1696B1), - Rp512(2, 3, 4, 5, 6, 7, 0, 1, 14, 0x9BDC06A725C71235), - Rp512(1, 2, 3, 4, 5, 6, 7, 0, 15, 0xC19BF174CF692694), - Rp512(0, 1, 2, 3, 4, 5, 6, 7, 16, 0xE49B69C19EF14AD2), - Rp512(7, 0, 1, 2, 3, 4, 5, 6, 17, 0xEFBE4786384F25E3), - Rp512(6, 7, 0, 1, 2, 3, 4, 5, 18, 0x0FC19DC68B8CD5B5), - Rp512(5, 6, 7, 0, 1, 2, 3, 4, 19, 0x240CA1CC77AC9C65), - Rp512(4, 5, 6, 7, 0, 1, 2, 3, 20, 0x2DE92C6F592B0275), - Rp512(3, 4, 5, 6, 7, 0, 1, 2, 21, 0x4A7484AA6EA6E483), - Rp512(2, 3, 4, 5, 6, 7, 0, 1, 22, 0x5CB0A9DCBD41FBD4), - Rp512(1, 2, 3, 4, 5, 6, 7, 0, 23, 0x76F988DA831153B5), - Rp512(0, 1, 2, 3, 4, 5, 6, 7, 24, 0x983E5152EE66DFAB), - Rp512(7, 0, 1, 2, 3, 4, 5, 6, 25, 0xA831C66D2DB43210), - Rp512(6, 7, 0, 1, 2, 3, 4, 5, 26, 0xB00327C898FB213F), - Rp512(5, 6, 7, 0, 1, 2, 3, 4, 27, 0xBF597FC7BEEF0EE4), - Rp512(4, 5, 6, 7, 0, 1, 2, 3, 28, 0xC6E00BF33DA88FC2), - Rp512(3, 4, 5, 6, 7, 0, 1, 2, 29, 0xD5A79147930AA725), - Rp512(2, 3, 4, 5, 6, 7, 0, 1, 30, 0x06CA6351E003826F), - Rp512(1, 2, 3, 4, 5, 6, 7, 0, 31, 0x142929670A0E6E70), - Rp512(0, 1, 2, 3, 4, 5, 6, 7, 32, 0x27B70A8546D22FFC), - Rp512(7, 0, 1, 2, 3, 4, 5, 6, 33, 0x2E1B21385C26C926), - Rp512(6, 7, 0, 1, 2, 3, 4, 5, 34, 0x4D2C6DFC5AC42AED), - Rp512(5, 6, 7, 0, 1, 2, 3, 4, 35, 0x53380D139D95B3DF), - Rp512(4, 5, 6, 7, 0, 1, 2, 3, 36, 0x650A73548BAF63DE), - Rp512(3, 4, 5, 6, 7, 0, 1, 2, 37, 0x766A0ABB3C77B2A8), - Rp512(2, 3, 4, 5, 6, 7, 0, 1, 38, 0x81C2C92E47EDAEE6), - Rp512(1, 2, 3, 4, 5, 6, 7, 0, 39, 0x92722C851482353B), - Rp512(0, 1, 2, 3, 4, 5, 6, 7, 40, 0xA2BFE8A14CF10364), - Rp512(7, 0, 1, 2, 3, 4, 5, 6, 41, 0xA81A664BBC423001), - Rp512(6, 7, 0, 1, 2, 3, 4, 5, 42, 0xC24B8B70D0F89791), - Rp512(5, 6, 7, 0, 1, 2, 3, 4, 43, 0xC76C51A30654BE30), - Rp512(4, 5, 6, 7, 0, 1, 2, 3, 44, 0xD192E819D6EF5218), - Rp512(3, 4, 5, 6, 7, 0, 1, 2, 45, 0xD69906245565A910), - Rp512(2, 3, 4, 5, 6, 7, 0, 1, 46, 0xF40E35855771202A), - Rp512(1, 2, 3, 4, 5, 6, 7, 0, 47, 0x106AA07032BBD1B8), - Rp512(0, 1, 2, 3, 4, 5, 6, 7, 48, 0x19A4C116B8D2D0C8), - Rp512(7, 0, 1, 2, 3, 4, 5, 6, 49, 0x1E376C085141AB53), - Rp512(6, 7, 0, 1, 2, 3, 4, 5, 50, 0x2748774CDF8EEB99), - Rp512(5, 6, 7, 0, 1, 2, 3, 4, 51, 0x34B0BCB5E19B48A8), - Rp512(4, 5, 6, 7, 0, 1, 2, 3, 52, 0x391C0CB3C5C95A63), - Rp512(3, 4, 5, 6, 7, 0, 1, 2, 53, 0x4ED8AA4AE3418ACB), - Rp512(2, 3, 4, 5, 6, 7, 0, 1, 54, 0x5B9CCA4F7763E373), - Rp512(1, 2, 3, 4, 5, 6, 7, 0, 55, 0x682E6FF3D6B2B8A3), - Rp512(0, 1, 2, 3, 4, 5, 6, 7, 56, 0x748F82EE5DEFB2FC), - Rp512(7, 0, 1, 2, 3, 4, 5, 6, 57, 0x78A5636F43172F60), - Rp512(6, 7, 0, 1, 2, 3, 4, 5, 58, 0x84C87814A1F0AB72), - Rp512(5, 6, 7, 0, 1, 2, 3, 4, 59, 0x8CC702081A6439EC), - Rp512(4, 5, 6, 7, 0, 1, 2, 3, 60, 0x90BEFFFA23631E28), - Rp512(3, 4, 5, 6, 7, 0, 1, 2, 61, 0xA4506CEBDE82BDE9), - Rp512(2, 3, 4, 5, 6, 7, 0, 1, 62, 0xBEF9A3F7B2C67915), - Rp512(1, 2, 3, 4, 5, 6, 7, 0, 63, 0xC67178F2E372532B), - Rp512(0, 1, 2, 3, 4, 5, 6, 7, 64, 0xCA273ECEEA26619C), - Rp512(7, 0, 1, 2, 3, 4, 5, 6, 65, 0xD186B8C721C0C207), - Rp512(6, 7, 0, 1, 2, 3, 4, 5, 66, 0xEADA7DD6CDE0EB1E), - Rp512(5, 6, 7, 0, 1, 2, 3, 4, 67, 0xF57D4F7FEE6ED178), - Rp512(4, 5, 6, 7, 0, 1, 2, 3, 68, 0x06F067AA72176FBA), - Rp512(3, 4, 5, 6, 7, 0, 1, 2, 69, 0x0A637DC5A2C898A6), - Rp512(2, 3, 4, 5, 6, 7, 0, 1, 70, 0x113F9804BEF90DAE), - Rp512(1, 2, 3, 4, 5, 6, 7, 0, 71, 0x1B710B35131C471B), - Rp512(0, 1, 2, 3, 4, 5, 6, 7, 72, 0x28DB77F523047D84), - Rp512(7, 0, 1, 2, 3, 4, 5, 6, 73, 0x32CAAB7B40C72493), - Rp512(6, 7, 0, 1, 2, 3, 4, 5, 74, 0x3C9EBE0A15C9BEBC), - Rp512(5, 6, 7, 0, 1, 2, 3, 4, 75, 0x431D67C49C100D4C), - Rp512(4, 5, 6, 7, 0, 1, 2, 3, 76, 0x4CC5D4BECB3E42B6), - Rp512(3, 4, 5, 6, 7, 0, 1, 2, 77, 0x597F299CFC657E2A), - Rp512(2, 3, 4, 5, 6, 7, 0, 1, 78, 0x5FCB6FAB3AD6FAEC), - Rp512(1, 2, 3, 4, 5, 6, 7, 0, 79, 0x6C44198C4A475817), + roundParam512(0, 1, 2, 3, 4, 5, 6, 7, 0, 0x428A2F98D728AE22), + roundParam512(7, 0, 1, 2, 3, 4, 5, 6, 1, 0x7137449123EF65CD), + roundParam512(6, 7, 0, 1, 2, 3, 4, 5, 2, 0xB5C0FBCFEC4D3B2F), + roundParam512(5, 6, 7, 0, 1, 2, 3, 4, 3, 0xE9B5DBA58189DBBC), + roundParam512(4, 5, 6, 7, 0, 1, 2, 3, 4, 0x3956C25BF348B538), + roundParam512(3, 4, 5, 6, 7, 0, 1, 2, 5, 0x59F111F1B605D019), + roundParam512(2, 3, 4, 5, 6, 7, 0, 1, 6, 0x923F82A4AF194F9B), + roundParam512(1, 2, 3, 4, 5, 6, 7, 0, 7, 0xAB1C5ED5DA6D8118), + roundParam512(0, 1, 2, 3, 4, 5, 6, 7, 8, 0xD807AA98A3030242), + roundParam512(7, 0, 1, 2, 3, 4, 5, 6, 9, 0x12835B0145706FBE), + roundParam512(6, 7, 0, 1, 2, 3, 4, 5, 10, 0x243185BE4EE4B28C), + roundParam512(5, 6, 7, 0, 1, 2, 3, 4, 11, 0x550C7DC3D5FFB4E2), + roundParam512(4, 5, 6, 7, 0, 1, 2, 3, 12, 0x72BE5D74F27B896F), + roundParam512(3, 4, 5, 6, 7, 0, 1, 2, 13, 0x80DEB1FE3B1696B1), + roundParam512(2, 3, 4, 5, 6, 7, 0, 1, 14, 0x9BDC06A725C71235), + roundParam512(1, 2, 3, 4, 5, 6, 7, 0, 15, 0xC19BF174CF692694), + roundParam512(0, 1, 2, 3, 4, 5, 6, 7, 16, 0xE49B69C19EF14AD2), + roundParam512(7, 0, 1, 2, 3, 4, 5, 6, 17, 0xEFBE4786384F25E3), + roundParam512(6, 7, 0, 1, 2, 3, 4, 5, 18, 0x0FC19DC68B8CD5B5), + roundParam512(5, 6, 7, 0, 1, 2, 3, 4, 19, 0x240CA1CC77AC9C65), + roundParam512(4, 5, 6, 7, 0, 1, 2, 3, 20, 0x2DE92C6F592B0275), + roundParam512(3, 4, 5, 6, 7, 0, 1, 2, 21, 0x4A7484AA6EA6E483), + roundParam512(2, 3, 4, 5, 6, 7, 0, 1, 22, 0x5CB0A9DCBD41FBD4), + roundParam512(1, 2, 3, 4, 5, 6, 7, 0, 23, 0x76F988DA831153B5), + roundParam512(0, 1, 2, 3, 4, 5, 6, 7, 24, 0x983E5152EE66DFAB), + roundParam512(7, 0, 1, 2, 3, 4, 5, 6, 25, 0xA831C66D2DB43210), + roundParam512(6, 7, 0, 1, 2, 3, 4, 5, 26, 0xB00327C898FB213F), + roundParam512(5, 6, 7, 0, 1, 2, 3, 4, 27, 0xBF597FC7BEEF0EE4), + roundParam512(4, 5, 6, 7, 0, 1, 2, 3, 28, 0xC6E00BF33DA88FC2), + roundParam512(3, 4, 5, 6, 7, 0, 1, 2, 29, 0xD5A79147930AA725), + roundParam512(2, 3, 4, 5, 6, 7, 0, 1, 30, 0x06CA6351E003826F), + roundParam512(1, 2, 3, 4, 5, 6, 7, 0, 31, 0x142929670A0E6E70), + roundParam512(0, 1, 2, 3, 4, 5, 6, 7, 32, 0x27B70A8546D22FFC), + roundParam512(7, 0, 1, 2, 3, 4, 5, 6, 33, 0x2E1B21385C26C926), + roundParam512(6, 7, 0, 1, 2, 3, 4, 5, 34, 0x4D2C6DFC5AC42AED), + roundParam512(5, 6, 7, 0, 1, 2, 3, 4, 35, 0x53380D139D95B3DF), + roundParam512(4, 5, 6, 7, 0, 1, 2, 3, 36, 0x650A73548BAF63DE), + roundParam512(3, 4, 5, 6, 7, 0, 1, 2, 37, 0x766A0ABB3C77B2A8), + roundParam512(2, 3, 4, 5, 6, 7, 0, 1, 38, 0x81C2C92E47EDAEE6), + roundParam512(1, 2, 3, 4, 5, 6, 7, 0, 39, 0x92722C851482353B), + roundParam512(0, 1, 2, 3, 4, 5, 6, 7, 40, 0xA2BFE8A14CF10364), + roundParam512(7, 0, 1, 2, 3, 4, 5, 6, 41, 0xA81A664BBC423001), + roundParam512(6, 7, 0, 1, 2, 3, 4, 5, 42, 0xC24B8B70D0F89791), + roundParam512(5, 6, 7, 0, 1, 2, 3, 4, 43, 0xC76C51A30654BE30), + roundParam512(4, 5, 6, 7, 0, 1, 2, 3, 44, 0xD192E819D6EF5218), + roundParam512(3, 4, 5, 6, 7, 0, 1, 2, 45, 0xD69906245565A910), + roundParam512(2, 3, 4, 5, 6, 7, 0, 1, 46, 0xF40E35855771202A), + roundParam512(1, 2, 3, 4, 5, 6, 7, 0, 47, 0x106AA07032BBD1B8), + roundParam512(0, 1, 2, 3, 4, 5, 6, 7, 48, 0x19A4C116B8D2D0C8), + roundParam512(7, 0, 1, 2, 3, 4, 5, 6, 49, 0x1E376C085141AB53), + roundParam512(6, 7, 0, 1, 2, 3, 4, 5, 50, 0x2748774CDF8EEB99), + roundParam512(5, 6, 7, 0, 1, 2, 3, 4, 51, 0x34B0BCB5E19B48A8), + roundParam512(4, 5, 6, 7, 0, 1, 2, 3, 52, 0x391C0CB3C5C95A63), + roundParam512(3, 4, 5, 6, 7, 0, 1, 2, 53, 0x4ED8AA4AE3418ACB), + roundParam512(2, 3, 4, 5, 6, 7, 0, 1, 54, 0x5B9CCA4F7763E373), + roundParam512(1, 2, 3, 4, 5, 6, 7, 0, 55, 0x682E6FF3D6B2B8A3), + roundParam512(0, 1, 2, 3, 4, 5, 6, 7, 56, 0x748F82EE5DEFB2FC), + roundParam512(7, 0, 1, 2, 3, 4, 5, 6, 57, 0x78A5636F43172F60), + roundParam512(6, 7, 0, 1, 2, 3, 4, 5, 58, 0x84C87814A1F0AB72), + roundParam512(5, 6, 7, 0, 1, 2, 3, 4, 59, 0x8CC702081A6439EC), + roundParam512(4, 5, 6, 7, 0, 1, 2, 3, 60, 0x90BEFFFA23631E28), + roundParam512(3, 4, 5, 6, 7, 0, 1, 2, 61, 0xA4506CEBDE82BDE9), + roundParam512(2, 3, 4, 5, 6, 7, 0, 1, 62, 0xBEF9A3F7B2C67915), + roundParam512(1, 2, 3, 4, 5, 6, 7, 0, 63, 0xC67178F2E372532B), + roundParam512(0, 1, 2, 3, 4, 5, 6, 7, 64, 0xCA273ECEEA26619C), + roundParam512(7, 0, 1, 2, 3, 4, 5, 6, 65, 0xD186B8C721C0C207), + roundParam512(6, 7, 0, 1, 2, 3, 4, 5, 66, 0xEADA7DD6CDE0EB1E), + roundParam512(5, 6, 7, 0, 1, 2, 3, 4, 67, 0xF57D4F7FEE6ED178), + roundParam512(4, 5, 6, 7, 0, 1, 2, 3, 68, 0x06F067AA72176FBA), + roundParam512(3, 4, 5, 6, 7, 0, 1, 2, 69, 0x0A637DC5A2C898A6), + roundParam512(2, 3, 4, 5, 6, 7, 0, 1, 70, 0x113F9804BEF90DAE), + roundParam512(1, 2, 3, 4, 5, 6, 7, 0, 71, 0x1B710B35131C471B), + roundParam512(0, 1, 2, 3, 4, 5, 6, 7, 72, 0x28DB77F523047D84), + roundParam512(7, 0, 1, 2, 3, 4, 5, 6, 73, 0x32CAAB7B40C72493), + roundParam512(6, 7, 0, 1, 2, 3, 4, 5, 74, 0x3C9EBE0A15C9BEBC), + roundParam512(5, 6, 7, 0, 1, 2, 3, 4, 75, 0x431D67C49C100D4C), + roundParam512(4, 5, 6, 7, 0, 1, 2, 3, 76, 0x4CC5D4BECB3E42B6), + roundParam512(3, 4, 5, 6, 7, 0, 1, 2, 77, 0x597F299CFC657E2A), + roundParam512(2, 3, 4, 5, 6, 7, 0, 1, 78, 0x5FCB6FAB3AD6FAEC), + roundParam512(1, 2, 3, 4, 5, 6, 7, 0, 79, 0x6C44198C4A475817), }; inline for (round0) |r| { v[r.h] = v[r.h] +% (math.rotr(u64, v[r.e], @as(u64, 14)) ^ math.rotr(u64, v[r.e], @as(u64, 18)) ^ math.rotr(u64, v[r.e], @as(u64, 41))) +% (v[r.g] ^ (v[r.e] & (v[r.f] ^ v[r.g]))) +% r.k +% s[r.i]; diff --git a/lib/std/crypto/sha3.zig b/lib/std/crypto/sha3.zig index 991eb3862c..3aecf25e5b 100644 --- a/lib/std/crypto/sha3.zig +++ b/lib/std/crypto/sha3.zig @@ -29,7 +29,7 @@ fn Keccak(comptime bits: usize, comptime delim: u8) type { return Self{ .s = [_]u8{0} ** 200, .offset = 0, .rate = 200 - (bits / 4) }; } - pub fn hash(b: []const u8, out: []u8, options: Options) void { + pub fn hash(b: []const u8, out: *[digest_length]u8, options: Options) void { var d = Self.init(options); d.update(b); d.final(out); @@ -46,7 +46,7 @@ fn Keccak(comptime bits: usize, comptime delim: u8) type { for (d.s[offset .. offset + rate]) |*r, i| r.* ^= b[ip..][i]; - keccak_f(1600, d.s[0..]); + keccakF(1600, &d.s); ip += rate; len -= rate; @@ -60,12 +60,12 @@ fn Keccak(comptime bits: usize, comptime delim: u8) type { d.offset = offset + len; } - pub fn final(d: *Self, out: []u8) void { + pub fn final(d: *Self, out: *[digest_length]u8) void { // padding d.s[d.offset] ^= delim; d.s[d.rate - 1] ^= 0x80; - keccak_f(1600, d.s[0..]); + keccakF(1600, &d.s); // squeeze var op: usize = 0; @@ -73,7 +73,7 @@ fn Keccak(comptime bits: usize, comptime delim: u8) type { while (len >= d.rate) { mem.copy(u8, out[op..], d.s[0..d.rate]); - keccak_f(1600, d.s[0..]); + keccakF(1600, &d.s); op += d.rate; len -= d.rate; } @@ -104,9 +104,7 @@ const M5 = [_]usize{ 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, }; -fn keccak_f(comptime F: usize, d: []u8) void { - debug.assert(d.len == F / 8); - +fn keccakF(comptime F: usize, d: *[F / 8]u8) void { const B = F / 25; const no_rounds = comptime x: { break :x 12 + 2 * math.log2(B); diff --git a/lib/std/crypto/siphash.zig b/lib/std/crypto/siphash.zig index ae059b2567..5dfd2bf326 100644 --- a/lib/std/crypto/siphash.zig +++ b/lib/std/crypto/siphash.zig @@ -51,8 +51,9 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round return struct { const Self = @This(); - const digest_size = 64; - const block_size = 64; + const block_length = 64; + const digest_length = 64; + const key_length = 16; v0: u64, v1: u64, @@ -60,9 +61,7 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round v3: u64, msg_len: u8, - pub fn init(key: []const u8) Self { - assert(key.len >= 16); - + pub fn init(key: *const [key_length]u8) Self { const k0 = mem.readIntLittle(u64, key[0..8]); const k1 = mem.readIntLittle(u64, key[8..16]); @@ -86,7 +85,7 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round var off: usize = 0; while (off < b.len) : (off += 8) { - @call(.{ .modifier = .always_inline }, self.round, .{b[off .. off + 8]}); + @call(.{ .modifier = .always_inline }, self.round, .{b[off..][0..8].*}); } self.msg_len +%= @truncate(u8, b.len); @@ -100,7 +99,7 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round var buf = [_]u8{0} ** 8; mem.copy(u8, buf[0..], b[0..]); buf[7] = self.msg_len; - self.round(buf[0..]); + self.round(buf); if (T == u128) { self.v2 ^= 0xee; @@ -132,9 +131,7 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round return (@as(u128, b2) << 64) | b1; } - fn round(self: *Self, b: []const u8) void { - assert(b.len == 8); - + fn round(self: *Self, b: [8]u8) void { const m = mem.readIntLittle(u64, b[0..8]); self.v3 ^= m; @@ -165,7 +162,7 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round d.v2 = math.rotl(u64, d.v2, @as(u64, 32)); } - pub fn hash(msg: []const u8, key: []const u8) T { + pub fn hash(msg: []const u8, key: *const [key_length]u8) T { const aligned_len = msg.len - (msg.len % 8); var c = Self.init(key); @call(.{ .modifier = .always_inline }, c.update, .{msg[0..aligned_len]}); @@ -181,7 +178,7 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize) return struct { const State = SipHashStateless(T, c_rounds, d_rounds); const Self = @This(); - pub const minimum_key_length = 16; + pub const key_length = 16; pub const mac_length = @sizeOf(T); pub const block_length = 8; @@ -190,7 +187,7 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize) buf_len: usize, /// Initialize a state for a SipHash function - pub fn init(key: []const u8) Self { + pub fn init(key: *const [key_length]u8) Self { return Self{ .state = State.init(key), .buf = undefined, @@ -219,16 +216,15 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize) /// Return an authentication tag for the current state /// Assumes `out` is less than or equal to `mac_length`. - pub fn final(self: *Self, out: []u8) void { - std.debug.assert(out.len <= mac_length); - mem.writeIntLittle(T, out[0..mac_length], self.state.final(self.buf[0..self.buf_len])); + pub fn final(self: *Self, out: *[mac_length]u8) void { + mem.writeIntLittle(T, out, self.state.final(self.buf[0..self.buf_len])); } /// Return an authentication tag for a message and a key - pub fn create(out: []u8, msg: []const u8, key: []const u8) void { + pub fn create(out: *[mac_length]u8, msg: []const u8, key: *const [key_length]u8) void { var ctx = Self.init(key); ctx.update(msg); - ctx.final(out[0..]); + ctx.final(out); } /// Return an authentication tag for the current state, as an integer @@ -237,7 +233,7 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize) } /// Return an authentication tag for a message and a key, as an integer - pub fn toInt(msg: []const u8, key: []const u8) T { + pub fn toInt(msg: []const u8, key: *const [key_length]u8) T { return State.hash(msg, key); } }; diff --git a/lib/std/crypto/test.zig b/lib/std/crypto/test.zig index 1655be7075..692e331e39 100644 --- a/lib/std/crypto/test.zig +++ b/lib/std/crypto/test.zig @@ -8,18 +8,18 @@ const testing = std.testing; const fmt = std.fmt; // Hash using the specified hasher `H` asserting `expected == H(input)`. -pub fn assertEqualHash(comptime Hasher: anytype, comptime expected: []const u8, input: []const u8) void { - var h: [expected.len / 2]u8 = undefined; - Hasher.hash(input, h[0..], .{}); +pub fn assertEqualHash(comptime Hasher: anytype, comptime expected_hex: *const [Hasher.digest_length * 2:0]u8, input: []const u8) void { + var h: [Hasher.digest_length]u8 = undefined; + Hasher.hash(input, &h, .{}); - assertEqual(expected, &h); + assertEqual(expected_hex, &h); } -// Assert `expected` == `input` where `input` is a bytestring. -pub fn assertEqual(comptime expected: []const u8, input: []const u8) void { - var expected_bytes: [expected.len / 2]u8 = undefined; +// Assert `expected` == hex(`input`) where `input` is a bytestring +pub fn assertEqual(comptime expected_hex: [:0]const u8, input: []const u8) void { + var expected_bytes: [expected_hex.len / 2]u8 = undefined; for (expected_bytes) |*r, i| { - r.* = fmt.parseInt(u8, expected[2 * i .. 2 * i + 2], 16) catch unreachable; + r.* = fmt.parseInt(u8, expected_hex[2 * i .. 2 * i + 2], 16) catch unreachable; } testing.expectEqualSlices(u8, &expected_bytes, input); diff --git a/src/Cache.zig b/src/Cache.zig index 1adf72d16f..299eb0cfa2 100644 --- a/src/Cache.zig +++ b/src/Cache.zig @@ -35,7 +35,7 @@ const manifest_file_size_max = 50 * 1024 * 1024; pub const Hasher = crypto.auth.siphash.SipHash128(1, 3); /// Initial state, that can be copied. -pub const hasher_init: Hasher = Hasher.init(&[_]u8{0} ** Hasher.minimum_key_length); +pub const hasher_init: Hasher = Hasher.init(&[_]u8{0} ** Hasher.key_length); pub const File = struct { path: ?[]const u8, @@ -600,7 +600,7 @@ pub fn writeSmallFile(dir: fs.Dir, sub_path: []const u8, data: []const u8) !void } } -fn hashFile(file: fs.File, bin_digest: []u8) !void { +fn hashFile(file: fs.File, bin_digest: *[Hasher.mac_length]u8) !void { var buf: [1024]u8 = undefined; var hasher = hasher_init;