feature. See also
. The project being documented here (as the example) is the Zig library itself.
soft.KeySchedule
fn KeySchedule(comptime Aes: type) type
File
Code
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_length / 4;
round_keys: [rounds + 1]Block,
fn expandKey(key: [key_length]u8) Self {
const subw = struct {
fn func(w: u32) u32 {
const x = sbox_lookup(&sbox_key_schedule, @as(u8, @truncate(w)), @as(u8, @truncate(w >> 8)), @as(u8, @truncate(w >> 16)), @as(u8, @truncate(w >> 24)));
return mem.readInt(u32, &x, .little);
}
}.func;
var round_keys: [rounds + 1]Block = undefined;
comptime var i: usize = 0;
inline while (i < words_in_key) : (i += 1) {
round_keys[i / 4].repr[i % 4] = mem.readInt(u32, key[4 * i ..][0..4], .big);
}
inline while (i < round_keys.len * 4) : (i += 1) {
var t = round_keys[(i - 1) / 4].repr[(i - 1) % 4];
if (i % words_in_key == 0) {
t = subw(std.math.rotl(u32, t, 8)) ^ (@as(u32, powx[i / words_in_key - 1]) << 24);
} else if (words_in_key > 6 and i % words_in_key == 4) {
t = subw(t);
}
round_keys[i / 4].repr[i % 4] = round_keys[(i - words_in_key) / 4].repr[(i - words_in_key) % 4] ^ t;
}
i = 0;
inline while (i < round_keys.len * 4) : (i += 1) {
round_keys[i / 4].repr[i % 4] = @byteSwap(round_keys[i / 4].repr[i % 4]);
}
return Self{ .round_keys = round_keys };
}
pub fn invert(key_schedule: Self) Self {
const round_keys = &key_schedule.round_keys;
var inv_round_keys: [rounds + 1]Block = undefined;
const total_words = 4 * round_keys.len;
var i: usize = 0;
while (i < total_words) : (i += 4) {
const ei = total_words - i - 4;
comptime var j: usize = 0;
inline while (j < 4) : (j += 1) {
var rk = round_keys[(ei + j) / 4].repr[(ei + j) % 4];
if (i > 0 and i + 4 < total_words) {
const x = sbox_lookup(&sbox_key_schedule, @as(u8, @truncate(rk >> 24)), @as(u8, @truncate(rk >> 16)), @as(u8, @truncate(rk >> 8)), @as(u8, @truncate(rk)));
const y = table_lookup(&table_decrypt, x[3], x[2], x[1], x[0]);
rk = y[0] ^ y[1] ^ y[2] ^ y[3];
}
inv_round_keys[(i + j) / 4].repr[(i + j) % 4] = rk;
}
}
return Self{ .round_keys = inv_round_keys };
}
};
}