scrypt: use encoding/binary to simplify smix

This CL simplifies the smix implementation.
It:
 - replaces the manual byte-int conversion
   with functionality from encoding/binary.
 - pre-computes the range `r * 32` as `R`.

Change-Id: Ife4920089c011fec82b234fb56df33e94204e0f8
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/253357
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Tobias Klauser <tobias.klauser@gmail.com>
diff --git a/scrypt/scrypt.go b/scrypt/scrypt.go
index 2f81fe4..bbe4494 100644
--- a/scrypt/scrypt.go
+++ b/scrypt/scrypt.go
@@ -9,6 +9,7 @@
 
 import (
 	"crypto/sha256"
+	"encoding/binary"
 	"errors"
 	"math/bits"
 
@@ -143,36 +144,34 @@
 
 func smix(b []byte, r, N int, v, xy []uint32) {
 	var tmp [16]uint32
+	R := 32 * r
 	x := xy
-	y := xy[32*r:]
+	y := xy[R:]
 
 	j := 0
-	for i := 0; i < 32*r; i++ {
-		x[i] = uint32(b[j]) | uint32(b[j+1])<<8 | uint32(b[j+2])<<16 | uint32(b[j+3])<<24
+	for i := 0; i < R; i++ {
+		x[i] = binary.LittleEndian.Uint32(b[j:])
 		j += 4
 	}
 	for i := 0; i < N; i += 2 {
-		blockCopy(v[i*(32*r):], x, 32*r)
+		blockCopy(v[i*R:], x, R)
 		blockMix(&tmp, x, y, r)
 
-		blockCopy(v[(i+1)*(32*r):], y, 32*r)
+		blockCopy(v[(i+1)*R:], y, R)
 		blockMix(&tmp, y, x, r)
 	}
 	for i := 0; i < N; i += 2 {
 		j := int(integer(x, r) & uint64(N-1))
-		blockXOR(x, v[j*(32*r):], 32*r)
+		blockXOR(x, v[j*R:], R)
 		blockMix(&tmp, x, y, r)
 
 		j = int(integer(y, r) & uint64(N-1))
-		blockXOR(y, v[j*(32*r):], 32*r)
+		blockXOR(y, v[j*R:], R)
 		blockMix(&tmp, y, x, r)
 	}
 	j = 0
-	for _, v := range x[:32*r] {
-		b[j+0] = byte(v >> 0)
-		b[j+1] = byte(v >> 8)
-		b[j+2] = byte(v >> 16)
-		b[j+3] = byte(v >> 24)
+	for _, v := range x[:R] {
+		binary.LittleEndian.PutUint32(b[j:], v)
 		j += 4
 	}
 }