2023-05-12 06:31:31 +00:00
|
|
|
// Copyright 2015 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 (amd64 || 386 || ppc64le) && !purego
|
|
|
|
|
|
|
|
package sha3
|
|
|
|
|
2023-06-04 09:24:30 +00:00
|
|
|
import (
|
|
|
|
"encoding/binary"
|
|
|
|
"unsafe"
|
|
|
|
)
|
2023-05-12 06:31:31 +00:00
|
|
|
|
|
|
|
// A storageBuf is an aligned array of maxRate bytes.
|
|
|
|
type storageBuf [maxRate / 8]uint64
|
|
|
|
|
|
|
|
func (b *storageBuf) asBytes() *[maxRate]byte {
|
|
|
|
return (*[maxRate]byte)(unsafe.Pointer(b))
|
|
|
|
}
|
|
|
|
|
|
|
|
// xorInUnaligned uses unaligned reads and writes to update d.a to contain d.a
|
|
|
|
// XOR buf.
|
2023-05-12 06:42:07 +00:00
|
|
|
func xorInUnaligned(d *HasherState, buf []byte) {
|
2023-05-12 06:31:31 +00:00
|
|
|
n := len(buf)
|
|
|
|
if n >= 72 {
|
2023-06-04 09:24:30 +00:00
|
|
|
d.a[0] ^= binary.LittleEndian.Uint64(buf[8*0:])
|
|
|
|
d.a[1] ^= binary.LittleEndian.Uint64(buf[8*1:])
|
|
|
|
d.a[2] ^= binary.LittleEndian.Uint64(buf[8*2:])
|
|
|
|
d.a[3] ^= binary.LittleEndian.Uint64(buf[8*3:])
|
|
|
|
d.a[4] ^= binary.LittleEndian.Uint64(buf[8*4:])
|
|
|
|
d.a[5] ^= binary.LittleEndian.Uint64(buf[8*5:])
|
|
|
|
d.a[6] ^= binary.LittleEndian.Uint64(buf[8*6:])
|
|
|
|
d.a[7] ^= binary.LittleEndian.Uint64(buf[8*7:])
|
|
|
|
d.a[8] ^= binary.LittleEndian.Uint64(buf[8*8:])
|
2023-05-12 06:31:31 +00:00
|
|
|
}
|
|
|
|
if n >= 104 {
|
2023-06-04 09:24:30 +00:00
|
|
|
d.a[9] ^= binary.LittleEndian.Uint64(buf[8*9:])
|
|
|
|
d.a[10] ^= binary.LittleEndian.Uint64(buf[8*10:])
|
|
|
|
d.a[11] ^= binary.LittleEndian.Uint64(buf[8*11:])
|
|
|
|
d.a[12] ^= binary.LittleEndian.Uint64(buf[8*12:])
|
2023-05-12 06:31:31 +00:00
|
|
|
}
|
|
|
|
if n >= 136 {
|
2023-06-04 09:24:30 +00:00
|
|
|
d.a[13] ^= binary.LittleEndian.Uint64(buf[8*13:])
|
|
|
|
d.a[14] ^= binary.LittleEndian.Uint64(buf[8*14:])
|
|
|
|
d.a[15] ^= binary.LittleEndian.Uint64(buf[8*15:])
|
|
|
|
d.a[16] ^= binary.LittleEndian.Uint64(buf[8*16:])
|
2023-05-12 06:31:31 +00:00
|
|
|
}
|
|
|
|
if n >= 144 {
|
2023-06-04 09:24:30 +00:00
|
|
|
d.a[17] ^= binary.LittleEndian.Uint64(buf[8*17:])
|
2023-05-12 06:31:31 +00:00
|
|
|
}
|
|
|
|
if n >= 168 {
|
2023-06-04 09:24:30 +00:00
|
|
|
d.a[18] ^= binary.LittleEndian.Uint64(buf[8*18:])
|
|
|
|
d.a[19] ^= binary.LittleEndian.Uint64(buf[8*19:])
|
|
|
|
d.a[20] ^= binary.LittleEndian.Uint64(buf[8*20:])
|
2023-05-12 06:31:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-12 06:42:07 +00:00
|
|
|
func copyOutUnaligned(d *HasherState, buf []byte) {
|
2023-05-12 06:31:31 +00:00
|
|
|
ab := (*[maxRate]uint8)(unsafe.Pointer(&d.a[0]))
|
|
|
|
copy(buf, ab[:])
|
|
|
|
}
|
|
|
|
|
2023-06-04 09:24:30 +00:00
|
|
|
func xorIn(d *HasherState, buf []byte) {
|
|
|
|
xorInUnaligned(d, buf)
|
|
|
|
}
|
|
|
|
|
2023-05-12 06:31:31 +00:00
|
|
|
var (
|
|
|
|
copyOut = copyOutUnaligned
|
|
|
|
)
|
|
|
|
|
|
|
|
const xorImplementationUnaligned = "unaligned"
|