Sebastian Walz 860d31cee1
Tohu vaBohu
2023-04-21 00:22:52 +02:00

174 lines
7.5 KiB
Nix

{ core, helpers, key, serde, ... }:
let
inherit(core) bool debug integer list path;
inherit(helpers) addRoundKey formatColumns unshiftRows4andUnsubstitute toBuffer;
inherit(key) AESkey;
inherit(serde) packDWordBuffer unpackDWord;
unmixColumns
= list.map
(
{ byte0, byte1, byte2, byte3, ... }:
let
getH = x: bool.select (x > 127) 27 0;
byte0' = integer.xor (integer.and (byte0 * 2) 255) (getH byte0);
byte1' = integer.xor (integer.and (byte1 * 2) 255) (getH byte1);
byte2' = integer.xor (integer.and (byte2 * 2) 255) (getH byte2);
byte3' = integer.xor (integer.and (byte3 * 2) 255) (getH byte3);
byte0'' = integer.xor (integer.and (byte0' * 2) 255) (getH byte0');
byte1'' = integer.xor (integer.and (byte1' * 2) 255) (getH byte1');
byte2'' = integer.xor (integer.and (byte2' * 2) 255) (getH byte2');
byte3'' = integer.xor (integer.and (byte3' * 2) 255) (getH byte3');
byte0''' = integer.xor (integer.and (byte0'' * 2) 255) (getH byte0'');
byte1''' = integer.xor (integer.and (byte1'' * 2) 255) (getH byte1'');
byte2''' = integer.xor (integer.and (byte2'' * 2) 255) (getH byte2'');
byte3''' = integer.xor (integer.and (byte3'' * 2) 255) (getH byte3'');
common = integer.xor (integer.xor byte0''' byte1''') (integer.xor byte2''' byte3''');
fold = list.fold integer.xor common;
in
{
byte0 = fold [ byte0'' byte0' byte1' byte1 byte2'' byte2 byte3 ];
byte1 = fold [ byte0 byte1'' byte1' byte2' byte2 byte3'' byte3 ];
byte2 = fold [ byte0'' byte0 byte1 byte2'' byte2' byte3' byte3 ];
byte3 = fold [ byte0' byte0 byte1'' byte1 byte2 byte3'' byte3' ];
}
);
slowRoundDecryption
= state:
let
state' = unmixColumns state;
state'' = unshiftRows4andUnsubstitute state';
in
debug.debug "slowRoundDecryption"
{
data
= {
state = formatColumns state;
state' = formatColumns state';
state'' = formatColumns state'';
};
nice = true;
}
state'';
# does not work, because it needs the key-inverse.
fastRoundDecryption
= let
td0 = path.import ./td0.nix;
td1 = path.import ./td1.nix;
td2 = path.import ./td2.nix;
td3 = path.import ./td3.nix;
subTD0 = list.get td0;
subTD1 = list.get td1;
subTD2 = list.get td2;
subTD3 = list.get td3;
in
state:
let
column0 = list.get state 0;
column1 = list.get state 1;
column2 = list.get state 2;
column3 = list.get state 3;
column0'
= unpackDWord
(
integer.xor
(integer.xor (subTD0 column0.byte0) (subTD1 column3.byte1))
(integer.xor (subTD2 column2.byte2) (subTD3 column1.byte3))
);
column1'
= unpackDWord
(
integer.xor
(integer.xor (subTD0 column1.byte0) (subTD1 column0.byte1))
(integer.xor (subTD2 column3.byte2) (subTD3 column2.byte3))
);
column2'
= unpackDWord
(
integer.xor
(integer.xor (subTD0 column2.byte0) (subTD1 column1.byte2))
(integer.xor (subTD2 column0.byte2) (subTD3 column3.byte3))
);
column3'
= unpackDWord
(
integer.xor
(integer.xor (subTD0 column3.byte0) (subTD1 column2.byte1))
(integer.xor (subTD2 column1.byte2) (subTD3 column0.byte3))
);
state' = [ column0' column1' column2' column3' ];
in
debug.debug "fastRoundDecryption"
{
data
= {
state = formatColumns state;
state' = formatColumns state';
};
hex = true;
nice = true;
}
state';
decrypt#: AESkey -> [ u8 ]
= applyRoundDecryption:
{ roundKeys, ... }:
message:
let
message' = toBuffer 4 message;
applyRoundDecryption'
= state:
roundKey:
let
state' = addRoundKey state roundKey;
in
debug.info "applyRoundDecryption'"
{
data
= {
state = formatColumns state;
state' = formatColumns state';
roundKey = formatColumns roundKey;
};
nice = true;
}
(applyRoundDecryption state');
firstRoundKey = list.head roundKeys;
lastRoundKey = list.foot roundKeys;
roundKeys' = list.body (list.tail roundKeys);
state = unshiftRows4andUnsubstitute (addRoundKey message' lastRoundKey);
state'
= list.foldReversed
applyRoundDecryption'
state
roundKeys';
in
debug.debug "decrypt"
{
data
= {
state = formatColumns state;
state' = formatColumns state';
};
hex = true;
nice = true;
}
addRoundKey state' firstRoundKey;
in
{
__functor = _: decrypt;
#fast = key: decrypt fastRoundDecryption (AESkey.expect key);
slow = key: decrypt slowRoundDecryption (AESkey.expect key);
inherit unmixColumns;
}