Add an assembly implementation of ChaCha20 for Loong64 using LSX SIMD
instructions. This significantly improves performance across all message
sizes on LoongArch machines.
Benchmark results on Loongson-3C6000 @ 2.20GHz:
goos: linux
goarch: loong64
pkg: golang.org/x/crypto/chacha20
cpu: Loongson-3C6000/S @ 2200.00MHz
│ old.bench │ new.bench │
│ sec/op │ sec/op vs base │
ChaCha20/64 188.4n ± 0% 156.9n ± 0% -16.72% (p=0.000 n=10)
ChaCha20/256 666.4n ± 0% 151.5n ± 0% -77.27% (p=0.000 n=10)
ChaCha20/10x25 1037.0n ± 0% 578.9n ± 0% -44.18% (p=0.000 n=10)
ChaCha20/4096 10.207µ ± 0% 1.955µ ± 0% -80.85% (p=0.000 n=10)
ChaCha20/100x40 11.856µ ± 0% 5.785µ ± 0% -51.21% (p=0.000 n=10)
ChaCha20/65536 162.99µ ± 0% 31.60µ ± 0% -80.61% (p=0.000 n=10)
ChaCha20/1000x65 165.57µ ± 0% 41.93µ ± 0% -74.67% (p=0.000 n=10)
geomean 6.369µ 2.141µ -66.38%
│ old.bench │ new.bench │
│ B/s │ B/s vs base │
ChaCha20/64 323.9Mi ± 0% 389.0Mi ± 0% +20.10% (p=0.000 n=10)
ChaCha20/256 366.4Mi ± 0% 1611.2Mi ± 0% +339.80% (p=0.000 n=10)
ChaCha20/10x25 229.8Mi ± 0% 411.8Mi ± 0% +79.19% (p=0.000 n=10)
ChaCha20/4096 382.7Mi ± 0% 1998.1Mi ± 0% +422.08% (p=0.000 n=10)
ChaCha20/100x40 321.8Mi ± 0% 659.4Mi ± 0% +104.94% (p=0.000 n=10)
ChaCha20/65536 383.5Mi ± 0% 1977.8Mi ± 0% +415.78% (p=0.000 n=10)
ChaCha20/1000x65 374.4Mi ± 0% 1478.4Mi ± 0% +294.86% (p=0.000 n=10)
geomean 335.9Mi 999.2Mi +197.50%
Change-Id: I6b8d243819d0ab1a1d6540648ed9bd00ecad5a2e
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/683196
Reviewed-by: Junyang Shao <shaojunyang@google.com>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: abner chenc <chenguoqi@loongson.cn>
Reviewed-by: Cherry Mui <cherryyz@google.com>
23 lines
551 B
Go
23 lines
551 B
Go
// 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.
|
|
|
|
//go:build gc && !purego
|
|
|
|
package chacha20
|
|
|
|
import "golang.org/x/sys/cpu"
|
|
|
|
const bufSize = 256
|
|
|
|
//go:noescape
|
|
func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32)
|
|
|
|
func (c *Cipher) xorKeyStreamBlocks(dst, src []byte) {
|
|
if cpu.Loong64.HasLSX {
|
|
xorKeyStreamVX(dst, src, &c.key, &c.nonce, &c.counter)
|
|
} else {
|
|
c.xorKeyStreamBlocksGeneric(dst, src)
|
|
}
|
|
}
|