diff --git a/cipher/ccm.go b/cipher/ccm.go index 7b26132..bfcfa57 100644 --- a/cipher/ccm.go +++ b/cipher/ccm.go @@ -4,12 +4,12 @@ package cipher import ( goCipher "crypto/cipher" goSubtle "crypto/subtle" - "encoding/binary" "math" "errors" "github.com/emmansun/gmsm/internal/alias" + "github.com/emmansun/gmsm/internal/byteorder" "github.com/emmansun/gmsm/internal/subtle" ) @@ -72,7 +72,6 @@ func NewCCMWithNonceSize(cipher goCipher.Block, size int) (goCipher.AEAD, error) // which generates tags with the given length. // // Tag sizes between 8 and 16 bytes are allowed. -// func NewCCMWithTagSize(cipher goCipher.Block, tagSize int) (goCipher.AEAD, error) { return NewCCMWithNonceAndTagSize(cipher, ccmStandardNonceSize, tagSize) } @@ -133,7 +132,7 @@ func (c *ccm) auth(nonce, plaintext, additionalData []byte, tagMask *[ccmBlockSi } out[0] |= byte(c.tagSize-2) << 2 // M' = ((tagSize - 2) / 2)*8 out[0] |= byte(14 - c.nonceSize) // L' - binary.BigEndian.PutUint64(out[ccmBlockSize-8:], uint64(len(plaintext))) + byteorder.BEPutUint64(out[ccmBlockSize-8:], uint64(len(plaintext))) copy(out[1:], nonce) // B0 c.cipher.Encrypt(out[:], out[:]) @@ -143,7 +142,7 @@ func (c *ccm) auth(nonce, plaintext, additionalData []byte, tagMask *[ccmBlockSi // First adata block includes adata length i := 2 if n <= 0xfeff { // l(a) < (2^16 - 2^8) - binary.BigEndian.PutUint16(block[:i], uint16(n)) + byteorder.BEPutUint16(block[:i], uint16(n)) } else { block[0] = 0xff // If (2^16 - 2^8) <= l(a) < 2^32, then the length field is encoded as @@ -152,14 +151,14 @@ func (c *ccm) auth(nonce, plaintext, additionalData []byte, tagMask *[ccmBlockSi if n < uint64(1<<32) { block[1] = 0xfe i = 2 + 4 - binary.BigEndian.PutUint32(block[2:i], uint32(n)) + byteorder.BEPutUint32(block[2:i], uint32(n)) } else { block[1] = 0xff // If 2^32 <= l(a) < 2^64, then the length field is encoded as ten // octets consisting of the octets 0xff, 0xff, and eight octets encoding // l(a) in most-significant-byte-first order. i = 2 + 8 - binary.BigEndian.PutUint64(block[2:i], uint64(n)) + byteorder.BEPutUint64(block[2:i], uint64(n)) } } i = copy(block[i:], additionalData) // first block start with additional data length diff --git a/cipher/hctr.go b/cipher/hctr.go index 03f2b1b..d7f23cf 100644 --- a/cipher/hctr.go +++ b/cipher/hctr.go @@ -2,10 +2,10 @@ package cipher import ( _cipher "crypto/cipher" - "encoding/binary" "errors" "github.com/emmansun/gmsm/internal/alias" + "github.com/emmansun/gmsm/internal/byteorder" "github.com/emmansun/gmsm/internal/subtle" ) @@ -131,8 +131,8 @@ func NewHCTR(cipher _cipher.Block, tweak, hkey []byte) (LengthPreservingMode, er // would expect, say, 4*key to be in index 4 of the table but due to // this bit ordering it will actually be in index 0010 (base 2) = 2. x := hctrFieldElement{ - binary.BigEndian.Uint64(hkey[:8]), - binary.BigEndian.Uint64(hkey[8:blockSize]), + byteorder.BEUint64(hkey[:8]), + byteorder.BEUint64(hkey[8:blockSize]), } c.productTable[reverseBits(1)] = x @@ -180,8 +180,8 @@ func (h *hctr) mul(y *hctrFieldElement) { } func (h *hctr) updateBlock(block []byte, y *hctrFieldElement) { - y.low ^= binary.BigEndian.Uint64(block) - y.high ^= binary.BigEndian.Uint64(block[8:]) + y.low ^= byteorder.BEUint64(block) + y.high ^= byteorder.BEUint64(block[8:]) h.mul(y) } @@ -214,8 +214,8 @@ func (h *hctr) uhash(m []byte, out *[blockSize]byte) { y.high ^= uint64(len(m)+blockSize) * 8 h.mul(&y) // output result - binary.BigEndian.PutUint64(out[:], y.low) - binary.BigEndian.PutUint64(out[8:], y.high) + byteorder.BEPutUint64(out[:], y.low) + byteorder.BEPutUint64(out[8:], y.high) } func (h *hctr) EncryptBytes(ciphertext, plaintext []byte) { @@ -281,7 +281,7 @@ func (h *hctr) ctr(dst, src []byte, baseCtr *[blockSize]byte) { for len(src) >= batchSize { for j := 0; j < concCipher.Concurrency(); j++ { // (i)₂ - binary.BigEndian.PutUint64(num[blockSize-8:], i) + byteorder.BEPutUint64(num[blockSize-8:], i) subtle.XORBytes(ctrs[j*blockSize:], baseCtr[:], num) i++ } @@ -295,7 +295,7 @@ func (h *hctr) ctr(dst, src []byte, baseCtr *[blockSize]byte) { for len(src) > 0 { // (i)₂ - binary.BigEndian.PutUint64(num[blockSize-8:], i) + byteorder.BEPutUint64(num[blockSize-8:], i) subtle.XORBytes(ctr, baseCtr[:], num) h.cipher.Encrypt(ctr, ctr) n := subtle.XORBytes(dst, src, ctr) diff --git a/cipher/xts.go b/cipher/xts.go index 17d0bc0..71b5341 100644 --- a/cipher/xts.go +++ b/cipher/xts.go @@ -2,10 +2,10 @@ package cipher import ( _cipher "crypto/cipher" - "encoding/binary" "errors" "github.com/emmansun/gmsm/internal/alias" + "github.com/emmansun/gmsm/internal/byteorder" "github.com/emmansun/gmsm/internal/subtle" ) @@ -50,7 +50,7 @@ func NewXTSEncrypter(cipherFunc CipherCreator, key, tweakKey, tweak []byte) (_ci // block cipher (which must have a block size of 16 bytes) with sector number. func NewXTSEncrypterWithSector(cipherFunc CipherCreator, key, tweakKey []byte, sectorNum uint64) (_cipher.BlockMode, error) { tweak := make([]byte, blockSize) - binary.LittleEndian.PutUint64(tweak[:8], sectorNum) + byteorder.LEPutUint64(tweak[:8], sectorNum) return NewXTSEncrypter(cipherFunc, key, tweakKey, tweak) } @@ -66,7 +66,7 @@ func NewGBXTSEncrypter(cipherFunc CipherCreator, key, tweakKey, tweak []byte) (_ // It follows GB/T 17964-2021. func NewGBXTSEncrypterWithSector(cipherFunc CipherCreator, key, tweakKey []byte, sectorNum uint64) (_cipher.BlockMode, error) { tweak := make([]byte, blockSize) - binary.LittleEndian.PutUint64(tweak[:8], sectorNum) + byteorder.LEPutUint64(tweak[:8], sectorNum) return NewGBXTSEncrypter(cipherFunc, key, tweakKey, tweak) } @@ -122,7 +122,7 @@ func NewXTSDecrypter(cipherFunc CipherCreator, key, tweakKey, tweak []byte) (_ci // block cipher (which must have a block size of 16 bytes) with sector number for decryption. func NewXTSDecrypterWithSector(cipherFunc CipherCreator, key, tweakKey []byte, sectorNum uint64) (_cipher.BlockMode, error) { tweak := make([]byte, blockSize) - binary.LittleEndian.PutUint64(tweak[:8], sectorNum) + byteorder.LEPutUint64(tweak[:8], sectorNum) return NewXTSDecrypter(cipherFunc, key, tweakKey, tweak) } @@ -138,7 +138,7 @@ func NewGBXTSDecrypter(cipherFunc CipherCreator, key, tweakKey, tweak []byte) (_ // It follows GB/T 17964-2021. func NewGBXTSDecrypterWithSector(cipherFunc CipherCreator, key, tweakKey []byte, sectorNum uint64) (_cipher.BlockMode, error) { tweak := make([]byte, blockSize) - binary.LittleEndian.PutUint64(tweak[:8], sectorNum) + byteorder.LEPutUint64(tweak[:8], sectorNum) return NewGBXTSDecrypter(cipherFunc, key, tweakKey, tweak) } @@ -336,7 +336,7 @@ func mul2Generic(tweak *[blockSize]byte, isGB bool) { tweak[0] ^= GF128_FDBK // 1<<7 | 1<<2 | 1<<1 | 1 } } else { - // GB/T 17964-2021, + // GB/T 17964-2021, // the coefficient of x⁰ can be obtained by tweak[0] >> 7 // the coefficient of x⁷ can be obtained by tweak[0] & 1 // the coefficient of x¹²⁰ can be obtained by tweak[15] >> 7 diff --git a/drbg/ctr_drbg.go b/drbg/ctr_drbg.go index e9446fb..e9d26d7 100644 --- a/drbg/ctr_drbg.go +++ b/drbg/ctr_drbg.go @@ -2,10 +2,10 @@ package drbg import ( "crypto/cipher" - "encoding/binary" "errors" "time" + "github.com/emmansun/gmsm/internal/byteorder" "github.com/emmansun/gmsm/internal/subtle" "github.com/emmansun/gmsm/sm4" ) @@ -185,8 +185,8 @@ func (cd *CtrDrbg) derive(seedMaterial []byte, returnBytes int) []byte { // S = counter || len(seed_material) || len(return_bytes) || seed_material || 0x80 // len(S) = ((outlen + 4 + 4 + len(seed_material) + 1 + outlen - 1) / outlen) * outlen - binary.BigEndian.PutUint32(S[outlen:], uint32(len(seedMaterial))) - binary.BigEndian.PutUint32(S[outlen+4:], uint32(returnBytes)) + byteorder.BEPutUint32(S[outlen:], uint32(len(seedMaterial))) + byteorder.BEPutUint32(S[outlen+4:], uint32(returnBytes)) copy(S[outlen+8:], seedMaterial) S[outlen+8+len(seedMaterial)] = 0x80 @@ -199,7 +199,7 @@ func (cd *CtrDrbg) derive(seedMaterial []byte, returnBytes int) []byte { block := cd.newBlockCipher(key) for i := 0; i < blocks; i++ { - binary.BigEndian.PutUint32(S, uint32(i)) + byteorder.BEPutUint32(S, uint32(i)) copy(temp[i*outlen:], cd.bcc(block, S)) } diff --git a/drbg/hash_drbg.go b/drbg/hash_drbg.go index 263359d..a8d51da 100644 --- a/drbg/hash_drbg.go +++ b/drbg/hash_drbg.go @@ -1,11 +1,11 @@ package drbg import ( - "encoding/binary" "errors" "hash" "time" + "github.com/emmansun/gmsm/internal/byteorder" "github.com/emmansun/gmsm/sm3" ) @@ -15,8 +15,8 @@ const HASH_DRBG_MAX_SEED_SIZE = 111 // HashDrbg hash DRBG structure, its instance is NOT goroutine safe!!! type HashDrbg struct { BaseDrbg - newHash func() hash.Hash - c []byte + newHash func() hash.Hash + c []byte hashSize int } @@ -146,7 +146,7 @@ func (hd *HashDrbg) addH() { func (hd *HashDrbg) addReseedCounter() { t := make([]byte, hd.seedLength) - binary.BigEndian.PutUint64(t[hd.seedLength-8:], hd.reseedCounter) + byteorder.BEPutUint64(t[hd.seedLength-8:], hd.reseedCounter) add(t, hd.v, hd.seedLength) } @@ -208,7 +208,7 @@ func (hd *HashDrbg) derive(seedMaterial []byte, len int) []byte { md := hd.newHash() limit := uint64(len+hd.hashSize-1) / uint64(hd.hashSize) var requireBytes [4]byte - binary.BigEndian.PutUint32(requireBytes[:], uint32(len<<3)) + byteorder.BEPutUint32(requireBytes[:], uint32(len<<3)) var ct byte = 1 k := make([]byte, len) for i := 0; i < int(limit); i++ { diff --git a/internal/bigmod/nat.go b/internal/bigmod/nat.go index 4f6b7e0..30176da 100644 --- a/internal/bigmod/nat.go +++ b/internal/bigmod/nat.go @@ -5,9 +5,10 @@ package bigmod import ( - "encoding/binary" "errors" "math/bits" + + "github.com/emmansun/gmsm/internal/byteorder" ) const ( @@ -205,9 +206,9 @@ func (x *Nat) SetOverflowedBytes(b []byte, m *Modulus) *Nat { // big-endian encoded uint value. func bigEndianUint(buf []byte) uint { if _W == 64 { - return uint(binary.BigEndian.Uint64(buf)) + return uint(byteorder.BEUint64(buf)) } - return uint(binary.BigEndian.Uint32(buf)) + return uint(byteorder.BEUint32(buf)) } func (x *Nat) setBytes(b []byte) error { diff --git a/internal/byteorder/byteorder.go b/internal/byteorder/byteorder.go new file mode 100644 index 0000000..01500a8 --- /dev/null +++ b/internal/byteorder/byteorder.go @@ -0,0 +1,149 @@ +// Copyright 2024 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. + +// Package byteorder provides functions for decoding and encoding +// little and big endian integer types from/to byte slices. +package byteorder + +func LEUint16(b []byte) uint16 { + _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808 + return uint16(b[0]) | uint16(b[1])<<8 +} + +func LEPutUint16(b []byte, v uint16) { + _ = b[1] // early bounds check to guarantee safety of writes below + b[0] = byte(v) + b[1] = byte(v >> 8) +} + +func LEAppendUint16(b []byte, v uint16) []byte { + return append(b, + byte(v), + byte(v>>8), + ) +} + +func LEUint32(b []byte) uint32 { + _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808 + return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 +} + +func LEPutUint32(b []byte, v uint32) { + _ = b[3] // early bounds check to guarantee safety of writes below + b[0] = byte(v) + b[1] = byte(v >> 8) + b[2] = byte(v >> 16) + b[3] = byte(v >> 24) +} + +func LEAppendUint32(b []byte, v uint32) []byte { + return append(b, + byte(v), + byte(v>>8), + byte(v>>16), + byte(v>>24), + ) +} + +func LEUint64(b []byte) uint64 { + _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808 + return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | + uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 +} + +func LEPutUint64(b []byte, v uint64) { + _ = b[7] // early bounds check to guarantee safety of writes below + b[0] = byte(v) + b[1] = byte(v >> 8) + b[2] = byte(v >> 16) + b[3] = byte(v >> 24) + b[4] = byte(v >> 32) + b[5] = byte(v >> 40) + b[6] = byte(v >> 48) + b[7] = byte(v >> 56) +} + +func LEAppendUint64(b []byte, v uint64) []byte { + return append(b, + byte(v), + byte(v>>8), + byte(v>>16), + byte(v>>24), + byte(v>>32), + byte(v>>40), + byte(v>>48), + byte(v>>56), + ) +} + +func BEUint16(b []byte) uint16 { + _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808 + return uint16(b[1]) | uint16(b[0])<<8 +} + +func BEPutUint16(b []byte, v uint16) { + _ = b[1] // early bounds check to guarantee safety of writes below + b[0] = byte(v >> 8) + b[1] = byte(v) +} + +func BEAppendUint16(b []byte, v uint16) []byte { + return append(b, + byte(v>>8), + byte(v), + ) +} + +func BEUint32(b []byte) uint32 { + _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808 + return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24 +} + +func BEPutUint32(b []byte, v uint32) { + _ = b[3] // early bounds check to guarantee safety of writes below + b[0] = byte(v >> 24) + b[1] = byte(v >> 16) + b[2] = byte(v >> 8) + b[3] = byte(v) +} + +func BEAppendUint32(b []byte, v uint32) []byte { + return append(b, + byte(v>>24), + byte(v>>16), + byte(v>>8), + byte(v), + ) +} + +func BEUint64(b []byte) uint64 { + _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808 + return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | + uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56 +} + +func BEPutUint64(b []byte, v uint64) { + _ = b[7] // early bounds check to guarantee safety of writes below + b[0] = byte(v >> 56) + b[1] = byte(v >> 48) + b[2] = byte(v >> 40) + b[3] = byte(v >> 32) + b[4] = byte(v >> 24) + b[5] = byte(v >> 16) + b[6] = byte(v >> 8) + b[7] = byte(v) +} + +func BEAppendUint64(b []byte, v uint64) []byte { + return append(b, + byte(v>>56), + byte(v>>48), + byte(v>>40), + byte(v>>32), + byte(v>>24), + byte(v>>16), + byte(v>>8), + byte(v), + ) +} diff --git a/internal/sm2ec/sm2p256_asm.go b/internal/sm2ec/sm2p256_asm.go index d4b0491..f8d933e 100644 --- a/internal/sm2ec/sm2p256_asm.go +++ b/internal/sm2ec/sm2p256_asm.go @@ -18,6 +18,7 @@ import ( "runtime" "unsafe" + "github.com/emmansun/gmsm/internal/byteorder" "golang.org/x/sys/cpu" ) @@ -385,18 +386,12 @@ var p256Precomputed *[43]p256AffineTable //go:embed p256_asm_table.bin var p256PrecomputedEmbed string -func leUint64(b []byte) uint64 { - _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808 - return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | - uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 -} - func init() { p256PrecomputedPtr := (*unsafe.Pointer)(unsafe.Pointer(&p256PrecomputedEmbed)) if runtime.GOARCH == "s390x" { var newTable [43 * 32 * 2 * 4]uint64 for i, x := range (*[43 * 32 * 2 * 4][8]byte)(*p256PrecomputedPtr) { - newTable[i] = leUint64(x[:]) + newTable[i] = byteorder.LEUint64(x[:]) } newTablePtr := unsafe.Pointer(&newTable) p256PrecomputedPtr = &newTablePtr diff --git a/internal/sm2ec/sm2p256_mqv.go b/internal/sm2ec/sm2p256_mqv.go index e402271..aab6f71 100644 --- a/internal/sm2ec/sm2p256_mqv.go +++ b/internal/sm2ec/sm2p256_mqv.go @@ -1,9 +1,10 @@ package sm2ec import ( - "encoding/binary" "errors" "math/bits" + + "github.com/emmansun/gmsm/internal/byteorder" ) var p256Order = [4]uint64{0x53bbf40939d54123, 0x7203df6b21c6052b, @@ -14,20 +15,20 @@ func fromBytes(bytes []byte) (*[4]uint64, error) { return nil, errors.New("invalid scalar length") } var t [4]uint64 - t[0] = binary.BigEndian.Uint64(bytes[24:]) - t[1] = binary.BigEndian.Uint64(bytes[16:]) - t[2] = binary.BigEndian.Uint64(bytes[8:]) - t[3] = binary.BigEndian.Uint64(bytes) + t[0] = byteorder.BEUint64(bytes[24:]) + t[1] = byteorder.BEUint64(bytes[16:]) + t[2] = byteorder.BEUint64(bytes[8:]) + t[3] = byteorder.BEUint64(bytes) return &t, nil } func toBytes(t *[4]uint64) []byte { var bytes [32]byte - binary.BigEndian.PutUint64(bytes[:], t[3]) - binary.BigEndian.PutUint64(bytes[8:], t[2]) - binary.BigEndian.PutUint64(bytes[16:], t[1]) - binary.BigEndian.PutUint64(bytes[24:], t[0]) + byteorder.BEPutUint64(bytes[:], t[3]) + byteorder.BEPutUint64(bytes[8:], t[2]) + byteorder.BEPutUint64(bytes[16:], t[1]) + byteorder.BEPutUint64(bytes[24:], t[0]) return bytes[:] } diff --git a/kdf/kdf.go b/kdf/kdf.go index 01e0358..df1a3d9 100644 --- a/kdf/kdf.go +++ b/kdf/kdf.go @@ -3,8 +3,9 @@ package kdf import ( "encoding" - "encoding/binary" "hash" + + "github.com/emmansun/gmsm/internal/byteorder" ) // KdfInterface is the interface implemented by some specific Hash implementations. @@ -30,7 +31,7 @@ func Kdf(newHash func() hash.Hash, z []byte, keyLen int) []byte { if marshaler, ok := baseMD.(encoding.BinaryMarshaler); limit == 1 || len(z) < baseMD.BlockSize() || !ok { for i := 0; i < int(limit); i++ { - binary.BigEndian.PutUint32(countBytes[:], ct) + byteorder.BEPutUint32(countBytes[:], ct) baseMD.Write(z) baseMD.Write(countBytes[:]) k = baseMD.Sum(k) @@ -46,11 +47,11 @@ func Kdf(newHash func() hash.Hash, z []byte, keyLen int) []byte { if err != nil { panic(err) } - binary.BigEndian.PutUint32(countBytes[:], ct) + byteorder.BEPutUint32(countBytes[:], ct) md.Write(countBytes[:]) k = md.Sum(k) ct++ - } + } } return k[:keyLen] diff --git a/pkcs/internal/md2/md2.go b/pkcs/internal/md2/md2.go index 376376f..5a98bbd 100644 --- a/pkcs/internal/md2/md2.go +++ b/pkcs/internal/md2/md2.go @@ -5,9 +5,10 @@ package md2 import ( - "encoding/binary" "errors" "hash" + + "github.com/emmansun/gmsm/internal/byteorder" ) // Size the size of a MD2 checksum in bytes. @@ -95,7 +96,7 @@ func (d *digest) UnmarshalBinary(b []byte) error { func appendUint64(b []byte, x uint64) []byte { var a [8]byte - binary.BigEndian.PutUint64(a[:], x) + byteorder.BEPutUint64(a[:], x) return append(b, a[:]...) } diff --git a/pkcs/internal/rc2/rc2.go b/pkcs/internal/rc2/rc2.go index 0e99e4d..89e85e7 100644 --- a/pkcs/internal/rc2/rc2.go +++ b/pkcs/internal/rc2/rc2.go @@ -13,10 +13,10 @@ package rc2 import ( "crypto/cipher" - "encoding/binary" "fmt" "github.com/emmansun/gmsm/internal/alias" + "github.com/emmansun/gmsm/internal/byteorder" ) // The rc2 block size in bytes @@ -109,10 +109,10 @@ func (c *rc2Cipher) Encrypt(dst, src []byte) { panic("rc2: invalid buffer overlap") } - r0 := binary.LittleEndian.Uint16(src[0:2]) - r1 := binary.LittleEndian.Uint16(src[2:4]) - r2 := binary.LittleEndian.Uint16(src[4:6]) - r3 := binary.LittleEndian.Uint16(src[6:BlockSize]) + r0 := byteorder.LEUint16(src[0:2]) + r1 := byteorder.LEUint16(src[2:4]) + r2 := byteorder.LEUint16(src[4:6]) + r3 := byteorder.LEUint16(src[6:BlockSize]) var j int @@ -197,10 +197,10 @@ func (c *rc2Cipher) Encrypt(dst, src []byte) { j++ } - binary.LittleEndian.PutUint16(dst[0:2], r0) - binary.LittleEndian.PutUint16(dst[2:4], r1) - binary.LittleEndian.PutUint16(dst[4:6], r2) - binary.LittleEndian.PutUint16(dst[6:BlockSize], r3) + byteorder.LEPutUint16(dst[0:2], r0) + byteorder.LEPutUint16(dst[2:4], r1) + byteorder.LEPutUint16(dst[4:6], r2) + byteorder.LEPutUint16(dst[6:BlockSize], r3) } func (c *rc2Cipher) Decrypt(dst, src []byte) { @@ -213,10 +213,10 @@ func (c *rc2Cipher) Decrypt(dst, src []byte) { if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) { panic("rc2: invalid buffer overlap") } - r0 := binary.LittleEndian.Uint16(src[0:2]) - r1 := binary.LittleEndian.Uint16(src[2:4]) - r2 := binary.LittleEndian.Uint16(src[4:6]) - r3 := binary.LittleEndian.Uint16(src[6:BlockSize]) + r0 := byteorder.LEUint16(src[0:2]) + r1 := byteorder.LEUint16(src[2:4]) + r2 := byteorder.LEUint16(src[4:6]) + r3 := byteorder.LEUint16(src[6:BlockSize]) j := 63 @@ -301,8 +301,8 @@ func (c *rc2Cipher) Decrypt(dst, src []byte) { j-- } - binary.LittleEndian.PutUint16(dst[0:2], r0) - binary.LittleEndian.PutUint16(dst[2:4], r1) - binary.LittleEndian.PutUint16(dst[4:6], r2) - binary.LittleEndian.PutUint16(dst[6:BlockSize], r3) + byteorder.LEPutUint16(dst[0:2], r0) + byteorder.LEPutUint16(dst[2:4], r1) + byteorder.LEPutUint16(dst[4:6], r2) + byteorder.LEPutUint16(dst[6:BlockSize], r3) } diff --git a/sm3/kdf_mult4_asm.go b/sm3/kdf_mult4_asm.go index 056785c..35bdc32 100644 --- a/sm3/kdf_mult4_asm.go +++ b/sm3/kdf_mult4_asm.go @@ -6,7 +6,7 @@ package sm3 -import "encoding/binary" +import "github.com/emmansun/gmsm/internal/byteorder" // prepare data template: remaining data + [ct] + padding + length // p will be 1 or 2 blocks according to the length of remaining data @@ -18,7 +18,7 @@ func prepareInitData(baseMD *digest, p []byte, len, lenStart uint64) { var tmp [64 + 8]byte // padding + length buffer tmp[0] = 0x80 padlen := tmp[:lenStart+8] - binary.BigEndian.PutUint64(padlen[lenStart:], len) + byteorder.BEPutUint64(padlen[lenStart:], len) copy(p[baseMD.nx+4:], padlen) } @@ -34,7 +34,7 @@ func kdfBy4(baseMD *digest, keyLen int, limit int) []byte { if limit < 4 { return kdfGeneric(baseMD, keyLen, limit) } - + var t uint64 blocks := 1 len := baseMD.len + 4 @@ -55,7 +55,7 @@ func kdfBy4(baseMD *digest, keyLen int, limit int) []byte { var data [parallelSize4][]byte var digs [parallelSize4]*[8]uint32 var states [parallelSize4][8]uint32 - + for j := 0; j < parallelSize4; j++ { digs[j] = &states[j] p := buffer[blocks*BlockSize*j:] @@ -77,7 +77,7 @@ func kdfBy4(baseMD *digest, keyLen int, limit int) []byte { // prepare states states[j] = baseMD.h // prepare data - binary.BigEndian.PutUint32(data[j][baseMD.nx:], ct) + byteorder.BEPutUint32(data[j][baseMD.nx:], ct) ct++ } blockMultBy4(&digs[0], &dataPtrs[0], &tmp[0], blocks) @@ -86,7 +86,7 @@ func kdfBy4(baseMD *digest, keyLen int, limit int) []byte { } remain := limit % parallelSize4 for i := 0; i < remain; i++ { - binary.BigEndian.PutUint32(tmp[:], ct) + byteorder.BEPutUint32(tmp[:], ct) md := *baseMD md.Write(tmp[:4]) h := md.checkSum() diff --git a/sm3/kdf_mult8_amd64.go b/sm3/kdf_mult8_amd64.go index 1e2fd49..b8b8ae1 100644 --- a/sm3/kdf_mult8_amd64.go +++ b/sm3/kdf_mult8_amd64.go @@ -6,7 +6,7 @@ package sm3 -import "encoding/binary" +import "github.com/emmansun/gmsm/internal/byteorder" // p || state || words // p = 64 * 8 * 2 = 1024 @@ -30,7 +30,7 @@ func kdfBy8(baseMD *digest, keyLen int, limit int) []byte { len <<= 3 var ct uint32 = 1 - k := make([]byte, limit * Size) + k := make([]byte, limit*Size) ret := k // prepare temporary buffer @@ -42,7 +42,7 @@ func kdfBy8(baseMD *digest, keyLen int, limit int) []byte { var data [parallelSize8][]byte var digs [parallelSize8]*[8]uint32 var states [parallelSize8][8]uint32 - + for j := 0; j < parallelSize8; j++ { digs[j] = &states[j] p := buffer[blocks*BlockSize*j:] @@ -54,14 +54,14 @@ func kdfBy8(baseMD *digest, keyLen int, limit int) []byte { copy(p, data[0]) } } - + times := limit / parallelSize8 for i := 0; i < times; i++ { for j := 0; j < parallelSize8; j++ { // prepare states states[j] = baseMD.h // prepare data - binary.BigEndian.PutUint32(data[j][baseMD.nx:], ct) + byteorder.BEPutUint32(data[j][baseMD.nx:], ct) ct++ } blockMultBy8(&digs[0], &dataPtrs[0], &tmp[0], blocks) @@ -75,7 +75,7 @@ func kdfBy8(baseMD *digest, keyLen int, limit int) []byte { // prepare states states[j] = baseMD.h // prepare data - binary.BigEndian.PutUint32(data[j][baseMD.nx:], ct) + byteorder.BEPutUint32(data[j][baseMD.nx:], ct) ct++ } blockMultBy4(&digs[0], &dataPtrs[0], &tmp[0], blocks) @@ -85,7 +85,7 @@ func kdfBy8(baseMD *digest, keyLen int, limit int) []byte { } for i := 0; i < remain; i++ { - binary.BigEndian.PutUint32(tmp[:], ct) + byteorder.BEPutUint32(tmp[:], ct) md := *baseMD md.Write(tmp[:4]) h := md.checkSum() diff --git a/sm3/sm3.go b/sm3/sm3.go index 9be1a78..094cfb2 100644 --- a/sm3/sm3.go +++ b/sm3/sm3.go @@ -4,9 +4,10 @@ package sm3 // [GM/T] SM3 GB/T 32905-2016 import ( - "encoding/binary" "errors" "hash" + + "github.com/emmansun/gmsm/internal/byteorder" ) // Size the size of a SM3 checksum in bytes. @@ -39,7 +40,7 @@ type digest struct { } const ( - magic = "sm3\x03" + magic = "sm3\x03" marshaledSize = len(magic) + 8*4 + chunk + 8 ) @@ -87,13 +88,13 @@ func (d *digest) UnmarshalBinary(b []byte) error { func appendUint64(b []byte, x uint64) []byte { var a [8]byte - binary.BigEndian.PutUint64(a[:], x) + byteorder.BEPutUint64(a[:], x) return append(b, a[:]...) } func appendUint32(b []byte, x uint32) []byte { var a [4]byte - binary.BigEndian.PutUint32(a[:], x) + byteorder.BEPutUint32(a[:], x) return append(b, a[:]...) } @@ -143,7 +144,7 @@ func (d *digest) checkSum() [Size]byte { // Length in bits. len <<= 3 padlen := tmp[:t+8] - binary.BigEndian.PutUint64(padlen[t:], len) + byteorder.BEPutUint64(padlen[t:], len) d.Write(padlen) if d.nx != 0 { @@ -152,14 +153,14 @@ func (d *digest) checkSum() [Size]byte { var digest [Size]byte - binary.BigEndian.PutUint32(digest[0:], d.h[0]) - binary.BigEndian.PutUint32(digest[4:], d.h[1]) - binary.BigEndian.PutUint32(digest[8:], d.h[2]) - binary.BigEndian.PutUint32(digest[12:], d.h[3]) - binary.BigEndian.PutUint32(digest[16:], d.h[4]) - binary.BigEndian.PutUint32(digest[20:], d.h[5]) - binary.BigEndian.PutUint32(digest[24:], d.h[6]) - binary.BigEndian.PutUint32(digest[28:], d.h[7]) + byteorder.BEPutUint32(digest[0:], d.h[0]) + byteorder.BEPutUint32(digest[4:], d.h[1]) + byteorder.BEPutUint32(digest[8:], d.h[2]) + byteorder.BEPutUint32(digest[12:], d.h[3]) + byteorder.BEPutUint32(digest[16:], d.h[4]) + byteorder.BEPutUint32(digest[20:], d.h[5]) + byteorder.BEPutUint32(digest[24:], d.h[6]) + byteorder.BEPutUint32(digest[28:], d.h[7]) return digest } @@ -231,7 +232,7 @@ func kdfGeneric(baseMD *digest, keyLen int, limit int) []byte { var ct uint32 = 1 k := make([]byte, keyLen) for i := 0; i < limit; i++ { - binary.BigEndian.PutUint32(countBytes[:], ct) + byteorder.BEPutUint32(countBytes[:], ct) md := *baseMD md.Write(countBytes[:]) h := md.checkSum() diff --git a/sm3/sm3blocks_test.go b/sm3/sm3blocks_test.go index 19a0f84..b0209d9 100644 --- a/sm3/sm3blocks_test.go +++ b/sm3/sm3blocks_test.go @@ -8,9 +8,10 @@ package sm3 import ( "bytes" - "encoding/binary" "fmt" "testing" + + "github.com/emmansun/gmsm/internal/byteorder" ) func initState4() [4]*[8]uint32 { @@ -119,7 +120,7 @@ func TestCopyResultsBy4(t *testing.T) { for i := 0; i < 4; i++ { for j := 0; j < 8; j++ { - binary.BigEndian.PutUint32(expected[i*32+j*4:], m[i][j]) + byteorder.BEPutUint32(expected[i*32+j*4:], m[i][j]) } } if !bytes.Equal(ret[:], expected[:]) { diff --git a/sm4/block.go b/sm4/block.go index 18554be..f0e5fb4 100644 --- a/sm4/block.go +++ b/sm4/block.go @@ -3,7 +3,7 @@ package sm4 // [GM/T] SM4 GB/T 32907-2016 import ( - "encoding/binary" + "github.com/emmansun/gmsm/internal/byteorder" ) // Encrypt one block from src into dst, using the expanded key xk. @@ -11,10 +11,10 @@ func encryptBlockGo(xk *[rounds]uint32, dst, src []byte) { _ = src[15] // early bounds check var b0, b1, b2, b3 uint32 - b0 = binary.BigEndian.Uint32(src[0:4]) - b1 = binary.BigEndian.Uint32(src[4:8]) - b2 = binary.BigEndian.Uint32(src[8:12]) - b3 = binary.BigEndian.Uint32(src[12:16]) + b0 = byteorder.BEUint32(src[0:4]) + b1 = byteorder.BEUint32(src[4:8]) + b2 = byteorder.BEUint32(src[8:12]) + b3 = byteorder.BEUint32(src[12:16]) // First round uses s-box directly and T transformation. b0 ^= t(b1 ^ b2 ^ b3 ^ xk[0]) @@ -60,10 +60,10 @@ func encryptBlockGo(xk *[rounds]uint32, dst, src []byte) { b3 ^= t(b0 ^ b1 ^ b2 ^ xk[31]) _ = dst[15] // early bounds check - binary.BigEndian.PutUint32(dst[0:4], b3) - binary.BigEndian.PutUint32(dst[4:8], b2) - binary.BigEndian.PutUint32(dst[8:12], b1) - binary.BigEndian.PutUint32(dst[12:16], b0) + byteorder.BEPutUint32(dst[0:4], b3) + byteorder.BEPutUint32(dst[4:8], b2) + byteorder.BEPutUint32(dst[8:12], b1) + byteorder.BEPutUint32(dst[12:16], b0) } // Key expansion algorithm. @@ -71,10 +71,10 @@ func expandKeyGo(key []byte, enc, dec *[rounds]uint32) { // Encryption key setup. key = key[:KeySize] var b0, b1, b2, b3 uint32 - b0 = binary.BigEndian.Uint32(key[:4]) ^ fk[0] - b1 = binary.BigEndian.Uint32(key[4:8]) ^ fk[1] - b2 = binary.BigEndian.Uint32(key[8:12]) ^ fk[2] - b3 = binary.BigEndian.Uint32(key[12:16]) ^ fk[3] + b0 = byteorder.BEUint32(key[:4]) ^ fk[0] + b1 = byteorder.BEUint32(key[4:8]) ^ fk[1] + b2 = byteorder.BEUint32(key[8:12]) ^ fk[2] + b3 = byteorder.BEUint32(key[12:16]) ^ fk[3] b0 = b0 ^ t2(b1^b2^b3^ck[0]) enc[0], dec[31] = b0, b0 diff --git a/sm4/gcm_cipher_asm.go b/sm4/gcm_cipher_asm.go index c068019..4a4045f 100644 --- a/sm4/gcm_cipher_asm.go +++ b/sm4/gcm_cipher_asm.go @@ -5,10 +5,10 @@ package sm4 import ( "crypto/cipher" goSubtle "crypto/subtle" - "encoding/binary" "errors" "github.com/emmansun/gmsm/internal/alias" + "github.com/emmansun/gmsm/internal/byteorder" "github.com/emmansun/gmsm/internal/subtle" ) @@ -27,8 +27,8 @@ func (c *sm4CipherAsm) NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) { // would expect, say, 4*key to be in index 4 of the table but due to // this bit ordering it will actually be in index 0010 (base 2) = 2. x := gcmFieldElement{ - binary.BigEndian.Uint64(key[:8]), - binary.BigEndian.Uint64(key[8:]), + byteorder.BEUint64(key[:8]), + byteorder.BEUint64(key[8:]), } g.productTable[8] = x // reverseBits(1) = 8 @@ -48,10 +48,11 @@ func (c *sm4CipherAsm) NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) { // gcmFieldElement represents a value in GF(2¹²⁸). In order to reflect the GCM // standard and make binary.BigEndian suitable for marshaling these values, the // bits are stored in big endian order. For example: -// the coefficient of x⁰ can be obtained by v.low >> 63. -// the coefficient of x⁶³ can be obtained by v.low & 1. -// the coefficient of x⁶⁴ can be obtained by v.high >> 63. -// the coefficient of x¹²⁷ can be obtained by v.high & 1. +// +// the coefficient of x⁰ can be obtained by v.low >> 63. +// the coefficient of x⁶³ can be obtained by v.low & 1. +// the coefficient of x⁶⁴ can be obtained by v.high >> 63. +// the coefficient of x¹²⁷ can be obtained by v.high & 1. type gcmFieldElement struct { low, high uint64 } @@ -233,8 +234,8 @@ func (g *gcm) mul(y *gcmFieldElement) { // Horner's rule. There must be a multiple of gcmBlockSize bytes in blocks. func (g *gcm) updateBlocks(y *gcmFieldElement, blocks []byte) { for len(blocks) > 0 { - y.low ^= binary.BigEndian.Uint64(blocks) - y.high ^= binary.BigEndian.Uint64(blocks[8:]) + y.low ^= byteorder.BEUint64(blocks) + y.high ^= byteorder.BEUint64(blocks[8:]) g.mul(y) blocks = blocks[gcmBlockSize:] } @@ -257,7 +258,7 @@ func (g *gcm) update(y *gcmFieldElement, data []byte) { // and increments it. func gcmInc32(counterBlock *[16]byte) { ctr := counterBlock[len(counterBlock)-4:] - binary.BigEndian.PutUint32(ctr, binary.BigEndian.Uint32(ctr)+1) + byteorder.BEPutUint32(ctr, byteorder.BEUint32(ctr)+1) } // counterCrypt crypts in to out using g.cipher in counter mode. @@ -305,8 +306,8 @@ func (g *gcm) deriveCounter(counter *[gcmBlockSize]byte, nonce []byte) { g.update(&y, nonce) y.high ^= uint64(len(nonce)) * 8 g.mul(&y) - binary.BigEndian.PutUint64(counter[:8], y.low) - binary.BigEndian.PutUint64(counter[8:], y.high) + byteorder.BEPutUint64(counter[:8], y.low) + byteorder.BEPutUint64(counter[8:], y.high) } } @@ -322,8 +323,8 @@ func (g *gcm) auth(out, ciphertext, additionalData []byte, tagMask *[gcmTagSize] g.mul(&y) - binary.BigEndian.PutUint64(out, y.low) - binary.BigEndian.PutUint64(out[8:], y.high) + byteorder.BEPutUint64(out, y.low) + byteorder.BEPutUint64(out[8:], y.high) subtle.XORBytes(out, out, tagMask[:]) } diff --git a/sm4/gcm_ppc64x.go b/sm4/gcm_ppc64x.go index a2a27e2..5c32cfa 100644 --- a/sm4/gcm_ppc64x.go +++ b/sm4/gcm_ppc64x.go @@ -9,11 +9,11 @@ package sm4 import ( "crypto/cipher" _subtle "crypto/subtle" - "encoding/binary" "errors" "runtime" "github.com/emmansun/gmsm/internal/alias" + "github.com/emmansun/gmsm/internal/byteorder" "github.com/emmansun/gmsm/internal/subtle" ) @@ -60,14 +60,14 @@ func (c *sm4CipherAsm) NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) { // Reverse the bytes in each 8 byte chunk // Load little endian, store big endian if runtime.GOARCH == "ppc64le" { - h1 = binary.LittleEndian.Uint64(hle[:8]) - h2 = binary.LittleEndian.Uint64(hle[8:]) + h1 = byteorder.LEUint64(hle[:8]) + h2 = byteorder.LEUint64(hle[8:]) } else { - h1 = binary.BigEndian.Uint64(hle[:8]) - h2 = binary.BigEndian.Uint64(hle[8:]) + h1 = byteorder.BEUint64(hle[:8]) + h2 = byteorder.BEUint64(hle[8:]) } - binary.BigEndian.PutUint64(hle[:8], h1) - binary.BigEndian.PutUint64(hle[8:], h2) + byteorder.BEPutUint64(hle[:8], h1) + byteorder.BEPutUint64(hle[8:], h2) gcmInit(&g.productTable, hle) return g, nil @@ -147,8 +147,8 @@ func (g *gcmAsm) counterCrypt(out, in []byte, counter *[gcmBlockSize]byte) { // increments the rightmost 32-bits of the count value by 1. func gcmInc32(counterBlock *[16]byte) { c := counterBlock[len(counterBlock)-4:] - x := binary.BigEndian.Uint32(c) + 1 - binary.BigEndian.PutUint32(c, x) + x := byteorder.BEUint32(c) + 1 + byteorder.BEPutUint32(c, x) } // paddedGHASH pads data with zeroes until its length is a multiple of diff --git a/sm4/gcm_ppc64x_test.go b/sm4/gcm_ppc64x_test.go index b766c0b..8e1b615 100644 --- a/sm4/gcm_ppc64x_test.go +++ b/sm4/gcm_ppc64x_test.go @@ -7,10 +7,11 @@ package sm4 import ( - "encoding/binary" "fmt" "runtime" "testing" + + "github.com/emmansun/gmsm/internal/byteorder" ) func TestCmul(t *testing.T) { @@ -26,14 +27,14 @@ func TestCmul(t *testing.T) { // Reverse the bytes in each 8 byte chunk // Load little endian, store big endian if runtime.GOARCH == "ppc64le" { - h1 = binary.LittleEndian.Uint64(hle[:8]) - h2 = binary.LittleEndian.Uint64(hle[8:]) + h1 = byteorder.LEUint64(hle[:8]) + h2 = byteorder.LEUint64(hle[8:]) } else { - h1 = binary.BigEndian.Uint64(hle[:8]) - h2 = binary.BigEndian.Uint64(hle[8:]) + h1 = byteorder.BEUint64(hle[:8]) + h2 = byteorder.BEUint64(hle[8:]) } - binary.BigEndian.PutUint64(hle[:8], h1) - binary.BigEndian.PutUint64(hle[8:], h2) + byteorder.BEPutUint64(hle[:8], h1) + byteorder.BEPutUint64(hle[8:], h2) if fmt.Sprintf("%x", hle) != "3811556fff7b1f9fd38f531e5330944d" { t.Errorf("2 got %x", hle) diff --git a/sm9/bn256/gfp.go b/sm9/bn256/gfp.go index 92d32ff..b64d1ac 100644 --- a/sm9/bn256/gfp.go +++ b/sm9/bn256/gfp.go @@ -1,11 +1,12 @@ package bn256 import ( - "encoding/binary" "errors" "fmt" "math/big" "math/bits" + + "github.com/emmansun/gmsm/internal/byteorder" ) type gfP [4]uint64 @@ -44,7 +45,7 @@ func fromBigInt(x *big.Int) (out *gfP) { } for i := 0; i < 4; i++ { start := len(bytes) - 8 - out[i] = binary.BigEndian.Uint64(bytes[start:]) + out[i] = byteorder.BEUint64(bytes[start:]) bytes = bytes[:start] } if x.Sign() < 0 { diff --git a/sm9/sm9.go b/sm9/sm9.go index a0f097f..e69a822 100644 --- a/sm9/sm9.go +++ b/sm9/sm9.go @@ -4,12 +4,12 @@ package sm9 import ( "crypto" goSubtle "crypto/subtle" - "encoding/binary" "errors" "io" "math/big" "github.com/emmansun/gmsm/internal/bigmod" + "github.com/emmansun/gmsm/internal/byteorder" "github.com/emmansun/gmsm/internal/randutil" "github.com/emmansun/gmsm/internal/subtle" "github.com/emmansun/gmsm/sm3" @@ -55,7 +55,7 @@ func hash(z []byte, h hashMode) *bigmod.Nat { var countBytes [4]byte var ct uint32 = 1 - binary.BigEndian.PutUint32(countBytes[:], ct) + byteorder.BEPutUint32(countBytes[:], ct) md.Write([]byte{byte(h)}) md.Write(z) md.Write(countBytes[:]) @@ -63,7 +63,7 @@ func hash(z []byte, h hashMode) *bigmod.Nat { ct++ md.Reset() - binary.BigEndian.PutUint32(countBytes[:], ct) + byteorder.BEPutUint32(countBytes[:], ct) md.Write([]byte{byte(h)}) md.Write(z) md.Write(countBytes[:]) diff --git a/zuc/core.go b/zuc/core.go index 148e19b..048e890 100644 --- a/zuc/core.go +++ b/zuc/core.go @@ -2,9 +2,10 @@ package zuc import ( - "encoding/binary" "fmt" "math/bits" + + "github.com/emmansun/gmsm/internal/byteorder" ) const ( @@ -108,8 +109,8 @@ func (s *zucState32) f32() uint32 { w2 := s.r2 ^ s.x2 u := l1((w1 << 16) | (w2 >> 16)) v := l2((w2 << 16) | (w1 >> 16)) - s.r1 = binary.BigEndian.Uint32([]byte{sbox0[u>>24], sbox1[(u>>16)&0xFF], sbox0[(u>>8)&0xFF], sbox1[u&0xFF]}) - s.r2 = binary.BigEndian.Uint32([]byte{sbox0[v>>24], sbox1[(v>>16)&0xFF], sbox0[(v>>8)&0xFF], sbox1[v&0xFF]}) + s.r1 = byteorder.BEUint32([]byte{sbox0[u>>24], sbox1[(u>>16)&0xFF], sbox0[(u>>8)&0xFF], sbox1[u&0xFF]}) + s.r2 = byteorder.BEUint32([]byte{sbox0[v>>24], sbox1[(v>>16)&0xFF], sbox0[(v>>8)&0xFF], sbox1[v&0xFF]}) return w } diff --git a/zuc/core_test.go b/zuc/core_test.go index 6a8bd46..06e9dd1 100644 --- a/zuc/core_test.go +++ b/zuc/core_test.go @@ -12,7 +12,7 @@ func Test_genKeyword_case1(t *testing.T) { t.Errorf("expected=%x, result=%x\n", 0x27bede74, z1) } if s.r1 != 0xc7ee7f13 { - t.Errorf("expected=%x, result=%x\n", 0xc7ee7f13, s.r1) + t.Errorf("expected=0xc7ee7f13, result=%x\n", s.r1) } if s.r2 != 0xc0fa817 { t.Errorf("expected=%x, result=%x\n", 0xc0fa817, s.r2) diff --git a/zuc/eea.go b/zuc/eea.go index ee189df..726510b 100644 --- a/zuc/eea.go +++ b/zuc/eea.go @@ -2,9 +2,9 @@ package zuc import ( "crypto/cipher" - "encoding/binary" "github.com/emmansun/gmsm/internal/alias" + "github.com/emmansun/gmsm/internal/byteorder" "github.com/emmansun/gmsm/internal/subtle" ) @@ -30,7 +30,7 @@ func NewCipher(key, iv []byte) (cipher.Stream, error) { // NewEEACipher create a stream cipher based on key, count, bearer and direction arguments according specification. func NewEEACipher(key []byte, count, bearer, direction uint32) (cipher.Stream, error) { iv := make([]byte, 16) - binary.BigEndian.PutUint32(iv, count) + byteorder.BEPutUint32(iv, count) copy(iv[8:12], iv[:4]) iv[4] = byte(((bearer << 1) | (direction & 1)) << 2) iv[12] = iv[4] @@ -46,7 +46,7 @@ func NewEEACipher(key []byte, count, bearer, direction uint32) (cipher.Stream, e func genKeyStreamRev32Generic(keyStream []byte, pState *zucState32) { for len(keyStream) >= 4 { z := genKeyword(pState) - binary.BigEndian.PutUint32(keyStream, z) + byteorder.BEPutUint32(keyStream, z) keyStream = keyStream[4:] } } diff --git a/zuc/eia.go b/zuc/eia.go index 1ed2a3b..b2ea401 100644 --- a/zuc/eia.go +++ b/zuc/eia.go @@ -1,8 +1,9 @@ package zuc import ( - "encoding/binary" "fmt" + + "github.com/emmansun/gmsm/internal/byteorder" ) const ( @@ -60,7 +61,7 @@ func NewHash(key, iv []byte) (*ZUC128Mac, error) { func genIV4EIA(count, bearer, direction uint32) []byte { iv := make([]byte, 16) - binary.BigEndian.PutUint32(iv, count) + byteorder.BEPutUint32(iv, count) copy(iv[9:12], iv[1:4]) iv[4] = byte(bearer << 3) iv[12] = iv[4] @@ -102,7 +103,7 @@ func blockGeneric(m *ZUC128Mac, p []byte) { m.genKeywords(m.k0[4:]) k64 = uint64(m.k0[0])<<32 | uint64(m.k0[1]) // process first 32 bits - w := binary.BigEndian.Uint32(p[0:4]) + w := byteorder.BEUint32(p[0:4]) for j := 0; j < 32; j++ { // t64 ^= (w >> 31) ? k64 : 0 t64 ^= ^(uint64(w>>31) - 1) & k64 @@ -111,7 +112,7 @@ func blockGeneric(m *ZUC128Mac, p []byte) { } // process second 32 bits k64 = uint64(m.k0[1])<<32 | uint64(m.k0[2]) - w = binary.BigEndian.Uint32(p[4:8]) + w = byteorder.BEUint32(p[4:8]) for j := 0; j < 32; j++ { t64 ^= ^(uint64(w>>31) - 1) & k64 w <<= 1 @@ -119,7 +120,7 @@ func blockGeneric(m *ZUC128Mac, p []byte) { } // process third 32 bits k64 = uint64(m.k0[2])<<32 | uint64(m.k0[3]) - w = binary.BigEndian.Uint32(p[8:12]) + w = byteorder.BEUint32(p[8:12]) for j := 0; j < 32; j++ { t64 ^= ^(uint64(w>>31) - 1) & k64 w <<= 1 @@ -127,7 +128,7 @@ func blockGeneric(m *ZUC128Mac, p []byte) { } // process fourth 32 bits k64 = uint64(m.k0[3])<<32 | uint64(m.k0[4]) - w = binary.BigEndian.Uint32(p[12:16]) + w = byteorder.BEUint32(p[12:16]) for j := 0; j < 32; j++ { t64 ^= ^(uint64(w>>31) - 1) & k64 w <<= 1 @@ -183,7 +184,7 @@ func (m *ZUC128Mac) checkSum(additionalBits int, b byte) [4]byte { // process 32 bits at a time for first complete words for i := 0; i < nwords-1; i++ { k64 = uint64(m.k0[i])<<32 | uint64(m.k0[i+1]) - w := binary.BigEndian.Uint32(m.x[i*4:]) + w := byteorder.BEUint32(m.x[i*4:]) for j := 0; j < 32; j++ { t64 ^= ^(uint64(w>>31) - 1) & k64 w <<= 1 @@ -196,7 +197,7 @@ func (m *ZUC128Mac) checkSum(additionalBits int, b byte) [4]byte { // process remaining bits less than 32 if nRemainBits > 0 { k64 = uint64(m.k0[kIdx])<<32 | uint64(m.k0[kIdx+1]) - w := binary.BigEndian.Uint32(m.x[(nwords-1)*4:]) + w := byteorder.BEUint32(m.x[(nwords-1)*4:]) for j := 0; j < nRemainBits; j++ { t64 ^= ^(uint64(w>>31) - 1) & k64 w <<= 1 @@ -212,11 +213,11 @@ func (m *ZUC128Mac) checkSum(additionalBits int, b byte) [4]byte { m.t ^= m.k0[kIdx+1] var digest [4]byte - binary.BigEndian.PutUint32(digest[:], m.t) + byteorder.BEPutUint32(digest[:], m.t) return digest } -// Finish this function hash nbits data in p and return mac value, after this function call, +// Finish this function hash nbits data in p and return mac value, after this function call, // the hash state will be reset. // In general, we will use byte level function, this is just for test/verify. // nbits: number of bits to hash in p. diff --git a/zuc/eia256.go b/zuc/eia256.go index 9d2ba70..b20d784 100644 --- a/zuc/eia256.go +++ b/zuc/eia256.go @@ -1,8 +1,9 @@ package zuc import ( - "encoding/binary" "fmt" + + "github.com/emmansun/gmsm/internal/byteorder" ) type ZUC256Mac struct { @@ -93,7 +94,7 @@ func block256Generic(m *ZUC256Mac, p []byte) { for len(p) >= chunk { m.genKeywords(m.k0[4:]) for l := 0; l < 4; l++ { - w := binary.BigEndian.Uint32(p[l*4:]) + w := byteorder.BEUint32(p[l*4:]) switch m.tagSize { case 4: k64 = uint64(m.k0[l])<<32 | uint64(m.k0[l+1]) @@ -164,7 +165,7 @@ func (m *ZUC256Mac) checkSum(additionalBits int, b byte) []byte { words := (nRemainBits + 31) / 32 for l := 0; l < words-1; l++ { - w := binary.BigEndian.Uint32(m.x[l*4:]) + w := byteorder.BEUint32(m.x[l*4:]) k1 := m.k0[m.tagSize/4+l] for i := 0; i < 32; i++ { wBit := ^(w>>31 - 1) @@ -183,7 +184,7 @@ func (m *ZUC256Mac) checkSum(additionalBits int, b byte) []byte { nRemainBits -= (words - 1) * 32 kIdx = words - 1 if nRemainBits > 0 { - w := binary.BigEndian.Uint32(m.x[(words-1)*4:]) + w := byteorder.BEUint32(m.x[(words-1)*4:]) for i := 0; i < nRemainBits; i++ { wBit := ^(w>>31 - 1) for j := 0; j < m.tagSize/4; j++ { @@ -202,7 +203,7 @@ func (m *ZUC256Mac) checkSum(additionalBits int, b byte) []byte { digest := make([]byte, m.tagSize) for j := 0; j < m.tagSize/4; j++ { m.t[j] ^= m.k0[j+kIdx] - binary.BigEndian.PutUint32(digest[j*4:], m.t[j]) + byteorder.BEPutUint32(digest[j*4:], m.t[j]) } return digest diff --git a/zuc/eia_test.go b/zuc/eia_test.go index 7650831..2b40946 100644 --- a/zuc/eia_test.go +++ b/zuc/eia_test.go @@ -1,11 +1,11 @@ package zuc import ( - "encoding/binary" "encoding/hex" "hash" "testing" + "github.com/emmansun/gmsm/internal/byteorder" "github.com/emmansun/gmsm/internal/cryptotest" ) @@ -144,7 +144,7 @@ func TestEIA_Finish(t *testing.T) { } in := make([]byte, len(test.in)*4) for j, v := range test.in { - binary.BigEndian.PutUint32(in[j*4:], v) + byteorder.BEPutUint32(in[j*4:], v) } mac := h.Finish(in, test.nbits)