raw
eucrypt_ch6_kecca...    1 with SMG_Keccak; use SMG_Keccak;
eucrypt_ch6_kecca... 2 with Ada.Exceptions; use Ada.Exceptions;
eucrypt_ch6_kecca... 3 with Ada.Text_IO; use Ada.Text_IO;
eucrypt_ch6_kecca... 4 with Ada.Strings.Fixed; use Ada.Strings.Fixed;
eucrypt_ch6_kecca... 5 with Interfaces; use Interfaces;
eucrypt_ch6_kecca... 6
eucrypt_ch6_kecca... 7 procedure SMG_Keccak.Test is
eucrypt_ch6_kecca... 8 --types
eucrypt_ch6_kecca... 9 type Keccak_Perms is (None, Theta, Rho, Pi, Chi, Iota);
eucrypt_ch6_kecca... 10 type Test_Vector is array(Keccak_Perms) of State;
eucrypt_ch6_kecca... 11 type Test_Round is array(Round_Index) of Test_Vector;
eucrypt_ch6_kecca... 12
eucrypt_ch6_kecca... 13 --helper methods
eucrypt_ch6_kecca... 14
eucrypt_ch6_kecca... 15 procedure print_state(S: in State; Title: in String) is
eucrypt_ch6_kecca... 16 Hex: array(0..15) of Character := ("0123456789ABCDEF");
eucrypt_ch6_kecca... 17 Len: constant Natural := Z_Length / 4;
eucrypt_ch6_kecca... 18 HexString: String(1..Len);
eucrypt_ch6_kecca... 19 W: ZWord;
eucrypt_ch6_kecca... 20 begin
eucrypt_ch6_kecca... 21 Put_Line("---------" & Title & "---------");
eucrypt_ch6_kecca... 22 for Y in XYCoord loop
eucrypt_ch6_kecca... 23 for X in XYCoord loop
eucrypt_ch6_kecca... 24 W := S(X,Y);
eucrypt_ch6_kecca... 25 for Z in 0..Len-1 loop
eucrypt_ch6_kecca... 26 HexString(Natural(Len-Z)) := Hex(Natural(W mod 16));
eucrypt_ch6_kecca... 27 W := W / 16;
eucrypt_ch6_kecca... 28 end loop;
eucrypt_ch6_kecca... 29 Put(HexString & " ");
eucrypt_ch6_kecca... 30 end loop;
eucrypt_ch6_kecca... 31 Put_Line("");
eucrypt_ch6_kecca... 32 end loop;
eucrypt_ch6_kecca... 33 end;
eucrypt_ch6_kecca... 34
eucrypt_ch6_kecca... 35 function read_state(File: in FILE_TYPE; Oct: Positive :=8) return State is
eucrypt_ch6_kecca... 36 S: State;
eucrypt_ch6_kecca... 37 Line1: String := "0000000000000000 " &
eucrypt_ch6_kecca... 38 "0000000000000000 " &
eucrypt_ch6_kecca... 39 "0000000000000000 " &
eucrypt_ch6_kecca... 40 "0000000000000000 " &
eucrypt_ch6_kecca... 41 "0000000000000000";
eucrypt_ch6_kecca... 42 StartPos, EndPos: Positive;
eucrypt_ch6_kecca... 43 Len: Positive := Oct*2;
eucrypt_ch6_kecca... 44 begin
eucrypt_ch6_kecca... 45 for Y in XYCoord loop
eucrypt_ch6_kecca... 46 Line1 := Get_Line(File);
eucrypt_ch6_kecca... 47 StartPos := Line1'First;
eucrypt_ch6_kecca... 48 EndPos := StartPos + Len-1;
eucrypt_ch6_kecca... 49
eucrypt_ch6_kecca... 50 for X in XYCoord loop
eucrypt_ch6_kecca... 51 S(X,Y) := ZWord'value("16#" & Line1(StartPos..EndPos) & "#");
eucrypt_ch6_kecca... 52 StartPos := EndPos + 2; --one space to skip
eucrypt_ch6_kecca... 53 EndPos := StartPos + Len - 1;
eucrypt_ch6_kecca... 54 end loop;
eucrypt_ch6_kecca... 55 end loop;
eucrypt_ch6_kecca... 56 return S;
eucrypt_ch6_kecca... 57 end read_state;
eucrypt_ch6_kecca... 58
eucrypt_ch6_kecca... 59 --reads a full test round from specified file (pre-defined format)
eucrypt_ch6_kecca... 60 function read_from_file (filename : in String;
eucrypt_ch6_kecca... 61 T : out Test_Round)
eucrypt_ch6_kecca... 62 return Boolean is
eucrypt_ch6_kecca... 63 file: FILE_TYPE;
eucrypt_ch6_kecca... 64 InputMarker: String := "lanes as 64-bit words:";
eucrypt_ch6_kecca... 65 octets: Positive := 8;
eucrypt_ch6_kecca... 66 RoundNo: Round_Index;
eucrypt_ch6_kecca... 67 begin
eucrypt_ch6_kecca... 68 -- try to open the input file
eucrypt_ch6_kecca... 69 begin
eucrypt_ch6_kecca... 70 open(file, In_File, filename);
eucrypt_ch6_kecca... 71 exception
eucrypt_ch6_kecca... 72 when others =>
eucrypt_ch6_kecca... 73 Put_Line(Standard_Error,
eucrypt_ch6_kecca... 74 "Can not open the file '" & filename & "'. Does it exist?");
eucrypt_ch6_kecca... 75 return False;
eucrypt_ch6_kecca... 76 end;
eucrypt_ch6_kecca... 77
eucrypt_ch6_kecca... 78 -- find & read input state first
eucrypt_ch6_kecca... 79 RoundNo := -1;
eucrypt_ch6_kecca... 80 loop
eucrypt_ch6_kecca... 81 declare
eucrypt_ch6_kecca... 82 Line: String := Get_Line(file);
eucrypt_ch6_kecca... 83 begin
eucrypt_ch6_kecca... 84 --check if this is test data of any known kind
eucrypt_ch6_kecca... 85 if index(Line, InputMarker, 1) > 0 then
eucrypt_ch6_kecca... 86 T(0)(None) := read_state(file, octets);
eucrypt_ch6_kecca... 87 print_state(T(0)(None), "Read Input State");
eucrypt_ch6_kecca... 88 elsif index(Line, "Round ", 1) > 0 then
eucrypt_ch6_kecca... 89 RoundNo := RoundNo +1;
eucrypt_ch6_kecca... 90 elsif index(Line, "theta", 1) > 0 then
eucrypt_ch6_kecca... 91 T(RoundNo)(Theta) := read_state(file, octets);
eucrypt_ch6_kecca... 92 if (RoundNo > 0) then
eucrypt_ch6_kecca... 93 T(RoundNo)(None) := T(RoundNo-1)(Iota); -- previous state as input
eucrypt_ch6_kecca... 94 end if;
eucrypt_ch6_kecca... 95 elsif index(Line, "rho", 1) > 0 then
eucrypt_ch6_kecca... 96 T(RoundNo)(Rho) := read_state(file, octets);
eucrypt_ch6_kecca... 97 elsif index(Line, "pi", 1) > 0 then
eucrypt_ch6_kecca... 98 T(RoundNo)(Pi) := read_state(file, octets);
eucrypt_ch6_kecca... 99 elsif index(Line, "chi", 1) > 0 then
eucrypt_ch6_kecca... 100 T(RoundNo)(Chi) := read_state(file, octets);
eucrypt_ch6_kecca... 101 elsif index(Line, "iota", 1) > 0 then
eucrypt_ch6_kecca... 102 T(RoundNo)(Iota) := read_state(file, octets);
eucrypt_ch6_kecca... 103 end if;
eucrypt_ch6_kecca... 104 exit when End_Of_File(file);
eucrypt_ch6_kecca... 105 end;
eucrypt_ch6_kecca... 106 end loop;
eucrypt_ch6_kecca... 107 Close(file);
eucrypt_ch6_kecca... 108 return True;
eucrypt_ch6_kecca... 109 end read_from_file;
eucrypt_ch6_kecca... 110
eucrypt_ch6_kecca... 111 -- performs one single round of Keccak, step by step
eucrypt_ch6_kecca... 112 -- each permutation is tested separately
eucrypt_ch6_kecca... 113 -- test fails with exception raised at first output not matching expected
eucrypt_ch6_kecca... 114 procedure test_one_round(T: Test_Vector; Round: Round_Index) is
eucrypt_ch6_kecca... 115 Input: State;
eucrypt_ch6_kecca... 116 Expected: State;
eucrypt_ch6_kecca... 117 Output: State;
eucrypt_ch6_kecca... 118 Test_One_Round_Fail: Exception;
eucrypt_ch6_kecca... 119 begin
eucrypt_ch6_kecca... 120 Input := T(None);
eucrypt_ch6_kecca... 121 for I in Keccak_Perms range Theta..Iota loop
eucrypt_ch6_kecca... 122 Expected := T(I);
eucrypt_ch6_kecca... 123 case I is
eucrypt_ch6_kecca... 124 when Theta => Output := SMG_Keccak.Theta(Input);
eucrypt_ch6_kecca... 125 when Rho => Output := SMG_Keccak.Rho(Input);
eucrypt_ch6_kecca... 126 when Pi => Output := SMG_Keccak.Pi(Input);
eucrypt_ch6_kecca... 127 when Chi => Output := SMG_Keccak.Chi(Input);
eucrypt_ch6_kecca... 128 when Iota => Output := SMG_Keccak.Iota(RC(Round), Input);
eucrypt_ch6_kecca... 129 when others => null;
eucrypt_ch6_kecca... 130 end case;
eucrypt_ch6_kecca... 131
eucrypt_ch6_kecca... 132 if (Output /= Expected) then
eucrypt_ch6_kecca... 133 print_state(Output, "----------real output-------");
eucrypt_ch6_kecca... 134 print_state(Expected, "----------expected output--------");
eucrypt_ch6_kecca... 135 raise Test_One_Round_Fail;
eucrypt_ch6_kecca... 136 else
eucrypt_ch6_kecca... 137 Put_Line("PASSED: " & Keccak_Perms'Image(I));
eucrypt_ch6_kecca... 138 end if;
eucrypt_ch6_kecca... 139 -- get ready for next permutation
eucrypt_ch6_kecca... 140 Input := Expected;
eucrypt_ch6_kecca... 141 end loop;
eucrypt_ch6_kecca... 142 end test_one_round;
eucrypt_ch6_kecca... 143 -- end of helper methods
eucrypt_ch6_kecca... 144
eucrypt_ch6_kecca... 145 --variables
eucrypt_ch6_kecca... 146 T: Test_Round;
eucrypt_ch6_kecca... 147 begin
eucrypt_ch6_kecca... 148 Put_Line("-----Testing with zero state as input------");
eucrypt_ch6_kecca... 149 if (not read_from_file("testvectorszero.txt", T)) then
eucrypt_ch6_kecca... 150 return;
eucrypt_ch6_kecca... 151 end if;
eucrypt_ch6_kecca... 152
eucrypt_ch6_kecca... 153 for I in Round_Index loop
eucrypt_ch6_kecca... 154 Put_Line("---round " & Round_Index'Image(I) & "---");
eucrypt_ch6_kecca... 155 test_one_round(T(I), I);
eucrypt_ch6_kecca... 156 end loop;
eucrypt_ch6_kecca... 157
eucrypt_ch6_kecca... 158 Put_Line("-----Testing with non-zero state as input------");
eucrypt_ch6_kecca... 159 if (not read_from_file("testvectorsnonzero.txt", T)) then
eucrypt_ch6_kecca... 160 return;
eucrypt_ch6_kecca... 161 end if;
eucrypt_ch6_kecca... 162
eucrypt_ch6_kecca... 163 for I in Round_Index loop
eucrypt_ch6_kecca... 164 Put_Line("---round " & Round_Index'Image(I) & "---");
eucrypt_ch6_kecca... 165 test_one_round(T(I), I);
eucrypt_ch6_kecca... 166 end loop;
eucrypt_ch6_kecca... 167
eucrypt_ch6_kecca... 168 end SMG_Keccak.Test;