]> Cypherpunks repositories - gogost.git/commitdiff
Use native pretty optimised subtle.XORBytes
authorSergey Matveev <stargrave@stargrave.org>
Tue, 16 Jul 2024 12:23:52 +0000 (15:23 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Tue, 16 Jul 2024 12:39:37 +0000 (15:39 +0300)
gost341194/hash.go
gost3412128/cipher.go
gost3412128/xor_safe.go [deleted file]
gost3412128/xor_words.go [deleted file]
internal/gost34112012/hash.go
mgm/mode.go

index ab96829fd168d93a7af70cdc66a7d192aa761e79..d12db62a0b2d2ae27e7a9b3f40d94a928039eca8 100644 (file)
@@ -18,6 +18,7 @@
 package gost341194
 
 import (
+       "crypto/subtle"
        "encoding/binary"
        "math/big"
 
@@ -128,9 +129,7 @@ func blockReverse(dst, src []byte) {
 }
 
 func blockXor(dst, a, b *[BlockSize]byte) {
-       for i := 0; i < BlockSize; i++ {
-               dst[i] = a[i] ^ b[i]
-       }
+       subtle.XORBytes(dst[:], a[:], b[:])
 }
 
 func (h *Hash) step(hin, m [BlockSize]byte) [BlockSize]byte {
index 5fba3f99d1ae81b130ee29d4cb31a9c1610a8c5e..f11fb6b9d800967bb6d4acfa37d2f2fd79edb6a9 100644 (file)
@@ -16,6 +16,8 @@
 // GOST 34.12-2015 128-bit (Кузнечик (Kuznechik)) block cipher.
 package gost3412128
 
+import "crypto/subtle"
+
 const (
        BlockSize = 16
        KeySize   = 32
@@ -209,10 +211,10 @@ func NewCipher(key []byte) *Cipher {
        copy(ks[1][:], kr1[:])
        for i := 0; i < 4; i++ {
                for j := 0; j < 8; j++ {
-                       xor(krt[:], kr0[:], cBlk[8*i+j][:])
+                       subtle.XORBytes(krt[:], kr0[:], cBlk[8*i+j][:])
                        s(&krt)
                        l(&krt)
-                       xor(krt[:], krt[:], kr1[:])
+                       subtle.XORBytes(krt[:], krt[:], kr1[:])
                        copy(kr1[:], kr0[:])
                        copy(kr0[:], krt[:])
                }
@@ -226,11 +228,11 @@ func (c *Cipher) Encrypt(dst, src []byte) {
        blk := new([BlockSize]byte)
        copy(blk[:], src)
        for i := 0; i < 9; i++ {
-               xor(blk[:], blk[:], c.ks[i][:])
+               subtle.XORBytes(blk[:], blk[:], c.ks[i][:])
                s(blk)
                l(blk)
        }
-       xor(blk[:], blk[:], c.ks[9][:])
+       subtle.XORBytes(blk[:], blk[:], c.ks[9][:])
        copy(dst, blk[:])
 }
 
@@ -238,9 +240,9 @@ func (c *Cipher) Decrypt(dst, src []byte) {
        blk := new([BlockSize]byte)
        copy(blk[:], src)
        for i := 9; i > 0; i-- {
-               xor(blk[:], blk[:], c.ks[i][:])
+               subtle.XORBytes(blk[:], blk[:], c.ks[i][:])
                lInv(blk)
                sInv(blk)
        }
-       xor(dst, blk[:], c.ks[0][:])
+       subtle.XORBytes(dst, blk[:], c.ks[0][:])
 }
diff --git a/gost3412128/xor_safe.go b/gost3412128/xor_safe.go
deleted file mode 100644 (file)
index eaa1ad1..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-//go:build !amd64 && !386 && !ppc64 && !ppc64le && !s390x
-// +build !amd64,!386,!ppc64,!ppc64le,!s390x
-
-package gost3412128
-
-func xor(dst, src1, src2 []byte) {
-       dst[0] = src1[0] ^ src2[0]
-       dst[1] = src1[1] ^ src2[1]
-       dst[2] = src1[2] ^ src2[2]
-       dst[3] = src1[3] ^ src2[3]
-       dst[4] = src1[4] ^ src2[4]
-       dst[5] = src1[5] ^ src2[5]
-       dst[6] = src1[6] ^ src2[6]
-       dst[7] = src1[7] ^ src2[7]
-       dst[8] = src1[8] ^ src2[8]
-       dst[9] = src1[9] ^ src2[9]
-       dst[10] = src1[10] ^ src2[10]
-       dst[11] = src1[11] ^ src2[11]
-       dst[12] = src1[12] ^ src2[12]
-       dst[13] = src1[13] ^ src2[13]
-       dst[14] = src1[14] ^ src2[14]
-       dst[15] = src1[15] ^ src2[15]
-}
diff --git a/gost3412128/xor_words.go b/gost3412128/xor_words.go
deleted file mode 100644 (file)
index 36582c3..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-//go:build amd64 || 386 || ppc64 || ppc64le || s390x
-// +build amd64 386 ppc64 ppc64le s390x
-
-// Fast XOR taken from native crypto/cipher
-
-package gost3412128
-
-import (
-       "unsafe"
-)
-
-const xorWords = BlockSize / int(unsafe.Sizeof(uintptr(0)))
-
-func xor(dst, a, b []byte) {
-       dw := *(*[]uintptr)(unsafe.Pointer(&dst))
-       aw := *(*[]uintptr)(unsafe.Pointer(&a))
-       bw := *(*[]uintptr)(unsafe.Pointer(&b))
-       for i := 0; i < xorWords; i++ {
-               dw[i] = aw[i] ^ bw[i]
-       }
-}
index 4aed02f2e7db155e56e69a24a081c17a2481baac..699539db90bcbc2bed4b28a464067b72831c0a53 100644 (file)
@@ -19,6 +19,7 @@ package gost34112012
 
 import (
        "bytes"
+       "crypto/subtle"
        "encoding/binary"
        "errors"
        "fmt"
@@ -381,6 +382,11 @@ func (h *Hash) add512bit(chk, data []byte) []byte {
        return h.addBuf
 }
 
+func blockXor(dst, x, y []byte) []byte {
+       subtle.XORBytes(dst, x, y)
+       return dst
+}
+
 func (h *Hash) g(n uint64, hsh, data []byte) []byte {
        out := h.gBuf
        copy(out, hsh)
@@ -403,13 +409,6 @@ func (h *Hash) e(k, msg []byte) []byte {
        return blockXor(h.eXorBuf, k, msg)
 }
 
-func blockXor(dst, x, y []byte) []byte {
-       for i := 0; i < BlockSize; i++ {
-               dst[i] = x[i] ^ y[i]
-       }
-       return dst
-}
-
 func (h *Hash) ps(data []byte) []byte {
        for i := 0; i < BlockSize; i++ {
                h.psBuf[tau[i]] = pi[int(data[i])]
index cbba435f4755fdeb862b4f1ab82224a482a9e063..ba41973e0b04bcf604b64d58413c572ad262e1c2 100644 (file)
@@ -19,6 +19,7 @@ package mgm
 import (
        "crypto/cipher"
        "crypto/hmac"
+       "crypto/subtle"
        "encoding/binary"
        "errors"
        "fmt"
@@ -87,12 +88,6 @@ func incr(data []byte) {
        }
 }
 
-func xor(dst, src1, src2 []byte) {
-       for i := 0; i < len(src1); i++ {
-               dst[i] = src1[i] ^ src2[i]
-       }
-}
-
 func (mgm *MGM) validateNonce(nonce []byte) {
        if len(nonce) != mgm.BlockSize {
                panic("nonce length must be equal to cipher's blocksize")
@@ -124,7 +119,7 @@ func (mgm *MGM) auth(out, text, ad []byte) {
        mgm.cipher.Encrypt(mgm.bufP, mgm.icn) // Z_1 = E_K(1 || ICN)
        for len(ad) >= mgm.BlockSize {
                mgm.cipher.Encrypt(mgm.bufC, mgm.bufP) // H_i = E_K(Z_i)
-               xor(                                   // sum (xor)= H_i (x) A_i
+               subtle.XORBytes(                       // sum (xor)= H_i (x) A_i
                        mgm.sum,
                        mgm.sum,
                        mgm.mul.Mul(mgm.bufC, ad[:mgm.BlockSize]),
@@ -138,13 +133,13 @@ func (mgm *MGM) auth(out, text, ad []byte) {
                        mgm.padded[i] = 0
                }
                mgm.cipher.Encrypt(mgm.bufC, mgm.bufP)
-               xor(mgm.sum, mgm.sum, mgm.mul.Mul(mgm.bufC, mgm.padded))
+               subtle.XORBytes(mgm.sum, mgm.sum, mgm.mul.Mul(mgm.bufC, mgm.padded))
                incr(mgm.bufP[:mgm.BlockSize/2])
        }
 
        for len(text) >= mgm.BlockSize {
                mgm.cipher.Encrypt(mgm.bufC, mgm.bufP) // H_{h+j} = E_K(Z_{h+j})
-               xor(                                   // sum (xor)= H_{h+j} (x) C_j
+               subtle.XORBytes(                       // sum (xor)= H_{h+j} (x) C_j
                        mgm.sum,
                        mgm.sum,
                        mgm.mul.Mul(mgm.bufC, text[:mgm.BlockSize]),
@@ -158,7 +153,7 @@ func (mgm *MGM) auth(out, text, ad []byte) {
                        mgm.padded[i] = 0
                }
                mgm.cipher.Encrypt(mgm.bufC, mgm.bufP)
-               xor(mgm.sum, mgm.sum, mgm.mul.Mul(mgm.bufC, mgm.padded))
+               subtle.XORBytes(mgm.sum, mgm.sum, mgm.mul.Mul(mgm.bufC, mgm.padded))
                incr(mgm.bufP[:mgm.BlockSize/2])
        }
 
@@ -172,7 +167,7 @@ func (mgm *MGM) auth(out, text, ad []byte) {
                binary.BigEndian.PutUint64(mgm.bufC[mgm.BlockSize/2:], uint64(textLen))
        }
        // sum (xor)= H_{h+q+1} (x) (len(A) || len(C))
-       xor(mgm.sum, mgm.sum, mgm.mul.Mul(mgm.bufC, mgm.bufP))
+       subtle.XORBytes(mgm.sum, mgm.sum, mgm.mul.Mul(mgm.bufC, mgm.bufP))
        mgm.cipher.Encrypt(mgm.bufP, mgm.sum) // E_K(sum)
        copy(out, mgm.bufP[:mgm.TagSize])     // MSB_S(E_K(sum))
 }
@@ -182,14 +177,16 @@ func (mgm *MGM) crypt(out, in []byte) {
        mgm.cipher.Encrypt(mgm.bufP, mgm.icn) // Y_1 = E_K(0 || ICN)
        for len(in) >= mgm.BlockSize {
                mgm.cipher.Encrypt(mgm.bufC, mgm.bufP) // E_K(Y_i)
-               xor(out, mgm.bufC, in)                 // C_i = P_i (xor) E_K(Y_i)
+               subtle.XORBytes(out, mgm.bufC, in)     // C_i = P_i (xor) E_K(Y_i)
                incr(mgm.bufP[mgm.BlockSize/2:])       // Y_i = incr_r(Y_{i-1})
                out = out[mgm.BlockSize:]
                in = in[mgm.BlockSize:]
        }
        if len(in) > 0 {
                mgm.cipher.Encrypt(mgm.bufC, mgm.bufP)
-               xor(out, in, mgm.bufC)
+               for i := 0; i < len(in); i++ {
+                       out[i] = in[i] ^ mgm.bufC[i]
+               }
        }
 }