This commit is contained in:
bluepython508 committed 2026-10-22 12:27:19 +01:00
1 parent 3530afb854
commit 6903fcff27
2146 files changed
+112256 -190703

No files matched your search

@@ -0,0 +1,114 @@
// SPDX-License-Identifier: BSD-3-Clause
//
// Generated from CryptoGAMS chacha-armv4.pl by plan9-xlate.pl. The
// generated chacha20_arm.s carries the upstream BSD-3-Clause notice
// in its file header.
//go:build arm
//go:generate sh ../regen/regen.sh
// Package chacha20 implements the ChaCha20 stream cipher with the
// CryptoGAMS ARMv4 assembly inner loop, regenerated by
// tsasm/arm/regen/plan9-xlate.pl. It only builds on GOARCH=arm;
// other architectures should use golang.org/x/crypto/chacha20.
package chacha20
import (
"encoding/binary"
"unsafe"
"golang.org/x/sys/cpu"
)
const (
KeySize = 32
NonceSize = 12
BlockSize = 64
)
// ChaCha20_ctr32 is the scalar upstream entry point: it XORs a
// ChaCha20 keystream against `length` bytes from inp into out, using
// key (32 bytes) and ctr_nonce (16 bytes: counter as little-endian
// u32 followed by the 12-byte nonce).
//
//go:noescape
func ChaCha20_ctr32(out, inp unsafe.Pointer, length uintptr, key, ctr_nonce unsafe.Pointer)
// ChaCha20_neon is the NEON entry point. The CryptoGAMS NEON loop's
// .Loop_neon_outer head does `cmp r11,#128; bls .Lbreak_neon` and
// then branches cross-function into ChaCha20_ctr32's main loop --
// which we rewrite to UDF, since Plan 9 has no way to express that
// cross-function branch. So `length` must be either 0..256, an exact
// multiple of 256, or 256*K + R with R in 129..255. XORKeyStream
// trims to a safe length and sends any leftover 1..128-byte tail
// through ChaCha20_ctr32.
//
//go:noescape
func ChaCha20_neon(out, inp unsafe.Pointer, length uintptr, key, ctr_nonce unsafe.Pointer)
// XORKeyStream XORs a ChaCha20 keystream into in, writing to out, using
// the given 32-byte key, 12-byte IETF nonce, and starting 32-bit block
// counter. out and in must have the same length and may overlap exactly
// or not at all. It returns the next block counter
// (counter + ceil(len/64)).
func XORKeyStream(out, in []byte, key *[KeySize]byte, nonce *[NonceSize]byte, counter uint32) uint32 {
if len(out) < len(in) {
panic("chacha20: output buffer shorter than input")
}
if len(in) == 0 {
return counter
}
// CryptoGAMS expects the counter+nonce as a single 16-byte block:
// 4 little-endian words.
var ctrNonce [16]byte
binary.LittleEndian.PutUint32(ctrNonce[0:4], counter)
copy(ctrNonce[4:], nonce[:])
// On NEON-capable hardware, hand a "good" prefix length to
// ChaCha20_neon. The CryptoGAMS NEON loop processes 256 bytes per
// outer iteration and only re-checks for break-out into the scalar
// path when entering .Loop_neon_outer; on the first pass through
// .Loop_neon_enter that check doesn't fire, so any length up to
// 256 bytes is safe. After that, the inner test `cmp r11,#128;
// bls .Lbreak_neon` jumps cross-function into ChaCha20_ctr32 --
// which we replaced with UDF -- whenever the post-iteration
// remainder falls in 1..128 bytes. We avoid that by trimming to a
// length whose mod-256 tail is either 0 or > 128, sending the
// trimmed remainder (the small 1..128 byte tail when it shows up)
// to the scalar path.
pos := 0
if cpu.ARM.HasNEON {
n := len(in)
neonLen := n
if n > 256 {
if rem := n % 256; rem != 0 && rem <= 128 {
neonLen = n - rem
}
}
if neonLen > 0 {
ChaCha20_neon(
unsafe.Pointer(&out[0]),
unsafe.Pointer(&in[0]),
uintptr(neonLen),
unsafe.Pointer(&key[0]),
unsafe.Pointer(&ctrNonce[0]),
)
pos = neonLen
binary.LittleEndian.PutUint32(ctrNonce[0:4], counter+uint32(neonLen>>6))
}
}
if pos < len(in) {
ChaCha20_ctr32(
unsafe.Pointer(&out[pos]),
unsafe.Pointer(&in[pos]),
uintptr(len(in)-pos),
unsafe.Pointer(&key[0]),
unsafe.Pointer(&ctrNonce[0]),
)
}
return counter + uint32((len(in)+63)>>6)
}
File diff suppressed because it is too large. Load diff