blob: e377b4327347efcbe6c1b6168a0024d5c0dc8089 [file]
// Copyright 2026 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// derived from chacha_arm64.s
//go:build gc && !purego
#include "textflag.h"
DATA ·constants+0x00(SB)/4, $0x61707865
DATA ·constants+0x04(SB)/4, $0x3320646e
DATA ·constants+0x08(SB)/4, $0x79622d32
DATA ·constants+0x0c(SB)/4, $0x6b206574
GLOBL ·constants(SB), NOPTR|RODATA, $32
DATA ·incRotMatrix+0x00(SB)/4, $0x00000000
DATA ·incRotMatrix+0x04(SB)/4, $0x00000001
DATA ·incRotMatrix+0x08(SB)/4, $0x00000002
DATA ·incRotMatrix+0x0c(SB)/4, $0x00000003
GLOBL ·incRotMatrix(SB), NOPTR|RODATA, $32
#define NUM_ROUNDS 10
// func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32)
TEXT ·xorKeyStreamVX(SB), NOSPLIT, $0
MOVV dst+0(FP), R4
MOVV src+24(FP), R5
MOVV src_len+32(FP), R6
MOVV key+48(FP), R7
MOVV nonce+56(FP), R8
MOVV counter+64(FP), R9
MOVV $·constants(SB), R10
MOVV $·incRotMatrix(SB), R11
MOVW (R9), R12
loop:
MOVV $NUM_ROUNDS, R15
// load 4-32bit data from incRotMatrix added to counter
VMOVQ (R11), V30
// load contants
VMOVQ (R10), V0.W4
VMOVQ 4(R10), V1.W4
VMOVQ 8(R10), V2.W4
VMOVQ 12(R10), V3.W4
// load keys
VMOVQ (R7), V4.W4
VMOVQ 4(R7), V5.W4
VMOVQ 8(R7), V6.W4
VMOVQ 12(R7), V7.W4
VMOVQ 16(R7), V8.W4
VMOVQ 20(R7), V9.W4
VMOVQ 24(R7), V10.W4
VMOVQ 28(R7), V11.W4
// load counter + nonce
VMOVQ (R9), V12.W4
VMOVQ (R8), V13.W4
VMOVQ 4(R8), V14.W4
VMOVQ 8(R8), V15.W4
// update counter
VADDW V30, V12, V12
chacha:
// V0..V3 += V4..V7
// V12..V15 <<<= ((V12..V15 XOR V0..V3), 16)
VADDW V0, V4, V0
VADDW V1, V5, V1
VADDW V2, V6, V2
VADDW V3, V7, V3
VXORV V12, V0, V12
VXORV V13, V1, V13
VXORV V14, V2, V14
VXORV V15, V3, V15
VROTRW $16, V12, V12
VROTRW $16, V13, V13
VROTRW $16, V14, V14
VROTRW $16, V15, V15
// V8..V11 += V12..V15
// V4..V7 <<<= ((V4..V7 XOR V8..V11), 12)
VADDW V8, V12, V8
VADDW V9, V13, V9
VADDW V10, V14, V10
VADDW V11, V15, V11
VXORV V4, V8, V4
VXORV V5, V9, V5
VXORV V6, V10, V6
VXORV V7, V11, V7
VROTRW $20, V4, V4
VROTRW $20, V5, V5
VROTRW $20, V6, V6
VROTRW $20, V7, V7
// V0..V3 += V4..V7
// V12..V15 <<<= ((V12..V15 XOR V0..V3), 8)
VADDW V0, V4, V0
VADDW V1, V5, V1
VADDW V2, V6, V2
VADDW V3, V7, V3
VXORV V12, V0, V12
VXORV V13, V1, V13
VXORV V14, V2, V14
VXORV V15, V3, V15
VROTRW $24, V12, V12
VROTRW $24, V13, V13
VROTRW $24, V14, V14
VROTRW $24, V15, V15
// V8..V11 += V12..V15
// V4..V7 <<<= ((V4..V7 XOR V8..V11), 7)
VADDW V12, V8, V8
VADDW V13, V9, V9
VADDW V14, V10, V10
VADDW V15, V11, V11
VXORV V4, V8, V4
VXORV V5, V9, V5
VXORV V6, V10, V6
VXORV V7, V11, V7
VROTRW $25, V4, V4
VROTRW $25, V5, V5
VROTRW $25, V6, V6
VROTRW $25, V7, V7
// V0..V3 += V5..V7, V4
// V15,V12-V14 <<<= ((V15,V12-V14 XOR V0..V3), 16)
VADDW V0, V5, V0
VADDW V1, V6, V1
VADDW V2, V7, V2
VADDW V3, V4, V3
VXORV V15, V0, V15
VXORV V12, V1, V12
VXORV V13, V2, V13
VXORV V14, V3, V14
VROTRW $16, V15, V15
VROTRW $16, V12, V12
VROTRW $16, V13, V13
VROTRW $16, V14, V14
// V10,V11,V8,V9 += V15,V12,V13,V14
// V5,V6,V7,V4 <<<= ((V5,V6,V7,V4 XOR V10,V11,V8,V9), 12)
VADDW V10, V15, V10
VADDW V11, V12, V11
VADDW V8, V13, V8
VADDW V9, V14, V9
VXORV V5, V10, V5
VXORV V6, V11, V6
VXORV V7, V8, V7
VXORV V4, V9, V4
VROTRW $20, V5, V5
VROTRW $20, V6, V6
VROTRW $20, V7, V7
VROTRW $20, V4, V4
// V0..V3 += V5..V7, V4
// V15,V12-V14 <<<= ((V15,V12-V14 XOR V0..V3), 8)
VADDW V5, V0, V0
VADDW V6, V1, V1
VADDW V7, V2, V2
VADDW V4, V3, V3
VXORV V15, V0, V15
VXORV V12, V1, V12
VXORV V13, V2, V13
VXORV V14, V3, V14
VROTRW $24, V15, V15
VROTRW $24, V12, V12
VROTRW $24, V13, V13
VROTRW $24, V14, V14
// V10,V11,V8,V9 += V15,V12,V13,V14
// V5,V6,V7,V4 <<<= ((V5,V6,V7,V4 XOR V10,V11,V8,V9), 7)
VADDW V15, V10, V10
VADDW V12, V11, V11
VADDW V13, V8, V8
VADDW V14, V9, V9
VXORV V5, V10, V5
VXORV V6, V11, V6
VXORV V7, V8, V7
VXORV V4, V9, V4
VROTRW $25, V5, V5
VROTRW $25, V6, V6
VROTRW $25, V7, V7
VROTRW $25, V4, V4
SUBV $1, R15
BNE R15, R0, chacha
// load origin contants
VMOVQ (R10), V16.W4
VMOVQ 4(R10), V17.W4
VMOVQ 8(R10), V18.W4
VMOVQ 12(R10), V19.W4
// load origin keys
VMOVQ (R7), V20.W4
VMOVQ 4(R7), V21.W4
VMOVQ 8(R7), V22.W4
VMOVQ 12(R7), V23.W4
VMOVQ 16(R7), V24.W4
VMOVQ 20(R7), V25.W4
VMOVQ 24(R7), V26.W4
VMOVQ 28(R7), V27.W4
// add back the initial state to generate the key stream
VADDW V30, V12, V12 // update counter in advance to prevent V30 from being overwritten
VADDW V16, V0, V0
VADDW V17, V1, V1
VADDW V18, V2, V2
VADDW V19, V3, V3
// load origin counter + nonce
VMOVQ (R9), V28.W4
VMOVQ (R8), V29.W4
VMOVQ 4(R8), V30.W4
VMOVQ 8(R8), V31.W4
VADDW V20, V4, V4
VADDW V21, V5, V5
VADDW V22, V6, V6
VADDW V23, V7, V7
VADDW V24, V8, V8
VADDW V25, V9, V9
VADDW V26, V10, V10
VADDW V27, V11, V11
VADDW V28, V12, V12
VADDW V29, V13, V13
VADDW V30, V14, V14
VADDW V31, V15, V15
// shuffle
VILVLW V0, V1, V16
VILVHW V0, V1, V17
VILVLW V2, V3, V18
VILVHW V2, V3, V19
VILVLW V4, V5 ,V20
VILVHW V4, V5, V21
VILVLW V6, V7, V22
VILVHW V6, V7, V23
VILVLW V8, V9, V24
VILVHW V8, V9, V25
VILVLW V10, V11, V26
VILVHW V10, V11, V27
VILVLW V12, V13, V28
VILVHW V12, V13, V29
VILVLW V14, V15, V30
VILVHW V14, V15, V31
VILVLV V16, V18, V0
VILVHV V16, V18, V4
VILVLV V17, V19, V8
VILVHV V17, V19, V12
// load src data from R5
VMOVQ 0(R5), V16
VMOVQ 16(R5), V17
VMOVQ 32(R5), V18
VMOVQ 48(R5), V19
VILVLV V20, V22, V1
VILVHV V20, V22, V5
VILVLV V21, V23, V9
VILVHV V21, V23, V13
VMOVQ 64(R5), V20
VMOVQ 80(R5), V21
VMOVQ 96(R5), V22
VMOVQ 112(R5), V23
VILVLV V24, V26, V2
VILVHV V24, V26, V6
VILVLV V25, V27, V10
VILVHV V25, V27, V14
VMOVQ 128(R5), V24
VMOVQ 144(R5), V25
VMOVQ 160(R5), V26
VMOVQ 176(R5), V27
VILVLV V28, V30, V3
VILVHV V28, V30, V7
VILVLV V29, V31, V11
VILVHV V29, V31, V15
VMOVQ 192(R5), V28
VMOVQ 208(R5), V29
VMOVQ 224(R5), V30
VMOVQ 240(R5), V31
VXORV V0, V16, V16
VXORV V1, V17, V17
VXORV V2, V18, V18
VXORV V3, V19, V19
VMOVQ V16, 0(R4)
VMOVQ V17, 16(R4)
VMOVQ V18, 32(R4)
VMOVQ V19, 48(R4)
VXORV V4, V20, V20
VXORV V5, V21, V21
VXORV V6, V22, V22
VXORV V7, V23, V23
VMOVQ V20, 64(R4)
VMOVQ V21, 80(R4)
VMOVQ V22, 96(R4)
VMOVQ V23, 112(R4)
VXORV V8, V24, V24
VXORV V9, V25, V25
VXORV V10, V26, V26
VXORV V11, V27, V27
VMOVQ V24, 128(R4)
VMOVQ V25, 144(R4)
VMOVQ V26, 160(R4)
VMOVQ V27, 176(R4)
VXORV V12, V28, V28
VXORV V13, V29, V29
VXORV V14, V30, V30
VXORV V15, V31, V31
VMOVQ V28, 192(R4)
VMOVQ V29, 208(R4)
VMOVQ V30, 224(R4)
VMOVQ V31, 240(R4)
ADD $4, R12, R12
MOVW R12, (R9) // update counter
ADDV $256, R4, R4
ADDV $256, R5, R5
SUBV $256, R6, R6
BNE R6, R0, loop
RET