-
+ A9D504265C8586C87744B5F92C0EEDCD51E2F94B68193E35146FBF4B19B123377AD66B84F8559D1525C1EE3B099D2E8E99BCD4C11A290112F407927FDB21DC76
eucrypt/smg_serpent/tests/test_serpent.adb
(0 . 0)(1 . 191)
11090 -- S.MG, 2018
11091 -- Testing of Serpent implementation using Nessie-format test vectors
11092
11093 with SMG_Serpent; use SMG_Serpent;
11094
11095 with Ada.Text_IO; use Ada.Text_IO;
11096 with Ada.Command_Line; use Ada.Command_Line; -- set exit status on fail
11097 with Interfaces; use Interfaces; -- unsigned_8
11098
11099 package body Test_Serpent is
11100 Test_Fail : exception; -- raised if a test fails
11101
11102 procedure test_from_file (filename: String) is
11103 file : FILE_TYPE;
11104 keylen : constant := 256;
11105 blocklen : constant := 128;
11106 octets : constant := 16;
11107 K : Key;
11108 P, P2 : Block; --plain text
11109 C, C2 : Block; --cipher (encrypted) text
11110 times100 : Block; --value after 100 iterations
11111 times1k : Block; --value after 1000 iterations
11112 W : Key_Schedule;
11113 Test_No : Positive := 1;
11114 begin
11115 begin
11116 open(file, In_File, filename);
11117 exception
11118 when others =>
11119 Put_Line(Standard_Error, "Can not open the file '" & filename &
11120 "'. Does it exist?");
11121 Set_Exit_Status(Failure);
11122 return;
11123 end;
11124
11125 loop
11126 declare
11127 Line1 : String := Get_Line(file);
11128 Line2 : String := Line1;
11129 key1, key2 : String( 1..octets*2 );
11130 len : Natural := 0;
11131 begin
11132 --check if this is test data of any known kind
11133 if index( Line1, "key=", 1 ) > 0 then
11134 Line2 := Get_Line( file );
11135 key1 := Tail( Line1, octets*2 );
11136 key2 := Tail( Line2, octets*2 );
11137 for jj in 1..octets loop
11138 K(jj-1) := Unsigned_8'Value("16#" &
11139 key1( ( jj - 1 ) * 2 + 1 .. jj * 2 ) &
11140 "#");
11141 K( jj + octets - 1 ) :=
11142 Unsigned_8'Value("16#" &
11143 key2( ( jj - 1 ) * 2 + 1 .. jj * 2 ) &
11144 "#");
11145 end loop;
11146
11147 elsif index( Line1, "plain=", 1 ) > 0 then
11148 key1 := Tail( Line1, octets * 2 );
11149 for jj in 1..octets loop
11150 P(jj-1) := Unsigned_8'Value("16#" &
11151 key1( ( jj - 1 ) * 2 + 1 .. jj * 2 ) &
11152 "#");
11153 end loop;
11154 elsif index( Line1, "cipher=", 1 ) > 0 then
11155 key1 := Tail( Line1, octets * 2 );
11156 for jj in 1..octets loop
11157 C(jj-1) := Unsigned_8'Value("16#" &
11158 key1( ( jj - 1 ) * 2 + 1 .. jj * 2) &
11159 "#");
11160 end loop;
11161 elsif index( Line1, "100 times=", 1 ) > 0 then
11162 key1 := Tail( Line1, octets * 2 );
11163 for jj in 1..octets loop
11164 times100(jj-1) :=
11165 Unsigned_8'Value("16#" &
11166 key1( ( jj - 1 ) * 2 + 1 .. jj * 2 ) &
11167 "#");
11168 end loop;
11169 elsif index( Line1, "1000 times=", 1 ) > 0 then
11170 key1 := Tail( Line1, octets * 2 );
11171 for jj in 1..octets loop
11172 times1k(jj-1) :=
11173 Unsigned_8'value("16#" &
11174 key1( ( jj - 1 ) * 2 + 1 .. jj * 2 ) &
11175 "#");
11176 end loop;
11177 --at this stage we should have ALL needed, so run test
11178 Put("-----Test " & Positive'Image(Test_No) & ": encryption...");
11179 Prepare_Key(K, W);
11180 Encrypt(W, P, C2);
11181 if C2 /= C then
11182 raise Test_Fail;
11183 else
11184 Put_Line("Passed-----");
11185 end if;
11186 Put("-----Test " & Positive'Image(Test_No) & ": decryption...");
11187 Decrypt(W, C2, P2);
11188 if P /= P2 then
11189 raise Test_Fail;
11190 else
11191 Put_Line("Passed-----");
11192 end if;
11193
11194 Put("-----Test " & Positive'Image(Test_No) & ": 100 iterations...");
11195 for jj in 1 .. 100 loop
11196 Encrypt(W, P, C2);
11197 Decrypt(W, C2, P2);
11198 if (P2 /= P) then
11199 raise Test_Fail;
11200 end if;
11201 P := C2;
11202 end loop;
11203 Put_Line("Passed-----");
11204
11205 Put("-----Test " & Positive'Image(Test_No) & ": 1000 iterations...");
11206
11207 for jj in 1 .. 900 loop
11208 Encrypt(W, P, C2);
11209 Decrypt(W, C2, P2);
11210 if (P2 /= P) then
11211 raise Test_Fail;
11212 end if;
11213 P := C2;
11214 end loop;
11215 Put_Line("Passed-----");
11216 Test_No := Test_No + 1;
11217 end if;
11218 exit when End_Of_File(file);
11219 end;
11220 end loop;
11221 Close(file);
11222 end test_from_file;
11223
11224 procedure test_one is
11225 K: Key;
11226 P, P2: Block;
11227 C: Block;
11228 W: Key_Schedule;
11229 begin
11230 K := (16#80#, 16#00#, 16#00#, 16#00#, 16#00#, 16#00#, 16#00#, 16#00#,
11231 16#00#, 16#00#, 16#00#, 16#00#, 16#00#, 16#00#, 16#00#, 16#00#,
11232 16#00#, 16#00#, 16#00#, 16#00#, 16#00#, 16#00#, 16#00#, 16#00#,
11233 16#00#, 16#00#, 16#00#, 16#00#, 16#00#, 16#00#, 16#00#, 16#00#);
11234
11235 P := (16#00#, 16#00#, 16#00#, 16#00#, 16#00#, 16#00#, 16#00#, 16#00#,
11236 16#00#, 16#00#, 16#00#, 16#00#, 16#00#, 16#00#, 16#00#, 16#00#);
11237
11238 SMG_Serpent.Prepare_Key(K, W);
11239 Encrypt(W, P, C);
11240 if C /= (16#A2#, 16#23#, 16#AA#, 16#12#, 16#88#, 16#46#, 16#3C#, 16#0E#,
11241 16#2B#, 16#E3#, 16#8E#, 16#BD#, 16#82#, 16#56#, 16#16#, 16#C0#)
11242 then
11243 raise Test_Fail;
11244 end if;
11245
11246 for I in 1 .. 100 loop
11247 Encrypt(W, P, C);
11248 Decrypt(W, C, P2);
11249 if (P2 /= P) then
11250 raise Test_Fail;
11251 end if;
11252 P := C;
11253 end loop;
11254
11255 if C /= (16#73#, 16#9E#, 16#01#, 16#48#, 16#97#, 16#1F#, 16#D9#, 16#75#,
11256 16#B5#, 16#85#, 16#EA#, 16#FD#, 16#BD#, 16#65#, 16#9E#, 16#2C#)
11257 then
11258 raise Test_Fail;
11259 end if;
11260
11261 for I in 1 .. 900 loop
11262 Encrypt(W, P, C);
11263 Decrypt(W, C, P2);
11264 if (P2 /= P) then
11265 raise Test_Fail;
11266 end if;
11267 P := C;
11268 end loop;
11269
11270 if C /= (16#BE#, 16#FD#, 16#00#, 16#E0#, 16#D6#, 16#E2#, 16#7E#, 16#56#,
11271 16#95#, 16#1D#, 16#C6#, 16#61#, 16#44#, 16#40#, 16#D2#, 16#86#)
11272 then
11273 raise Test_Fail;
11274 else
11275 Put_Line("PASSED: test single case.");
11276 end if;
11277
11278 end test_one;
11279
11280 end Test_Serpent;