mirror of
https://github.com/emmansun/gmsm.git
synced 2025-04-26 04:06:18 +08:00
zuc: reduce bounds checking
This commit is contained in:
parent
79f0fb6b0d
commit
008e826fdf
50
zuc/core.go
50
zuc/core.go
@ -62,7 +62,7 @@ var zuc256_d0 = [16]byte{
|
|||||||
0x40, 0x40, 0x40, 0x40, 0x40, 0x52, 0x10, 0x30,
|
0x40, 0x40, 0x40, 0x40, 0x40, 0x52, 0x10, 0x30,
|
||||||
}
|
}
|
||||||
|
|
||||||
var zuc256_d = [][16]byte{
|
var zuc256_d = [3][16]byte{
|
||||||
{
|
{
|
||||||
0x22, 0x2F, 0x25, 0x2A, 0x6D, 0x40, 0x40, 0x40,
|
0x22, 0x2F, 0x25, 0x2A, 0x6D, 0x40, 0x40, 0x40,
|
||||||
0x40, 0x40, 0x40, 0x40, 0x40, 0x52, 0x10, 0x30,
|
0x40, 0x40, 0x40, 0x40, 0x40, 0x52, 0x10, 0x30,
|
||||||
@ -113,15 +113,16 @@ func (s *zucState32) f32() uint32 {
|
|||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
func rotateLeft31(x uint32, k int) uint32 {
|
/*
|
||||||
return (x<<k | x>>(31-k)) & 0x7FFFFFFF
|
func rotateLeft31(x uint32, k int) uint32 {
|
||||||
}
|
return (x<<k | x>>(31-k)) & 0x7FFFFFFF
|
||||||
|
}
|
||||||
func add31(x, y uint32) uint32 {
|
|
||||||
resut := x + y
|
|
||||||
return (resut & 0x7FFFFFFF) + (resut >> 31)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
func add31(x, y uint32) uint32 {
|
||||||
|
resut := x + y
|
||||||
|
return (resut & 0x7FFFFFFF) + (resut >> 31)
|
||||||
|
}
|
||||||
|
*/
|
||||||
func (s *zucState32) enterInitMode(w uint32) {
|
func (s *zucState32) enterInitMode(w uint32) {
|
||||||
v := uint64(s.lfsr[15])<<15 + uint64(s.lfsr[13])<<17 + uint64(s.lfsr[10])<<21 + uint64(s.lfsr[4])<<20 + uint64(s.lfsr[0])<<8 + uint64(s.lfsr[0]) + uint64(w)
|
v := uint64(s.lfsr[15])<<15 + uint64(s.lfsr[13])<<17 + uint64(s.lfsr[10])<<21 + uint64(s.lfsr[4])<<20 + uint64(s.lfsr[0])<<8 + uint64(s.lfsr[0]) + uint64(w)
|
||||||
v = (v & 0x7FFFFFFF) + (v >> 31)
|
v = (v & 0x7FFFFFFF) + (v >> 31)
|
||||||
@ -146,12 +147,27 @@ func makeFieldValue4(a, b, c, d uint32) uint32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *zucState32) loadKeyIV16(key, iv []byte) {
|
func (s *zucState32) loadKeyIV16(key, iv []byte) {
|
||||||
for i := 0; i < 16; i++ {
|
s.lfsr[15] = makeFieldValue3(uint32(key[15]), kd[15], uint32(iv[15]))
|
||||||
s.lfsr[i] = makeFieldValue3(uint32(key[i]), kd[i], uint32(iv[i]))
|
s.lfsr[0] = makeFieldValue3(uint32(key[0]), kd[0], uint32(iv[0]))
|
||||||
}
|
s.lfsr[1] = makeFieldValue3(uint32(key[1]), kd[1], uint32(iv[1]))
|
||||||
|
s.lfsr[2] = makeFieldValue3(uint32(key[2]), kd[2], uint32(iv[2]))
|
||||||
|
s.lfsr[3] = makeFieldValue3(uint32(key[3]), kd[3], uint32(iv[3]))
|
||||||
|
s.lfsr[4] = makeFieldValue3(uint32(key[4]), kd[4], uint32(iv[4]))
|
||||||
|
s.lfsr[5] = makeFieldValue3(uint32(key[5]), kd[5], uint32(iv[5]))
|
||||||
|
s.lfsr[6] = makeFieldValue3(uint32(key[6]), kd[6], uint32(iv[6]))
|
||||||
|
s.lfsr[7] = makeFieldValue3(uint32(key[7]), kd[7], uint32(iv[7]))
|
||||||
|
s.lfsr[8] = makeFieldValue3(uint32(key[8]), kd[8], uint32(iv[8]))
|
||||||
|
s.lfsr[9] = makeFieldValue3(uint32(key[9]), kd[9], uint32(iv[9]))
|
||||||
|
s.lfsr[10] = makeFieldValue3(uint32(key[10]), kd[10], uint32(iv[10]))
|
||||||
|
s.lfsr[11] = makeFieldValue3(uint32(key[11]), kd[11], uint32(iv[11]))
|
||||||
|
s.lfsr[12] = makeFieldValue3(uint32(key[12]), kd[12], uint32(iv[12]))
|
||||||
|
s.lfsr[13] = makeFieldValue3(uint32(key[13]), kd[13], uint32(iv[13]))
|
||||||
|
s.lfsr[14] = makeFieldValue3(uint32(key[14]), kd[14], uint32(iv[14]))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *zucState32) loadKeyIV32(key, iv, d []byte) {
|
func (s *zucState32) loadKeyIV32(key, iv, d []byte) {
|
||||||
|
_ = iv[22]
|
||||||
|
_ = key[31]
|
||||||
iv17 := iv[17] >> 2
|
iv17 := iv[17] >> 2
|
||||||
iv18 := ((iv[17] & 0x3) << 4) | (iv[18] >> 4)
|
iv18 := ((iv[17] & 0x3) << 4) | (iv[18] >> 4)
|
||||||
iv19 := ((iv[18] & 0xf) << 2) | (iv[19] >> 6)
|
iv19 := ((iv[18] & 0xf) << 2) | (iv[19] >> 6)
|
||||||
@ -160,6 +176,7 @@ func (s *zucState32) loadKeyIV32(key, iv, d []byte) {
|
|||||||
iv22 := ((iv[20] & 0x3) << 4) | (iv[21] >> 4)
|
iv22 := ((iv[20] & 0x3) << 4) | (iv[21] >> 4)
|
||||||
iv23 := ((iv[21] & 0xf) << 2) | (iv[22] >> 6)
|
iv23 := ((iv[21] & 0xf) << 2) | (iv[22] >> 6)
|
||||||
iv24 := iv[22] & 0x3f
|
iv24 := iv[22] & 0x3f
|
||||||
|
s.lfsr[15] = makeFieldValue4(uint32(key[15]), uint32(d[15]|(key[31]&0x0f)), uint32(key[30]), uint32(key[29]))
|
||||||
s.lfsr[0] = makeFieldValue4(uint32(key[0]), uint32(d[0]), uint32(key[21]), uint32(key[16]))
|
s.lfsr[0] = makeFieldValue4(uint32(key[0]), uint32(d[0]), uint32(key[21]), uint32(key[16]))
|
||||||
s.lfsr[1] = makeFieldValue4(uint32(key[1]), uint32(d[1]), uint32(key[22]), uint32(key[17]))
|
s.lfsr[1] = makeFieldValue4(uint32(key[1]), uint32(d[1]), uint32(key[22]), uint32(key[17]))
|
||||||
s.lfsr[2] = makeFieldValue4(uint32(key[2]), uint32(d[2]), uint32(key[23]), uint32(key[18]))
|
s.lfsr[2] = makeFieldValue4(uint32(key[2]), uint32(d[2]), uint32(key[23]), uint32(key[18]))
|
||||||
@ -175,7 +192,6 @@ func (s *zucState32) loadKeyIV32(key, iv, d []byte) {
|
|||||||
s.lfsr[12] = makeFieldValue4(uint32(key[12]), uint32(d[12]|iv24), uint32(iv[7]), uint32(iv[14]))
|
s.lfsr[12] = makeFieldValue4(uint32(key[12]), uint32(d[12]|iv24), uint32(iv[7]), uint32(iv[14]))
|
||||||
s.lfsr[13] = makeFieldValue4(uint32(key[13]), uint32(d[13]), uint32(iv[15]), uint32(iv[8]))
|
s.lfsr[13] = makeFieldValue4(uint32(key[13]), uint32(d[13]), uint32(iv[15]), uint32(iv[8]))
|
||||||
s.lfsr[14] = makeFieldValue4(uint32(key[14]), uint32(d[14]|(key[31]>>4)), uint32(iv[16]), uint32(iv[9]))
|
s.lfsr[14] = makeFieldValue4(uint32(key[14]), uint32(d[14]|(key[31]>>4)), uint32(iv[16]), uint32(iv[9]))
|
||||||
s.lfsr[15] = makeFieldValue4(uint32(key[15]), uint32(d[15]|(key[31]&0x0f)), uint32(key[30]), uint32(key[29]))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newZUCState(key, iv []byte) (*zucState32, error) {
|
func newZUCState(key, iv []byte) (*zucState32, error) {
|
||||||
@ -221,3 +237,11 @@ func (s *zucState32) genKeywords(words []uint32) {
|
|||||||
}
|
}
|
||||||
genKeyStream(words, s)
|
genKeyStream(words, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func genKeyStreamRev32(keyStream []byte, pState *zucState32) {
|
||||||
|
for len(keyStream) >= 4 {
|
||||||
|
z := genKeyword(pState)
|
||||||
|
binary.BigEndian.PutUint32(keyStream, z)
|
||||||
|
keyStream = keyStream[4:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//go:build !amd64 && !arm64 || purego
|
//go:build (!amd64 && !arm64) || purego
|
||||||
// +build !amd64,!arm64 purego
|
// +build !amd64,!arm64 purego
|
||||||
|
|
||||||
package zuc
|
package zuc
|
||||||
|
11
zuc/eea.go
11
zuc/eea.go
@ -28,22 +28,15 @@ func NewEEACipher(key []byte, count, bearer, direction uint32) (cipher.Stream, e
|
|||||||
func xorKeyStreamGeneric(c *zucState32, dst, src []byte) {
|
func xorKeyStreamGeneric(c *zucState32, dst, src []byte) {
|
||||||
words := (len(src) + 3) / 4
|
words := (len(src) + 3) / 4
|
||||||
rounds := words / RoundWords
|
rounds := words / RoundWords
|
||||||
var keyWords [RoundWords]uint32
|
|
||||||
var keyBytes [RoundWords * 4]byte
|
var keyBytes [RoundWords * 4]byte
|
||||||
for i := 0; i < rounds; i++ {
|
for i := 0; i < rounds; i++ {
|
||||||
c.genKeywords(keyWords[:])
|
genKeyStreamRev32(keyBytes[:], c)
|
||||||
for j := 0; j < RoundWords; j++ {
|
|
||||||
binary.BigEndian.PutUint32(keyBytes[j*4:], keyWords[j])
|
|
||||||
}
|
|
||||||
subtle.XORBytes(dst, src, keyBytes[:])
|
subtle.XORBytes(dst, src, keyBytes[:])
|
||||||
dst = dst[RoundWords*4:]
|
dst = dst[RoundWords*4:]
|
||||||
src = src[RoundWords*4:]
|
src = src[RoundWords*4:]
|
||||||
}
|
}
|
||||||
if rounds*RoundWords < words {
|
if rounds*RoundWords < words {
|
||||||
c.genKeywords(keyWords[:words-rounds*RoundWords])
|
genKeyStreamRev32(keyBytes[:4*(words-rounds*RoundWords)], c)
|
||||||
for j := 0; j < words-rounds*RoundWords; j++ {
|
|
||||||
binary.BigEndian.PutUint32(keyBytes[j*4:], keyWords[j])
|
|
||||||
}
|
|
||||||
subtle.XORBytes(dst, src, keyBytes[:])
|
subtle.XORBytes(dst, src, keyBytes[:])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
35
zuc/eia.go
35
zuc/eia.go
@ -98,14 +98,33 @@ func blockGeneric(m *ZUC128Mac, p []byte) {
|
|||||||
t64 = uint64(m.t) << 32
|
t64 = uint64(m.t) << 32
|
||||||
for len(p) >= chunk {
|
for len(p) >= chunk {
|
||||||
m.genKeywords(m.k0[4:])
|
m.genKeywords(m.k0[4:])
|
||||||
for i := 0; i < 4; i++ {
|
k64 = uint64(m.k0[0])<<32 | uint64(m.k0[1])
|
||||||
k64 = uint64(m.k0[i])<<32 | uint64(m.k0[i+1])
|
w := binary.BigEndian.Uint32(p[0:4])
|
||||||
w := binary.BigEndian.Uint32(p[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
|
k64 <<= 1
|
||||||
k64 <<= 1
|
}
|
||||||
}
|
k64 = uint64(m.k0[1])<<32 | uint64(m.k0[2])
|
||||||
|
w = binary.BigEndian.Uint32(p[4:8])
|
||||||
|
for j := 0; j < 32; j++ {
|
||||||
|
t64 ^= ^(uint64(w>>31) - 1) & k64
|
||||||
|
w <<= 1
|
||||||
|
k64 <<= 1
|
||||||
|
}
|
||||||
|
k64 = uint64(m.k0[2])<<32 | uint64(m.k0[3])
|
||||||
|
w = binary.BigEndian.Uint32(p[8:12])
|
||||||
|
for j := 0; j < 32; j++ {
|
||||||
|
t64 ^= ^(uint64(w>>31) - 1) & k64
|
||||||
|
w <<= 1
|
||||||
|
k64 <<= 1
|
||||||
|
}
|
||||||
|
k64 = uint64(m.k0[3])<<32 | uint64(m.k0[4])
|
||||||
|
w = binary.BigEndian.Uint32(p[12:16])
|
||||||
|
for j := 0; j < 32; j++ {
|
||||||
|
t64 ^= ^(uint64(w>>31) - 1) & k64
|
||||||
|
w <<= 1
|
||||||
|
k64 <<= 1
|
||||||
}
|
}
|
||||||
copy(m.k0[:4], m.k0[4:])
|
copy(m.k0[:4], m.k0[4:])
|
||||||
p = p[chunk:]
|
p = p[chunk:]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user