1
/*************************************************
2
* Serpent Source File *
3
* (C) 1999-2007 The Botan Project *
4
*************************************************/
6
#include <botan/asm_macr.h>
8
START_LISTING(serp_asm.S)
10
#define SBOX_E1(A, B, C, D, T) \
33
#define SBOX_E2(A, B, C, D, T) \
57
#define SBOX_E3(A, B, C, D, T) \
79
#define SBOX_E4(A, B, C, D, T) \
104
#define SBOX_E5(A, B, C, D, T) \
129
#define SBOX_E6(A, B, C, D, T) \
154
#define SBOX_E7(A, B, C, D, T) \
176
#define SBOX_E8(A, B, C, D, T) \
202
#define SBOX_D1(A, B, C, D, T) \
225
#define SBOX_D2(A, B, C, D, T) \
251
#define SBOX_D3(A, B, C, D, T) \
274
#define SBOX_D4(A, B, C, D, T) \
298
#define SBOX_D5(A, B, C, D, T) \
322
#define SBOX_D6(A, B, C, D, T) \
348
#define SBOX_D7(A, B, C, D, T) \
370
#define SBOX_D8(A, B, C, D, T) \
395
#define TRANSFORM(A, B, C, D, T) \
414
#define I_TRANSFORM(A, B, C, D, T) \
433
#define KEY_XOR(A, B, C, D, N) \
434
XOR(A, ARRAY4(EDI, (4*N ))) ; \
435
XOR(B, ARRAY4(EDI, (4*N+1))) ; \
436
XOR(C, ARRAY4(EDI, (4*N+2))) ; \
437
XOR(D, ARRAY4(EDI, (4*N+3))) ;
439
/*************************************************
440
* Serpent Encryption *
441
*************************************************/
442
START_FUNCTION(serpent_encrypt)
446
ASSIGN(EBP, ARG(1)) /* input block */
447
ASSIGN(EAX, ARRAY4(EBP, 0))
448
ASSIGN(EBX, ARRAY4(EBP, 1))
449
ASSIGN(ECX, ARRAY4(EBP, 2))
450
ASSIGN(EDX, ARRAY4(EBP, 3))
452
ASSIGN(EDI, ARG(3)) /* round keys */
455
#define E_ROUND(A, B, C, D, T, N, SBOX) \
456
KEY_XOR(A, B, C, D, N) \
457
SBOX(A, B, C, D, T) \
458
TRANSFORM(A, B, C, D, T)
461
E_ROUND(EAX, EBX, ECX, EDX, EBP, 0, SBOX_E1)
462
E_ROUND(EAX, EBX, ECX, EDX, EBP, 1, SBOX_E2)
463
E_ROUND(EAX, EBX, ECX, EDX, EBP, 2, SBOX_E3)
464
E_ROUND(EAX, EBX, ECX, EDX, EBP, 3, SBOX_E4)
465
E_ROUND(EAX, EBX, ECX, EDX, EBP, 4, SBOX_E5)
466
E_ROUND(EAX, EBX, ECX, EDX, EBP, 5, SBOX_E6)
467
E_ROUND(EAX, EBX, ECX, EDX, EBP, 6, SBOX_E7)
468
E_ROUND(EAX, EBX, ECX, EDX, EBP, 7, SBOX_E8)
470
E_ROUND(EAX, EBX, ECX, EDX, EBP, 8, SBOX_E1)
471
E_ROUND(EAX, EBX, ECX, EDX, EBP, 9, SBOX_E2)
472
E_ROUND(EAX, EBX, ECX, EDX, EBP, 10, SBOX_E3)
473
E_ROUND(EAX, EBX, ECX, EDX, EBP, 11, SBOX_E4)
474
E_ROUND(EAX, EBX, ECX, EDX, EBP, 12, SBOX_E5)
475
E_ROUND(EAX, EBX, ECX, EDX, EBP, 13, SBOX_E6)
476
E_ROUND(EAX, EBX, ECX, EDX, EBP, 14, SBOX_E7)
477
E_ROUND(EAX, EBX, ECX, EDX, EBP, 15, SBOX_E8)
479
E_ROUND(EAX, EBX, ECX, EDX, EBP, 16, SBOX_E1)
480
E_ROUND(EAX, EBX, ECX, EDX, EBP, 17, SBOX_E2)
481
E_ROUND(EAX, EBX, ECX, EDX, EBP, 18, SBOX_E3)
482
E_ROUND(EAX, EBX, ECX, EDX, EBP, 19, SBOX_E4)
483
E_ROUND(EAX, EBX, ECX, EDX, EBP, 20, SBOX_E5)
484
E_ROUND(EAX, EBX, ECX, EDX, EBP, 21, SBOX_E6)
485
E_ROUND(EAX, EBX, ECX, EDX, EBP, 22, SBOX_E7)
486
E_ROUND(EAX, EBX, ECX, EDX, EBP, 23, SBOX_E8)
488
E_ROUND(EAX, EBX, ECX, EDX, EBP, 24, SBOX_E1)
489
E_ROUND(EAX, EBX, ECX, EDX, EBP, 25, SBOX_E2)
490
E_ROUND(EAX, EBX, ECX, EDX, EBP, 26, SBOX_E3)
491
E_ROUND(EAX, EBX, ECX, EDX, EBP, 27, SBOX_E4)
492
E_ROUND(EAX, EBX, ECX, EDX, EBP, 28, SBOX_E5)
493
E_ROUND(EAX, EBX, ECX, EDX, EBP, 29, SBOX_E6)
494
E_ROUND(EAX, EBX, ECX, EDX, EBP, 30, SBOX_E7)
496
KEY_XOR(EAX, EBX, ECX, EDX, 31)
497
SBOX_E8(EAX, EBX, ECX, EDX, EBP)
498
KEY_XOR(EAX, EBX, ECX, EDX, 32)
500
ASSIGN(EBP, ARG(2)) /* output block */
501
ASSIGN(ARRAY4(EBP, 0), EAX)
502
ASSIGN(ARRAY4(EBP, 1), EBX)
503
ASSIGN(ARRAY4(EBP, 2), ECX)
504
ASSIGN(ARRAY4(EBP, 3), EDX)
508
END_FUNCTION(serpent_encrypt)
510
/*************************************************
511
* Serpent Decryption *
512
*************************************************/
513
START_FUNCTION(serpent_decrypt)
517
ASSIGN(EBP, ARG(1)) /* input block */
518
ASSIGN(EAX, ARRAY4(EBP, 0))
519
ASSIGN(EBX, ARRAY4(EBP, 1))
520
ASSIGN(ECX, ARRAY4(EBP, 2))
521
ASSIGN(EDX, ARRAY4(EBP, 3))
523
ASSIGN(EDI, ARG(3)) /* round keys */
527
#define D_ROUND(A, B, C, D, T, N, SBOX) \
528
I_TRANSFORM(A, B, C, D, T) \
529
SBOX(A, B, C, D, T) \
530
KEY_XOR(A, B, C, D, N) \
532
KEY_XOR(EAX, EBX, ECX, EDX, 32)
533
SBOX_D8(EAX, EBX, ECX, EDX, EBP)
534
KEY_XOR(EAX, EBX, ECX, EDX, 31)
536
D_ROUND(EAX, EBX, ECX, EDX, EBP, 30, SBOX_D7)
537
D_ROUND(EAX, EBX, ECX, EDX, EBP, 29, SBOX_D6)
538
D_ROUND(EAX, EBX, ECX, EDX, EBP, 28, SBOX_D5)
539
D_ROUND(EAX, EBX, ECX, EDX, EBP, 27, SBOX_D4)
540
D_ROUND(EAX, EBX, ECX, EDX, EBP, 26, SBOX_D3)
541
D_ROUND(EAX, EBX, ECX, EDX, EBP, 25, SBOX_D2)
542
D_ROUND(EAX, EBX, ECX, EDX, EBP, 24, SBOX_D1)
544
D_ROUND(EAX, EBX, ECX, EDX, EBP, 23, SBOX_D8)
545
D_ROUND(EAX, EBX, ECX, EDX, EBP, 22, SBOX_D7)
546
D_ROUND(EAX, EBX, ECX, EDX, EBP, 21, SBOX_D6)
547
D_ROUND(EAX, EBX, ECX, EDX, EBP, 20, SBOX_D5)
548
D_ROUND(EAX, EBX, ECX, EDX, EBP, 19, SBOX_D4)
549
D_ROUND(EAX, EBX, ECX, EDX, EBP, 18, SBOX_D3)
550
D_ROUND(EAX, EBX, ECX, EDX, EBP, 17, SBOX_D2)
551
D_ROUND(EAX, EBX, ECX, EDX, EBP, 16, SBOX_D1)
553
D_ROUND(EAX, EBX, ECX, EDX, EBP, 15, SBOX_D8)
554
D_ROUND(EAX, EBX, ECX, EDX, EBP, 14, SBOX_D7)
555
D_ROUND(EAX, EBX, ECX, EDX, EBP, 13, SBOX_D6)
556
D_ROUND(EAX, EBX, ECX, EDX, EBP, 12, SBOX_D5)
557
D_ROUND(EAX, EBX, ECX, EDX, EBP, 11, SBOX_D4)
558
D_ROUND(EAX, EBX, ECX, EDX, EBP, 10, SBOX_D3)
559
D_ROUND(EAX, EBX, ECX, EDX, EBP, 9, SBOX_D2)
560
D_ROUND(EAX, EBX, ECX, EDX, EBP, 8, SBOX_D1)
562
D_ROUND(EAX, EBX, ECX, EDX, EBP, 7, SBOX_D8)
563
D_ROUND(EAX, EBX, ECX, EDX, EBP, 6, SBOX_D7)
564
D_ROUND(EAX, EBX, ECX, EDX, EBP, 5, SBOX_D6)
565
D_ROUND(EAX, EBX, ECX, EDX, EBP, 4, SBOX_D5)
566
D_ROUND(EAX, EBX, ECX, EDX, EBP, 3, SBOX_D4)
567
D_ROUND(EAX, EBX, ECX, EDX, EBP, 2, SBOX_D3)
568
D_ROUND(EAX, EBX, ECX, EDX, EBP, 1, SBOX_D2)
569
D_ROUND(EAX, EBX, ECX, EDX, EBP, 0, SBOX_D1)
571
ASSIGN(EBP, ARG(2)) /* output block */
572
ASSIGN(ARRAY4(EBP, 0), EAX)
573
ASSIGN(ARRAY4(EBP, 1), EBX)
574
ASSIGN(ARRAY4(EBP, 2), ECX)
575
ASSIGN(ARRAY4(EBP, 3), EDX)
579
END_FUNCTION(serpent_decrypt)
581
/*************************************************
582
* Serpent Key Schedule *
583
*************************************************/
584
START_FUNCTION(serpent_key_schedule)
588
ASSIGN(EDI, ARG(1)) /* round keys */
592
START_LOOP(.EXPANSION)
593
ASSIGN(EAX, ARRAY4(EDI, -1))
594
ASSIGN(EBX, ARRAY4(EDI, -3))
595
ASSIGN(ECX, ARRAY4(EDI, -5))
596
ASSIGN(EDX, ARRAY4(EDI, -8))
600
XOR(EBP, IMM(0x9E3779B9))
608
ASSIGN(ARRAY4(EDI, 0), EAX)
612
LOOP_UNTIL_EQ(ESI, 140, .EXPANSION)
614
ASSIGN(EDI, ARG(1)) /* round keys */
616
#define LOAD_AND_SBOX(MSG, SBOX) \
617
ASSIGN(EAX, ARRAY4(EDI, (4*MSG+ 8))) ; \
618
ASSIGN(EBX, ARRAY4(EDI, (4*MSG+ 9))) ; \
619
ASSIGN(ECX, ARRAY4(EDI, (4*MSG+10))) ; \
620
ASSIGN(EDX, ARRAY4(EDI, (4*MSG+11))) ; \
621
SBOX(EAX, EBX, ECX, EDX, EBP) ; \
622
ASSIGN(ARRAY4(EDI, (4*MSG+ 8)), EAX) ; \
623
ASSIGN(ARRAY4(EDI, (4*MSG+ 9)), EBX) ; \
624
ASSIGN(ARRAY4(EDI, (4*MSG+10)), ECX) ; \
625
ASSIGN(ARRAY4(EDI, (4*MSG+11)), EDX)
627
LOAD_AND_SBOX( 0, SBOX_E4)
628
LOAD_AND_SBOX( 1, SBOX_E3)
629
LOAD_AND_SBOX( 2, SBOX_E2)
630
LOAD_AND_SBOX( 3, SBOX_E1)
632
LOAD_AND_SBOX( 4, SBOX_E8)
633
LOAD_AND_SBOX( 5, SBOX_E7)
634
LOAD_AND_SBOX( 6, SBOX_E6)
635
LOAD_AND_SBOX( 7, SBOX_E5)
636
LOAD_AND_SBOX( 8, SBOX_E4)
637
LOAD_AND_SBOX( 9, SBOX_E3)
638
LOAD_AND_SBOX(10, SBOX_E2)
639
LOAD_AND_SBOX(11, SBOX_E1)
641
LOAD_AND_SBOX(12, SBOX_E8)
642
LOAD_AND_SBOX(13, SBOX_E7)
643
LOAD_AND_SBOX(14, SBOX_E6)
644
LOAD_AND_SBOX(15, SBOX_E5)
645
LOAD_AND_SBOX(16, SBOX_E4)
646
LOAD_AND_SBOX(17, SBOX_E3)
647
LOAD_AND_SBOX(18, SBOX_E2)
648
LOAD_AND_SBOX(19, SBOX_E1)
650
LOAD_AND_SBOX(20, SBOX_E8)
651
LOAD_AND_SBOX(21, SBOX_E7)
652
LOAD_AND_SBOX(22, SBOX_E6)
653
LOAD_AND_SBOX(23, SBOX_E5)
654
LOAD_AND_SBOX(24, SBOX_E4)
655
LOAD_AND_SBOX(25, SBOX_E3)
656
LOAD_AND_SBOX(26, SBOX_E2)
657
LOAD_AND_SBOX(27, SBOX_E1)
659
LOAD_AND_SBOX(28, SBOX_E8)
660
LOAD_AND_SBOX(29, SBOX_E7)
661
LOAD_AND_SBOX(30, SBOX_E6)
662
LOAD_AND_SBOX(31, SBOX_E5)
663
LOAD_AND_SBOX(32, SBOX_E4)
667
END_FUNCTION(serpent_key_schedule)