-
+ E0071E8372C50670886565CC5EF6F69E310AB5F4922ABD6CB20FA281087C6790CE0EC1980AF4A2504DCB189A8009CF5354D7581CF9B4F4D1F515086ECD08B248
eucrypt/smg_keccak/tests/smg_keccak-test.adb
(0 . 0)(1 . 168)
230 with SMG_Keccak; use SMG_Keccak;
231 with Ada.Exceptions; use Ada.Exceptions;
232 with Ada.Text_IO; use Ada.Text_IO;
233 with Ada.Strings.Fixed; use Ada.Strings.Fixed;
234 with Interfaces; use Interfaces;
235
236 procedure SMG_Keccak.Test is
237 --types
238 type Keccak_Perms is (None, Theta, Rho, Pi, Chi, Iota);
239 type Test_Vector is array(Keccak_Perms) of State;
240 type Test_Round is array(Round_Index) of Test_Vector;
241
242 --helper methods
243
244 procedure print_state(S: in State; Title: in String) is
245 Hex: array(0..15) of Character := ("0123456789ABCDEF");
246 Len: constant Natural := Z_Length / 4;
247 HexString: String(1..Len);
248 W: ZWord;
249 begin
250 Put_Line("---------" & Title & "---------");
251 for Y in XYCoord loop
252 for X in XYCoord loop
253 W := S(X,Y);
254 for Z in 0..Len-1 loop
255 HexString(Natural(Len-Z)) := Hex(Natural(W mod 16));
256 W := W / 16;
257 end loop;
258 Put(HexString & " ");
259 end loop;
260 Put_Line("");
261 end loop;
262 end;
263
264 function read_state(File: in FILE_TYPE; Oct: Positive :=8) return State is
265 S: State;
266 Line1: String := "0000000000000000 " &
267 "0000000000000000 " &
268 "0000000000000000 " &
269 "0000000000000000 " &
270 "0000000000000000";
271 StartPos, EndPos: Positive;
272 Len: Positive := Oct*2;
273 begin
274 for Y in XYCoord loop
275 Line1 := Get_Line(File);
276 StartPos := Line1'First;
277 EndPos := StartPos + Len-1;
278
279 for X in XYCoord loop
280 S(X,Y) := ZWord'value("16#" & Line1(StartPos..EndPos) & "#");
281 StartPos := EndPos + 2; --one space to skip
282 EndPos := StartPos + Len - 1;
283 end loop;
284 end loop;
285 return S;
286 end read_state;
287
288 --reads a full test round from specified file (pre-defined format)
289 function read_from_file (filename : in String;
290 T : out Test_Round)
291 return Boolean is
292 file: FILE_TYPE;
293 InputMarker: String := "lanes as 64-bit words:";
294 octets: Positive := 8;
295 RoundNo: Round_Index;
296 begin
297 -- try to open the input file
298 begin
299 open(file, In_File, filename);
300 exception
301 when others =>
302 Put_Line(Standard_Error,
303 "Can not open the file '" & filename & "'. Does it exist?");
304 return False;
305 end;
306
307 -- find & read input state first
308 RoundNo := -1;
309 loop
310 declare
311 Line: String := Get_Line(file);
312 begin
313 --check if this is test data of any known kind
314 if index(Line, InputMarker, 1) > 0 then
315 T(0)(None) := read_state(file, octets);
316 print_state(T(0)(None), "Read Input State");
317 elsif index(Line, "Round ", 1) > 0 then
318 RoundNo := RoundNo +1;
319 elsif index(Line, "theta", 1) > 0 then
320 T(RoundNo)(Theta) := read_state(file, octets);
321 if (RoundNo > 0) then
322 T(RoundNo)(None) := T(RoundNo-1)(Iota); -- previous state as input
323 end if;
324 elsif index(Line, "rho", 1) > 0 then
325 T(RoundNo)(Rho) := read_state(file, octets);
326 elsif index(Line, "pi", 1) > 0 then
327 T(RoundNo)(Pi) := read_state(file, octets);
328 elsif index(Line, "chi", 1) > 0 then
329 T(RoundNo)(Chi) := read_state(file, octets);
330 elsif index(Line, "iota", 1) > 0 then
331 T(RoundNo)(Iota) := read_state(file, octets);
332 end if;
333 exit when End_Of_File(file);
334 end;
335 end loop;
336 Close(file);
337 return True;
338 end read_from_file;
339
340 -- performs one single round of Keccak, step by step
341 -- each permutation is tested separately
342 -- test fails with exception raised at first output not matching expected
343 procedure test_one_round(T: Test_Vector; Round: Round_Index) is
344 Input: State;
345 Expected: State;
346 Output: State;
347 Test_One_Round_Fail: Exception;
348 begin
349 Input := T(None);
350 for I in Keccak_Perms range Theta..Iota loop
351 Expected := T(I);
352 case I is
353 when Theta => Output := SMG_Keccak.Theta(Input);
354 when Rho => Output := SMG_Keccak.Rho(Input);
355 when Pi => Output := SMG_Keccak.Pi(Input);
356 when Chi => Output := SMG_Keccak.Chi(Input);
357 when Iota => Output := SMG_Keccak.Iota(RC(Round), Input);
358 when others => null;
359 end case;
360
361 if (Output /= Expected) then
362 print_state(Output, "----------real output-------");
363 print_state(Expected, "----------expected output--------");
364 raise Test_One_Round_Fail;
365 else
366 Put_Line("PASSED: " & Keccak_Perms'Image(I));
367 end if;
368 -- get ready for next permutation
369 Input := Expected;
370 end loop;
371 end test_one_round;
372 -- end of helper methods
373
374 --variables
375 T: Test_Round;
376 begin
377 Put_Line("-----Testing with zero state as input------");
378 if (not read_from_file("testvectorszero.txt", T)) then
379 return;
380 end if;
381
382 for I in Round_Index loop
383 Put_Line("---round " & Round_Index'Image(I) & "---");
384 test_one_round(T(I), I);
385 end loop;
386
387 Put_Line("-----Testing with non-zero state as input------");
388 if (not read_from_file("testvectorsnonzero.txt", T)) then
389 return;
390 end if;
391
392 for I in Round_Index loop
393 Put_Line("---round " & Round_Index'Image(I) & "---");
394 test_one_round(T(I), I);
395 end loop;
396
397 end SMG_Keccak.Test;