Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

keccakP

Apply Keccak-p[1600,12] to a single state (byte representation)

kangarootwelve.keccakP
fn keccakP(state: *[200]u8) void

File

lib/std/crypto/kangarootwelve.zig:320

Code

fn keccakP(state: *[200]u8) void {
    @setEvalBranchQuota(10000);
    var lanes: [5][5]u64 = undefined;

    // Load state into lanes
    inline for (0..5) |x| {
        inline for (0..5) |y| {
            lanes[x][y] = load64(state[8 * (x + 5 * y) ..]);
        }
    }

    // Apply 12 rounds
    var round: usize = 0;
    while (round < 12) : (round += 2) {
        inline for (0..2) |i| {
            // θ
            var C: [5]u64 = undefined;
            inline for (0..5) |x| {
                C[x] = lanes[x][0] ^ lanes[x][1] ^ lanes[x][2] ^ lanes[x][3] ^ lanes[x][4];
            }
            var D: [5]u64 = undefined;
            inline for (0..5) |x| {
                D[x] = C[(x + 4) % 5] ^ std.math.rotl(u64, C[(x + 1) % 5], 1);
            }
            inline for (0..5) |x| {
                inline for (0..5) |y| {
                    lanes[x][y] ^= D[x];
                }
            }

            // ρ and π
            var current = lanes[1][0];
            var px: usize = 1;
            var py: usize = 0;
            inline for (0..24) |t| {
                const temp = lanes[py][(2 * px + 3 * py) % 5];
                const rot_amount = ((t + 1) * (t + 2) / 2) % 64;
                lanes[py][(2 * px + 3 * py) % 5] = std.math.rotl(u64, current, @as(u6, @intCast(rot_amount)));
                current = temp;
                const temp_x = py;
                py = (2 * px + 3 * py) % 5;
                px = temp_x;
            }

            // χ
            inline for (0..5) |y| {
                const T = [5]u64{ lanes[0][y], lanes[1][y], lanes[2][y], lanes[3][y], lanes[4][y] };
                inline for (0..5) |x| {
                    lanes[x][y] = T[x] ^ (~T[(x + 1) % 5] & T[(x + 2) % 5]);
                }
            }

            // ι
            lanes[0][0] ^= RC[round + i];
        }
    }

    // Store lanes back to state
    inline for (0..5) |x| {
        inline for (0..5) |y| {
            store64(lanes[x][y], state[8 * (x + 5 * y) ..]);
        }
    }
}