ecc: Fix ec_mulm_25519.
[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     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
20
21 #ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
22 # define ELF(...) __VA_ARGS__
23 #else
24 # define ELF(...) /*_*/
25 #endif
26
27 .text
28 .align 16
29 .globl _gcry_arcfour_amd64
30 ELF(.type _gcry_arcfour_amd64,@function)
31 _gcry_arcfour_amd64:
32         push    %rbp
33         push    %rbx
34         mov     %rdi,           %rbp    # key = ARG(key)
35         mov     %rsi,           %rbx    # rbx = ARG(len)
36         mov     %rdx,           %rsi    # in = ARG(in)
37         mov     %rcx,           %rdi    # out = ARG(out)
38         mov     (4*256)(%rbp),  %ecx    # x = key->x
39         mov     (4*256+4)(%rbp),%edx    # y = key->y
40         inc     %rcx                    # x++
41         and     $255,           %rcx    # x &= 0xff
42         lea     -8(%rbx,%rsi),  %rbx    # rbx = in+len-8
43         mov     %rbx,           %r9     # tmp = in+len-8
44         mov     (%rbp,%rcx,4),  %eax    # tx = d[x]
45         cmp     %rsi,           %rbx    # cmp in with in+len-8
46         jl      .Lend                   # jump if (in+len-8 < in)
47
48 .Lstart:
49         add     $8,             %rsi            # increment in
50         add     $8,             %rdi            # increment out
51
52         # generate the next 8 bytes of the rc4 stream into %r8
53         mov     $8,             %r11            # byte counter
54 1:      add     %al,            %dl             # y += tx
55         mov     (%rbp,%rdx,4),  %ebx            # ty = d[y]
56         mov     %ebx,           (%rbp,%rcx,4)   # d[x] = ty
57         add     %al,            %bl             # val = ty + tx
58         mov     %eax,           (%rbp,%rdx,4)   # d[y] = tx
59         inc     %cl                             # x++           (NEXT ROUND)
60         mov     (%rbp,%rcx,4),  %eax            # tx = d[x]     (NEXT ROUND)
61         shl     $8,             %r8
62         movb    (%rbp,%rbx,4),  %r8b            # val = d[val]
63         dec     %r11b
64         jnz 1b
65
66         # xor 8 bytes
67         bswap   %r8
68         xor     -8(%rsi),       %r8
69         cmp     %r9,            %rsi            # cmp in+len-8 with in
70         mov     %r8,            -8(%rdi)
71         jle     .Lstart                         # jump if (in <= in+len-8)
72
73 .Lend:
74         add     $8,             %r9             # tmp = in+len
75
76         # handle the last bytes, one by one
77 1:      cmp     %rsi,           %r9             # cmp in with in+len
78         jle     .Lfinished                      # jump if (in+len <= in)
79         add     %al,            %dl             # y += tx
80         mov     (%rbp,%rdx,4),  %ebx            # ty = d[y]
81         mov     %ebx,           (%rbp,%rcx,4)   # d[x] = ty
82         add     %al,            %bl             # val = ty + tx
83         mov     %eax,           (%rbp,%rdx,4)   # d[y] = tx
84         inc     %cl                             # x++           (NEXT ROUND)
85         mov     (%rbp,%rcx,4),  %eax            # tx = d[x]     (NEXT ROUND)
86         movb    (%rbp,%rbx,4),  %r8b            # val = d[val]
87         xor     (%rsi),         %r8b            # xor 1 byte
88         movb    %r8b,           (%rdi)
89         inc     %rsi                            # in++
90         inc     %rdi                            # out++
91         jmp 1b
92
93 .Lfinished:
94         dec     %rcx                            # x--
95         movb    %cl,            (4*256)(%rbp)   # key->y = y
96         movb    %dl,            (4*256+4)(%rbp) # key->x = x
97         pop     %rbx
98         pop     %rbp
99         ret
100 .L__gcry_arcfour_amd64_end:
101 ELF(.size _gcry_arcfour_amd64,.L__gcry_arcfour_amd64_end-_gcry_arcfour_amd64)
102
103 #endif
104 #endif