mirror of
https://github.com/emmansun/gmsm.git
synced 2025-04-21 17:56:19 +08:00
internal/byteorder: new package #275
This commit is contained in:
parent
4f7504c6b9
commit
bf14e70c4b
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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++ {
|
||||||
|
@ -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 {
|
||||||
|
149
internal/byteorder/byteorder.go
Normal file
149
internal/byteorder/byteorder.go
Normal 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),
|
||||||
|
)
|
||||||
|
}
|
@ -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
|
||||||
|
@ -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[:]
|
||||||
}
|
}
|
||||||
|
@ -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++
|
||||||
|
@ -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[:]...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
@ -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()
|
||||||
|
29
sm3/sm3.go
29
sm3/sm3.go
@ -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()
|
||||||
|
@ -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[:]) {
|
||||||
|
26
sm4/block.go
26
sm4/block.go
@ -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
|
||||||
|
@ -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[:])
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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 {
|
||||||
|
@ -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[:])
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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:]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
19
zuc/eia.go
19
zuc/eia.go
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user