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