raw
eucrypt_ch11_serpent    1  -------------------------------------------------------------------------------
eucrypt_ch11_serpent 2 --
eucrypt_ch11_serpent 3 -- Serpent Blockcipher
eucrypt_ch11_serpent 4 --
eucrypt_ch11_serpent 5 -- Copyright (c) 1998 Markus G. Kuhn <mkuhn@acm.org>. All rights reserved.
eucrypt_ch11_serpent 6 --
eucrypt_ch11_serpent 7 -- Modified by S.MG, 2018
eucrypt_ch11_serpent 8 --
eucrypt_ch11_serpent 9 -------------------------------------------------------------------------------
eucrypt_ch11_serpent 10 --
eucrypt_ch11_serpent 11 -- This implementation is optimized for best execution time by use of
eucrypt_ch11_serpent 12 -- function inlining and loop unrolling. It is not intended to be used in
eucrypt_ch11_serpent 13 -- applications (such as smartcards) where machine code size matters. Best
eucrypt_ch11_serpent 14 -- compiled with highest optimization level activated and all run-time
eucrypt_ch11_serpent 15 -- checks supressed.
eucrypt_ch11_serpent 16 --
eucrypt_ch11_serpent 17 -------------------------------------------------------------------------------
eucrypt_ch11_serpent 18
eucrypt_ch11_serpent 19 with System, Ada.Unchecked_Conversion;
eucrypt_ch11_serpent 20 use System;
eucrypt_ch11_serpent 21
eucrypt_ch11_serpent 22 package body SMG_Serpent is
eucrypt_ch11_serpent 23
eucrypt_ch11_serpent 24 pragma Optimize( Time );
eucrypt_ch11_serpent 25
eucrypt_ch11_serpent 26 -- Auxiliary functions for byte array to word array conversion with
eucrypt_ch11_serpent 27 -- Bigendian/Littleendian handling.
eucrypt_ch11_serpent 28 --
eucrypt_ch11_serpent 29 -- The convention followed here is that the input byte array
eucrypt_ch11_serpent 30 --
eucrypt_ch11_serpent 31 -- 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
eucrypt_ch11_serpent 32 --
eucrypt_ch11_serpent 33 -- is converted into the register values
eucrypt_ch11_serpent 34 --
eucrypt_ch11_serpent 35 -- X0 = 03020100, X1 = 07060504, X2 = 0b0a0908, X3 = 0f0e0d0c
eucrypt_ch11_serpent 36
eucrypt_ch11_serpent 37 subtype Bytes_4 is Bytes (0 .. 3);
eucrypt_ch11_serpent 38 function Cast is new Ada.Unchecked_Conversion (Bytes_4, Unsigned_32);
eucrypt_ch11_serpent 39 function Cast is new Ada.Unchecked_Conversion (Unsigned_32, Bytes_4);
eucrypt_ch11_serpent 40
eucrypt_ch11_serpent 41 function Bytes_To_Word (X : Bytes_4) return Unsigned_32 is
eucrypt_ch11_serpent 42 begin
eucrypt_ch11_serpent 43 if Default_Bit_Order = Low_Order_First then
eucrypt_ch11_serpent 44 -- we have a Littleendian processor
eucrypt_ch11_serpent 45 return Cast(X);
eucrypt_ch11_serpent 46 else
eucrypt_ch11_serpent 47 -- word sex change
eucrypt_ch11_serpent 48 return Cast((X(3), X(2), X(1), X(0)));
eucrypt_ch11_serpent 49 end if;
eucrypt_ch11_serpent 50 end Bytes_To_Word;
eucrypt_ch11_serpent 51
eucrypt_ch11_serpent 52 function Word_To_Bytes (X : Unsigned_32) return Bytes_4 is
eucrypt_ch11_serpent 53 begin
eucrypt_ch11_serpent 54 if Default_Bit_Order = Low_Order_First then
eucrypt_ch11_serpent 55 -- we have a Littleendian processor
eucrypt_ch11_serpent 56 return Cast(X);
eucrypt_ch11_serpent 57 else
eucrypt_ch11_serpent 58 -- word sex change
eucrypt_ch11_serpent 59 return (Cast(X)(3), Cast(X)(2), Cast(X)(1), Cast(X)(0));
eucrypt_ch11_serpent 60 end if;
eucrypt_ch11_serpent 61 end Word_To_Bytes;
eucrypt_ch11_serpent 62
eucrypt_ch11_serpent 63 pragma Inline(Bytes_To_Word, Word_To_Bytes);
eucrypt_ch11_serpent 64 -- inline functions for the Encryption and Decryption procedures
eucrypt_ch11_serpent 65
eucrypt_ch11_serpent 66 -- Sbox function
eucrypt_ch11_serpent 67 procedure S (R : Integer; X0, X1, X2, X3 : in out Unsigned_32) is
eucrypt_ch11_serpent 68 T01, T02, T03, T04, T05, T06, T07, T08, T09,
eucrypt_ch11_serpent 69 T10, T11, T12, T13, T14, T15, T16, T17, T18 : Unsigned_32;
eucrypt_ch11_serpent 70 W, X, Y, Z : Unsigned_32;
eucrypt_ch11_serpent 71 begin
eucrypt_ch11_serpent 72 if R = 0 then
eucrypt_ch11_serpent 73 -- S0: 3 8 15 1 10 6 5 11 14 13 4 2 7 0 9 12
eucrypt_ch11_serpent 74 -- depth = 5,7,4,2, Total gates=18
eucrypt_ch11_serpent 75 T01 := X1 xor X2;
eucrypt_ch11_serpent 76 T02 := X0 or X3;
eucrypt_ch11_serpent 77 T03 := X0 xor X1;
eucrypt_ch11_serpent 78 Z := T02 xor T01;
eucrypt_ch11_serpent 79 T05 := X2 or z;
eucrypt_ch11_serpent 80 T06 := X0 xor X3;
eucrypt_ch11_serpent 81 T07 := X1 or X2;
eucrypt_ch11_serpent 82 T08 := X3 and T05;
eucrypt_ch11_serpent 83 T09 := T03 and T07;
eucrypt_ch11_serpent 84 Y := T09 xor T08;
eucrypt_ch11_serpent 85 T11 := T09 and y;
eucrypt_ch11_serpent 86 T12 := X2 xor X3;
eucrypt_ch11_serpent 87 T13 := T07 xor T11;
eucrypt_ch11_serpent 88 T14 := X1 and T06;
eucrypt_ch11_serpent 89 T15 := T06 xor T13;
eucrypt_ch11_serpent 90 W := not T15;
eucrypt_ch11_serpent 91 T17 := W xor T14;
eucrypt_ch11_serpent 92 X := T12 xor T17;
eucrypt_ch11_serpent 93 elsif R = 1 then
eucrypt_ch11_serpent 94 -- S1: 15 12 2 7 9 0 5 10 1 11 14 8 6 13 3 4
eucrypt_ch11_serpent 95 -- depth = 10,7,3,5, Total gates=18
eucrypt_ch11_serpent 96 T01 := X0 or X3;
eucrypt_ch11_serpent 97 T02 := X2 xor X3;
eucrypt_ch11_serpent 98 T03 := not X1;
eucrypt_ch11_serpent 99 T04 := X0 xor X2;
eucrypt_ch11_serpent 100 T05 := X0 or T03;
eucrypt_ch11_serpent 101 T06 := X3 and T04;
eucrypt_ch11_serpent 102 T07 := T01 and T02;
eucrypt_ch11_serpent 103 T08 := X1 or T06;
eucrypt_ch11_serpent 104 Y := T02 xor T05;
eucrypt_ch11_serpent 105 T10 := T07 xor T08;
eucrypt_ch11_serpent 106 T11 := T01 xor T10;
eucrypt_ch11_serpent 107 T12 := Y xor T11;
eucrypt_ch11_serpent 108 T13 := X1 and X3;
eucrypt_ch11_serpent 109 Z := not T10;
eucrypt_ch11_serpent 110 X := T13 xor T12;
eucrypt_ch11_serpent 111 T16 := T10 or x;
eucrypt_ch11_serpent 112 T17 := T05 and T16;
eucrypt_ch11_serpent 113 W := X2 xor T17;
eucrypt_ch11_serpent 114 elsif R = 2 then
eucrypt_ch11_serpent 115 -- S2: 8 6 7 9 3 12 10 15 13 1 14 4 0 11 5 2
eucrypt_ch11_serpent 116 -- depth = 3,8,11,7, Total gates=16
eucrypt_ch11_serpent 117 T01 := X0 or X2;
eucrypt_ch11_serpent 118 T02 := X0 xor X1;
eucrypt_ch11_serpent 119 T03 := X3 xor T01;
eucrypt_ch11_serpent 120 W := T02 xor T03;
eucrypt_ch11_serpent 121 T05 := X2 xor w;
eucrypt_ch11_serpent 122 T06 := X1 xor T05;
eucrypt_ch11_serpent 123 T07 := X1 or T05;
eucrypt_ch11_serpent 124 T08 := T01 and T06;
eucrypt_ch11_serpent 125 T09 := T03 xor T07;
eucrypt_ch11_serpent 126 T10 := T02 or T09;
eucrypt_ch11_serpent 127 X := T10 xor T08;
eucrypt_ch11_serpent 128 T12 := X0 or X3;
eucrypt_ch11_serpent 129 T13 := T09 xor x;
eucrypt_ch11_serpent 130 T14 := X1 xor T13;
eucrypt_ch11_serpent 131 Z := not T09;
eucrypt_ch11_serpent 132 Y := T12 xor T14;
eucrypt_ch11_serpent 133 elsif R = 3 then
eucrypt_ch11_serpent 134 -- S3: 0 15 11 8 12 9 6 3 13 1 2 4 10 7 5 14
eucrypt_ch11_serpent 135 -- depth = 8,3,5,5, Total gates=18
eucrypt_ch11_serpent 136 T01 := X0 xor X2;
eucrypt_ch11_serpent 137 T02 := X0 or X3;
eucrypt_ch11_serpent 138 T03 := X0 and X3;
eucrypt_ch11_serpent 139 T04 := T01 and T02;
eucrypt_ch11_serpent 140 T05 := X1 or T03;
eucrypt_ch11_serpent 141 T06 := X0 and X1;
eucrypt_ch11_serpent 142 T07 := X3 xor T04;
eucrypt_ch11_serpent 143 T08 := X2 or T06;
eucrypt_ch11_serpent 144 T09 := X1 xor T07;
eucrypt_ch11_serpent 145 T10 := X3 and T05;
eucrypt_ch11_serpent 146 T11 := T02 xor T10;
eucrypt_ch11_serpent 147 Z := T08 xor T09;
eucrypt_ch11_serpent 148 T13 := X3 or z;
eucrypt_ch11_serpent 149 T14 := X0 or T07;
eucrypt_ch11_serpent 150 T15 := X1 and T13;
eucrypt_ch11_serpent 151 Y := T08 xor T11;
eucrypt_ch11_serpent 152 W := T14 xor T15;
eucrypt_ch11_serpent 153 X := T05 xor T04;
eucrypt_ch11_serpent 154 elsif R = 4 then
eucrypt_ch11_serpent 155 -- S4: 1 15 8 3 12 0 11 6 2 5 4 10 9 14 7 13
eucrypt_ch11_serpent 156 -- depth = 6,7,5,3, Total gates=19
eucrypt_ch11_serpent 157 T01 := X0 or X1;
eucrypt_ch11_serpent 158 T02 := X1 or X2;
eucrypt_ch11_serpent 159 T03 := X0 xor T02;
eucrypt_ch11_serpent 160 T04 := X1 xor X3;
eucrypt_ch11_serpent 161 T05 := X3 or T03;
eucrypt_ch11_serpent 162 T06 := X3 and T01;
eucrypt_ch11_serpent 163 Z := T03 xor T06;
eucrypt_ch11_serpent 164 T08 := Z and T04;
eucrypt_ch11_serpent 165 T09 := T04 and T05;
eucrypt_ch11_serpent 166 T10 := X2 xor T06;
eucrypt_ch11_serpent 167 T11 := X1 and X2;
eucrypt_ch11_serpent 168 T12 := T04 xor T08;
eucrypt_ch11_serpent 169 T13 := T11 or T03;
eucrypt_ch11_serpent 170 T14 := T10 xor T09;
eucrypt_ch11_serpent 171 T15 := X0 and T05;
eucrypt_ch11_serpent 172 T16 := T11 or T12;
eucrypt_ch11_serpent 173 Y := T13 xor T08;
eucrypt_ch11_serpent 174 X := T15 xor T16;
eucrypt_ch11_serpent 175 W := not T14;
eucrypt_ch11_serpent 176 elsif R = 5 then
eucrypt_ch11_serpent 177 -- S5: 15 5 2 11 4 10 9 12 0 3 14 8 13 6 7 1
eucrypt_ch11_serpent 178 -- depth = 4,6,8,6, Total gates=17
eucrypt_ch11_serpent 179 T01 := X1 xor X3;
eucrypt_ch11_serpent 180 T02 := X1 or X3;
eucrypt_ch11_serpent 181 T03 := X0 and T01;
eucrypt_ch11_serpent 182 T04 := X2 xor T02;
eucrypt_ch11_serpent 183 T05 := T03 xor T04;
eucrypt_ch11_serpent 184 W := not T05;
eucrypt_ch11_serpent 185 T07 := X0 xor T01;
eucrypt_ch11_serpent 186 T08 := X3 or w;
eucrypt_ch11_serpent 187 T09 := X1 or T05;
eucrypt_ch11_serpent 188 T10 := X3 xor T08;
eucrypt_ch11_serpent 189 T11 := X1 or T07;
eucrypt_ch11_serpent 190 T12 := T03 or w;
eucrypt_ch11_serpent 191 T13 := T07 or T10;
eucrypt_ch11_serpent 192 T14 := T01 xor T11;
eucrypt_ch11_serpent 193 Y := T09 xor T13;
eucrypt_ch11_serpent 194 X := T07 xor T08;
eucrypt_ch11_serpent 195 Z := T12 xor T14;
eucrypt_ch11_serpent 196 elsif R = 6 then
eucrypt_ch11_serpent 197 -- S6: 7 2 12 5 8 4 6 11 14 9 1 15 13 3 10 0
eucrypt_ch11_serpent 198 -- depth = 8,3,6,3, Total gates=19
eucrypt_ch11_serpent 199 T01 := X0 and X3;
eucrypt_ch11_serpent 200 T02 := X1 xor X2;
eucrypt_ch11_serpent 201 T03 := X0 xor X3;
eucrypt_ch11_serpent 202 T04 := T01 xor T02;
eucrypt_ch11_serpent 203 T05 := X1 or X2;
eucrypt_ch11_serpent 204 X := not T04;
eucrypt_ch11_serpent 205 T07 := T03 and T05;
eucrypt_ch11_serpent 206 T08 := X1 and x;
eucrypt_ch11_serpent 207 T09 := X0 or X2;
eucrypt_ch11_serpent 208 T10 := T07 xor T08;
eucrypt_ch11_serpent 209 T11 := X1 or X3;
eucrypt_ch11_serpent 210 T12 := X2 xor T11;
eucrypt_ch11_serpent 211 T13 := T09 xor T10;
eucrypt_ch11_serpent 212 Y := not T13;
eucrypt_ch11_serpent 213 T15 := X and T03;
eucrypt_ch11_serpent 214 Z := T12 xor T07;
eucrypt_ch11_serpent 215 T17 := X0 xor X1;
eucrypt_ch11_serpent 216 T18 := Y xor T15;
eucrypt_ch11_serpent 217 W := T17 xor T18;
eucrypt_ch11_serpent 218 elsif R = 7 then
eucrypt_ch11_serpent 219 -- S7: 1 13 15 0 14 8 2 11 7 4 12 10 9 3 5 6
eucrypt_ch11_serpent 220 -- depth = 10,7,10,4, Total gates=19
eucrypt_ch11_serpent 221 T01 := X0 and X2;
eucrypt_ch11_serpent 222 T02 := not X3;
eucrypt_ch11_serpent 223 T03 := X0 and T02;
eucrypt_ch11_serpent 224 T04 := X1 or T01;
eucrypt_ch11_serpent 225 T05 := X0 and X1;
eucrypt_ch11_serpent 226 T06 := X2 xor T04;
eucrypt_ch11_serpent 227 Z := T03 xor T06;
eucrypt_ch11_serpent 228 T08 := X2 or z;
eucrypt_ch11_serpent 229 T09 := X3 or T05;
eucrypt_ch11_serpent 230 T10 := X0 xor T08;
eucrypt_ch11_serpent 231 T11 := T04 and z;
eucrypt_ch11_serpent 232 X := T09 xor T10;
eucrypt_ch11_serpent 233 T13 := X1 xor x;
eucrypt_ch11_serpent 234 T14 := T01 xor x;
eucrypt_ch11_serpent 235 T15 := X2 xor T05;
eucrypt_ch11_serpent 236 T16 := T11 or T13;
eucrypt_ch11_serpent 237 T17 := T02 or T14;
eucrypt_ch11_serpent 238 W := T15 xor T17;
eucrypt_ch11_serpent 239 Y := X0 xor T16;
eucrypt_ch11_serpent 240 end if;
eucrypt_ch11_serpent 241 X0 := W;
eucrypt_ch11_serpent 242 X1 := X;
eucrypt_ch11_serpent 243 X2 := Y;
eucrypt_ch11_serpent 244 X3 := Z;
eucrypt_ch11_serpent 245 end S;
eucrypt_ch11_serpent 246
eucrypt_ch11_serpent 247
eucrypt_ch11_serpent 248 -- Inverse Sbox function
eucrypt_ch11_serpent 249
eucrypt_ch11_serpent 250 procedure SI (R : Integer; X0, X1, X2, X3 : in out Unsigned_32) is
eucrypt_ch11_serpent 251 T01, T02, T03, T04, T05, T06, T07, T08, T09,
eucrypt_ch11_serpent 252 T10, T11, T12, T13, T14, T15, T16, T17, T18 : Unsigned_32;
eucrypt_ch11_serpent 253 W, X, Y, Z : Unsigned_32;
eucrypt_ch11_serpent 254 begin
eucrypt_ch11_serpent 255 if R = 0 then
eucrypt_ch11_serpent 256 -- InvS0: 13 3 11 0 10 6 5 12 1 14 4 7 15 9 8 2
eucrypt_ch11_serpent 257 -- depth = 8,4,3,6, Total gates=19
eucrypt_ch11_serpent 258 T01 := X2 xor X3;
eucrypt_ch11_serpent 259 T02 := X0 or X1;
eucrypt_ch11_serpent 260 T03 := X1 or X2;
eucrypt_ch11_serpent 261 T04 := X2 and T01;
eucrypt_ch11_serpent 262 T05 := T02 xor T01;
eucrypt_ch11_serpent 263 T06 := X0 or T04;
eucrypt_ch11_serpent 264 Y := not T05;
eucrypt_ch11_serpent 265 T08 := X1 xor X3;
eucrypt_ch11_serpent 266 T09 := T03 and T08;
eucrypt_ch11_serpent 267 T10 := X3 or y;
eucrypt_ch11_serpent 268 X := T09 xor T06;
eucrypt_ch11_serpent 269 T12 := X0 or T05;
eucrypt_ch11_serpent 270 T13 := X xor T12;
eucrypt_ch11_serpent 271 T14 := T03 xor T10;
eucrypt_ch11_serpent 272 T15 := X0 xor X2;
eucrypt_ch11_serpent 273 Z := T14 xor T13;
eucrypt_ch11_serpent 274 T17 := T05 and T13;
eucrypt_ch11_serpent 275 T18 := T14 or T17;
eucrypt_ch11_serpent 276 W := T15 xor T18;
eucrypt_ch11_serpent 277 elsif R = 1 then
eucrypt_ch11_serpent 278 -- InvS1: 5 8 2 14 15 6 12 3 11 4 7 9 1 13 10 0
eucrypt_ch11_serpent 279 -- depth = 7,4,5,3, Total gates=18
eucrypt_ch11_serpent 280 T01 := X0 xor X1;
eucrypt_ch11_serpent 281 T02 := X1 or X3;
eucrypt_ch11_serpent 282 T03 := X0 and X2;
eucrypt_ch11_serpent 283 T04 := X2 xor T02;
eucrypt_ch11_serpent 284 T05 := X0 or T04;
eucrypt_ch11_serpent 285 T06 := T01 and T05;
eucrypt_ch11_serpent 286 T07 := X3 or T03;
eucrypt_ch11_serpent 287 T08 := X1 xor T06;
eucrypt_ch11_serpent 288 T09 := T07 xor T06;
eucrypt_ch11_serpent 289 T10 := T04 or T03;
eucrypt_ch11_serpent 290 T11 := X3 and T08;
eucrypt_ch11_serpent 291 Y := not T09;
eucrypt_ch11_serpent 292 X := T10 xor T11;
eucrypt_ch11_serpent 293 T14 := X0 or y;
eucrypt_ch11_serpent 294 T15 := T06 xor x;
eucrypt_ch11_serpent 295 Z := T01 xor T04;
eucrypt_ch11_serpent 296 T17 := X2 xor T15;
eucrypt_ch11_serpent 297 W := T14 xor T17;
eucrypt_ch11_serpent 298 elsif R = 2 then
eucrypt_ch11_serpent 299 -- InvS2: 12 9 15 4 11 14 1 2 0 3 6 13 5 8 10 7
eucrypt_ch11_serpent 300 -- depth = 3,6,8,3, Total gates=18
eucrypt_ch11_serpent 301 T01 := X0 xor X3;
eucrypt_ch11_serpent 302 T02 := X2 xor X3;
eucrypt_ch11_serpent 303 T03 := X0 and X2;
eucrypt_ch11_serpent 304 T04 := X1 or T02;
eucrypt_ch11_serpent 305 W := T01 xor T04;
eucrypt_ch11_serpent 306 T06 := X0 or X2;
eucrypt_ch11_serpent 307 T07 := X3 or w;
eucrypt_ch11_serpent 308 T08 := not X3;
eucrypt_ch11_serpent 309 T09 := X1 and T06;
eucrypt_ch11_serpent 310 T10 := T08 or T03;
eucrypt_ch11_serpent 311 T11 := X1 and T07;
eucrypt_ch11_serpent 312 T12 := T06 and T02;
eucrypt_ch11_serpent 313 Z := T09 xor T10;
eucrypt_ch11_serpent 314 X := T12 xor T11;
eucrypt_ch11_serpent 315 T15 := X2 and z;
eucrypt_ch11_serpent 316 T16 := W xor x;
eucrypt_ch11_serpent 317 T17 := T10 xor T15;
eucrypt_ch11_serpent 318 Y := T16 xor T17;
eucrypt_ch11_serpent 319 elsif R = 3 then
eucrypt_ch11_serpent 320 -- InvS3: 0 9 10 7 11 14 6 13 3 5 12 2 4 8 15 1
eucrypt_ch11_serpent 321 -- depth = 3,6,4,4, Total gates=17
eucrypt_ch11_serpent 322 T01 := X2 or X3;
eucrypt_ch11_serpent 323 T02 := X0 or X3;
eucrypt_ch11_serpent 324 T03 := X2 xor T02;
eucrypt_ch11_serpent 325 T04 := X1 xor T02;
eucrypt_ch11_serpent 326 T05 := X0 xor X3;
eucrypt_ch11_serpent 327 T06 := T04 and T03;
eucrypt_ch11_serpent 328 T07 := X1 and T01;
eucrypt_ch11_serpent 329 Y := T05 xor T06;
eucrypt_ch11_serpent 330 T09 := X0 xor T03;
eucrypt_ch11_serpent 331 W := T07 xor T03;
eucrypt_ch11_serpent 332 T11 := W or T05;
eucrypt_ch11_serpent 333 T12 := T09 and T11;
eucrypt_ch11_serpent 334 T13 := X0 and y;
eucrypt_ch11_serpent 335 T14 := T01 xor T05;
eucrypt_ch11_serpent 336 X := X1 xor T12;
eucrypt_ch11_serpent 337 T16 := X1 or T13;
eucrypt_ch11_serpent 338 Z := T14 xor T16;
eucrypt_ch11_serpent 339 elsif R = 4 then
eucrypt_ch11_serpent 340 -- InvS4: 5 0 8 3 10 9 7 14 2 12 11 6 4 15 13 1
eucrypt_ch11_serpent 341 -- depth = 6,4,7,3, Total gates=17
eucrypt_ch11_serpent 342 T01 := X1 or X3;
eucrypt_ch11_serpent 343 T02 := X2 or X3;
eucrypt_ch11_serpent 344 T03 := X0 and T01;
eucrypt_ch11_serpent 345 T04 := X1 xor T02;
eucrypt_ch11_serpent 346 T05 := X2 xor X3;
eucrypt_ch11_serpent 347 T06 := not T03;
eucrypt_ch11_serpent 348 T07 := X0 and T04;
eucrypt_ch11_serpent 349 X := T05 xor T07;
eucrypt_ch11_serpent 350 T09 := X or T06;
eucrypt_ch11_serpent 351 T10 := X0 xor T07;
eucrypt_ch11_serpent 352 T11 := T01 xor T09;
eucrypt_ch11_serpent 353 T12 := X3 xor T04;
eucrypt_ch11_serpent 354 T13 := X2 or T10;
eucrypt_ch11_serpent 355 Z := T03 xor T12;
eucrypt_ch11_serpent 356 T15 := X0 xor T04;
eucrypt_ch11_serpent 357 Y := T11 xor T13;
eucrypt_ch11_serpent 358 W := T15 xor T09;
eucrypt_ch11_serpent 359 elsif R = 5 then
eucrypt_ch11_serpent 360 -- InvS5: 8 15 2 9 4 1 13 14 11 6 5 3 7 12 10 0
eucrypt_ch11_serpent 361 -- depth = 4,6,9,7, Total gates=17
eucrypt_ch11_serpent 362 T01 := X0 and X3;
eucrypt_ch11_serpent 363 T02 := X2 xor T01;
eucrypt_ch11_serpent 364 T03 := X0 xor X3;
eucrypt_ch11_serpent 365 T04 := X1 and T02;
eucrypt_ch11_serpent 366 T05 := X0 and X2;
eucrypt_ch11_serpent 367 W := T03 xor T04;
eucrypt_ch11_serpent 368 T07 := X0 and w;
eucrypt_ch11_serpent 369 T08 := T01 xor w;
eucrypt_ch11_serpent 370 T09 := X1 or T05;
eucrypt_ch11_serpent 371 T10 := not X1;
eucrypt_ch11_serpent 372 X := T08 xor T09;
eucrypt_ch11_serpent 373 T12 := T10 or T07;
eucrypt_ch11_serpent 374 T13 := W or x;
eucrypt_ch11_serpent 375 Z := T02 xor T12;
eucrypt_ch11_serpent 376 T15 := T02 xor T13;
eucrypt_ch11_serpent 377 T16 := X1 xor X3;
eucrypt_ch11_serpent 378 Y := T16 xor T15;
eucrypt_ch11_serpent 379 elsif R = 6 then
eucrypt_ch11_serpent 380 -- InvS6: 15 10 1 13 5 3 6 0 4 9 14 7 2 12 8 11
eucrypt_ch11_serpent 381 -- depth = 5,3,8,6, Total gates=19
eucrypt_ch11_serpent 382 T01 := X0 xor X2;
eucrypt_ch11_serpent 383 T02 := not X2;
eucrypt_ch11_serpent 384 T03 := X1 and T01;
eucrypt_ch11_serpent 385 T04 := X1 or T02;
eucrypt_ch11_serpent 386 T05 := X3 or T03;
eucrypt_ch11_serpent 387 T06 := X1 xor X3;
eucrypt_ch11_serpent 388 T07 := X0 and T04;
eucrypt_ch11_serpent 389 T08 := X0 or T02;
eucrypt_ch11_serpent 390 T09 := T07 xor T05;
eucrypt_ch11_serpent 391 X := T06 xor T08;
eucrypt_ch11_serpent 392 W := not T09;
eucrypt_ch11_serpent 393 T12 := X1 and w;
eucrypt_ch11_serpent 394 T13 := T01 and T05;
eucrypt_ch11_serpent 395 T14 := T01 xor T12;
eucrypt_ch11_serpent 396 T15 := T07 xor T13;
eucrypt_ch11_serpent 397 T16 := X3 or T02;
eucrypt_ch11_serpent 398 T17 := X0 xor x;
eucrypt_ch11_serpent 399 Z := T17 xor T15;
eucrypt_ch11_serpent 400 Y := T16 xor T14;
eucrypt_ch11_serpent 401 elsif R = 7 then
eucrypt_ch11_serpent 402 -- InvS7: 3 0 6 13 9 14 15 8 5 12 11 7 10 1 4 2
eucrypt_ch11_serpent 403 -- depth := 9,7,3,3, Total gates:=18
eucrypt_ch11_serpent 404 T01 := X0 and X1;
eucrypt_ch11_serpent 405 T02 := X0 or X1;
eucrypt_ch11_serpent 406 T03 := X2 or T01;
eucrypt_ch11_serpent 407 T04 := X3 and T02;
eucrypt_ch11_serpent 408 Z := T03 xor T04;
eucrypt_ch11_serpent 409 T06 := X1 xor T04;
eucrypt_ch11_serpent 410 T07 := X3 xor z;
eucrypt_ch11_serpent 411 T08 := not T07;
eucrypt_ch11_serpent 412 T09 := T06 or T08;
eucrypt_ch11_serpent 413 T10 := X1 xor X3;
eucrypt_ch11_serpent 414 T11 := X0 or X3;
eucrypt_ch11_serpent 415 X := X0 xor T09;
eucrypt_ch11_serpent 416 T13 := X2 xor T06;
eucrypt_ch11_serpent 417 T14 := X2 and T11;
eucrypt_ch11_serpent 418 T15 := X3 or x;
eucrypt_ch11_serpent 419 T16 := T01 or T10;
eucrypt_ch11_serpent 420 W := T13 xor T15;
eucrypt_ch11_serpent 421 Y := T14 xor T16;
eucrypt_ch11_serpent 422 end if;
eucrypt_ch11_serpent 423 X0 := W;
eucrypt_ch11_serpent 424 X1 := X;
eucrypt_ch11_serpent 425 X2 := Y;
eucrypt_ch11_serpent 426 X3 := Z;
eucrypt_ch11_serpent 427 end SI;
eucrypt_ch11_serpent 428
eucrypt_ch11_serpent 429
eucrypt_ch11_serpent 430 -- Linear Transform
eucrypt_ch11_serpent 431
eucrypt_ch11_serpent 432 procedure Tr (X0, X1, X2, X3 : in out Unsigned_32) is
eucrypt_ch11_serpent 433 begin
eucrypt_ch11_serpent 434 X0 := Rotate_Left(X0, 13);
eucrypt_ch11_serpent 435 X2 := Rotate_Left(X2, 3);
eucrypt_ch11_serpent 436 X1 := X1 xor X0 xor X2;
eucrypt_ch11_serpent 437 X3 := X3 xor X2 xor Shift_Left(X0, 3);
eucrypt_ch11_serpent 438 X1 := Rotate_Left(X1, 1);
eucrypt_ch11_serpent 439 X3 := Rotate_Left(X3, 7);
eucrypt_ch11_serpent 440 X0 := X0 xor X1 xor X3;
eucrypt_ch11_serpent 441 X2 := X2 xor X3 xor Shift_Left(X1, 7);
eucrypt_ch11_serpent 442 X0 := Rotate_Left(X0, 5);
eucrypt_ch11_serpent 443 X2 := Rotate_Left(X2, 22);
eucrypt_ch11_serpent 444 end Tr;
eucrypt_ch11_serpent 445
eucrypt_ch11_serpent 446
eucrypt_ch11_serpent 447 -- Inverse Linear Transform
eucrypt_ch11_serpent 448
eucrypt_ch11_serpent 449 procedure TrI (X0, X1, X2, X3 : in out Unsigned_32) is
eucrypt_ch11_serpent 450 begin
eucrypt_ch11_serpent 451 X2 := Rotate_Right(X2, 22);
eucrypt_ch11_serpent 452 X0 := Rotate_Right(X0, 5);
eucrypt_ch11_serpent 453 X2 := X2 xor X3 xor Shift_Left(X1, 7);
eucrypt_ch11_serpent 454 X0 := X0 xor X1 xor X3;
eucrypt_ch11_serpent 455 X3 := Rotate_Right(X3, 7);
eucrypt_ch11_serpent 456 X1 := Rotate_Right(X1, 1);
eucrypt_ch11_serpent 457 X3 := X3 xor X2 xor Shift_Left(X0, 3);
eucrypt_ch11_serpent 458 X1 := X1 xor X0 xor X2;
eucrypt_ch11_serpent 459 X2 := Rotate_Right(X2, 3);
eucrypt_ch11_serpent 460 X0 := Rotate_Right(X0, 13);
eucrypt_ch11_serpent 461 end TrI;
eucrypt_ch11_serpent 462
eucrypt_ch11_serpent 463
eucrypt_ch11_serpent 464 procedure Keying (W : Key_Schedule;
eucrypt_ch11_serpent 465 R : Integer;
eucrypt_ch11_serpent 466 X0, X1, X2, X3 : in out Unsigned_32) is
eucrypt_ch11_serpent 467 begin
eucrypt_ch11_serpent 468 X0 := X0 xor W(4*R);
eucrypt_ch11_serpent 469 X1 := X1 xor W(4*R+1);
eucrypt_ch11_serpent 470 X2 := X2 xor W(4*R+2);
eucrypt_ch11_serpent 471 X3 := X3 xor W(4*R+3);
eucrypt_ch11_serpent 472 end Keying;
eucrypt_ch11_serpent 473
eucrypt_ch11_serpent 474
eucrypt_ch11_serpent 475 pragma Inline(S, SI, Tr, TrI, Keying);
eucrypt_ch11_serpent 476
eucrypt_ch11_serpent 477
eucrypt_ch11_serpent 478 procedure Prepare_Key (K : in Key; W : out Key_Schedule) is
eucrypt_ch11_serpent 479 begin
eucrypt_ch11_serpent 480 for I in 0..7 loop
eucrypt_ch11_serpent 481 W(-8+I) := Bytes_To_Word(K(4*I .. 4*I+3));
eucrypt_ch11_serpent 482 end loop;
eucrypt_ch11_serpent 483 for I in 0..131 loop
eucrypt_ch11_serpent 484 W(I) := Rotate_Left(W(I-8) xor W(I-5) xor W(I-3) xor W(I-1) xor
eucrypt_ch11_serpent 485 16#9e3779b9# xor Unsigned_32(I), 11);
eucrypt_ch11_serpent 486 end loop;
eucrypt_ch11_serpent 487 S(3, W( 0), W( 1), W( 2), W( 3));
eucrypt_ch11_serpent 488 S(2, W( 4), W( 5), W( 6), W( 7));
eucrypt_ch11_serpent 489 S(1, W( 8), W( 9), W( 10), W( 11));
eucrypt_ch11_serpent 490 S(0, W( 12), W( 13), W( 14), W( 15));
eucrypt_ch11_serpent 491 S(7, W( 16), W( 17), W( 18), W( 19));
eucrypt_ch11_serpent 492 S(6, W( 20), W( 21), W( 22), W( 23));
eucrypt_ch11_serpent 493 S(5, W( 24), W( 25), W( 26), W( 27));
eucrypt_ch11_serpent 494 S(4, W( 28), W( 29), W( 30), W( 31));
eucrypt_ch11_serpent 495 S(3, W( 32), W( 33), W( 34), W( 35));
eucrypt_ch11_serpent 496 S(2, W( 36), W( 37), W( 38), W( 39));
eucrypt_ch11_serpent 497 S(1, W( 40), W( 41), W( 42), W( 43));
eucrypt_ch11_serpent 498 S(0, W( 44), W( 45), W( 46), W( 47));
eucrypt_ch11_serpent 499 S(7, W( 48), W( 49), W( 50), W( 51));
eucrypt_ch11_serpent 500 S(6, W( 52), W( 53), W( 54), W( 55));
eucrypt_ch11_serpent 501 S(5, W( 56), W( 57), W( 58), W( 59));
eucrypt_ch11_serpent 502 S(4, W( 60), W( 61), W( 62), W( 63));
eucrypt_ch11_serpent 503 S(3, W( 64), W( 65), W( 66), W( 67));
eucrypt_ch11_serpent 504 S(2, W( 68), W( 69), W( 70), W( 71));
eucrypt_ch11_serpent 505 S(1, W( 72), W( 73), W( 74), W( 75));
eucrypt_ch11_serpent 506 S(0, W( 76), W( 77), W( 78), W( 79));
eucrypt_ch11_serpent 507 S(7, W( 80), W( 81), W( 82), W( 83));
eucrypt_ch11_serpent 508 S(6, W( 84), W( 85), W( 86), W( 87));
eucrypt_ch11_serpent 509 S(5, W( 88), W( 89), W( 90), W( 91));
eucrypt_ch11_serpent 510 S(4, W( 92), W( 93), W( 94), W( 95));
eucrypt_ch11_serpent 511 S(3, W( 96), W( 97), W( 98), W( 99));
eucrypt_ch11_serpent 512 S(2, W(100), W(101), W(102), W(103));
eucrypt_ch11_serpent 513 S(1, W(104), W(105), W(106), W(107));
eucrypt_ch11_serpent 514 S(0, W(108), W(109), W(110), W(111));
eucrypt_ch11_serpent 515 S(7, W(112), W(113), W(114), W(115));
eucrypt_ch11_serpent 516 S(6, W(116), W(117), W(118), W(119));
eucrypt_ch11_serpent 517 S(5, W(120), W(121), W(122), W(123));
eucrypt_ch11_serpent 518 S(4, W(124), W(125), W(126), W(127));
eucrypt_ch11_serpent 519 S(3, W(128), W(129), W(130), W(131));
eucrypt_ch11_serpent 520 end Prepare_Key;
eucrypt_ch11_serpent 521
eucrypt_ch11_serpent 522
eucrypt_ch11_serpent 523 procedure Encrypt (W : in Key_Schedule; Plaintext : in Block;
eucrypt_ch11_serpent 524 Ciphertext : out Block) is
eucrypt_ch11_serpent 525 X0, X1, X2, X3 : Unsigned_32;
eucrypt_ch11_serpent 526 begin
eucrypt_ch11_serpent 527 X0 := Bytes_To_Word(Plaintext( 0 .. 3));
eucrypt_ch11_serpent 528 X1 := Bytes_To_Word(Plaintext( 4 .. 7));
eucrypt_ch11_serpent 529 X2 := Bytes_To_Word(Plaintext( 8 .. 11));
eucrypt_ch11_serpent 530 X3 := Bytes_To_Word(Plaintext(12 .. 15));
eucrypt_ch11_serpent 531
eucrypt_ch11_serpent 532 Keying(W, 0, X0, X1, X2, X3); S(0, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 533 Keying(W, 1, X0, X1, X2, X3); S(1, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 534 Keying(W, 2, X0, X1, X2, X3); S(2, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 535 Keying(W, 3, X0, X1, X2, X3); S(3, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 536 Keying(W, 4, X0, X1, X2, X3); S(4, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 537 Keying(W, 5, X0, X1, X2, X3); S(5, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 538 Keying(W, 6, X0, X1, X2, X3); S(6, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 539 Keying(W, 7, X0, X1, X2, X3); S(7, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 540 Keying(W, 8, X0, X1, X2, X3); S(0, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 541 Keying(W, 9, X0, X1, X2, X3); S(1, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 542 Keying(W, 10, X0, X1, X2, X3); S(2, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 543 Keying(W, 11, X0, X1, X2, X3); S(3, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 544 Keying(W, 12, X0, X1, X2, X3); S(4, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 545 Keying(W, 13, X0, X1, X2, X3); S(5, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 546 Keying(W, 14, X0, X1, X2, X3); S(6, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 547 Keying(W, 15, X0, X1, X2, X3); S(7, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 548 Keying(W, 16, X0, X1, X2, X3); S(0, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 549 Keying(W, 17, X0, X1, X2, X3); S(1, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 550 Keying(W, 18, X0, X1, X2, X3); S(2, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 551 Keying(W, 19, X0, X1, X2, X3); S(3, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 552 Keying(W, 20, X0, X1, X2, X3); S(4, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 553 Keying(W, 21, X0, X1, X2, X3); S(5, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 554 Keying(W, 22, X0, X1, X2, X3); S(6, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 555 Keying(W, 23, X0, X1, X2, X3); S(7, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 556 Keying(W, 24, X0, X1, X2, X3); S(0, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 557 Keying(W, 25, X0, X1, X2, X3); S(1, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 558 Keying(W, 26, X0, X1, X2, X3); S(2, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 559 Keying(W, 27, X0, X1, X2, X3); S(3, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 560 Keying(W, 28, X0, X1, X2, X3); S(4, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 561 Keying(W, 29, X0, X1, X2, X3); S(5, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 562 Keying(W, 30, X0, X1, X2, X3); S(6, X0, X1, X2, X3); Tr(X0, X1, X2, X3);
eucrypt_ch11_serpent 563 Keying(W, 31, X0, X1, X2, X3);
eucrypt_ch11_serpent 564 S(7, X0, X1, X2, X3);
eucrypt_ch11_serpent 565 Keying(W, 32, X0, X1, X2, X3);
eucrypt_ch11_serpent 566
eucrypt_ch11_serpent 567 Ciphertext( 0 .. 3) := Word_To_Bytes(X0);
eucrypt_ch11_serpent 568 Ciphertext( 4 .. 7) := Word_To_Bytes(X1);
eucrypt_ch11_serpent 569 Ciphertext( 8 .. 11) := Word_To_Bytes(X2);
eucrypt_ch11_serpent 570 Ciphertext(12 .. 15) := Word_To_Bytes(X3);
eucrypt_ch11_serpent 571 end Encrypt;
eucrypt_ch11_serpent 572
eucrypt_ch11_serpent 573
eucrypt_ch11_serpent 574 procedure Decrypt (W : in Key_Schedule; Ciphertext : in Block;
eucrypt_ch11_serpent 575 Plaintext : out Block) is
eucrypt_ch11_serpent 576 X0, X1, X2, X3 : Unsigned_32;
eucrypt_ch11_serpent 577 begin
eucrypt_ch11_serpent 578 X0 := Bytes_To_Word(Ciphertext( 0 .. 3));
eucrypt_ch11_serpent 579 X1 := Bytes_To_Word(Ciphertext( 4 .. 7));
eucrypt_ch11_serpent 580 X2 := Bytes_To_Word(Ciphertext( 8 .. 11));
eucrypt_ch11_serpent 581 X3 := Bytes_To_Word(Ciphertext(12 .. 15));
eucrypt_ch11_serpent 582
eucrypt_ch11_serpent 583 Keying(W, 32, X0, X1, X2, X3);
eucrypt_ch11_serpent 584 SI(7, X0, X1, X2, X3);
eucrypt_ch11_serpent 585 Keying(W, 31, X0, X1, X2, X3);
eucrypt_ch11_serpent 586 TrI(X0, X1, X2, X3); SI(6, X0, X1, X2, X3); Keying(W,30, X0, X1, X2, X3);
eucrypt_ch11_serpent 587 TrI(X0, X1, X2, X3); SI(5, X0, X1, X2, X3); Keying(W,29, X0, X1, X2, X3);
eucrypt_ch11_serpent 588 TrI(X0, X1, X2, X3); SI(4, X0, X1, X2, X3); Keying(W,28, X0, X1, X2, X3);
eucrypt_ch11_serpent 589 TrI(X0, X1, X2, X3); SI(3, X0, X1, X2, X3); Keying(W,27, X0, X1, X2, X3);
eucrypt_ch11_serpent 590 TrI(X0, X1, X2, X3); SI(2, X0, X1, X2, X3); Keying(W,26, X0, X1, X2, X3);
eucrypt_ch11_serpent 591 TrI(X0, X1, X2, X3); SI(1, X0, X1, X2, X3); Keying(W,25, X0, X1, X2, X3);
eucrypt_ch11_serpent 592 TrI(X0, X1, X2, X3); SI(0, X0, X1, X2, X3); Keying(W,24, X0, X1, X2, X3);
eucrypt_ch11_serpent 593 TrI(X0, X1, X2, X3); SI(7, X0, X1, X2, X3); Keying(W,23, X0, X1, X2, X3);
eucrypt_ch11_serpent 594 TrI(X0, X1, X2, X3); SI(6, X0, X1, X2, X3); Keying(W,22, X0, X1, X2, X3);
eucrypt_ch11_serpent 595 TrI(X0, X1, X2, X3); SI(5, X0, X1, X2, X3); Keying(W,21, X0, X1, X2, X3);
eucrypt_ch11_serpent 596 TrI(X0, X1, X2, X3); SI(4, X0, X1, X2, X3); Keying(W,20, X0, X1, X2, X3);
eucrypt_ch11_serpent 597 TrI(X0, X1, X2, X3); SI(3, X0, X1, X2, X3); Keying(W,19, X0, X1, X2, X3);
eucrypt_ch11_serpent 598 TrI(X0, X1, X2, X3); SI(2, X0, X1, X2, X3); Keying(W,18, X0, X1, X2, X3);
eucrypt_ch11_serpent 599 TrI(X0, X1, X2, X3); SI(1, X0, X1, X2, X3); Keying(W,17, X0, X1, X2, X3);
eucrypt_ch11_serpent 600 TrI(X0, X1, X2, X3); SI(0, X0, X1, X2, X3); Keying(W,16, X0, X1, X2, X3);
eucrypt_ch11_serpent 601 TrI(X0, X1, X2, X3); SI(7, X0, X1, X2, X3); Keying(W,15, X0, X1, X2, X3);
eucrypt_ch11_serpent 602 TrI(X0, X1, X2, X3); SI(6, X0, X1, X2, X3); Keying(W,14, X0, X1, X2, X3);
eucrypt_ch11_serpent 603 TrI(X0, X1, X2, X3); SI(5, X0, X1, X2, X3); Keying(W,13, X0, X1, X2, X3);
eucrypt_ch11_serpent 604 TrI(X0, X1, X2, X3); SI(4, X0, X1, X2, X3); Keying(W,12, X0, X1, X2, X3);
eucrypt_ch11_serpent 605 TrI(X0, X1, X2, X3); SI(3, X0, X1, X2, X3); Keying(W,11, X0, X1, X2, X3);
eucrypt_ch11_serpent 606 TrI(X0, X1, X2, X3); SI(2, X0, X1, X2, X3); Keying(W,10, X0, X1, X2, X3);
eucrypt_ch11_serpent 607 TrI(X0, X1, X2, X3); SI(1, X0, X1, X2, X3); Keying(W, 9, X0, X1, X2, X3);
eucrypt_ch11_serpent 608 TrI(X0, X1, X2, X3); SI(0, X0, X1, X2, X3); Keying(W, 8, X0, X1, X2, X3);
eucrypt_ch11_serpent 609 TrI(X0, X1, X2, X3); SI(7, X0, X1, X2, X3); Keying(W, 7, X0, X1, X2, X3);
eucrypt_ch11_serpent 610 TrI(X0, X1, X2, X3); SI(6, X0, X1, X2, X3); Keying(W, 6, X0, X1, X2, X3);
eucrypt_ch11_serpent 611 TrI(X0, X1, X2, X3); SI(5, X0, X1, X2, X3); Keying(W, 5, X0, X1, X2, X3);
eucrypt_ch11_serpent 612 TrI(X0, X1, X2, X3); SI(4, X0, X1, X2, X3); Keying(W, 4, X0, X1, X2, X3);
eucrypt_ch11_serpent 613 TrI(X0, X1, X2, X3); SI(3, X0, X1, X2, X3); Keying(W, 3, X0, X1, X2, X3);
eucrypt_ch11_serpent 614 TrI(X0, X1, X2, X3); SI(2, X0, X1, X2, X3); Keying(W, 2, X0, X1, X2, X3);
eucrypt_ch11_serpent 615 TrI(X0, X1, X2, X3); SI(1, X0, X1, X2, X3); Keying(W, 1, X0, X1, X2, X3);
eucrypt_ch11_serpent 616 TrI(X0, X1, X2, X3); SI(0, X0, X1, X2, X3); Keying(W, 0, X0, X1, X2, X3);
eucrypt_ch11_serpent 617
eucrypt_ch11_serpent 618 Plaintext( 0 .. 3) := Word_To_Bytes(X0);
eucrypt_ch11_serpent 619 Plaintext( 4 .. 7) := Word_To_Bytes(X1);
eucrypt_ch11_serpent 620 Plaintext( 8 .. 11) := Word_To_Bytes(X2);
eucrypt_ch11_serpent 621 Plaintext(12 .. 15) := Word_To_Bytes(X3);
eucrypt_ch11_serpent 622 end Decrypt;
eucrypt_ch11_serpent 623
eucrypt_ch11_serpent 624
eucrypt_ch11_serpent 625 procedure Selftest is
eucrypt_ch11_serpent 626 K : Key := (others => 0);
eucrypt_ch11_serpent 627 P : Block := (others => 0);
eucrypt_ch11_serpent 628 P2, C : Block;
eucrypt_ch11_serpent 629 W : Key_Schedule;
eucrypt_ch11_serpent 630 begin
eucrypt_ch11_serpent 631 for I in 1 .. 128 loop
eucrypt_ch11_serpent 632 Prepare_Key(K, W);
eucrypt_ch11_serpent 633 Encrypt(W, P, C);
eucrypt_ch11_serpent 634 Decrypt(W, C, P2);
eucrypt_ch11_serpent 635 if (P2 /= P) then
eucrypt_ch11_serpent 636 raise Implementation_Error;
eucrypt_ch11_serpent 637 end if;
eucrypt_ch11_serpent 638 P := K( 0 .. 15);
eucrypt_ch11_serpent 639 K( 0 .. 15) := K(16 .. 31);
eucrypt_ch11_serpent 640 K(16 .. 31) := C;
eucrypt_ch11_serpent 641 end loop;
eucrypt_ch11_serpent 642 if C /= (16#A2#, 16#46#, 16#AB#, 16#69#, 16#0A#, 16#E6#, 16#8D#, 16#FB#,
eucrypt_ch11_serpent 643 16#02#, 16#04#, 16#CB#, 16#E2#, 16#8E#, 16#D8#, 16#EB#, 16#7A#)
eucrypt_ch11_serpent 644 then
eucrypt_ch11_serpent 645 raise Implementation_Error;
eucrypt_ch11_serpent 646 end if;
eucrypt_ch11_serpent 647 end Selftest;
eucrypt_ch11_serpent 648
eucrypt_ch11_serpent 649 end SMG_Serpent;