internal/byteorder: new package #275

This commit is contained in:
Sun Yimin 2024-11-21 14:32:32 +08:00 committed by GitHub
parent 4f7504c6b9
commit bf14e70c4b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 328 additions and 173 deletions

View File

@ -4,12 +4,12 @@ package cipher
import ( import (
goCipher "crypto/cipher" goCipher "crypto/cipher"
goSubtle "crypto/subtle" goSubtle "crypto/subtle"
"encoding/binary"
"math" "math"
"errors" "errors"
"github.com/emmansun/gmsm/internal/alias" "github.com/emmansun/gmsm/internal/alias"
"github.com/emmansun/gmsm/internal/byteorder"
"github.com/emmansun/gmsm/internal/subtle" "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. // which generates tags with the given length.
// //
// Tag sizes between 8 and 16 bytes are allowed. // Tag sizes between 8 and 16 bytes are allowed.
//
func NewCCMWithTagSize(cipher goCipher.Block, tagSize int) (goCipher.AEAD, error) { func NewCCMWithTagSize(cipher goCipher.Block, tagSize int) (goCipher.AEAD, error) {
return NewCCMWithNonceAndTagSize(cipher, ccmStandardNonceSize, tagSize) 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(c.tagSize-2) << 2 // M' = ((tagSize - 2) / 2)*8
out[0] |= byte(14 - c.nonceSize) // L' 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) copy(out[1:], nonce)
// B0 // B0
c.cipher.Encrypt(out[:], out[:]) 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 // First adata block includes adata length
i := 2 i := 2
if n <= 0xfeff { // l(a) < (2^16 - 2^8) if n <= 0xfeff { // l(a) < (2^16 - 2^8)
binary.BigEndian.PutUint16(block[:i], uint16(n)) byteorder.BEPutUint16(block[:i], uint16(n))
} else { } else {
block[0] = 0xff block[0] = 0xff
// If (2^16 - 2^8) <= l(a) < 2^32, then the length field is encoded as // 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) { if n < uint64(1<<32) {
block[1] = 0xfe block[1] = 0xfe
i = 2 + 4 i = 2 + 4
binary.BigEndian.PutUint32(block[2:i], uint32(n)) byteorder.BEPutUint32(block[2:i], uint32(n))
} else { } else {
block[1] = 0xff block[1] = 0xff
// If 2^32 <= l(a) < 2^64, then the length field is encoded as ten // 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 // octets consisting of the octets 0xff, 0xff, and eight octets encoding
// l(a) in most-significant-byte-first order. // l(a) in most-significant-byte-first order.
i = 2 + 8 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 i = copy(block[i:], additionalData) // first block start with additional data length

View File

@ -2,10 +2,10 @@ package cipher
import ( import (
_cipher "crypto/cipher" _cipher "crypto/cipher"
"encoding/binary"
"errors" "errors"
"github.com/emmansun/gmsm/internal/alias" "github.com/emmansun/gmsm/internal/alias"
"github.com/emmansun/gmsm/internal/byteorder"
"github.com/emmansun/gmsm/internal/subtle" "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 // 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. // this bit ordering it will actually be in index 0010 (base 2) = 2.
x := hctrFieldElement{ x := hctrFieldElement{
binary.BigEndian.Uint64(hkey[:8]), byteorder.BEUint64(hkey[:8]),
binary.BigEndian.Uint64(hkey[8:blockSize]), byteorder.BEUint64(hkey[8:blockSize]),
} }
c.productTable[reverseBits(1)] = x c.productTable[reverseBits(1)] = x
@ -180,8 +180,8 @@ func (h *hctr) mul(y *hctrFieldElement) {
} }
func (h *hctr) updateBlock(block []byte, y *hctrFieldElement) { func (h *hctr) updateBlock(block []byte, y *hctrFieldElement) {
y.low ^= binary.BigEndian.Uint64(block) y.low ^= byteorder.BEUint64(block)
y.high ^= binary.BigEndian.Uint64(block[8:]) y.high ^= byteorder.BEUint64(block[8:])
h.mul(y) h.mul(y)
} }
@ -214,8 +214,8 @@ func (h *hctr) uhash(m []byte, out *[blockSize]byte) {
y.high ^= uint64(len(m)+blockSize) * 8 y.high ^= uint64(len(m)+blockSize) * 8
h.mul(&y) h.mul(&y)
// output result // output result
binary.BigEndian.PutUint64(out[:], y.low) byteorder.BEPutUint64(out[:], y.low)
binary.BigEndian.PutUint64(out[8:], y.high) byteorder.BEPutUint64(out[8:], y.high)
} }
func (h *hctr) EncryptBytes(ciphertext, plaintext []byte) { 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 len(src) >= batchSize {
for j := 0; j < concCipher.Concurrency(); j++ { for j := 0; j < concCipher.Concurrency(); j++ {
// (i)₂ // (i)₂
binary.BigEndian.PutUint64(num[blockSize-8:], i) byteorder.BEPutUint64(num[blockSize-8:], i)
subtle.XORBytes(ctrs[j*blockSize:], baseCtr[:], num) subtle.XORBytes(ctrs[j*blockSize:], baseCtr[:], num)
i++ i++
} }
@ -295,7 +295,7 @@ func (h *hctr) ctr(dst, src []byte, baseCtr *[blockSize]byte) {
for len(src) > 0 { for len(src) > 0 {
// (i)₂ // (i)₂
binary.BigEndian.PutUint64(num[blockSize-8:], i) byteorder.BEPutUint64(num[blockSize-8:], i)
subtle.XORBytes(ctr, baseCtr[:], num) subtle.XORBytes(ctr, baseCtr[:], num)
h.cipher.Encrypt(ctr, ctr) h.cipher.Encrypt(ctr, ctr)
n := subtle.XORBytes(dst, src, ctr) n := subtle.XORBytes(dst, src, ctr)

View File

@ -2,10 +2,10 @@ package cipher
import ( import (
_cipher "crypto/cipher" _cipher "crypto/cipher"
"encoding/binary"
"errors" "errors"
"github.com/emmansun/gmsm/internal/alias" "github.com/emmansun/gmsm/internal/alias"
"github.com/emmansun/gmsm/internal/byteorder"
"github.com/emmansun/gmsm/internal/subtle" "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. // 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) { func NewXTSEncrypterWithSector(cipherFunc CipherCreator, key, tweakKey []byte, sectorNum uint64) (_cipher.BlockMode, error) {
tweak := make([]byte, blockSize) tweak := make([]byte, blockSize)
binary.LittleEndian.PutUint64(tweak[:8], sectorNum) byteorder.LEPutUint64(tweak[:8], sectorNum)
return NewXTSEncrypter(cipherFunc, key, tweakKey, tweak) return NewXTSEncrypter(cipherFunc, key, tweakKey, tweak)
} }
@ -66,7 +66,7 @@ func NewGBXTSEncrypter(cipherFunc CipherCreator, key, tweakKey, tweak []byte) (_
// It follows GB/T 17964-2021. // It follows GB/T 17964-2021.
func NewGBXTSEncrypterWithSector(cipherFunc CipherCreator, key, tweakKey []byte, sectorNum uint64) (_cipher.BlockMode, error) { func NewGBXTSEncrypterWithSector(cipherFunc CipherCreator, key, tweakKey []byte, sectorNum uint64) (_cipher.BlockMode, error) {
tweak := make([]byte, blockSize) tweak := make([]byte, blockSize)
binary.LittleEndian.PutUint64(tweak[:8], sectorNum) byteorder.LEPutUint64(tweak[:8], sectorNum)
return NewGBXTSEncrypter(cipherFunc, key, tweakKey, tweak) 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. // 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) { func NewXTSDecrypterWithSector(cipherFunc CipherCreator, key, tweakKey []byte, sectorNum uint64) (_cipher.BlockMode, error) {
tweak := make([]byte, blockSize) tweak := make([]byte, blockSize)
binary.LittleEndian.PutUint64(tweak[:8], sectorNum) byteorder.LEPutUint64(tweak[:8], sectorNum)
return NewXTSDecrypter(cipherFunc, key, tweakKey, tweak) return NewXTSDecrypter(cipherFunc, key, tweakKey, tweak)
} }
@ -138,7 +138,7 @@ func NewGBXTSDecrypter(cipherFunc CipherCreator, key, tweakKey, tweak []byte) (_
// It follows GB/T 17964-2021. // It follows GB/T 17964-2021.
func NewGBXTSDecrypterWithSector(cipherFunc CipherCreator, key, tweakKey []byte, sectorNum uint64) (_cipher.BlockMode, error) { func NewGBXTSDecrypterWithSector(cipherFunc CipherCreator, key, tweakKey []byte, sectorNum uint64) (_cipher.BlockMode, error) {
tweak := make([]byte, blockSize) tweak := make([]byte, blockSize)
binary.LittleEndian.PutUint64(tweak[:8], sectorNum) byteorder.LEPutUint64(tweak[:8], sectorNum)
return NewGBXTSDecrypter(cipherFunc, key, tweakKey, tweak) return NewGBXTSDecrypter(cipherFunc, key, tweakKey, tweak)
} }

View File

@ -2,10 +2,10 @@ package drbg
import ( import (
"crypto/cipher" "crypto/cipher"
"encoding/binary"
"errors" "errors"
"time" "time"
"github.com/emmansun/gmsm/internal/byteorder"
"github.com/emmansun/gmsm/internal/subtle" "github.com/emmansun/gmsm/internal/subtle"
"github.com/emmansun/gmsm/sm4" "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 // S = counter || len(seed_material) || len(return_bytes) || seed_material || 0x80
// len(S) = ((outlen + 4 + 4 + len(seed_material) + 1 + outlen - 1) / outlen) * outlen // len(S) = ((outlen + 4 + 4 + len(seed_material) + 1 + outlen - 1) / outlen) * outlen
binary.BigEndian.PutUint32(S[outlen:], uint32(len(seedMaterial))) byteorder.BEPutUint32(S[outlen:], uint32(len(seedMaterial)))
binary.BigEndian.PutUint32(S[outlen+4:], uint32(returnBytes)) byteorder.BEPutUint32(S[outlen+4:], uint32(returnBytes))
copy(S[outlen+8:], seedMaterial) copy(S[outlen+8:], seedMaterial)
S[outlen+8+len(seedMaterial)] = 0x80 S[outlen+8+len(seedMaterial)] = 0x80
@ -199,7 +199,7 @@ func (cd *CtrDrbg) derive(seedMaterial []byte, returnBytes int) []byte {
block := cd.newBlockCipher(key) block := cd.newBlockCipher(key)
for i := 0; i < blocks; i++ { 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)) copy(temp[i*outlen:], cd.bcc(block, S))
} }

View File

@ -1,11 +1,11 @@
package drbg package drbg
import ( import (
"encoding/binary"
"errors" "errors"
"hash" "hash"
"time" "time"
"github.com/emmansun/gmsm/internal/byteorder"
"github.com/emmansun/gmsm/sm3" "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!!! // HashDrbg hash DRBG structure, its instance is NOT goroutine safe!!!
type HashDrbg struct { type HashDrbg struct {
BaseDrbg BaseDrbg
newHash func() hash.Hash newHash func() hash.Hash
c []byte c []byte
hashSize int hashSize int
} }
@ -146,7 +146,7 @@ func (hd *HashDrbg) addH() {
func (hd *HashDrbg) addReseedCounter() { func (hd *HashDrbg) addReseedCounter() {
t := make([]byte, hd.seedLength) 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) add(t, hd.v, hd.seedLength)
} }
@ -208,7 +208,7 @@ func (hd *HashDrbg) derive(seedMaterial []byte, len int) []byte {
md := hd.newHash() md := hd.newHash()
limit := uint64(len+hd.hashSize-1) / uint64(hd.hashSize) limit := uint64(len+hd.hashSize-1) / uint64(hd.hashSize)
var requireBytes [4]byte var requireBytes [4]byte
binary.BigEndian.PutUint32(requireBytes[:], uint32(len<<3)) byteorder.BEPutUint32(requireBytes[:], uint32(len<<3))
var ct byte = 1 var ct byte = 1
k := make([]byte, len) k := make([]byte, len)
for i := 0; i < int(limit); i++ { for i := 0; i < int(limit); i++ {

View File

@ -5,9 +5,10 @@
package bigmod package bigmod
import ( import (
"encoding/binary"
"errors" "errors"
"math/bits" "math/bits"
"github.com/emmansun/gmsm/internal/byteorder"
) )
const ( const (
@ -205,9 +206,9 @@ func (x *Nat) SetOverflowedBytes(b []byte, m *Modulus) *Nat {
// big-endian encoded uint value. // big-endian encoded uint value.
func bigEndianUint(buf []byte) uint { func bigEndianUint(buf []byte) uint {
if _W == 64 { 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 { func (x *Nat) setBytes(b []byte) error {

View File

@ -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),
)
}

View File

@ -18,6 +18,7 @@ import (
"runtime" "runtime"
"unsafe" "unsafe"
"github.com/emmansun/gmsm/internal/byteorder"
"golang.org/x/sys/cpu" "golang.org/x/sys/cpu"
) )
@ -385,18 +386,12 @@ var p256Precomputed *[43]p256AffineTable
//go:embed p256_asm_table.bin //go:embed p256_asm_table.bin
var p256PrecomputedEmbed string 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() { func init() {
p256PrecomputedPtr := (*unsafe.Pointer)(unsafe.Pointer(&p256PrecomputedEmbed)) p256PrecomputedPtr := (*unsafe.Pointer)(unsafe.Pointer(&p256PrecomputedEmbed))
if runtime.GOARCH == "s390x" { if runtime.GOARCH == "s390x" {
var newTable [43 * 32 * 2 * 4]uint64 var newTable [43 * 32 * 2 * 4]uint64
for i, x := range (*[43 * 32 * 2 * 4][8]byte)(*p256PrecomputedPtr) { for i, x := range (*[43 * 32 * 2 * 4][8]byte)(*p256PrecomputedPtr) {
newTable[i] = leUint64(x[:]) newTable[i] = byteorder.LEUint64(x[:])
} }
newTablePtr := unsafe.Pointer(&newTable) newTablePtr := unsafe.Pointer(&newTable)
p256PrecomputedPtr = &newTablePtr p256PrecomputedPtr = &newTablePtr

View File

@ -1,9 +1,10 @@
package sm2ec package sm2ec
import ( import (
"encoding/binary"
"errors" "errors"
"math/bits" "math/bits"
"github.com/emmansun/gmsm/internal/byteorder"
) )
var p256Order = [4]uint64{0x53bbf40939d54123, 0x7203df6b21c6052b, var p256Order = [4]uint64{0x53bbf40939d54123, 0x7203df6b21c6052b,
@ -14,20 +15,20 @@ func fromBytes(bytes []byte) (*[4]uint64, error) {
return nil, errors.New("invalid scalar length") return nil, errors.New("invalid scalar length")
} }
var t [4]uint64 var t [4]uint64
t[0] = binary.BigEndian.Uint64(bytes[24:]) t[0] = byteorder.BEUint64(bytes[24:])
t[1] = binary.BigEndian.Uint64(bytes[16:]) t[1] = byteorder.BEUint64(bytes[16:])
t[2] = binary.BigEndian.Uint64(bytes[8:]) t[2] = byteorder.BEUint64(bytes[8:])
t[3] = binary.BigEndian.Uint64(bytes) t[3] = byteorder.BEUint64(bytes)
return &t, nil return &t, nil
} }
func toBytes(t *[4]uint64) []byte { func toBytes(t *[4]uint64) []byte {
var bytes [32]byte var bytes [32]byte
binary.BigEndian.PutUint64(bytes[:], t[3]) byteorder.BEPutUint64(bytes[:], t[3])
binary.BigEndian.PutUint64(bytes[8:], t[2]) byteorder.BEPutUint64(bytes[8:], t[2])
binary.BigEndian.PutUint64(bytes[16:], t[1]) byteorder.BEPutUint64(bytes[16:], t[1])
binary.BigEndian.PutUint64(bytes[24:], t[0]) byteorder.BEPutUint64(bytes[24:], t[0])
return bytes[:] return bytes[:]
} }

View File

@ -3,8 +3,9 @@ package kdf
import ( import (
"encoding" "encoding"
"encoding/binary"
"hash" "hash"
"github.com/emmansun/gmsm/internal/byteorder"
) )
// KdfInterface is the interface implemented by some specific Hash implementations. // 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 { if marshaler, ok := baseMD.(encoding.BinaryMarshaler); limit == 1 || len(z) < baseMD.BlockSize() || !ok {
for i := 0; i < int(limit); i++ { for i := 0; i < int(limit); i++ {
binary.BigEndian.PutUint32(countBytes[:], ct) byteorder.BEPutUint32(countBytes[:], ct)
baseMD.Write(z) baseMD.Write(z)
baseMD.Write(countBytes[:]) baseMD.Write(countBytes[:])
k = baseMD.Sum(k) k = baseMD.Sum(k)
@ -46,7 +47,7 @@ func Kdf(newHash func() hash.Hash, z []byte, keyLen int) []byte {
if err != nil { if err != nil {
panic(err) panic(err)
} }
binary.BigEndian.PutUint32(countBytes[:], ct) byteorder.BEPutUint32(countBytes[:], ct)
md.Write(countBytes[:]) md.Write(countBytes[:])
k = md.Sum(k) k = md.Sum(k)
ct++ ct++

View File

@ -5,9 +5,10 @@
package md2 package md2
import ( import (
"encoding/binary"
"errors" "errors"
"hash" "hash"
"github.com/emmansun/gmsm/internal/byteorder"
) )
// Size the size of a MD2 checksum in bytes. // 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 { func appendUint64(b []byte, x uint64) []byte {
var a [8]byte var a [8]byte
binary.BigEndian.PutUint64(a[:], x) byteorder.BEPutUint64(a[:], x)
return append(b, a[:]...) return append(b, a[:]...)
} }

View File

@ -13,10 +13,10 @@ package rc2
import ( import (
"crypto/cipher" "crypto/cipher"
"encoding/binary"
"fmt" "fmt"
"github.com/emmansun/gmsm/internal/alias" "github.com/emmansun/gmsm/internal/alias"
"github.com/emmansun/gmsm/internal/byteorder"
) )
// The rc2 block size in bytes // The rc2 block size in bytes
@ -109,10 +109,10 @@ func (c *rc2Cipher) Encrypt(dst, src []byte) {
panic("rc2: invalid buffer overlap") panic("rc2: invalid buffer overlap")
} }
r0 := binary.LittleEndian.Uint16(src[0:2]) r0 := byteorder.LEUint16(src[0:2])
r1 := binary.LittleEndian.Uint16(src[2:4]) r1 := byteorder.LEUint16(src[2:4])
r2 := binary.LittleEndian.Uint16(src[4:6]) r2 := byteorder.LEUint16(src[4:6])
r3 := binary.LittleEndian.Uint16(src[6:BlockSize]) r3 := byteorder.LEUint16(src[6:BlockSize])
var j int var j int
@ -197,10 +197,10 @@ func (c *rc2Cipher) Encrypt(dst, src []byte) {
j++ j++
} }
binary.LittleEndian.PutUint16(dst[0:2], r0) byteorder.LEPutUint16(dst[0:2], r0)
binary.LittleEndian.PutUint16(dst[2:4], r1) byteorder.LEPutUint16(dst[2:4], r1)
binary.LittleEndian.PutUint16(dst[4:6], r2) byteorder.LEPutUint16(dst[4:6], r2)
binary.LittleEndian.PutUint16(dst[6:BlockSize], r3) byteorder.LEPutUint16(dst[6:BlockSize], r3)
} }
func (c *rc2Cipher) Decrypt(dst, src []byte) { 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]) { if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
panic("rc2: invalid buffer overlap") panic("rc2: invalid buffer overlap")
} }
r0 := binary.LittleEndian.Uint16(src[0:2]) r0 := byteorder.LEUint16(src[0:2])
r1 := binary.LittleEndian.Uint16(src[2:4]) r1 := byteorder.LEUint16(src[2:4])
r2 := binary.LittleEndian.Uint16(src[4:6]) r2 := byteorder.LEUint16(src[4:6])
r3 := binary.LittleEndian.Uint16(src[6:BlockSize]) r3 := byteorder.LEUint16(src[6:BlockSize])
j := 63 j := 63
@ -301,8 +301,8 @@ func (c *rc2Cipher) Decrypt(dst, src []byte) {
j-- j--
} }
binary.LittleEndian.PutUint16(dst[0:2], r0) byteorder.LEPutUint16(dst[0:2], r0)
binary.LittleEndian.PutUint16(dst[2:4], r1) byteorder.LEPutUint16(dst[2:4], r1)
binary.LittleEndian.PutUint16(dst[4:6], r2) byteorder.LEPutUint16(dst[4:6], r2)
binary.LittleEndian.PutUint16(dst[6:BlockSize], r3) byteorder.LEPutUint16(dst[6:BlockSize], r3)
} }

View File

@ -6,7 +6,7 @@
package sm3 package sm3
import "encoding/binary" import "github.com/emmansun/gmsm/internal/byteorder"
// prepare data template: remaining data + [ct] + padding + length // prepare data template: remaining data + [ct] + padding + length
// p will be 1 or 2 blocks according to the length of remaining data // 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 var tmp [64 + 8]byte // padding + length buffer
tmp[0] = 0x80 tmp[0] = 0x80
padlen := tmp[:lenStart+8] padlen := tmp[:lenStart+8]
binary.BigEndian.PutUint64(padlen[lenStart:], len) byteorder.BEPutUint64(padlen[lenStart:], len)
copy(p[baseMD.nx+4:], padlen) copy(p[baseMD.nx+4:], padlen)
} }
@ -77,7 +77,7 @@ func kdfBy4(baseMD *digest, keyLen int, limit int) []byte {
// prepare states // prepare states
states[j] = baseMD.h states[j] = baseMD.h
// prepare data // prepare data
binary.BigEndian.PutUint32(data[j][baseMD.nx:], ct) byteorder.BEPutUint32(data[j][baseMD.nx:], ct)
ct++ ct++
} }
blockMultBy4(&digs[0], &dataPtrs[0], &tmp[0], blocks) blockMultBy4(&digs[0], &dataPtrs[0], &tmp[0], blocks)
@ -86,7 +86,7 @@ func kdfBy4(baseMD *digest, keyLen int, limit int) []byte {
} }
remain := limit % parallelSize4 remain := limit % parallelSize4
for i := 0; i < remain; i++ { for i := 0; i < remain; i++ {
binary.BigEndian.PutUint32(tmp[:], ct) byteorder.BEPutUint32(tmp[:], ct)
md := *baseMD md := *baseMD
md.Write(tmp[:4]) md.Write(tmp[:4])
h := md.checkSum() h := md.checkSum()

View File

@ -6,7 +6,7 @@
package sm3 package sm3
import "encoding/binary" import "github.com/emmansun/gmsm/internal/byteorder"
// p || state || words // p || state || words
// p = 64 * 8 * 2 = 1024 // p = 64 * 8 * 2 = 1024
@ -30,7 +30,7 @@ func kdfBy8(baseMD *digest, keyLen int, limit int) []byte {
len <<= 3 len <<= 3
var ct uint32 = 1 var ct uint32 = 1
k := make([]byte, limit * Size) k := make([]byte, limit*Size)
ret := k ret := k
// prepare temporary buffer // prepare temporary buffer
@ -61,7 +61,7 @@ func kdfBy8(baseMD *digest, keyLen int, limit int) []byte {
// prepare states // prepare states
states[j] = baseMD.h states[j] = baseMD.h
// prepare data // prepare data
binary.BigEndian.PutUint32(data[j][baseMD.nx:], ct) byteorder.BEPutUint32(data[j][baseMD.nx:], ct)
ct++ ct++
} }
blockMultBy8(&digs[0], &dataPtrs[0], &tmp[0], blocks) blockMultBy8(&digs[0], &dataPtrs[0], &tmp[0], blocks)
@ -75,7 +75,7 @@ func kdfBy8(baseMD *digest, keyLen int, limit int) []byte {
// prepare states // prepare states
states[j] = baseMD.h states[j] = baseMD.h
// prepare data // prepare data
binary.BigEndian.PutUint32(data[j][baseMD.nx:], ct) byteorder.BEPutUint32(data[j][baseMD.nx:], ct)
ct++ ct++
} }
blockMultBy4(&digs[0], &dataPtrs[0], &tmp[0], blocks) 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++ { for i := 0; i < remain; i++ {
binary.BigEndian.PutUint32(tmp[:], ct) byteorder.BEPutUint32(tmp[:], ct)
md := *baseMD md := *baseMD
md.Write(tmp[:4]) md.Write(tmp[:4])
h := md.checkSum() h := md.checkSum()

View File

@ -4,9 +4,10 @@ package sm3
// [GM/T] SM3 GB/T 32905-2016 // [GM/T] SM3 GB/T 32905-2016
import ( import (
"encoding/binary"
"errors" "errors"
"hash" "hash"
"github.com/emmansun/gmsm/internal/byteorder"
) )
// Size the size of a SM3 checksum in bytes. // Size the size of a SM3 checksum in bytes.
@ -39,7 +40,7 @@ type digest struct {
} }
const ( const (
magic = "sm3\x03" magic = "sm3\x03"
marshaledSize = len(magic) + 8*4 + chunk + 8 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 { func appendUint64(b []byte, x uint64) []byte {
var a [8]byte var a [8]byte
binary.BigEndian.PutUint64(a[:], x) byteorder.BEPutUint64(a[:], x)
return append(b, a[:]...) return append(b, a[:]...)
} }
func appendUint32(b []byte, x uint32) []byte { func appendUint32(b []byte, x uint32) []byte {
var a [4]byte var a [4]byte
binary.BigEndian.PutUint32(a[:], x) byteorder.BEPutUint32(a[:], x)
return append(b, a[:]...) return append(b, a[:]...)
} }
@ -143,7 +144,7 @@ func (d *digest) checkSum() [Size]byte {
// Length in bits. // Length in bits.
len <<= 3 len <<= 3
padlen := tmp[:t+8] padlen := tmp[:t+8]
binary.BigEndian.PutUint64(padlen[t:], len) byteorder.BEPutUint64(padlen[t:], len)
d.Write(padlen) d.Write(padlen)
if d.nx != 0 { if d.nx != 0 {
@ -152,14 +153,14 @@ func (d *digest) checkSum() [Size]byte {
var digest [Size]byte var digest [Size]byte
binary.BigEndian.PutUint32(digest[0:], d.h[0]) byteorder.BEPutUint32(digest[0:], d.h[0])
binary.BigEndian.PutUint32(digest[4:], d.h[1]) byteorder.BEPutUint32(digest[4:], d.h[1])
binary.BigEndian.PutUint32(digest[8:], d.h[2]) byteorder.BEPutUint32(digest[8:], d.h[2])
binary.BigEndian.PutUint32(digest[12:], d.h[3]) byteorder.BEPutUint32(digest[12:], d.h[3])
binary.BigEndian.PutUint32(digest[16:], d.h[4]) byteorder.BEPutUint32(digest[16:], d.h[4])
binary.BigEndian.PutUint32(digest[20:], d.h[5]) byteorder.BEPutUint32(digest[20:], d.h[5])
binary.BigEndian.PutUint32(digest[24:], d.h[6]) byteorder.BEPutUint32(digest[24:], d.h[6])
binary.BigEndian.PutUint32(digest[28:], d.h[7]) byteorder.BEPutUint32(digest[28:], d.h[7])
return digest return digest
} }
@ -231,7 +232,7 @@ func kdfGeneric(baseMD *digest, keyLen int, limit int) []byte {
var ct uint32 = 1 var ct uint32 = 1
k := make([]byte, keyLen) k := make([]byte, keyLen)
for i := 0; i < limit; i++ { for i := 0; i < limit; i++ {
binary.BigEndian.PutUint32(countBytes[:], ct) byteorder.BEPutUint32(countBytes[:], ct)
md := *baseMD md := *baseMD
md.Write(countBytes[:]) md.Write(countBytes[:])
h := md.checkSum() h := md.checkSum()

View File

@ -8,9 +8,10 @@ package sm3
import ( import (
"bytes" "bytes"
"encoding/binary"
"fmt" "fmt"
"testing" "testing"
"github.com/emmansun/gmsm/internal/byteorder"
) )
func initState4() [4]*[8]uint32 { func initState4() [4]*[8]uint32 {
@ -119,7 +120,7 @@ func TestCopyResultsBy4(t *testing.T) {
for i := 0; i < 4; i++ { for i := 0; i < 4; i++ {
for j := 0; j < 8; j++ { 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[:]) { if !bytes.Equal(ret[:], expected[:]) {

View File

@ -3,7 +3,7 @@ package sm4
// [GM/T] SM4 GB/T 32907-2016 // [GM/T] SM4 GB/T 32907-2016
import ( import (
"encoding/binary" "github.com/emmansun/gmsm/internal/byteorder"
) )
// Encrypt one block from src into dst, using the expanded key xk. // 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 _ = src[15] // early bounds check
var b0, b1, b2, b3 uint32 var b0, b1, b2, b3 uint32
b0 = binary.BigEndian.Uint32(src[0:4]) b0 = byteorder.BEUint32(src[0:4])
b1 = binary.BigEndian.Uint32(src[4:8]) b1 = byteorder.BEUint32(src[4:8])
b2 = binary.BigEndian.Uint32(src[8:12]) b2 = byteorder.BEUint32(src[8:12])
b3 = binary.BigEndian.Uint32(src[12:16]) b3 = byteorder.BEUint32(src[12:16])
// First round uses s-box directly and T transformation. // First round uses s-box directly and T transformation.
b0 ^= t(b1 ^ b2 ^ b3 ^ xk[0]) 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]) b3 ^= t(b0 ^ b1 ^ b2 ^ xk[31])
_ = dst[15] // early bounds check _ = dst[15] // early bounds check
binary.BigEndian.PutUint32(dst[0:4], b3) byteorder.BEPutUint32(dst[0:4], b3)
binary.BigEndian.PutUint32(dst[4:8], b2) byteorder.BEPutUint32(dst[4:8], b2)
binary.BigEndian.PutUint32(dst[8:12], b1) byteorder.BEPutUint32(dst[8:12], b1)
binary.BigEndian.PutUint32(dst[12:16], b0) byteorder.BEPutUint32(dst[12:16], b0)
} }
// Key expansion algorithm. // Key expansion algorithm.
@ -71,10 +71,10 @@ func expandKeyGo(key []byte, enc, dec *[rounds]uint32) {
// Encryption key setup. // Encryption key setup.
key = key[:KeySize] key = key[:KeySize]
var b0, b1, b2, b3 uint32 var b0, b1, b2, b3 uint32
b0 = binary.BigEndian.Uint32(key[:4]) ^ fk[0] b0 = byteorder.BEUint32(key[:4]) ^ fk[0]
b1 = binary.BigEndian.Uint32(key[4:8]) ^ fk[1] b1 = byteorder.BEUint32(key[4:8]) ^ fk[1]
b2 = binary.BigEndian.Uint32(key[8:12]) ^ fk[2] b2 = byteorder.BEUint32(key[8:12]) ^ fk[2]
b3 = binary.BigEndian.Uint32(key[12:16]) ^ fk[3] b3 = byteorder.BEUint32(key[12:16]) ^ fk[3]
b0 = b0 ^ t2(b1^b2^b3^ck[0]) b0 = b0 ^ t2(b1^b2^b3^ck[0])
enc[0], dec[31] = b0, b0 enc[0], dec[31] = b0, b0

View File

@ -5,10 +5,10 @@ package sm4
import ( import (
"crypto/cipher" "crypto/cipher"
goSubtle "crypto/subtle" goSubtle "crypto/subtle"
"encoding/binary"
"errors" "errors"
"github.com/emmansun/gmsm/internal/alias" "github.com/emmansun/gmsm/internal/alias"
"github.com/emmansun/gmsm/internal/byteorder"
"github.com/emmansun/gmsm/internal/subtle" "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 // 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. // this bit ordering it will actually be in index 0010 (base 2) = 2.
x := gcmFieldElement{ x := gcmFieldElement{
binary.BigEndian.Uint64(key[:8]), byteorder.BEUint64(key[:8]),
binary.BigEndian.Uint64(key[8:]), byteorder.BEUint64(key[8:]),
} }
g.productTable[8] = x // reverseBits(1) = 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 // gcmFieldElement represents a value in GF(2¹²⁸). In order to reflect the GCM
// standard and make binary.BigEndian suitable for marshaling these values, the // standard and make binary.BigEndian suitable for marshaling these values, the
// bits are stored in big endian order. For example: // 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.low >> 63.
// the coefficient of x⁶⁴ can be obtained by v.high >> 63. // the coefficient of x⁶³ can be obtained by v.low & 1.
// the coefficient of x¹²⁷ can be obtained by v.high & 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 { type gcmFieldElement struct {
low, high uint64 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. // Horner's rule. There must be a multiple of gcmBlockSize bytes in blocks.
func (g *gcm) updateBlocks(y *gcmFieldElement, blocks []byte) { func (g *gcm) updateBlocks(y *gcmFieldElement, blocks []byte) {
for len(blocks) > 0 { for len(blocks) > 0 {
y.low ^= binary.BigEndian.Uint64(blocks) y.low ^= byteorder.BEUint64(blocks)
y.high ^= binary.BigEndian.Uint64(blocks[8:]) y.high ^= byteorder.BEUint64(blocks[8:])
g.mul(y) g.mul(y)
blocks = blocks[gcmBlockSize:] blocks = blocks[gcmBlockSize:]
} }
@ -257,7 +258,7 @@ func (g *gcm) update(y *gcmFieldElement, data []byte) {
// and increments it. // and increments it.
func gcmInc32(counterBlock *[16]byte) { func gcmInc32(counterBlock *[16]byte) {
ctr := counterBlock[len(counterBlock)-4:] 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. // 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) g.update(&y, nonce)
y.high ^= uint64(len(nonce)) * 8 y.high ^= uint64(len(nonce)) * 8
g.mul(&y) g.mul(&y)
binary.BigEndian.PutUint64(counter[:8], y.low) byteorder.BEPutUint64(counter[:8], y.low)
binary.BigEndian.PutUint64(counter[8:], y.high) byteorder.BEPutUint64(counter[8:], y.high)
} }
} }
@ -322,8 +323,8 @@ func (g *gcm) auth(out, ciphertext, additionalData []byte, tagMask *[gcmTagSize]
g.mul(&y) g.mul(&y)
binary.BigEndian.PutUint64(out, y.low) byteorder.BEPutUint64(out, y.low)
binary.BigEndian.PutUint64(out[8:], y.high) byteorder.BEPutUint64(out[8:], y.high)
subtle.XORBytes(out, out, tagMask[:]) subtle.XORBytes(out, out, tagMask[:])
} }

View File

@ -9,11 +9,11 @@ package sm4
import ( import (
"crypto/cipher" "crypto/cipher"
_subtle "crypto/subtle" _subtle "crypto/subtle"
"encoding/binary"
"errors" "errors"
"runtime" "runtime"
"github.com/emmansun/gmsm/internal/alias" "github.com/emmansun/gmsm/internal/alias"
"github.com/emmansun/gmsm/internal/byteorder"
"github.com/emmansun/gmsm/internal/subtle" "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 // Reverse the bytes in each 8 byte chunk
// Load little endian, store big endian // Load little endian, store big endian
if runtime.GOARCH == "ppc64le" { if runtime.GOARCH == "ppc64le" {
h1 = binary.LittleEndian.Uint64(hle[:8]) h1 = byteorder.LEUint64(hle[:8])
h2 = binary.LittleEndian.Uint64(hle[8:]) h2 = byteorder.LEUint64(hle[8:])
} else { } else {
h1 = binary.BigEndian.Uint64(hle[:8]) h1 = byteorder.BEUint64(hle[:8])
h2 = binary.BigEndian.Uint64(hle[8:]) h2 = byteorder.BEUint64(hle[8:])
} }
binary.BigEndian.PutUint64(hle[:8], h1) byteorder.BEPutUint64(hle[:8], h1)
binary.BigEndian.PutUint64(hle[8:], h2) byteorder.BEPutUint64(hle[8:], h2)
gcmInit(&g.productTable, hle) gcmInit(&g.productTable, hle)
return g, nil 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. // increments the rightmost 32-bits of the count value by 1.
func gcmInc32(counterBlock *[16]byte) { func gcmInc32(counterBlock *[16]byte) {
c := counterBlock[len(counterBlock)-4:] c := counterBlock[len(counterBlock)-4:]
x := binary.BigEndian.Uint32(c) + 1 x := byteorder.BEUint32(c) + 1
binary.BigEndian.PutUint32(c, x) byteorder.BEPutUint32(c, x)
} }
// paddedGHASH pads data with zeroes until its length is a multiple of // paddedGHASH pads data with zeroes until its length is a multiple of

View File

@ -7,10 +7,11 @@
package sm4 package sm4
import ( import (
"encoding/binary"
"fmt" "fmt"
"runtime" "runtime"
"testing" "testing"
"github.com/emmansun/gmsm/internal/byteorder"
) )
func TestCmul(t *testing.T) { func TestCmul(t *testing.T) {
@ -26,14 +27,14 @@ func TestCmul(t *testing.T) {
// Reverse the bytes in each 8 byte chunk // Reverse the bytes in each 8 byte chunk
// Load little endian, store big endian // Load little endian, store big endian
if runtime.GOARCH == "ppc64le" { if runtime.GOARCH == "ppc64le" {
h1 = binary.LittleEndian.Uint64(hle[:8]) h1 = byteorder.LEUint64(hle[:8])
h2 = binary.LittleEndian.Uint64(hle[8:]) h2 = byteorder.LEUint64(hle[8:])
} else { } else {
h1 = binary.BigEndian.Uint64(hle[:8]) h1 = byteorder.BEUint64(hle[:8])
h2 = binary.BigEndian.Uint64(hle[8:]) h2 = byteorder.BEUint64(hle[8:])
} }
binary.BigEndian.PutUint64(hle[:8], h1) byteorder.BEPutUint64(hle[:8], h1)
binary.BigEndian.PutUint64(hle[8:], h2) byteorder.BEPutUint64(hle[8:], h2)
if fmt.Sprintf("%x", hle) != "3811556fff7b1f9fd38f531e5330944d" { if fmt.Sprintf("%x", hle) != "3811556fff7b1f9fd38f531e5330944d" {
t.Errorf("2 got %x", hle) t.Errorf("2 got %x", hle)

View File

@ -1,11 +1,12 @@
package bn256 package bn256
import ( import (
"encoding/binary"
"errors" "errors"
"fmt" "fmt"
"math/big" "math/big"
"math/bits" "math/bits"
"github.com/emmansun/gmsm/internal/byteorder"
) )
type gfP [4]uint64 type gfP [4]uint64
@ -44,7 +45,7 @@ func fromBigInt(x *big.Int) (out *gfP) {
} }
for i := 0; i < 4; i++ { for i := 0; i < 4; i++ {
start := len(bytes) - 8 start := len(bytes) - 8
out[i] = binary.BigEndian.Uint64(bytes[start:]) out[i] = byteorder.BEUint64(bytes[start:])
bytes = bytes[:start] bytes = bytes[:start]
} }
if x.Sign() < 0 { if x.Sign() < 0 {

View File

@ -4,12 +4,12 @@ package sm9
import ( import (
"crypto" "crypto"
goSubtle "crypto/subtle" goSubtle "crypto/subtle"
"encoding/binary"
"errors" "errors"
"io" "io"
"math/big" "math/big"
"github.com/emmansun/gmsm/internal/bigmod" "github.com/emmansun/gmsm/internal/bigmod"
"github.com/emmansun/gmsm/internal/byteorder"
"github.com/emmansun/gmsm/internal/randutil" "github.com/emmansun/gmsm/internal/randutil"
"github.com/emmansun/gmsm/internal/subtle" "github.com/emmansun/gmsm/internal/subtle"
"github.com/emmansun/gmsm/sm3" "github.com/emmansun/gmsm/sm3"
@ -55,7 +55,7 @@ func hash(z []byte, h hashMode) *bigmod.Nat {
var countBytes [4]byte var countBytes [4]byte
var ct uint32 = 1 var ct uint32 = 1
binary.BigEndian.PutUint32(countBytes[:], ct) byteorder.BEPutUint32(countBytes[:], ct)
md.Write([]byte{byte(h)}) md.Write([]byte{byte(h)})
md.Write(z) md.Write(z)
md.Write(countBytes[:]) md.Write(countBytes[:])
@ -63,7 +63,7 @@ func hash(z []byte, h hashMode) *bigmod.Nat {
ct++ ct++
md.Reset() md.Reset()
binary.BigEndian.PutUint32(countBytes[:], ct) byteorder.BEPutUint32(countBytes[:], ct)
md.Write([]byte{byte(h)}) md.Write([]byte{byte(h)})
md.Write(z) md.Write(z)
md.Write(countBytes[:]) md.Write(countBytes[:])

View File

@ -2,9 +2,10 @@
package zuc package zuc
import ( import (
"encoding/binary"
"fmt" "fmt"
"math/bits" "math/bits"
"github.com/emmansun/gmsm/internal/byteorder"
) )
const ( const (
@ -108,8 +109,8 @@ func (s *zucState32) f32() uint32 {
w2 := s.r2 ^ s.x2 w2 := s.r2 ^ s.x2
u := l1((w1 << 16) | (w2 >> 16)) u := l1((w1 << 16) | (w2 >> 16))
v := l2((w2 << 16) | (w1 >> 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.r1 = byteorder.BEUint32([]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.r2 = byteorder.BEUint32([]byte{sbox0[v>>24], sbox1[(v>>16)&0xFF], sbox0[(v>>8)&0xFF], sbox1[v&0xFF]})
return w return w
} }

View File

@ -12,7 +12,7 @@ func Test_genKeyword_case1(t *testing.T) {
t.Errorf("expected=%x, result=%x\n", 0x27bede74, z1) t.Errorf("expected=%x, result=%x\n", 0x27bede74, z1)
} }
if s.r1 != 0xc7ee7f13 { 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 { if s.r2 != 0xc0fa817 {
t.Errorf("expected=%x, result=%x\n", 0xc0fa817, s.r2) t.Errorf("expected=%x, result=%x\n", 0xc0fa817, s.r2)

View File

@ -2,9 +2,9 @@ package zuc
import ( import (
"crypto/cipher" "crypto/cipher"
"encoding/binary"
"github.com/emmansun/gmsm/internal/alias" "github.com/emmansun/gmsm/internal/alias"
"github.com/emmansun/gmsm/internal/byteorder"
"github.com/emmansun/gmsm/internal/subtle" "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. // 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) { func NewEEACipher(key []byte, count, bearer, direction uint32) (cipher.Stream, error) {
iv := make([]byte, 16) iv := make([]byte, 16)
binary.BigEndian.PutUint32(iv, count) byteorder.BEPutUint32(iv, count)
copy(iv[8:12], iv[:4]) copy(iv[8:12], iv[:4])
iv[4] = byte(((bearer << 1) | (direction & 1)) << 2) iv[4] = byte(((bearer << 1) | (direction & 1)) << 2)
iv[12] = iv[4] 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) { func genKeyStreamRev32Generic(keyStream []byte, pState *zucState32) {
for len(keyStream) >= 4 { for len(keyStream) >= 4 {
z := genKeyword(pState) z := genKeyword(pState)
binary.BigEndian.PutUint32(keyStream, z) byteorder.BEPutUint32(keyStream, z)
keyStream = keyStream[4:] keyStream = keyStream[4:]
} }
} }

View File

@ -1,8 +1,9 @@
package zuc package zuc
import ( import (
"encoding/binary"
"fmt" "fmt"
"github.com/emmansun/gmsm/internal/byteorder"
) )
const ( const (
@ -60,7 +61,7 @@ func NewHash(key, iv []byte) (*ZUC128Mac, error) {
func genIV4EIA(count, bearer, direction uint32) []byte { func genIV4EIA(count, bearer, direction uint32) []byte {
iv := make([]byte, 16) iv := make([]byte, 16)
binary.BigEndian.PutUint32(iv, count) byteorder.BEPutUint32(iv, count)
copy(iv[9:12], iv[1:4]) copy(iv[9:12], iv[1:4])
iv[4] = byte(bearer << 3) iv[4] = byte(bearer << 3)
iv[12] = iv[4] iv[12] = iv[4]
@ -102,7 +103,7 @@ func blockGeneric(m *ZUC128Mac, p []byte) {
m.genKeywords(m.k0[4:]) m.genKeywords(m.k0[4:])
k64 = uint64(m.k0[0])<<32 | uint64(m.k0[1]) k64 = uint64(m.k0[0])<<32 | uint64(m.k0[1])
// process first 32 bits // process first 32 bits
w := binary.BigEndian.Uint32(p[0:4]) w := byteorder.BEUint32(p[0:4])
for j := 0; j < 32; j++ { for j := 0; j < 32; j++ {
// t64 ^= (w >> 31) ? k64 : 0 // t64 ^= (w >> 31) ? k64 : 0
t64 ^= ^(uint64(w>>31) - 1) & k64 t64 ^= ^(uint64(w>>31) - 1) & k64
@ -111,7 +112,7 @@ func blockGeneric(m *ZUC128Mac, p []byte) {
} }
// process second 32 bits // process second 32 bits
k64 = uint64(m.k0[1])<<32 | uint64(m.k0[2]) 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++ { for j := 0; j < 32; j++ {
t64 ^= ^(uint64(w>>31) - 1) & k64 t64 ^= ^(uint64(w>>31) - 1) & k64
w <<= 1 w <<= 1
@ -119,7 +120,7 @@ func blockGeneric(m *ZUC128Mac, p []byte) {
} }
// process third 32 bits // process third 32 bits
k64 = uint64(m.k0[2])<<32 | uint64(m.k0[3]) 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++ { for j := 0; j < 32; j++ {
t64 ^= ^(uint64(w>>31) - 1) & k64 t64 ^= ^(uint64(w>>31) - 1) & k64
w <<= 1 w <<= 1
@ -127,7 +128,7 @@ func blockGeneric(m *ZUC128Mac, p []byte) {
} }
// process fourth 32 bits // process fourth 32 bits
k64 = uint64(m.k0[3])<<32 | uint64(m.k0[4]) 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++ { for j := 0; j < 32; j++ {
t64 ^= ^(uint64(w>>31) - 1) & k64 t64 ^= ^(uint64(w>>31) - 1) & k64
w <<= 1 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 // process 32 bits at a time for first complete words
for i := 0; i < nwords-1; i++ { for i := 0; i < nwords-1; i++ {
k64 = uint64(m.k0[i])<<32 | uint64(m.k0[i+1]) 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++ { for j := 0; j < 32; j++ {
t64 ^= ^(uint64(w>>31) - 1) & k64 t64 ^= ^(uint64(w>>31) - 1) & k64
w <<= 1 w <<= 1
@ -196,7 +197,7 @@ func (m *ZUC128Mac) checkSum(additionalBits int, b byte) [4]byte {
// process remaining bits less than 32 // process remaining bits less than 32
if nRemainBits > 0 { if nRemainBits > 0 {
k64 = uint64(m.k0[kIdx])<<32 | uint64(m.k0[kIdx+1]) 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++ { for j := 0; j < nRemainBits; j++ {
t64 ^= ^(uint64(w>>31) - 1) & k64 t64 ^= ^(uint64(w>>31) - 1) & k64
w <<= 1 w <<= 1
@ -212,7 +213,7 @@ func (m *ZUC128Mac) checkSum(additionalBits int, b byte) [4]byte {
m.t ^= m.k0[kIdx+1] m.t ^= m.k0[kIdx+1]
var digest [4]byte var digest [4]byte
binary.BigEndian.PutUint32(digest[:], m.t) byteorder.BEPutUint32(digest[:], m.t)
return digest return digest
} }

View File

@ -1,8 +1,9 @@
package zuc package zuc
import ( import (
"encoding/binary"
"fmt" "fmt"
"github.com/emmansun/gmsm/internal/byteorder"
) )
type ZUC256Mac struct { type ZUC256Mac struct {
@ -93,7 +94,7 @@ func block256Generic(m *ZUC256Mac, p []byte) {
for len(p) >= chunk { for len(p) >= chunk {
m.genKeywords(m.k0[4:]) m.genKeywords(m.k0[4:])
for l := 0; l < 4; l++ { for l := 0; l < 4; l++ {
w := binary.BigEndian.Uint32(p[l*4:]) w := byteorder.BEUint32(p[l*4:])
switch m.tagSize { switch m.tagSize {
case 4: case 4:
k64 = uint64(m.k0[l])<<32 | uint64(m.k0[l+1]) 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 words := (nRemainBits + 31) / 32
for l := 0; l < words-1; l++ { 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] k1 := m.k0[m.tagSize/4+l]
for i := 0; i < 32; i++ { for i := 0; i < 32; i++ {
wBit := ^(w>>31 - 1) wBit := ^(w>>31 - 1)
@ -183,7 +184,7 @@ func (m *ZUC256Mac) checkSum(additionalBits int, b byte) []byte {
nRemainBits -= (words - 1) * 32 nRemainBits -= (words - 1) * 32
kIdx = words - 1 kIdx = words - 1
if nRemainBits > 0 { 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++ { for i := 0; i < nRemainBits; i++ {
wBit := ^(w>>31 - 1) wBit := ^(w>>31 - 1)
for j := 0; j < m.tagSize/4; j++ { 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) digest := make([]byte, m.tagSize)
for j := 0; j < m.tagSize/4; j++ { for j := 0; j < m.tagSize/4; j++ {
m.t[j] ^= m.k0[j+kIdx] 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 return digest

View File

@ -1,11 +1,11 @@
package zuc package zuc
import ( import (
"encoding/binary"
"encoding/hex" "encoding/hex"
"hash" "hash"
"testing" "testing"
"github.com/emmansun/gmsm/internal/byteorder"
"github.com/emmansun/gmsm/internal/cryptotest" "github.com/emmansun/gmsm/internal/cryptotest"
) )
@ -144,7 +144,7 @@ func TestEIA_Finish(t *testing.T) {
} }
in := make([]byte, len(test.in)*4) in := make([]byte, len(test.in)*4)
for j, v := range test.in { 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) mac := h.Finish(in, test.nbits)