nixfiles/libs/aes/lib/key/default.nix
Sebastian Walz 860d31cee1
Tohu vaBohu
2023-04-21 00:22:52 +02:00

160 lines
6.6 KiB
Nix

{ core, helpers, serde, ... }:
let
inherit(core) bool debug integer list set string type;
inherit(helpers) formatColumns getRoundConstant repeat rotateColumn substituteColumn toBuffer;
inherit(serde) packDWord unpackDWord;
expandRoundKey
= length:
key:
round:
let
prevKey = list.foot key;
finalLine
= let
afterRotWord = rotateColumn (unpackDWord prevKey.final);
afterSubWord = packDWord (substituteColumn afterRotWord);
afterXor = integer.xor roundConstant afterSubWord;
roundConstant = getRoundConstant round;
in
debug.debug "expandRoundKey"
{
text = "Final Coulumn";
data
= {
inherit afterSubWord afterXor roundConstant;
afterRotWord = packDWord afterRotWord;
before = prevKey.final;
};
hex = true;
}
afterXor;
dword0 = integer.xor prevKey.dword0 finalLine;
dword1 = integer.xor prevKey.dword1 dword0;
dword2 = integer.xor prevKey.dword2 dword1;
dword3 = integer.xor prevKey.dword3 dword2;
dword3'
= bool.select (length > 6)
(packDWord (substituteColumn (unpackDWord dword3)))
dword3;
dword4 = integer.xor prevKey.dword4 dword3';
dword5 = integer.xor prevKey.dword5 dword4;
dword6 = integer.xor prevKey.dword6 dword5;
dword7 = integer.xor prevKey.dword7 dword6;
final
= list.get
[ dword0 dword1 dword2 dword3 dword4 dword5 dword6 dword7 ]
(length - 1);
in
key
++ (
debug.debug "expandRoundKey"
{
text = "Round ${string round}";
data
= { inherit dword0 dword1 dword2 dword3 final; }
// (set.ifOrEmpty (length > 4) { inherit dword4; })
// (set.ifOrEmpty (length > 5) { inherit dword5; })
// (set.ifOrEmpty (length > 6) { inherit dword6; })
// (set.ifOrEmpty (length > 7) { inherit dword7; });
hex = true;
}
[ { inherit dword0 dword1 dword2 dword3 dword4 dword5 dword6 dword7 final; } ]
);
from
= { length, rounds }:
key:
let
key' = toBuffer length' key;
get = index: (list.get key' index).dword;
length' = length / 32;
roundKeys
= repeat ((rounds * 4 + length' - 1) / length' - 1)
[
{
dword0 = get 0;
dword1 = get 1;
dword2 = get 2;
dword3 = get 3;
dword4 = get 4;
dword5 = get 5;
dword6 = get 6;
dword7 = get 7;
final = get (length' - 1);
}
]
(
debug.debug "expandKey"
{
text = "Key (${string length'})";
data = list.generate get length';
hex = true;
}
expandRoundKey length'
);
roundKeys'
= list.concatMap
(
{ dword0, dword1, dword2, dword3, dword4, dword5, dword6, dword7, final }:
[ (unpackDWord dword0) ]
++ (list.ifOrEmpty (length' > 1) (unpackDWord dword1))
++ (list.ifOrEmpty (length' > 2) (unpackDWord dword2))
++ (list.ifOrEmpty (length' > 3) (unpackDWord dword3))
++ (list.ifOrEmpty (length' > 4) (unpackDWord dword4))
++ (list.ifOrEmpty (length' > 5) (unpackDWord dword5))
++ (list.ifOrEmpty (length' > 6) (unpackDWord dword6))
++ (list.ifOrEmpty (length' > 7) (unpackDWord dword7))
)
roundKeys;
columns = list.generate (list.get roundKeys') (rounds*4);
in
AESkey.instanciate
{
inherit columns length rounds;
inherit
(
list.fold
(
{ count, roundKeys, state }:
column:
let
state' = state ++ [ column ];
in
if count != 0
then
{
inherit roundKeys;
count = count - 1;
state = state';
}
else
{
count = 3;
roundKeys = roundKeys ++ [ state' ];
state = [];
}
)
{
count = 3;
roundKeys = [];
state = [];
}
columns
)
roundKeys;
};
AESkey
= type "AESkey"
{
inherit from;
from128bit = from { length = 128; rounds = 11; };
from192bit = from { length = 192; rounds = 13; };
from256bit = from { length = 256; rounds = 15; };
};
in
AESkey // { inherit AESkey; }