This corrects a compile error due to a mismatch between function description and the assembler code that first appeared when running TryBots on the change to vendor this code. This fixes that problem and adds and minor change based on a comment in CL 195959. Change-Id: I42cbd3f75e281913f12f74850deaedf14eb21989 Reviewed-on: https://go-review.googlesource.com/c/crypto/+/205659 Reviewed-by: Filippo Valsorda <filippo@golang.org>
55 lines
1.7 KiB
Go
55 lines
1.7 KiB
Go
// Copyright 2019 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.
|
|
|
|
// +build ppc64le,!gccgo,!appengine
|
|
|
|
package chacha20
|
|
|
|
import (
|
|
"encoding/binary"
|
|
)
|
|
|
|
const (
|
|
bufSize = 256
|
|
haveAsm = true
|
|
)
|
|
|
|
//go:noescape
|
|
func chaCha20_ctr32_vsx(out, inp *byte, len int, key *[8]uint32, counter *uint32)
|
|
|
|
func (c *Cipher) xorKeyStreamAsm(dst, src []byte) {
|
|
// This implementation can handle buffers that aren't multiples of
|
|
// 256.
|
|
if len(src) >= bufSize {
|
|
chaCha20_ctr32_vsx(&dst[0], &src[0], len(src), &c.key, &c.counter)
|
|
} else if len(src)%bufSize != 0 {
|
|
chaCha20_ctr32_vsx(&c.buf[0], &c.buf[0], bufSize, &c.key, &c.counter)
|
|
start := len(src) - len(src)%bufSize
|
|
ts, td, tb := src[start:], dst[start:], c.buf[:]
|
|
// Unroll loop to XOR 32 bytes per iteration.
|
|
for i := 0; i < len(ts)-32; i += 32 {
|
|
td, tb = td[:len(ts)], tb[:len(ts)] // bounds check elimination
|
|
s0 := binary.LittleEndian.Uint64(ts[0:8])
|
|
s1 := binary.LittleEndian.Uint64(ts[8:16])
|
|
s2 := binary.LittleEndian.Uint64(ts[16:24])
|
|
s3 := binary.LittleEndian.Uint64(ts[24:32])
|
|
b0 := binary.LittleEndian.Uint64(tb[0:8])
|
|
b1 := binary.LittleEndian.Uint64(tb[8:16])
|
|
b2 := binary.LittleEndian.Uint64(tb[16:24])
|
|
b3 := binary.LittleEndian.Uint64(tb[24:32])
|
|
binary.LittleEndian.PutUint64(td[0:8], s0^b0)
|
|
binary.LittleEndian.PutUint64(td[8:16], s1^b1)
|
|
binary.LittleEndian.PutUint64(td[16:24], s2^b2)
|
|
binary.LittleEndian.PutUint64(td[24:32], s3^b3)
|
|
ts, td, tb = ts[32:], td[32:], tb[32:]
|
|
}
|
|
td, tb = td[:len(ts)], tb[:len(ts)] // bounds check elimination
|
|
for i, v := range ts {
|
|
td[i] = tb[i] ^ v
|
|
}
|
|
c.len = bufSize - (len(src) % bufSize)
|
|
}
|
|
|
|
}
|