rijndael: refactor to reduce number of #ifdefs and branches
[libgcrypt.git] / cipher / arcfour-amd64.S
1 /*
2 ** RC4 implementation optimized for AMD64.
3 **
4 ** Author: Marc Bevand <bevand_m (at) epita.fr>
5 ** Licence: I hereby disclaim the copyright on this code and place it
6 ** in the public domain.
7 **
8 ** The throughput achieved by this code is about 320 MBytes/sec, on
9 ** a 1.8 GHz AMD Opteron (rev C0) processor.
10 **
11 ** 2013/12/20 <jussi.kivilinna@iki.fi>:
12 **  - Integrated to libgcrypt
13 **  - 4.18 cycles/byte on Intel i5-4570
14 */
15
16 #ifdef __x86_64__
17 #include <config.h>
18 #if defined(USE_ARCFOUR) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS)
19
20 .text
21 .align 16
22 .globl _gcry_arcfour_amd64
23 .type _gcry_arcfour_amd64,@function
24 _gcry_arcfour_amd64:
25         push    %rbp
26         push    %rbx
27         mov     %rdi,           %rbp    # key = ARG(key)
28         mov     %rsi,           %rbx    # rbx = ARG(len)
29         mov     %rdx,           %rsi    # in = ARG(in)
30         mov     %rcx,           %rdi    # out = ARG(out)
31         mov     (4*256)(%rbp),  %ecx    # x = key->x
32         mov     (4*256+4)(%rbp),%edx    # y = key->y
33         inc     %rcx                    # x++
34         and     $255,           %rcx    # x &= 0xff
35         lea     -8(%rbx,%rsi),  %rbx    # rbx = in+len-8
36         mov     %rbx,           %r9     # tmp = in+len-8
37         mov     (%rbp,%rcx,4),  %eax    # tx = d[x]
38         cmp     %rsi,           %rbx    # cmp in with in+len-8
39         jl      .Lend                   # jump if (in+len-8 < in)
40
41 .Lstart:
42         add     $8,             %rsi            # increment in
43         add     $8,             %rdi            # increment out
44
45         # generate the next 8 bytes of the rc4 stream into %r8
46         mov     $8,             %r11            # byte counter
47 1:      add     %al,            %dl             # y += tx
48         mov     (%rbp,%rdx,4),  %ebx            # ty = d[y]
49         mov     %ebx,           (%rbp,%rcx,4)   # d[x] = ty
50         add     %al,            %bl             # val = ty + tx
51         mov     %eax,           (%rbp,%rdx,4)   # d[y] = tx
52         inc     %cl                             # x++           (NEXT ROUND)
53         mov     (%rbp,%rcx,4),  %eax            # tx = d[x]     (NEXT ROUND)
54         shl     $8,             %r8
55         movb    (%rbp,%rbx,4),  %r8b            # val = d[val]
56         dec     %r11b
57         jnz 1b
58
59         # xor 8 bytes
60         bswap   %r8
61         xor     -8(%rsi),       %r8
62         cmp     %r9,            %rsi            # cmp in+len-8 with in
63         mov     %r8,            -8(%rdi)
64         jle     .Lstart                         # jump if (in <= in+len-8)
65
66 .Lend:
67         add     $8,             %r9             # tmp = in+len
68
69         # handle the last bytes, one by one
70 1:      cmp     %rsi,           %r9             # cmp in with in+len
71         jle     .Lfinished                      # jump if (in+len <= in)
72         add     %al,            %dl             # y += tx
73         mov     (%rbp,%rdx,4),  %ebx            # ty = d[y]
74         mov     %ebx,           (%rbp,%rcx,4)   # d[x] = ty
75         add     %al,            %bl             # val = ty + tx
76         mov     %eax,           (%rbp,%rdx,4)   # d[y] = tx
77         inc     %cl                             # x++           (NEXT ROUND)
78         mov     (%rbp,%rcx,4),  %eax            # tx = d[x]     (NEXT ROUND)
79         movb    (%rbp,%rbx,4),  %r8b            # val = d[val]
80         xor     (%rsi),         %r8b            # xor 1 byte
81         movb    %r8b,           (%rdi)
82         inc     %rsi                            # in++
83         inc     %rdi                            # out++
84         jmp 1b
85
86 .Lfinished:
87         dec     %rcx                            # x--
88         movb    %dl,            (4*256)(%rbp)   # key->y = y
89         movb    %cl,            (4*256+4)(%rbp) # key->x = x
90         pop     %rbx
91         pop     %rbp
92         ret
93 .L__gcry_arcfour_amd64_end:
94 .size _gcry_arcfour_amd64,.L__gcry_arcfour_amd64_end-_gcry_arcfour_amd64
95
96 #endif
97 #endif