diff options
| author | Andrea Orru <andrea@orru.io> | 2018-08-06 01:43:19 -0400 |
|---|---|---|
| committer | Andrea Orru <andrea@orru.io> | 2018-08-06 01:43:19 -0400 |
| commit | d2f5e57b68da0b16e5789ca19045ccbcb4ecfa8d (patch) | |
| tree | e9fa3caec533a0d1e2b434868b2fde1f9240e5c8 /std/crypto/sha3.zig | |
| parent | 06614b3fa09954464c2e2f32756cacedc178a282 (diff) | |
| parent | 63a23e848a62d5f167f8d5478de9766cb24aa6eb (diff) | |
| download | zig-d2f5e57b68da0b16e5789ca19045ccbcb4ecfa8d.tar.gz zig-d2f5e57b68da0b16e5789ca19045ccbcb4ecfa8d.zip | |
Merge branch 'master' into zen_stdlib
Diffstat (limited to 'std/crypto/sha3.zig')
| -rw-r--r-- | std/crypto/sha3.zig | 281 |
1 files changed, 180 insertions, 101 deletions
diff --git a/std/crypto/sha3.zig b/std/crypto/sha3.zig index f92f56d68f..ae02d7a482 100644 --- a/std/crypto/sha3.zig +++ b/std/crypto/sha3.zig @@ -10,148 +10,228 @@ pub const Sha3_256 = Keccak(256, 0x06); pub const Sha3_384 = Keccak(384, 0x06); pub const Sha3_512 = Keccak(512, 0x06); -fn Keccak(comptime bits: usize, comptime delim: u8) type { return struct { - const Self = this; - const block_size = 200; - const digest_size = bits / 8; - - s: [200]u8, - offset: usize, - rate: usize, - - pub fn init() Self { - var d: Self = undefined; - d.reset(); - return d; - } +fn Keccak(comptime bits: usize, comptime delim: u8) type { + return struct { + const Self = this; + const block_size = 200; + const digest_size = bits / 8; + + s: [200]u8, + offset: usize, + rate: usize, + + pub fn init() Self { + var d: Self = undefined; + d.reset(); + return d; + } - pub fn reset(d: &Self) void { - mem.set(u8, d.s[0..], 0); - d.offset = 0; - d.rate = 200 - (bits / 4); - } + pub fn reset(d: *Self) void { + mem.set(u8, d.s[0..], 0); + d.offset = 0; + d.rate = 200 - (bits / 4); + } - pub fn hash(b: []const u8, out: []u8) void { - var d = Self.init(); - d.update(b); - d.final(out); - } + pub fn hash(b: []const u8, out: []u8) void { + var d = Self.init(); + d.update(b); + d.final(out); + } - pub fn update(d: &Self, b: []const u8) void { - var ip: usize = 0; - var len = b.len; - var rate = d.rate - d.offset; - var offset = d.offset; + pub fn update(d: *Self, b: []const u8) void { + var ip: usize = 0; + var len = b.len; + var rate = d.rate - d.offset; + var offset = d.offset; - // absorb - while (len >= rate) { - for (d.s[offset .. offset + rate]) |*r, i| - *r ^= b[ip..][i]; + // absorb + while (len >= rate) { + for (d.s[offset .. offset + rate]) |*r, i| + r.* ^= b[ip..][i]; - keccak_f(1600, d.s[0..]); + keccak_f(1600, d.s[0..]); - ip += rate; - len -= rate; - rate = d.rate; - offset = 0; - } + ip += rate; + len -= rate; + rate = d.rate; + offset = 0; + } - for (d.s[offset .. offset + len]) |*r, i| - *r ^= b[ip..][i]; + for (d.s[offset .. offset + len]) |*r, i| + r.* ^= b[ip..][i]; - d.offset = offset + len; - } + d.offset = offset + len; + } - pub fn final(d: &Self, out: []u8) void { - // padding - d.s[d.offset] ^= delim; - d.s[d.rate - 1] ^= 0x80; + pub fn final(d: *Self, out: []u8) void { + // padding + d.s[d.offset] ^= delim; + d.s[d.rate - 1] ^= 0x80; - keccak_f(1600, d.s[0..]); + keccak_f(1600, d.s[0..]); - // squeeze - var op: usize = 0; - var len: usize = bits / 8; + // squeeze + var op: usize = 0; + var len: usize = bits / 8; - while (len >= d.rate) { - mem.copy(u8, out[op..], d.s[0..d.rate]); - keccak_f(1600, d.s[0..]); - op += d.rate; - len -= d.rate; + while (len >= d.rate) { + mem.copy(u8, out[op..], d.s[0..d.rate]); + keccak_f(1600, d.s[0..]); + op += d.rate; + len -= d.rate; + } + + mem.copy(u8, out[op..], d.s[0..len]); } + }; +} - mem.copy(u8, out[op..], d.s[0..len]); - } -};} - -const RC = []const u64 { - 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000, - 0x000000000000808b, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009, - 0x000000000000008a, 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, - 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 0x8000000000008003, - 0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a, - 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008, +const RC = []const u64{ + 0x0000000000000001, + 0x0000000000008082, + 0x800000000000808a, + 0x8000000080008000, + 0x000000000000808b, + 0x0000000080000001, + 0x8000000080008081, + 0x8000000000008009, + 0x000000000000008a, + 0x0000000000000088, + 0x0000000080008009, + 0x000000008000000a, + 0x000000008000808b, + 0x800000000000008b, + 0x8000000000008089, + 0x8000000000008003, + 0x8000000000008002, + 0x8000000000000080, + 0x000000000000800a, + 0x800000008000000a, + 0x8000000080008081, + 0x8000000000008080, + 0x0000000080000001, + 0x8000000080008008, }; -const ROTC = []const usize { - 1, 3, 6, 10, 15, 21, 28, 36, - 45, 55, 2, 14, 27, 41, 56, 8, - 25, 43, 62, 18, 39, 61, 20, 44 +const ROTC = []const usize{ + 1, + 3, + 6, + 10, + 15, + 21, + 28, + 36, + 45, + 55, + 2, + 14, + 27, + 41, + 56, + 8, + 25, + 43, + 62, + 18, + 39, + 61, + 20, + 44, }; -const PIL = []const usize { - 10, 7, 11, 17, 18, 3, 5, 16, - 8, 21, 24, 4, 15, 23, 19, 13, - 12, 2, 20, 14, 22, 9, 6, 1 +const PIL = []const usize{ + 10, + 7, + 11, + 17, + 18, + 3, + 5, + 16, + 8, + 21, + 24, + 4, + 15, + 23, + 19, + 13, + 12, + 2, + 20, + 14, + 22, + 9, + 6, + 1, }; -const M5 = []const usize { - 0, 1, 2, 3, 4, 0, 1, 2, 3, 4 +const M5 = []const 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); const B = F / 25; - const no_rounds = comptime x: { break :x 12 + 2 * math.log2(B); }; + const no_rounds = comptime x: { + break :x 12 + 2 * math.log2(B); + }; - var s = []const u64 {0} ** 25; - var t = []const u64 {0} ** 1; - var c = []const u64 {0} ** 5; + var s = []const u64{0} ** 25; + var t = []const u64{0} ** 1; + var c = []const u64{0} ** 5; for (s) |*r, i| { - *r = mem.readIntLE(u64, d[8*i .. 8*i + 8]); + r.* = mem.readIntLE(u64, d[8 * i .. 8 * i + 8]); } comptime var x: usize = 0; comptime var y: usize = 0; for (RC[0..no_rounds]) |round| { // theta - x = 0; inline while (x < 5) : (x += 1) { - c[x] = s[x] ^ s[x+5] ^ s[x+10] ^ s[x+15] ^ s[x+20]; + x = 0; + inline while (x < 5) : (x += 1) { + c[x] = s[x] ^ s[x + 5] ^ s[x + 10] ^ s[x + 15] ^ s[x + 20]; } - x = 0; inline while (x < 5) : (x += 1) { - t[0] = c[M5[x+4]] ^ math.rotl(u64, c[M5[x+1]], usize(1)); - y = 0; inline while (y < 5) : (y += 1) { - s[x + y*5] ^= t[0]; + x = 0; + inline while (x < 5) : (x += 1) { + t[0] = c[M5[x + 4]] ^ math.rotl(u64, c[M5[x + 1]], usize(1)); + y = 0; + inline while (y < 5) : (y += 1) { + s[x + y * 5] ^= t[0]; } } // rho+pi t[0] = s[1]; - x = 0; inline while (x < 24) : (x += 1) { + x = 0; + inline while (x < 24) : (x += 1) { c[0] = s[PIL[x]]; s[PIL[x]] = math.rotl(u64, t[0], ROTC[x]); t[0] = c[0]; } // chi - y = 0; inline while (y < 5) : (y += 1) { - x = 0; inline while (x < 5) : (x += 1) { - c[x] = s[x + y*5]; + y = 0; + inline while (y < 5) : (y += 1) { + x = 0; + inline while (x < 5) : (x += 1) { + c[x] = s[x + y * 5]; } - x = 0; inline while (x < 5) : (x += 1) { - s[x + y*5] = c[x] ^ (~c[M5[x+1]] & c[M5[x+2]]); + x = 0; + inline while (x < 5) : (x += 1) { + s[x + y * 5] = c[x] ^ (~c[M5[x + 1]] & c[M5[x + 2]]); } } @@ -160,11 +240,10 @@ fn keccak_f(comptime F: usize, d: []u8) void { } for (s) |r, i| { - mem.writeInt(d[8*i .. 8*i + 8], r, builtin.Endian.Little); + mem.writeInt(d[8 * i .. 8 * i + 8], r, builtin.Endian.Little); } } - test "sha3-224 single" { htest.assertEqualHash(Sha3_224, "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7", ""); htest.assertEqualHash(Sha3_224, "e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf", "abc"); @@ -192,7 +271,7 @@ test "sha3-224 streaming" { } test "sha3-256 single" { - htest.assertEqualHash(Sha3_256, "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a" , ""); + htest.assertEqualHash(Sha3_256, "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a", ""); htest.assertEqualHash(Sha3_256, "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532", "abc"); htest.assertEqualHash(Sha3_256, "916f6061fe879741ca6469b43971dfdb28b1a32dc36cb3254e812be27aad1d18", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"); } @@ -218,7 +297,7 @@ test "sha3-256 streaming" { } test "sha3-256 aligned final" { - var block = []u8 {0} ** Sha3_256.block_size; + var block = []u8{0} ** Sha3_256.block_size; var out: [Sha3_256.digest_size]u8 = undefined; var h = Sha3_256.init(); @@ -228,7 +307,7 @@ test "sha3-256 aligned final" { test "sha3-384 single" { const h1 = "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004"; - htest.assertEqualHash(Sha3_384, h1 , ""); + htest.assertEqualHash(Sha3_384, h1, ""); const h2 = "ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25"; htest.assertEqualHash(Sha3_384, h2, "abc"); const h3 = "79407d3b5916b59c3e30b09822974791c313fb9ecc849e406f23592d04f625dc8c709b98b43b3852b337216179aa7fc7"; @@ -259,7 +338,7 @@ test "sha3-384 streaming" { test "sha3-512 single" { const h1 = "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26"; - htest.assertEqualHash(Sha3_512, h1 , ""); + htest.assertEqualHash(Sha3_512, h1, ""); const h2 = "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0"; htest.assertEqualHash(Sha3_512, h2, "abc"); const h3 = "afebb2ef542e6579c50cad06d2e578f9f8dd6881d7dc824d26360feebf18a4fa73e3261122948efcfd492e74e82e2189ed0fb440d187f382270cb455f21dd185"; @@ -289,7 +368,7 @@ test "sha3-512 streaming" { } test "sha3-512 aligned final" { - var block = []u8 {0} ** Sha3_512.block_size; + var block = []u8{0} ** Sha3_512.block_size; var out: [Sha3_512.digest_size]u8 = undefined; var h = Sha3_512.init(); |
