From: Sergey Matveev Date: Tue, 16 Jul 2024 12:23:52 +0000 (+0300) Subject: Use native pretty optimised subtle.XORBytes X-Git-Tag: v5.15.0~8 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=5f36a678bb380b2846cbb1689a8788d82f738368;p=gogost.git Use native pretty optimised subtle.XORBytes --- diff --git a/gost341194/hash.go b/gost341194/hash.go index ab96829..d12db62 100644 --- a/gost341194/hash.go +++ b/gost341194/hash.go @@ -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 { diff --git a/gost3412128/cipher.go b/gost3412128/cipher.go index 5fba3f9..f11fb6b 100644 --- a/gost3412128/cipher.go +++ b/gost3412128/cipher.go @@ -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 index eaa1ad1..0000000 --- a/gost3412128/xor_safe.go +++ /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 index 36582c3..0000000 --- a/gost3412128/xor_words.go +++ /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] - } -} diff --git a/internal/gost34112012/hash.go b/internal/gost34112012/hash.go index 4aed02f..699539d 100644 --- a/internal/gost34112012/hash.go +++ b/internal/gost34112012/hash.go @@ -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])] diff --git a/mgm/mode.go b/mgm/mode.go index cbba435..ba41973 100644 --- a/mgm/mode.go +++ b/mgm/mode.go @@ -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] + } } }