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 procedure print_state(S: in State; Title: in String) is
eucrypt_ch6_kecca... 15 Hex: array(0..15) of Character := ("0123456789ABCDEF");
eucrypt_ch6_kecca... 16 Len: constant Natural := Z_Length / 4;
eucrypt_ch6_kecca... 17 HexString: String(1..Len);
eucrypt_ch6_kecca... 18 W: ZWord;
eucrypt_ch6_kecca... 19 begin
eucrypt_ch6_kecca... 20 Put_Line("---------" & Title & "---------");
eucrypt_ch6_kecca... 21 for Y in XYCoord loop
eucrypt_ch6_kecca... 22 for X in XYCoord loop
eucrypt_ch6_kecca... 23 W := S(X,Y);
eucrypt_ch6_kecca... 24 for Z in 0..Len-1 loop
eucrypt_ch6_kecca... 25 HexString(Natural(Len-Z)) := Hex(Natural(W mod 16));
eucrypt_ch6_kecca... 26 W := W / 16;
eucrypt_ch6_kecca... 27 end loop;
eucrypt_ch6_kecca... 28 Put(HexString & " ");
eucrypt_ch6_kecca... 29 end loop;
eucrypt_ch6_kecca... 30 Put_Line("");
eucrypt_ch6_kecca... 31 end loop;
eucrypt_ch6_kecca... 32 end;
eucrypt_ch6_kecca... 33
eucrypt_ch7_kecca... 34 procedure print_bitstream(B: in Bitstream; Title: in String) is
eucrypt_ch7_kecca... 35 Hex : array(0..15) of Character := ("0123456789ABCDEF");
eucrypt_ch7_kecca... 36 HexString : String(1..B'Length/4);
eucrypt_ch7_kecca... 37 C : Natural;
eucrypt_ch7_kecca... 38 Pos : Natural;
eucrypt_ch7_kecca... 39 begin
eucrypt_ch7_kecca... 40 for I in 1..B'Length/4 loop
eucrypt_ch7_kecca... 41 Pos := (I-1)*4 + B'First;
eucrypt_ch7_kecca... 42 C := Natural( B(Pos) ) * 8 +
eucrypt_ch7_kecca... 43 Natural( B(Pos + 1) ) * 4 +
eucrypt_ch7_kecca... 44 Natural( B(Pos + 2) ) * 2 +
eucrypt_ch7_kecca... 45 Natural( B(Pos + 3) );
eucrypt_ch7_kecca... 46 HexString(I) := Hex(C);
eucrypt_ch7_kecca... 47 end loop;
eucrypt_ch7_kecca... 48 Put_Line("---" & Title & "---");
eucrypt_ch7_kecca... 49 Put_Line(HexString);
eucrypt_ch7_kecca... 50 end print_bitstream;
eucrypt_ch7_kecca... 51
eucrypt_ch6_kecca... 52 function read_state(File: in FILE_TYPE; Oct: Positive :=8) return State is
eucrypt_ch6_kecca... 53 S: State;
eucrypt_ch6_kecca... 54 Line1: String := "0000000000000000 " &
eucrypt_ch6_kecca... 55 "0000000000000000 " &
eucrypt_ch6_kecca... 56 "0000000000000000 " &
eucrypt_ch6_kecca... 57 "0000000000000000 " &
eucrypt_ch6_kecca... 58 "0000000000000000";
eucrypt_ch6_kecca... 59 StartPos, EndPos: Positive;
eucrypt_ch6_kecca... 60 Len: Positive := Oct*2;
eucrypt_ch6_kecca... 61 begin
eucrypt_ch6_kecca... 62 for Y in XYCoord loop
eucrypt_ch6_kecca... 63 Line1 := Get_Line(File);
eucrypt_ch6_kecca... 64 StartPos := Line1'First;
eucrypt_ch6_kecca... 65 EndPos := StartPos + Len-1;
eucrypt_ch6_kecca... 66
eucrypt_ch6_kecca... 67 for X in XYCoord loop
eucrypt_ch6_kecca... 68 S(X,Y) := ZWord'value("16#" & Line1(StartPos..EndPos) & "#");
eucrypt_ch6_kecca... 69 StartPos := EndPos + 2; --one space to skip
eucrypt_ch6_kecca... 70 EndPos := StartPos + Len - 1;
eucrypt_ch6_kecca... 71 end loop;
eucrypt_ch6_kecca... 72 end loop;
eucrypt_ch6_kecca... 73 return S;
eucrypt_ch6_kecca... 74 end read_state;
eucrypt_ch6_kecca... 75
eucrypt_ch6_kecca... 76 --reads a full test round from specified file (pre-defined format)
eucrypt_ch6_kecca... 77 function read_from_file (filename : in String;
eucrypt_ch6_kecca... 78 T : out Test_Round)
eucrypt_ch6_kecca... 79 return Boolean is
eucrypt_ch6_kecca... 80 file: FILE_TYPE;
eucrypt_ch6_kecca... 81 InputMarker: String := "lanes as 64-bit words:";
eucrypt_ch6_kecca... 82 octets: Positive := 8;
eucrypt_ch6_kecca... 83 RoundNo: Round_Index;
eucrypt_ch6_kecca... 84 begin
eucrypt_ch6_kecca... 85 -- try to open the input file
eucrypt_ch6_kecca... 86 begin
eucrypt_ch6_kecca... 87 open(file, In_File, filename);
eucrypt_ch6_kecca... 88 exception
eucrypt_ch6_kecca... 89 when others =>
eucrypt_ch6_kecca... 90 Put_Line(Standard_Error,
eucrypt_ch6_kecca... 91 "Can not open the file '" & filename & "'. Does it exist?");
eucrypt_ch6_kecca... 92 return False;
eucrypt_ch6_kecca... 93 end;
eucrypt_ch6_kecca... 94
eucrypt_ch6_kecca... 95 -- find & read input state first
eucrypt_ch6_kecca... 96 RoundNo := -1;
eucrypt_ch6_kecca... 97 loop
eucrypt_ch6_kecca... 98 declare
eucrypt_ch6_kecca... 99 Line: String := Get_Line(file);
eucrypt_ch6_kecca... 100 begin
eucrypt_ch6_kecca... 101 --check if this is test data of any known kind
eucrypt_ch6_kecca... 102 if index(Line, InputMarker, 1) > 0 then
eucrypt_ch6_kecca... 103 T(0)(None) := read_state(file, octets);
eucrypt_ch6_kecca... 104 print_state(T(0)(None), "Read Input State");
eucrypt_ch6_kecca... 105 elsif index(Line, "Round ", 1) > 0 then
eucrypt_ch6_kecca... 106 RoundNo := RoundNo +1;
eucrypt_ch6_kecca... 107 elsif index(Line, "theta", 1) > 0 then
eucrypt_ch6_kecca... 108 T(RoundNo)(Theta) := read_state(file, octets);
eucrypt_ch6_kecca... 109 if (RoundNo > 0) then
eucrypt_ch6_kecca... 110 T(RoundNo)(None) := T(RoundNo-1)(Iota); -- previous state as input
eucrypt_ch6_kecca... 111 end if;
eucrypt_ch6_kecca... 112 elsif index(Line, "rho", 1) > 0 then
eucrypt_ch6_kecca... 113 T(RoundNo)(Rho) := read_state(file, octets);
eucrypt_ch6_kecca... 114 elsif index(Line, "pi", 1) > 0 then
eucrypt_ch6_kecca... 115 T(RoundNo)(Pi) := read_state(file, octets);
eucrypt_ch6_kecca... 116 elsif index(Line, "chi", 1) > 0 then
eucrypt_ch6_kecca... 117 T(RoundNo)(Chi) := read_state(file, octets);
eucrypt_ch6_kecca... 118 elsif index(Line, "iota", 1) > 0 then
eucrypt_ch6_kecca... 119 T(RoundNo)(Iota) := read_state(file, octets);
eucrypt_ch6_kecca... 120 end if;
eucrypt_ch6_kecca... 121 exit when End_Of_File(file);
eucrypt_ch6_kecca... 122 end;
eucrypt_ch6_kecca... 123 end loop;
eucrypt_ch6_kecca... 124 Close(file);
eucrypt_ch6_kecca... 125 return True;
eucrypt_ch6_kecca... 126 end read_from_file;
eucrypt_ch6_kecca... 127
eucrypt_ch6_kecca... 128 -- performs one single round of Keccak, step by step
eucrypt_ch6_kecca... 129 -- each permutation is tested separately
eucrypt_ch6_kecca... 130 -- test fails with exception raised at first output not matching expected
eucrypt_ch6_kecca... 131 procedure test_one_round(T: Test_Vector; Round: Round_Index) is
eucrypt_ch6_kecca... 132 Input: State;
eucrypt_ch6_kecca... 133 Expected: State;
eucrypt_ch6_kecca... 134 Output: State;
eucrypt_ch6_kecca... 135 Test_One_Round_Fail: Exception;
eucrypt_ch6_kecca... 136 begin
eucrypt_ch6_kecca... 137 Input := T(None);
eucrypt_ch6_kecca... 138 for I in Keccak_Perms range Theta..Iota loop
eucrypt_ch6_kecca... 139 Expected := T(I);
eucrypt_ch6_kecca... 140 case I is
eucrypt_ch6_kecca... 141 when Theta => Output := SMG_Keccak.Theta(Input);
eucrypt_ch6_kecca... 142 when Rho => Output := SMG_Keccak.Rho(Input);
eucrypt_ch6_kecca... 143 when Pi => Output := SMG_Keccak.Pi(Input);
eucrypt_ch6_kecca... 144 when Chi => Output := SMG_Keccak.Chi(Input);
eucrypt_ch6_kecca... 145 when Iota => Output := SMG_Keccak.Iota(RC(Round), Input);
eucrypt_ch6_kecca... 146 when others => null;
eucrypt_ch6_kecca... 147 end case;
eucrypt_ch6_kecca... 148
eucrypt_ch6_kecca... 149 if (Output /= Expected) then
eucrypt_ch6_kecca... 150 print_state(Output, "----------real output-------");
eucrypt_ch6_kecca... 151 print_state(Expected, "----------expected output--------");
eucrypt_ch6_kecca... 152 raise Test_One_Round_Fail;
eucrypt_ch6_kecca... 153 else
eucrypt_ch6_kecca... 154 Put_Line("PASSED: " & Keccak_Perms'Image(I));
eucrypt_ch6_kecca... 155 end if;
eucrypt_ch6_kecca... 156 -- get ready for next permutation
eucrypt_ch6_kecca... 157 Input := Expected;
eucrypt_ch6_kecca... 158 end loop;
eucrypt_ch6_kecca... 159 end test_one_round;
eucrypt_ch7_kecca... 160
eucrypt_ch7_kecca... 161 procedure test_bits_to_word_conversion is
eucrypt_ch7_kecca... 162 bits: Bitword := (others => 0);
eucrypt_ch7_kecca... 163 obtained_bits: Bitword := (others => 0);
eucrypt_ch7_kecca... 164 expected: ZWord;
eucrypt_ch7_kecca... 165 obtained: ZWord;
eucrypt_ch7_kecca... 166 begin
eucrypt_ch7_kecca... 167 expected := 16#E7DDE140798F25F1#;
eucrypt_ch7_kecca... 168 bits := (1,1,1,0, 0,1,1,1, 1,1,0,1, 1,1,0,1, 1,1,1,0, 0,0,0,1, 0,1,0,0,
eucrypt_ch7_kecca... 169 0,0,0,0, 0,1,1,1, 1,0,0,1, 1,0,0,0, 1,1,1,1, 0,0,1,0, 0,1,0,1,
eucrypt_ch7_kecca... 170 1,1,1,1, 0,0,0,1);
eucrypt_ch7_kecca... 171 obtained := BitsToWord(bits);
eucrypt_ch7_kecca... 172 obtained_bits := WordToBits(expected);
eucrypt_ch7_kecca... 173
eucrypt_ch7_kecca... 174 if obtained /= expected then
eucrypt_ch7_kecca... 175 Put_Line("FAIL: bits to word");
eucrypt_ch7_kecca... 176 Put_Line("Expected: " & ZWord'Image(expected));
eucrypt_ch7_kecca... 177 Put_Line("Obtained: " & ZWord'Image(obtained));
eucrypt_ch7_kecca... 178 else
eucrypt_ch7_kecca... 179 Put_Line("PASSED: bits to word");
eucrypt_ch7_kecca... 180 end if;
eucrypt_ch7_kecca... 181
eucrypt_ch7_kecca... 182 if obtained_bits /= bits then
eucrypt_ch7_kecca... 183 Put_Line("FAIL: word to bits");
eucrypt_ch7_kecca... 184 Put("Expected: ");
eucrypt_ch7_kecca... 185 for I in Bitword'Range loop
eucrypt_ch7_kecca... 186 Put(Bit'Image(bits(I)));
eucrypt_ch7_kecca... 187 end loop;
eucrypt_ch7_kecca... 188 Put_Line("");
eucrypt_ch7_kecca... 189 Put_Line("Obtained: ");
eucrypt_ch7_kecca... 190 for I in Bitword'Range loop
eucrypt_ch7_kecca... 191 Put(Bit'Image(obtained_bits(I)));
eucrypt_ch7_kecca... 192 end loop;
eucrypt_ch7_kecca... 193 Put_Line("");
eucrypt_ch7_kecca... 194 else
eucrypt_ch7_kecca... 195 Put_Line("PASSED: word to bits");
eucrypt_ch7_kecca... 196 end if;
eucrypt_ch7_kecca... 197 end test_bits_to_word_conversion;
eucrypt_ch7_kecca... 198
eucrypt_ch7_kecca... 199 procedure test_sponge is
eucrypt_ch7_kecca... 200 Bitrate : constant Keccak_Rate := 1344;
eucrypt_ch7_kecca... 201 Input : Bitstream(1..5) := (1, 1, 0, 0, 1);
eucrypt_ch7_kecca... 202 Output : Bitstream(1..Bitrate*2);
eucrypt_ch7_kecca... 203 Hex : array(0..15) of Character := ("0123456789ABCDEF");
eucrypt_ch7_kecca... 204 HexString : String(1..Bitrate/2);
eucrypt_ch7_kecca... 205 C : Natural;
eucrypt_ch7_kecca... 206 ExpHex : String(1..Bitrate/2);
eucrypt_ch7_kecca... 207 Error : Natural;
eucrypt_ch7_kecca... 208 Pos : Natural;
eucrypt_ch7_kecca... 209 begin
eucrypt_ch7_kecca... 210 ExpHex := "B57B7DAED6330F79BA5783C5D45EABFFA1461FAC6CEA09BD"&
eucrypt_ch7_kecca... 211 "AAC114F17E23E5B349EECBC907E07FA36ECF8374079811E8"&
eucrypt_ch7_kecca... 212 "5E49243D04182C389E68C733BE698468423DB9891D3A7B10"&
eucrypt_ch7_kecca... 213 "320E0356AB4AB916F68C0EA20365A1D4DBA48218CA89CBB8"&
eucrypt_ch7_kecca... 214 "6D08A34E04544D4100FFE9CB138EADC2D3FC0E8CC2BC15A7"&
eucrypt_ch7_kecca... 215 "5B950776970BFC310F33BF609630D73CAD918CF54657589E"&
eucrypt_ch7_kecca... 216 "42CF7CBF20DE677D2AB7E49389F6F6C3B3FE2992905325CE"&
eucrypt_ch7_kecca... 217 "60931C1515043595ADC1619CB7E034EF52BDC485D03B7FDD"&
eucrypt_ch7_kecca... 218 "7345E849FFB4C4426195C8D88C1E7BF9ADA41B92E006C3DA"&
eucrypt_ch7_kecca... 219 "F1ED0FD63ADD9408A3FC815F727457692727637687C1F79D"&
eucrypt_ch7_kecca... 220 "837DE20798E64C878181C02DF56A533F684459E8A03C8EF6"&
eucrypt_ch7_kecca... 221 "234854531110E6CD9BDEFEA85E35C802B1ACDDF29C9332E2"&
eucrypt_ch7_kecca... 222 "53C0FA72F3ED1ABA274838CFE6EF8BD572E89E1C2135F6A7"&
eucrypt_ch7_kecca... 223 "5BC5D6EA4F85C9A757E68E561A56AC0FC19F1F086C43272F";
eucrypt_ch7_kecca... 224
eucrypt_ch7_kecca... 225 Put_Line("---sponge test---");
eucrypt_ch7_kecca... 226 Sponge(Input, Bitrate, Output);
eucrypt_ch7_kecca... 227 Put_Line("Input is:");
eucrypt_ch7_kecca... 228 for I of Input loop
eucrypt_ch7_kecca... 229 Put(Bit'Image(I));
eucrypt_ch7_kecca... 230 end loop;
eucrypt_ch7_kecca... 231 new_line(1);
eucrypt_ch7_kecca... 232
eucrypt_ch7_kecca... 233 Put_Line("Output is:");
eucrypt_ch7_kecca... 234 for I of Output loop
eucrypt_ch7_kecca... 235 Put(Bit'Image(I));
eucrypt_ch7_kecca... 236 end loop;
eucrypt_ch7_kecca... 237 new_line(1);
eucrypt_ch7_kecca... 238
eucrypt_ch7_kecca... 239 Error := 0;
eucrypt_ch7_kecca... 240 for I in 1..Output'Length/4 loop
eucrypt_ch7_kecca... 241 Pos := Output'First + (I-1)*4;
eucrypt_ch7_kecca... 242 C := Natural( Output( Pos ) ) * 8 +
eucrypt_ch7_kecca... 243 Natural( Output( Pos + 1 ) ) * 4 +
eucrypt_ch7_kecca... 244 Natural( Output( Pos + 2 ) ) * 2 +
eucrypt_ch7_kecca... 245 Natural( Output( Pos + 3 ) );
eucrypt_ch7_kecca... 246 Hexstring(I) := Hex(C);
eucrypt_ch7_kecca... 247 if Hexstring(I) /= ExpHex(I) then
eucrypt_ch7_kecca... 248 Error := Error + 1;
eucrypt_ch7_kecca... 249 end if;
eucrypt_ch7_kecca... 250 end loop;
eucrypt_ch7_kecca... 251 Put_Line("Expected: ");
eucrypt_ch7_kecca... 252 Put_Line(ExpHex);
eucrypt_ch7_kecca... 253 Put_Line("Obtained: ");
eucrypt_ch7_kecca... 254 Put_Line(Hexstring);
eucrypt_ch7_kecca... 255 Put_Line("Errors found: " & Natural'Image(Error));
eucrypt_ch7_kecca... 256
eucrypt_ch7_kecca... 257 end test_sponge;
eucrypt_ch7_kecca... 258
eucrypt_ch7_kecca... 259 procedure test_keccak_function(T: in Test_Round) is
eucrypt_ch7_kecca... 260 S: State;
eucrypt_ch7_kecca... 261 begin
eucrypt_ch7_kecca... 262 Put_Line("---Full Keccak Function test---");
eucrypt_ch7_kecca... 263 S := Keccak_Function(T(Round_Index'First)(None));
eucrypt_ch7_kecca... 264 if S /= T(Round_Index'Last)(Iota) then
eucrypt_ch7_kecca... 265 Put_Line("FAILED: full keccak function test");
eucrypt_ch7_kecca... 266 else
eucrypt_ch7_kecca... 267 Put_Line("PASSED: full keccak function test");
eucrypt_ch7_kecca... 268 end if;
eucrypt_ch7_kecca... 269 end test_keccak_function;
eucrypt_ch7_kecca... 270
eucrypt_ch6_kecca... 271 -- end of helper methods
eucrypt_ch6_kecca... 272
eucrypt_ch6_kecca... 273 --variables
eucrypt_ch6_kecca... 274 T: Test_Round;
eucrypt_ch6_kecca... 275 begin
eucrypt_ch6_kecca... 276 Put_Line("-----Testing with zero state as input------");
eucrypt_ch6_kecca... 277 if (not read_from_file("testvectorszero.txt", T)) then
eucrypt_ch6_kecca... 278 return;
eucrypt_ch6_kecca... 279 end if;
eucrypt_ch6_kecca... 280
eucrypt_ch6_kecca... 281 for I in Round_Index loop
eucrypt_ch6_kecca... 282 Put_Line("---round " & Round_Index'Image(I) & "---");
eucrypt_ch6_kecca... 283 test_one_round(T(I), I);
eucrypt_ch6_kecca... 284 end loop;
eucrypt_ch6_kecca... 285
eucrypt_ch7_kecca... 286 -- test also Keccak_Function as a whole --
eucrypt_ch7_kecca... 287 test_keccak_function(T);
eucrypt_ch7_kecca... 288
eucrypt_ch6_kecca... 289 Put_Line("-----Testing with non-zero state as input------");
eucrypt_ch6_kecca... 290 if (not read_from_file("testvectorsnonzero.txt", T)) then
eucrypt_ch6_kecca... 291 return;
eucrypt_ch6_kecca... 292 end if;
eucrypt_ch6_kecca... 293
eucrypt_ch6_kecca... 294 for I in Round_Index loop
eucrypt_ch6_kecca... 295 Put_Line("---round " & Round_Index'Image(I) & "---");
eucrypt_ch6_kecca... 296 test_one_round(T(I), I);
eucrypt_ch6_kecca... 297 end loop;
eucrypt_ch6_kecca... 298
eucrypt_ch7_kecca... 299 -- test also Keccak_Function as a whole --
eucrypt_ch7_kecca... 300 test_keccak_function(T);
eucrypt_ch7_kecca... 301
eucrypt_ch7_kecca... 302 -- test BitsToWord and WordToBits
eucrypt_ch7_kecca... 303 test_bits_to_word_conversion;
eucrypt_ch7_kecca... 304
eucrypt_ch7_kecca... 305 -- test Sponge construction
eucrypt_ch7_kecca... 306 test_sponge;
eucrypt_ch7_kecca... 307
eucrypt_ch6_kecca... 308 end SMG_Keccak.Test;