/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* ChaCha 256-bit cipher algorithm, x64 AVX2 functions
*
* Copyright (C) 2015 Martin Willi
*/
#include <linux/linkage.h>
.section .rodata.cst32.ROT8, "aM" , @progbits, 32
.align 32
ROT8: .octa 0 x0e0d0c0f0a09080b0605040702010003
.octa 0 x0e0d0c0f0a09080b0605040702010003
.section .rodata.cst32.ROT16, "aM" , @progbits, 32
.align 32
ROT16: .octa 0 x0d0c0f0e09080b0a0504070601000302
.octa 0 x0d0c0f0e09080b0a0504070601000302
.section .rodata.cst32.CTRINC, "aM" , @progbits, 32
.align 32
CTRINC: .octa 0 x00000003000000020000000100000000
.octa 0 x00000007000000060000000500000004
.section .rodata.cst32.CTR2BL, "aM" , @progbits, 32
.align 32
CTR2BL: .octa 0 x00000000000000000000000000000000
.octa 0 x00000000000000000000000000000001
.section .rodata.cst32.CTR4BL, "aM" , @progbits, 32
.align 32
CTR4BL: .octa 0 x00000000000000000000000000000002
.octa 0 x00000000000000000000000000000003
.text
SYM_FUNC_START(chacha_2block_xor_avx2)
# %rdi: Input state matrix, s
# %rsi: up to 2 data blocks output, o
# %rdx: up to 2 data blocks input, i
# %rcx: input/output length in bytes
# %r8d: nrounds
# This function encrypts two ChaCha blocks by loading the state
# matrix twice across four AVX registers. It performs matrix operations
# on four words in each matrix in parallel, but requires shuffling to
# rearrange the words after each round.
vzeroupper
# x0..3 [0 -2 ] = s0..3
vbroadcasti128 0 x00(%rdi),%ymm0
vbroadcasti128 0 x10(%rdi),%ymm1
vbroadcasti128 0 x20(%rdi),%ymm2
vbroadcasti128 0 x30(%rdi),%ymm3
vpaddd CTR2BL(%rip),%ymm3,%ymm3
vmovdqa %ymm0,%ymm8
vmovdqa %ymm1,%ymm9
vmovdqa %ymm2,%ymm10
vmovdqa %ymm3,%ymm11
vmovdqa ROT8(%rip),%ymm4
vmovdqa ROT16(%rip),%ymm5
mov %rcx,%rax
.Ldoubleround:
# x0 += x1, x3 = rotl32(x3 ^ x0, 16 )
vpaddd %ymm1,%ymm0,%ymm0
vpxor %ymm0,%ymm3,%ymm3
vpshufb %ymm5,%ymm3,%ymm3
# x2 += x3, x1 = rotl32(x1 ^ x2, 12 )
vpaddd %ymm3,%ymm2,%ymm2
vpxor %ymm2,%ymm1,%ymm1
vmovdqa %ymm1,%ymm6
vpslld $12 ,%ymm6,%ymm6
vpsrld $20 ,%ymm1,%ymm1
vpor %ymm6,%ymm1,%ymm1
# x0 += x1, x3 = rotl32(x3 ^ x0, 8 )
vpaddd %ymm1,%ymm0,%ymm0
vpxor %ymm0,%ymm3,%ymm3
vpshufb %ymm4,%ymm3,%ymm3
# x2 += x3, x1 = rotl32(x1 ^ x2, 7 )
vpaddd %ymm3,%ymm2,%ymm2
vpxor %ymm2,%ymm1,%ymm1
vmovdqa %ymm1,%ymm7
vpslld $7 ,%ymm7,%ymm7
vpsrld $25 ,%ymm1,%ymm1
vpor %ymm7,%ymm1,%ymm1
# x1 = shuffle32(x1, MASK(0 , 3 , 2 , 1 ))
vpshufd $0 x39,%ymm1,%ymm1
# x2 = shuffle32(x2, MASK(1 , 0 , 3 , 2 ))
vpshufd $0 x4e,%ymm2,%ymm2
# x3 = shuffle32(x3, MASK(2 , 1 , 0 , 3 ))
vpshufd $0 x93,%ymm3,%ymm3
# x0 += x1, x3 = rotl32(x3 ^ x0, 16 )
vpaddd %ymm1,%ymm0,%ymm0
vpxor %ymm0,%ymm3,%ymm3
vpshufb %ymm5,%ymm3,%ymm3
# x2 += x3, x1 = rotl32(x1 ^ x2, 12 )
vpaddd %ymm3,%ymm2,%ymm2
vpxor %ymm2,%ymm1,%ymm1
vmovdqa %ymm1,%ymm6
vpslld $12 ,%ymm6,%ymm6
vpsrld $20 ,%ymm1,%ymm1
vpor %ymm6,%ymm1,%ymm1
# x0 += x1, x3 = rotl32(x3 ^ x0, 8 )
vpaddd %ymm1,%ymm0,%ymm0
vpxor %ymm0,%ymm3,%ymm3
vpshufb %ymm4,%ymm3,%ymm3
# x2 += x3, x1 = rotl32(x1 ^ x2, 7 )
vpaddd %ymm3,%ymm2,%ymm2
vpxor %ymm2,%ymm1,%ymm1
vmovdqa %ymm1,%ymm7
vpslld $7 ,%ymm7,%ymm7
vpsrld $25 ,%ymm1,%ymm1
vpor %ymm7,%ymm1,%ymm1
# x1 = shuffle32(x1, MASK(2 , 1 , 0 , 3 ))
vpshufd $0 x93,%ymm1,%ymm1
# x2 = shuffle32(x2, MASK(1 , 0 , 3 , 2 ))
vpshufd $0 x4e,%ymm2,%ymm2
# x3 = shuffle32(x3, MASK(0 , 3 , 2 , 1 ))
vpshufd $0 x39,%ymm3,%ymm3
sub $2 ,%r8d
jnz .Ldoubleround
# o0 = i0 ^ (x0 + s0)
vpaddd %ymm8,%ymm0,%ymm7
cmp $0 x10,%rax
jl .Lxorpart2
vpxor 0 x00(%rdx),%xmm7,%xmm6
vmovdqu %xmm6,0 x00(%rsi)
vextracti128 $1 ,%ymm7,%xmm0
# o1 = i1 ^ (x1 + s1)
vpaddd %ymm9,%ymm1,%ymm7
cmp $0 x20,%rax
jl .Lxorpart2
vpxor 0 x10(%rdx),%xmm7,%xmm6
vmovdqu %xmm6,0 x10(%rsi)
vextracti128 $1 ,%ymm7,%xmm1
# o2 = i2 ^ (x2 + s2)
vpaddd %ymm10,%ymm2,%ymm7
cmp $0 x30,%rax
jl .Lxorpart2
vpxor 0 x20(%rdx),%xmm7,%xmm6
vmovdqu %xmm6,0 x20(%rsi)
vextracti128 $1 ,%ymm7,%xmm2
# o3 = i3 ^ (x3 + s3)
vpaddd %ymm11,%ymm3,%ymm7
cmp $0 x40,%rax
jl .Lxorpart2
vpxor 0 x30(%rdx),%xmm7,%xmm6
vmovdqu %xmm6,0 x30(%rsi)
vextracti128 $1 ,%ymm7,%xmm3
# xor and write second block
vmovdqa %xmm0,%xmm7
cmp $0 x50,%rax
jl .Lxorpart2
vpxor 0 x40(%rdx),%xmm7,%xmm6
vmovdqu %xmm6,0 x40(%rsi)
vmovdqa %xmm1,%xmm7
cmp $0 x60,%rax
jl .Lxorpart2
vpxor 0 x50(%rdx),%xmm7,%xmm6
vmovdqu %xmm6,0 x50(%rsi)
vmovdqa %xmm2,%xmm7
cmp $0 x70,%rax
jl .Lxorpart2
vpxor 0 x60(%rdx),%xmm7,%xmm6
vmovdqu %xmm6,0 x60(%rsi)
vmovdqa %xmm3,%xmm7
cmp $0 x80,%rax
jl .Lxorpart2
vpxor 0 x70(%rdx),%xmm7,%xmm6
vmovdqu %xmm6,0 x70(%rsi)
.Ldone2:
vzeroupper
RET
.Lxorpart2:
# xor remaining bytes from partial register into output
mov %rax,%r9
and $0 x0f,%r9
jz .Ldone2
and $~0 x0f,%rax
mov %rsi,%r11
lea 8 (%rsp),%r10
sub $0 x10,%rsp
and $~31 ,%rsp
lea (%rdx,%rax),%rsi
mov %rsp,%rdi
mov %r9,%rcx
rep movsb
vpxor 0 x00(%rsp),%xmm7,%xmm7
vmovdqa %xmm7,0 x00(%rsp)
mov %rsp,%rsi
lea (%r11,%rax),%rdi
mov %r9,%rcx
rep movsb
lea -8 (%r10),%rsp
jmp .Ldone2
SYM_FUNC_END(chacha_2block_xor_avx2)
SYM_FUNC_START(chacha_4block_xor_avx2)
# %rdi: Input state matrix, s
# %rsi: up to 4 data blocks output, o
# %rdx: up to 4 data blocks input, i
# %rcx: input/output length in bytes
# %r8d: nrounds
# This function encrypts four ChaCha blocks by loading the state
# matrix four times across eight AVX registers. It performs matrix
# operations on four words in two matrices in parallel, sequentially
# to the operations on the four words of the other two matrices. The
# required word shuffling has a rather high latency, we can do the
# arithmetic on two matrix-pairs without much slowdown.
vzeroupper
# x0..3 [0 -4 ] = s0..3
vbroadcasti128 0 x00(%rdi),%ymm0
vbroadcasti128 0 x10(%rdi),%ymm1
vbroadcasti128 0 x20(%rdi),%ymm2
vbroadcasti128 0 x30(%rdi),%ymm3
vmovdqa %ymm0,%ymm4
vmovdqa %ymm1,%ymm5
vmovdqa %ymm2,%ymm6
vmovdqa %ymm3,%ymm7
vpaddd CTR2BL(%rip),%ymm3,%ymm3
vpaddd CTR4BL(%rip),%ymm7,%ymm7
vmovdqa %ymm0,%ymm11
vmovdqa %ymm1,%ymm12
vmovdqa %ymm2,%ymm13
vmovdqa %ymm3,%ymm14
vmovdqa %ymm7,%ymm15
vmovdqa ROT8(%rip),%ymm8
vmovdqa ROT16(%rip),%ymm9
mov %rcx,%rax
.Ldoubleround4:
# x0 += x1, x3 = rotl32(x3 ^ x0, 16 )
vpaddd %ymm1,%ymm0,%ymm0
vpxor %ymm0,%ymm3,%ymm3
vpshufb %ymm9,%ymm3,%ymm3
vpaddd %ymm5,%ymm4,%ymm4
vpxor %ymm4,%ymm7,%ymm7
vpshufb %ymm9,%ymm7,%ymm7
# x2 += x3, x1 = rotl32(x1 ^ x2, 12 )
vpaddd %ymm3,%ymm2,%ymm2
vpxor %ymm2,%ymm1,%ymm1
vmovdqa %ymm1,%ymm10
vpslld $12 ,%ymm10,%ymm10
vpsrld $20 ,%ymm1,%ymm1
vpor %ymm10,%ymm1,%ymm1
vpaddd %ymm7,%ymm6,%ymm6
vpxor %ymm6,%ymm5,%ymm5
vmovdqa %ymm5,%ymm10
vpslld $12 ,%ymm10,%ymm10
vpsrld $20 ,%ymm5,%ymm5
vpor %ymm10,%ymm5,%ymm5
# x0 += x1, x3 = rotl32(x3 ^ x0, 8 )
vpaddd %ymm1,%ymm0,%ymm0
vpxor %ymm0,%ymm3,%ymm3
vpshufb %ymm8,%ymm3,%ymm3
vpaddd %ymm5,%ymm4,%ymm4
vpxor %ymm4,%ymm7,%ymm7
vpshufb %ymm8,%ymm7,%ymm7
# x2 += x3, x1 = rotl32(x1 ^ x2, 7 )
vpaddd %ymm3,%ymm2,%ymm2
vpxor %ymm2,%ymm1,%ymm1
vmovdqa %ymm1,%ymm10
vpslld $7 ,%ymm10,%ymm10
vpsrld $25 ,%ymm1,%ymm1
vpor %ymm10,%ymm1,%ymm1
vpaddd %ymm7,%ymm6,%ymm6
vpxor %ymm6,%ymm5,%ymm5
vmovdqa %ymm5,%ymm10
vpslld $7 ,%ymm10,%ymm10
vpsrld $25 ,%ymm5,%ymm5
vpor %ymm10,%ymm5,%ymm5
# x1 = shuffle32(x1, MASK(0 , 3 , 2 , 1 ))
vpshufd $0 x39,%ymm1,%ymm1
vpshufd $0 x39,%ymm5,%ymm5
# x2 = shuffle32(x2, MASK(1 , 0 , 3 , 2 ))
vpshufd $0 x4e,%ymm2,%ymm2
vpshufd $0 x4e,%ymm6,%ymm6
# x3 = shuffle32(x3, MASK(2 , 1 , 0 , 3 ))
vpshufd $0 x93,%ymm3,%ymm3
vpshufd $0 x93,%ymm7,%ymm7
# x0 += x1, x3 = rotl32(x3 ^ x0, 16 )
vpaddd %ymm1,%ymm0,%ymm0
vpxor %ymm0,%ymm3,%ymm3
vpshufb %ymm9,%ymm3,%ymm3
vpaddd %ymm5,%ymm4,%ymm4
vpxor %ymm4,%ymm7,%ymm7
vpshufb %ymm9,%ymm7,%ymm7
# x2 += x3, x1 = rotl32(x1 ^ x2, 12 )
vpaddd %ymm3,%ymm2,%ymm2
vpxor %ymm2,%ymm1,%ymm1
vmovdqa %ymm1,%ymm10
vpslld $12 ,%ymm10,%ymm10
vpsrld $20 ,%ymm1,%ymm1
vpor %ymm10,%ymm1,%ymm1
vpaddd %ymm7,%ymm6,%ymm6
vpxor %ymm6,%ymm5,%ymm5
vmovdqa %ymm5,%ymm10
vpslld $12 ,%ymm10,%ymm10
vpsrld $20 ,%ymm5,%ymm5
vpor %ymm10,%ymm5,%ymm5
# x0 += x1, x3 = rotl32(x3 ^ x0, 8 )
vpaddd %ymm1,%ymm0,%ymm0
vpxor %ymm0,%ymm3,%ymm3
vpshufb %ymm8,%ymm3,%ymm3
vpaddd %ymm5,%ymm4,%ymm4
vpxor %ymm4,%ymm7,%ymm7
vpshufb %ymm8,%ymm7,%ymm7
# x2 += x3, x1 = rotl32(x1 ^ x2, 7 )
vpaddd %ymm3,%ymm2,%ymm2
vpxor %ymm2,%ymm1,%ymm1
vmovdqa %ymm1,%ymm10
vpslld $7 ,%ymm10,%ymm10
vpsrld $25 ,%ymm1,%ymm1
vpor %ymm10,%ymm1,%ymm1
vpaddd %ymm7,%ymm6,%ymm6
vpxor %ymm6,%ymm5,%ymm5
vmovdqa %ymm5,%ymm10
vpslld $7 ,%ymm10,%ymm10
vpsrld $25 ,%ymm5,%ymm5
vpor %ymm10,%ymm5,%ymm5
# x1 = shuffle32(x1, MASK(2 , 1 , 0 , 3 ))
vpshufd $0 x93,%ymm1,%ymm1
vpshufd $0 x93,%ymm5,%ymm5
# x2 = shuffle32(x2, MASK(1 , 0 , 3 , 2 ))
vpshufd $0 x4e,%ymm2,%ymm2
vpshufd $0 x4e,%ymm6,%ymm6
# x3 = shuffle32(x3, MASK(0 , 3 , 2 , 1 ))
vpshufd $0 x39,%ymm3,%ymm3
vpshufd $0 x39,%ymm7,%ymm7
sub $2 ,%r8d
jnz .Ldoubleround4
# o0 = i0 ^ (x0 + s0), first block
vpaddd %ymm11,%ymm0,%ymm10
cmp $0 x10,%rax
jl .Lxorpart4
vpxor 0 x00(%rdx),%xmm10,%xmm9
vmovdqu %xmm9,0 x00(%rsi)
vextracti128 $1 ,%ymm10,%xmm0
# o1 = i1 ^ (x1 + s1), first block
vpaddd %ymm12,%ymm1,%ymm10
cmp $0 x20,%rax
jl .Lxorpart4
vpxor 0 x10(%rdx),%xmm10,%xmm9
vmovdqu %xmm9,0 x10(%rsi)
vextracti128 $1 ,%ymm10,%xmm1
# o2 = i2 ^ (x2 + s2), first block
vpaddd %ymm13,%ymm2,%ymm10
cmp $0 x30,%rax
jl .Lxorpart4
vpxor 0 x20(%rdx),%xmm10,%xmm9
vmovdqu %xmm9,0 x20(%rsi)
vextracti128 $1 ,%ymm10,%xmm2
# o3 = i3 ^ (x3 + s3), first block
vpaddd %ymm14,%ymm3,%ymm10
cmp $0 x40,%rax
jl .Lxorpart4
vpxor 0 x30(%rdx),%xmm10,%xmm9
vmovdqu %xmm9,0 x30(%rsi)
vextracti128 $1 ,%ymm10,%xmm3
# xor and write second block
vmovdqa %xmm0,%xmm10
cmp $0 x50,%rax
jl .Lxorpart4
vpxor 0 x40(%rdx),%xmm10,%xmm9
vmovdqu %xmm9,0 x40(%rsi)
vmovdqa %xmm1,%xmm10
cmp $0 x60,%rax
jl .Lxorpart4
vpxor 0 x50(%rdx),%xmm10,%xmm9
vmovdqu %xmm9,0 x50(%rsi)
vmovdqa %xmm2,%xmm10
cmp $0 x70,%rax
jl .Lxorpart4
vpxor 0 x60(%rdx),%xmm10,%xmm9
vmovdqu %xmm9,0 x60(%rsi)
vmovdqa %xmm3,%xmm10
cmp $0 x80,%rax
jl .Lxorpart4
vpxor 0 x70(%rdx),%xmm10,%xmm9
vmovdqu %xmm9,0 x70(%rsi)
# o0 = i0 ^ (x0 + s0), third block
vpaddd %ymm11,%ymm4,%ymm10
cmp $0 x90,%rax
jl .Lxorpart4
vpxor 0 x80(%rdx),%xmm10,%xmm9
vmovdqu %xmm9,0 x80(%rsi)
vextracti128 $1 ,%ymm10,%xmm4
# o1 = i1 ^ (x1 + s1), third block
vpaddd %ymm12,%ymm5,%ymm10
cmp $0 xa0,%rax
jl .Lxorpart4
vpxor 0 x90(%rdx),%xmm10,%xmm9
vmovdqu %xmm9,0 x90(%rsi)
vextracti128 $1 ,%ymm10,%xmm5
# o2 = i2 ^ (x2 + s2), third block
vpaddd %ymm13,%ymm6,%ymm10
cmp $0 xb0,%rax
jl .Lxorpart4
vpxor 0 xa0(%rdx),%xmm10,%xmm9
vmovdqu %xmm9,0 xa0(%rsi)
vextracti128 $1 ,%ymm10,%xmm6
# o3 = i3 ^ (x3 + s3), third block
vpaddd %ymm15,%ymm7,%ymm10
cmp $0 xc0,%rax
jl .Lxorpart4
vpxor 0 xb0(%rdx),%xmm10,%xmm9
vmovdqu %xmm9,0 xb0(%rsi)
vextracti128 $1 ,%ymm10,%xmm7
# xor and write fourth block
vmovdqa %xmm4,%xmm10
cmp $0 xd0,%rax
jl .Lxorpart4
vpxor 0 xc0(%rdx),%xmm10,%xmm9
vmovdqu %xmm9,0 xc0(%rsi)
vmovdqa %xmm5,%xmm10
cmp $0 xe0,%rax
jl .Lxorpart4
vpxor 0 xd0(%rdx),%xmm10,%xmm9
vmovdqu %xmm9,0 xd0(%rsi)
vmovdqa %xmm6,%xmm10
cmp $0 xf0,%rax
jl .Lxorpart4
vpxor 0 xe0(%rdx),%xmm10,%xmm9
vmovdqu %xmm9,0 xe0(%rsi)
vmovdqa %xmm7,%xmm10
cmp $0 x100,%rax
jl .Lxorpart4
vpxor 0 xf0(%rdx),%xmm10,%xmm9
vmovdqu %xmm9,0 xf0(%rsi)
.Ldone4:
vzeroupper
RET
.Lxorpart4:
# xor remaining bytes from partial register into output
mov %rax,%r9
and $0 x0f,%r9
jz .Ldone4
and $~0 x0f,%rax
mov %rsi,%r11
lea 8 (%rsp),%r10
sub $0 x10,%rsp
and $~31 ,%rsp
lea (%rdx,%rax),%rsi
mov %rsp,%rdi
mov %r9,%rcx
rep movsb
vpxor 0 x00(%rsp),%xmm10,%xmm10
vmovdqa %xmm10,0 x00(%rsp)
mov %rsp,%rsi
lea (%r11,%rax),%rdi
mov %r9,%rcx
rep movsb
lea -8 (%r10),%rsp
jmp .Ldone4
SYM_FUNC_END(chacha_4block_xor_avx2)
SYM_FUNC_START(chacha_8block_xor_avx2)
# %rdi: Input state matrix, s
# %rsi: up to 8 data blocks output, o
# %rdx: up to 8 data blocks input, i
# %rcx: input/output length in bytes
# %r8d: nrounds
# This function encrypts eight consecutive ChaCha blocks by loading
# the state matrix in AVX registers eight times. As we need some
# scratch registers, we save the first four registers on the stack. The
# algorithm performs each operation on the corresponding word of each
# state matrix, hence requires no word shuffling. For final XORing step
# we transpose the matrix by interleaving 32 -, 64 - and then 128 -bit
# words, which allows us to do XOR in AVX registers. 8 /16 -bit word
# rotation is done with the slightly better performing byte shuffling,
# 7 /12 -bit word rotation uses traditional shift+OR.
vzeroupper
# 4 * 32 byte stack, 32 -byte aligned
lea 8 (%rsp),%r10
and $~31 , %rsp
sub $0 x80, %rsp
mov %rcx,%rax
# x0..15 [0 -7 ] = s[0 ..15 ]
vpbroadcastd 0 x00(%rdi),%ymm0
vpbroadcastd 0 x04(%rdi),%ymm1
vpbroadcastd 0 x08(%rdi),%ymm2
vpbroadcastd 0 x0c(%rdi),%ymm3
vpbroadcastd 0 x10(%rdi),%ymm4
vpbroadcastd 0 x14(%rdi),%ymm5
vpbroadcastd 0 x18(%rdi),%ymm6
vpbroadcastd 0 x1c(%rdi),%ymm7
vpbroadcastd 0 x20(%rdi),%ymm8
vpbroadcastd 0 x24(%rdi),%ymm9
vpbroadcastd 0 x28(%rdi),%ymm10
vpbroadcastd 0 x2c(%rdi),%ymm11
vpbroadcastd 0 x30(%rdi),%ymm12
vpbroadcastd 0 x34(%rdi),%ymm13
vpbroadcastd 0 x38(%rdi),%ymm14
vpbroadcastd 0 x3c(%rdi),%ymm15
# x0..3 on stack
vmovdqa %ymm0,0 x00(%rsp)
vmovdqa %ymm1,0 x20(%rsp)
vmovdqa %ymm2,0 x40(%rsp)
vmovdqa %ymm3,0 x60(%rsp)
vmovdqa CTRINC(%rip),%ymm1
vmovdqa ROT8(%rip),%ymm2
vmovdqa ROT16(%rip),%ymm3
# x12 += counter values 0 -3
vpaddd %ymm1,%ymm12,%ymm12
.Ldoubleround8:
# x0 += x4, x12 = rotl32(x12 ^ x0, 16 )
vpaddd 0 x00(%rsp),%ymm4,%ymm0
vmovdqa %ymm0,0 x00(%rsp)
vpxor %ymm0,%ymm12,%ymm12
vpshufb %ymm3,%ymm12,%ymm12
# x1 += x5, x13 = rotl32(x13 ^ x1, 16 )
vpaddd 0 x20(%rsp),%ymm5,%ymm0
vmovdqa %ymm0,0 x20(%rsp)
vpxor %ymm0,%ymm13,%ymm13
vpshufb %ymm3,%ymm13,%ymm13
# x2 += x6, x14 = rotl32(x14 ^ x2, 16 )
vpaddd 0 x40(%rsp),%ymm6,%ymm0
vmovdqa %ymm0,0 x40(%rsp)
vpxor %ymm0,%ymm14,%ymm14
vpshufb %ymm3,%ymm14,%ymm14
# x3 += x7, x15 = rotl32(x15 ^ x3, 16 )
vpaddd 0 x60(%rsp),%ymm7,%ymm0
vmovdqa %ymm0,0 x60(%rsp)
vpxor %ymm0,%ymm15,%ymm15
vpshufb %ymm3,%ymm15,%ymm15
# x8 += x12, x4 = rotl32(x4 ^ x8, 12 )
vpaddd %ymm12,%ymm8,%ymm8
vpxor %ymm8,%ymm4,%ymm4
vpslld $12 ,%ymm4,%ymm0
vpsrld $20 ,%ymm4,%ymm4
vpor %ymm0,%ymm4,%ymm4
# x9 += x13, x5 = rotl32(x5 ^ x9, 12 )
vpaddd %ymm13,%ymm9,%ymm9
vpxor %ymm9,%ymm5,%ymm5
vpslld $12 ,%ymm5,%ymm0
vpsrld $20 ,%ymm5,%ymm5
vpor %ymm0,%ymm5,%ymm5
# x10 += x14, x6 = rotl32(x6 ^ x10, 12 )
vpaddd %ymm14,%ymm10,%ymm10
vpxor %ymm10,%ymm6,%ymm6
vpslld $12 ,%ymm6,%ymm0
vpsrld $20 ,%ymm6,%ymm6
vpor %ymm0,%ymm6,%ymm6
# x11 += x15, x7 = rotl32(x7 ^ x11, 12 )
vpaddd %ymm15,%ymm11,%ymm11
vpxor %ymm11,%ymm7,%ymm7
vpslld $12 ,%ymm7,%ymm0
vpsrld $20 ,%ymm7,%ymm7
vpor %ymm0,%ymm7,%ymm7
# x0 += x4, x12 = rotl32(x12 ^ x0, 8 )
vpaddd 0 x00(%rsp),%ymm4,%ymm0
vmovdqa %ymm0,0 x00(%rsp)
vpxor %ymm0,%ymm12,%ymm12
vpshufb %ymm2,%ymm12,%ymm12
# x1 += x5, x13 = rotl32(x13 ^ x1, 8 )
vpaddd 0 x20(%rsp),%ymm5,%ymm0
vmovdqa %ymm0,0 x20(%rsp)
vpxor %ymm0,%ymm13,%ymm13
vpshufb %ymm2,%ymm13,%ymm13
# x2 += x6, x14 = rotl32(x14 ^ x2, 8 )
vpaddd 0 x40(%rsp),%ymm6,%ymm0
vmovdqa %ymm0,0 x40(%rsp)
vpxor %ymm0,%ymm14,%ymm14
vpshufb %ymm2,%ymm14,%ymm14
# x3 += x7, x15 = rotl32(x15 ^ x3, 8 )
vpaddd 0 x60(%rsp),%ymm7,%ymm0
vmovdqa %ymm0,0 x60(%rsp)
vpxor %ymm0,%ymm15,%ymm15
vpshufb %ymm2,%ymm15,%ymm15
# x8 += x12, x4 = rotl32(x4 ^ x8, 7 )
vpaddd %ymm12,%ymm8,%ymm8
vpxor %ymm8,%ymm4,%ymm4
vpslld $7 ,%ymm4,%ymm0
vpsrld $25 ,%ymm4,%ymm4
vpor %ymm0,%ymm4,%ymm4
# x9 += x13, x5 = rotl32(x5 ^ x9, 7 )
vpaddd %ymm13,%ymm9,%ymm9
vpxor %ymm9,%ymm5,%ymm5
vpslld $7 ,%ymm5,%ymm0
vpsrld $25 ,%ymm5,%ymm5
vpor %ymm0,%ymm5,%ymm5
# x10 += x14, x6 = rotl32(x6 ^ x10, 7 )
vpaddd %ymm14,%ymm10,%ymm10
vpxor %ymm10,%ymm6,%ymm6
vpslld $7 ,%ymm6,%ymm0
vpsrld $25 ,%ymm6,%ymm6
vpor %ymm0,%ymm6,%ymm6
# x11 += x15, x7 = rotl32(x7 ^ x11, 7 )
vpaddd %ymm15,%ymm11,%ymm11
vpxor %ymm11,%ymm7,%ymm7
vpslld $7 ,%ymm7,%ymm0
vpsrld $25 ,%ymm7,%ymm7
vpor %ymm0,%ymm7,%ymm7
# x0 += x5, x15 = rotl32(x15 ^ x0, 16 )
vpaddd 0 x00(%rsp),%ymm5,%ymm0
vmovdqa %ymm0,0 x00(%rsp)
vpxor %ymm0,%ymm15,%ymm15
vpshufb %ymm3,%ymm15,%ymm15
# x1 += x6, x12 = rotl32(x12 ^ x1, 16 )%ymm0
vpaddd 0 x20(%rsp),%ymm6,%ymm0
vmovdqa %ymm0,0 x20(%rsp)
vpxor %ymm0,%ymm12,%ymm12
vpshufb %ymm3,%ymm12,%ymm12
# x2 += x7, x13 = rotl32(x13 ^ x2, 16 )
vpaddd 0 x40(%rsp),%ymm7,%ymm0
vmovdqa %ymm0,0 x40(%rsp)
vpxor %ymm0,%ymm13,%ymm13
vpshufb %ymm3,%ymm13,%ymm13
# x3 += x4, x14 = rotl32(x14 ^ x3, 16 )
vpaddd 0 x60(%rsp),%ymm4,%ymm0
vmovdqa %ymm0,0 x60(%rsp)
vpxor %ymm0,%ymm14,%ymm14
vpshufb %ymm3,%ymm14,%ymm14
# x10 += x15, x5 = rotl32(x5 ^ x10, 12 )
vpaddd %ymm15,%ymm10,%ymm10
vpxor %ymm10,%ymm5,%ymm5
vpslld $12 ,%ymm5,%ymm0
vpsrld $20 ,%ymm5,%ymm5
vpor %ymm0,%ymm5,%ymm5
# x11 += x12, x6 = rotl32(x6 ^ x11, 12 )
vpaddd %ymm12,%ymm11,%ymm11
vpxor %ymm11,%ymm6,%ymm6
vpslld $12 ,%ymm6,%ymm0
vpsrld $20 ,%ymm6,%ymm6
vpor %ymm0,%ymm6,%ymm6
# x8 += x13, x7 = rotl32(x7 ^ x8, 12 )
vpaddd %ymm13,%ymm8,%ymm8
vpxor %ymm8,%ymm7,%ymm7
vpslld $12 ,%ymm7,%ymm0
vpsrld $20 ,%ymm7,%ymm7
vpor %ymm0,%ymm7,%ymm7
# x9 += x14, x4 = rotl32(x4 ^ x9, 12 )
vpaddd %ymm14,%ymm9,%ymm9
vpxor %ymm9,%ymm4,%ymm4
vpslld $12 ,%ymm4,%ymm0
vpsrld $20 ,%ymm4,%ymm4
vpor %ymm0,%ymm4,%ymm4
# x0 += x5, x15 = rotl32(x15 ^ x0, 8 )
vpaddd 0 x00(%rsp),%ymm5,%ymm0
vmovdqa %ymm0,0 x00(%rsp)
vpxor %ymm0,%ymm15,%ymm15
vpshufb %ymm2,%ymm15,%ymm15
# x1 += x6, x12 = rotl32(x12 ^ x1, 8 )
vpaddd 0 x20(%rsp),%ymm6,%ymm0
vmovdqa %ymm0,0 x20(%rsp)
vpxor %ymm0,%ymm12,%ymm12
vpshufb %ymm2,%ymm12,%ymm12
# x2 += x7, x13 = rotl32(x13 ^ x2, 8 )
vpaddd 0 x40(%rsp),%ymm7,%ymm0
vmovdqa %ymm0,0 x40(%rsp)
vpxor %ymm0,%ymm13,%ymm13
vpshufb %ymm2,%ymm13,%ymm13
# x3 += x4, x14 = rotl32(x14 ^ x3, 8 )
vpaddd 0 x60(%rsp),%ymm4,%ymm0
vmovdqa %ymm0,0 x60(%rsp)
vpxor %ymm0,%ymm14,%ymm14
vpshufb %ymm2,%ymm14,%ymm14
# x10 += x15, x5 = rotl32(x5 ^ x10, 7 )
vpaddd %ymm15,%ymm10,%ymm10
vpxor %ymm10,%ymm5,%ymm5
vpslld $7 ,%ymm5,%ymm0
vpsrld $25 ,%ymm5,%ymm5
vpor %ymm0,%ymm5,%ymm5
# x11 += x12, x6 = rotl32(x6 ^ x11, 7 )
vpaddd %ymm12,%ymm11,%ymm11
vpxor %ymm11,%ymm6,%ymm6
vpslld $7 ,%ymm6,%ymm0
vpsrld $25 ,%ymm6,%ymm6
vpor %ymm0,%ymm6,%ymm6
# x8 += x13, x7 = rotl32(x7 ^ x8, 7 )
vpaddd %ymm13,%ymm8,%ymm8
vpxor %ymm8,%ymm7,%ymm7
vpslld $7 ,%ymm7,%ymm0
vpsrld $25 ,%ymm7,%ymm7
vpor %ymm0,%ymm7,%ymm7
# x9 += x14, x4 = rotl32(x4 ^ x9, 7 )
vpaddd %ymm14,%ymm9,%ymm9
vpxor %ymm9,%ymm4,%ymm4
vpslld $7 ,%ymm4,%ymm0
vpsrld $25 ,%ymm4,%ymm4
vpor %ymm0,%ymm4,%ymm4
sub $2 ,%r8d
jnz .Ldoubleround8
# x0..15 [0 -3 ] += s[0 ..15 ]
vpbroadcastd 0 x00(%rdi),%ymm0
vpaddd 0 x00(%rsp),%ymm0,%ymm0
vmovdqa %ymm0,0 x00(%rsp)
vpbroadcastd 0 x04(%rdi),%ymm0
vpaddd 0 x20(%rsp),%ymm0,%ymm0
vmovdqa %ymm0,0 x20(%rsp)
vpbroadcastd 0 x08(%rdi),%ymm0
vpaddd 0 x40(%rsp),%ymm0,%ymm0
vmovdqa %ymm0,0 x40(%rsp)
vpbroadcastd 0 x0c(%rdi),%ymm0
vpaddd 0 x60(%rsp),%ymm0,%ymm0
vmovdqa %ymm0,0 x60(%rsp)
vpbroadcastd 0 x10(%rdi),%ymm0
vpaddd %ymm0,%ymm4,%ymm4
vpbroadcastd 0 x14(%rdi),%ymm0
vpaddd %ymm0,%ymm5,%ymm5
vpbroadcastd 0 x18(%rdi),%ymm0
vpaddd %ymm0,%ymm6,%ymm6
vpbroadcastd 0 x1c(%rdi),%ymm0
vpaddd %ymm0,%ymm7,%ymm7
vpbroadcastd 0 x20(%rdi),%ymm0
vpaddd %ymm0,%ymm8,%ymm8
vpbroadcastd 0 x24(%rdi),%ymm0
vpaddd %ymm0,%ymm9,%ymm9
vpbroadcastd 0 x28(%rdi),%ymm0
vpaddd %ymm0,%ymm10,%ymm10
vpbroadcastd 0 x2c(%rdi),%ymm0
vpaddd %ymm0,%ymm11,%ymm11
vpbroadcastd 0 x30(%rdi),%ymm0
vpaddd %ymm0,%ymm12,%ymm12
vpbroadcastd 0 x34(%rdi),%ymm0
vpaddd %ymm0,%ymm13,%ymm13
vpbroadcastd 0 x38(%rdi),%ymm0
vpaddd %ymm0,%ymm14,%ymm14
vpbroadcastd 0 x3c(%rdi),%ymm0
vpaddd %ymm0,%ymm15,%ymm15
# x12 += counter values 0 -3
vpaddd %ymm1,%ymm12,%ymm12
# interleave 32 -bit words in state n, n+1
vmovdqa 0 x00(%rsp),%ymm0
vmovdqa 0 x20(%rsp),%ymm1
vpunpckldq %ymm1,%ymm0,%ymm2
vpunpckhdq %ymm1,%ymm0,%ymm1
vmovdqa %ymm2,0 x00(%rsp)
vmovdqa %ymm1,0 x20(%rsp)
vmovdqa 0 x40(%rsp),%ymm0
vmovdqa 0 x60(%rsp),%ymm1
vpunpckldq %ymm1,%ymm0,%ymm2
vpunpckhdq %ymm1,%ymm0,%ymm1
vmovdqa %ymm2,0 x40(%rsp)
vmovdqa %ymm1,0 x60(%rsp)
vmovdqa %ymm4,%ymm0
vpunpckldq %ymm5,%ymm0,%ymm4
vpunpckhdq %ymm5,%ymm0,%ymm5
vmovdqa %ymm6,%ymm0
vpunpckldq %ymm7,%ymm0,%ymm6
vpunpckhdq %ymm7,%ymm0,%ymm7
vmovdqa %ymm8,%ymm0
vpunpckldq %ymm9,%ymm0,%ymm8
vpunpckhdq %ymm9,%ymm0,%ymm9
vmovdqa %ymm10,%ymm0
vpunpckldq %ymm11,%ymm0,%ymm10
vpunpckhdq %ymm11,%ymm0,%ymm11
vmovdqa %ymm12,%ymm0
vpunpckldq %ymm13,%ymm0,%ymm12
vpunpckhdq %ymm13,%ymm0,%ymm13
vmovdqa %ymm14,%ymm0
vpunpckldq %ymm15,%ymm0,%ymm14
vpunpckhdq %ymm15,%ymm0,%ymm15
# interleave 64 -bit words in state n, n+2
vmovdqa 0 x00(%rsp),%ymm0
vmovdqa 0 x40(%rsp),%ymm2
vpunpcklqdq %ymm2,%ymm0,%ymm1
vpunpckhqdq %ymm2,%ymm0,%ymm2
vmovdqa %ymm1,0 x00(%rsp)
vmovdqa %ymm2,0 x40(%rsp)
vmovdqa 0 x20(%rsp),%ymm0
vmovdqa 0 x60(%rsp),%ymm2
vpunpcklqdq %ymm2,%ymm0,%ymm1
vpunpckhqdq %ymm2,%ymm0,%ymm2
vmovdqa %ymm1,0 x20(%rsp)
vmovdqa %ymm2,0 x60(%rsp)
vmovdqa %ymm4,%ymm0
vpunpcklqdq %ymm6,%ymm0,%ymm4
vpunpckhqdq %ymm6,%ymm0,%ymm6
vmovdqa %ymm5,%ymm0
vpunpcklqdq %ymm7,%ymm0,%ymm5
vpunpckhqdq %ymm7,%ymm0,%ymm7
vmovdqa %ymm8,%ymm0
vpunpcklqdq %ymm10,%ymm0,%ymm8
vpunpckhqdq %ymm10,%ymm0,%ymm10
vmovdqa %ymm9,%ymm0
vpunpcklqdq %ymm11,%ymm0,%ymm9
vpunpckhqdq %ymm11,%ymm0,%ymm11
vmovdqa %ymm12,%ymm0
vpunpcklqdq %ymm14,%ymm0,%ymm12
vpunpckhqdq %ymm14,%ymm0,%ymm14
vmovdqa %ymm13,%ymm0
vpunpcklqdq %ymm15,%ymm0,%ymm13
vpunpckhqdq %ymm15,%ymm0,%ymm15
# interleave 128 -bit words in state n, n+4
# xor/write first four blocks
vmovdqa 0 x00(%rsp),%ymm1
vperm2i128 $0 x20,%ymm4,%ymm1,%ymm0
cmp $0 x0020,%rax
jl .Lxorpart8
vpxor 0 x0000(%rdx),%ymm0,%ymm0
vmovdqu %ymm0,0 x0000(%rsi)
vperm2i128 $0 x31,%ymm4,%ymm1,%ymm4
vperm2i128 $0 x20,%ymm12,%ymm8,%ymm0
cmp $0 x0040,%rax
jl .Lxorpart8
vpxor 0 x0020(%rdx),%ymm0,%ymm0
vmovdqu %ymm0,0 x0020(%rsi)
vperm2i128 $0 x31,%ymm12,%ymm8,%ymm12
vmovdqa 0 x40(%rsp),%ymm1
vperm2i128 $0 x20,%ymm6,%ymm1,%ymm0
cmp $0 x0060,%rax
jl .Lxorpart8
vpxor 0 x0040(%rdx),%ymm0,%ymm0
vmovdqu %ymm0,0 x0040(%rsi)
vperm2i128 $0 x31,%ymm6,%ymm1,%ymm6
vperm2i128 $0 x20,%ymm14,%ymm10,%ymm0
cmp $0 x0080,%rax
jl .Lxorpart8
vpxor 0 x0060(%rdx),%ymm0,%ymm0
vmovdqu %ymm0,0 x0060(%rsi)
vperm2i128 $0 x31,%ymm14,%ymm10,%ymm14
vmovdqa 0 x20(%rsp),%ymm1
vperm2i128 $0 x20,%ymm5,%ymm1,%ymm0
cmp $0 x00a0,%rax
jl .Lxorpart8
vpxor 0 x0080(%rdx),%ymm0,%ymm0
vmovdqu %ymm0,0 x0080(%rsi)
vperm2i128 $0 x31,%ymm5,%ymm1,%ymm5
vperm2i128 $0 x20,%ymm13,%ymm9,%ymm0
cmp $0 x00c0,%rax
jl .Lxorpart8
vpxor 0 x00a0(%rdx),%ymm0,%ymm0
vmovdqu %ymm0,0 x00a0(%rsi)
vperm2i128 $0 x31,%ymm13,%ymm9,%ymm13
vmovdqa 0 x60(%rsp),%ymm1
vperm2i128 $0 x20,%ymm7,%ymm1,%ymm0
cmp $0 x00e0,%rax
jl .Lxorpart8
vpxor 0 x00c0(%rdx),%ymm0,%ymm0
vmovdqu %ymm0,0 x00c0(%rsi)
vperm2i128 $0 x31,%ymm7,%ymm1,%ymm7
vperm2i128 $0 x20,%ymm15,%ymm11,%ymm0
cmp $0 x0100,%rax
jl .Lxorpart8
vpxor 0 x00e0(%rdx),%ymm0,%ymm0
vmovdqu %ymm0,0 x00e0(%rsi)
vperm2i128 $0 x31,%ymm15,%ymm11,%ymm15
# xor remaining blocks, write to output
vmovdqa %ymm4,%ymm0
cmp $0 x0120,%rax
jl .Lxorpart8
vpxor 0 x0100(%rdx),%ymm0,%ymm0
vmovdqu %ymm0,0 x0100(%rsi)
vmovdqa %ymm12,%ymm0
cmp $0 x0140,%rax
jl .Lxorpart8
vpxor 0 x0120(%rdx),%ymm0,%ymm0
vmovdqu %ymm0,0 x0120(%rsi)
vmovdqa %ymm6,%ymm0
cmp $0 x0160,%rax
jl .Lxorpart8
vpxor 0 x0140(%rdx),%ymm0,%ymm0
vmovdqu %ymm0,0 x0140(%rsi)
vmovdqa %ymm14,%ymm0
cmp $0 x0180,%rax
jl .Lxorpart8
vpxor 0 x0160(%rdx),%ymm0,%ymm0
vmovdqu %ymm0,0 x0160(%rsi)
vmovdqa %ymm5,%ymm0
cmp $0 x01a0,%rax
jl .Lxorpart8
vpxor 0 x0180(%rdx),%ymm0,%ymm0
vmovdqu %ymm0,0 x0180(%rsi)
vmovdqa %ymm13,%ymm0
cmp $0 x01c0,%rax
jl .Lxorpart8
vpxor 0 x01a0(%rdx),%ymm0,%ymm0
vmovdqu %ymm0,0 x01a0(%rsi)
vmovdqa %ymm7,%ymm0
cmp $0 x01e0,%rax
jl .Lxorpart8
vpxor 0 x01c0(%rdx),%ymm0,%ymm0
vmovdqu %ymm0,0 x01c0(%rsi)
vmovdqa %ymm15,%ymm0
cmp $0 x0200,%rax
jl .Lxorpart8
vpxor 0 x01e0(%rdx),%ymm0,%ymm0
vmovdqu %ymm0,0 x01e0(%rsi)
.Ldone8:
vzeroupper
lea -8 (%r10),%rsp
RET
.Lxorpart8:
# xor remaining bytes from partial register into output
mov %rax,%r9
and $0 x1f,%r9
jz .Ldone8
and $~0 x1f,%rax
mov %rsi,%r11
lea (%rdx,%rax),%rsi
mov %rsp,%rdi
mov %r9,%rcx
rep movsb
vpxor 0 x00(%rsp),%ymm0,%ymm0
vmovdqa %ymm0,0 x00(%rsp)
mov %rsp,%rsi
lea (%r11,%rax),%rdi
mov %r9,%rcx
rep movsb
jmp .Ldone8
SYM_FUNC_END(chacha_8block_xor_avx2)
Messung V0.5 in Prozent C=94 H=94 G=93
¤ Dauer der Verarbeitung: 0.17 Sekunden
(vorverarbeitet am 2026-06-07)
¤
*© Formatika GbR, Deutschland