-- S.MG, 2018 package body SMG_Keccak is function Theta(Input : in State) return State is Output : State; C : Plane; W : ZWord; begin for X in XYCoord loop C(X) := Input(X, 0); for Y in 1..XYCoord'Last loop C(X) := C(X) xor Input(X, Y); end loop; end loop; for X in XYCoord loop W := C(X-1) xor Rotate_Left(C(X+1), 1); for Y in XYCoord loop Output(X,Y) := Input(X,Y) xor W; end loop; end loop; return Output; end Theta; function Rho(Input : in State) return State is Output : State; X, Y, Old_Y : XYCoord; begin Output(0,0) := Input(0,0); X := 1; Y := 0; for T in 0..23 loop Output(X, Y) := Rotate_Left(Input(X,Y), ((T+1)*(T+2)/2) mod Z_Length); Old_Y := Y; Y := 2*X + 3*Y; X := Old_Y; end loop; return Output; end rho; function Pi(Input : in State) return State is Output: State; begin for X in XYCoord loop for Y in XYCoord loop Output(Y, 2*X + 3*Y) := Input(X, Y); end loop; end loop; return Output; end pi; function Chi(Input : in State) return State is Output: State; begin for Y in XYCoord loop for X in XYCoord loop Output(X, Y) := Input(X, Y) xor ( (not Input(X + 1, Y)) and Input(X + 2, Y) ); end loop; end loop; return Output; end chi; function Iota(Round_Const : in ZWord; Input : in State) return State is Output: State; begin Output := Input; Output(0,0) := Input(0,0) xor Round_Const; return Output; end iota; function Keccak_Function(Input: in State) return State is Output: State; begin Output := Input; for I in Round_Index loop Output := Iota(RC(I), Chi(Pi(Rho(Theta(Output))))); end loop; return Output; end Keccak_Function; end SMG_Keccak;