Source file src/crypto/internal/fips140/subtle/xor_mipsx.go

     1  // Copyright 2025 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build (mips || mipsle || mips64 || mips64le) && !purego
     6  
     7  package subtle
     8  
     9  import (
    10  	"unsafe"
    11  )
    12  
    13  const wordSize = unsafe.Sizeof(uintptr(0))
    14  
    15  // dst,a,b,n, all be wordSize aligned, and n must be > 0 and a multiple of wordSize
    16  //
    17  //go:noescape
    18  func xorBytesAligned(dst, a, b *byte, n int)
    19  
    20  func xorBytes(dstb, xb, yb *byte, n int) {
    21  	xp := uintptr(unsafe.Pointer(xb)) % wordSize
    22  	yp := uintptr(unsafe.Pointer(yb)) % wordSize
    23  	dp := uintptr(unsafe.Pointer(dstb)) % wordSize
    24  	if xp != yp || xp != dp {
    25  		dst := unsafe.Slice(dstb, n)
    26  		x := unsafe.Slice(xb, n)
    27  		y := unsafe.Slice(yb, n)
    28  		xorLoop(dst, x, y)
    29  		return
    30  	}
    31  	for (uintptr(unsafe.Pointer(dstb))%wordSize) != 0 && n > 0 {
    32  		*dstb = *xb ^ *yb
    33  		dstb = (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(dstb)) + 1))
    34  		xb = (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(xb)) + 1))
    35  		yb = (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(yb)) + 1))
    36  		n--
    37  	}
    38  	alignedN := n & -int(wordSize)
    39  	if alignedN > 0 {
    40  		xorBytesAligned(dstb, xb, yb, alignedN)
    41  		dstb = (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(dstb)) + uintptr(alignedN)))
    42  		xb = (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(xb)) + uintptr(alignedN)))
    43  		yb = (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(yb)) + uintptr(alignedN)))
    44  		n -= alignedN
    45  	}
    46  	for n > 0 {
    47  		*dstb = *xb ^ *yb
    48  		dstb = (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(dstb)) + 1))
    49  		xb = (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(xb)) + 1))
    50  		yb = (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(yb)) + 1))
    51  		n--
    52  	}
    53  }
    54  
    55  func xorLoop[T byte | uintptr](dst, x, y []T) {
    56  	x = x[:len(dst)] // remove bounds check in loop
    57  	y = y[:len(dst)] // remove bounds check in loop
    58  	for i := range dst {
    59  		dst[i] = x[i] ^ y[i]
    60  	}
    61  }
    62  

View as plain text