support zuc256 for eea

This commit is contained in:
Emman 2022-04-19 17:42:21 +08:00
parent ca98bd6f5c
commit 772beacfb0
2 changed files with 132 additions and 10 deletions

View File

@ -50,6 +50,12 @@ var sbox1 = [256]byte{
0x64, 0xbe, 0x85, 0x9b, 0x2f, 0x59, 0x8a, 0xd7, 0xb0, 0x25, 0xac, 0xaf, 0x12, 0x03, 0xe2, 0xf2,
}
// constant D-0 for ZUC-256
var zuc256_d0 = [16]byte{
0x22, 0x2F, 0x24, 0x2A, 0x6D, 0x40, 0x40, 0x40,
0x40, 0x40, 0x40, 0x40, 0x40, 0x52, 0x10, 0x30,
}
type zucState32 struct {
lfsr [16]uint32 // linear feedback shift register
r1 uint32
@ -114,17 +120,64 @@ func (s *zucState32) enterWorkMode() {
s.enterInitMode(0)
}
func newZUCState(key, iv []byte) (*zucState32, error) {
if len(key) != 16 {
return nil, fmt.Errorf("zuc: invalid key size %d, expect 16 in bytes", len(key))
}
if len(iv) != 16 {
return nil, fmt.Errorf("zuc: invalid iv size %d, expect 16 in bytes", len(iv))
}
state := &zucState32{}
// loading key and iv
func makeFieldValue3(a, b, c uint32) uint32 {
return (a << 23) | (b << 8) | c
}
func makeFieldValue4(a, b, c, d uint32) uint32 {
return (a << 23) | (b << 16) | (c << 8) | d
}
func (s *zucState32) loadKeyIV16(key, iv []byte) {
for i := 0; i < 16; i++ {
state.lfsr[i] = (uint32(key[i]) << 23) | (kd[i] << 8) | uint32(iv[i])
s.lfsr[i] = makeFieldValue3(uint32(key[i]), kd[i], uint32(iv[i]))
}
}
func (s *zucState32) loadKeyIV32(key, iv, d []byte) {
iv17 := iv[17] >> 2
iv18 := ((iv[17] & 0x3) << 4) | (iv[18] >> 4)
iv19 := ((iv[18] & 0xf) << 2) | (iv[19] >> 6)
iv20 := iv[19] & 0x3f
iv21 := iv[20] >> 2
iv22 := ((iv[20] & 0x3) << 4) | (iv[21] >> 4)
iv23 := ((iv[21] & 0xf) << 2) | (iv[22] >> 6)
iv24 := iv[22] & 0x3f
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[2] = makeFieldValue4(uint32(key[2]), uint32(d[2]), uint32(key[23]), uint32(key[18]))
s.lfsr[3] = makeFieldValue4(uint32(key[3]), uint32(d[3]), uint32(key[24]), uint32(key[19]))
s.lfsr[4] = makeFieldValue4(uint32(key[4]), uint32(d[4]), uint32(key[25]), uint32(key[20]))
s.lfsr[5] = makeFieldValue4(uint32(iv[0]), uint32(d[5]|iv17), uint32(key[5]), uint32(key[26]))
s.lfsr[6] = makeFieldValue4(uint32(iv[1]), uint32(d[6]|iv18), uint32(key[6]), uint32(key[27]))
s.lfsr[7] = makeFieldValue4(uint32(iv[10]), uint32(d[7]|iv19), uint32(key[7]), uint32(iv[2]))
s.lfsr[8] = makeFieldValue4(uint32(key[8]), uint32(d[8]|iv20), uint32(iv[3]), uint32(iv[11]))
s.lfsr[9] = makeFieldValue4(uint32(key[9]), uint32(d[9]|iv21), uint32(iv[12]), uint32(iv[4]))
s.lfsr[10] = makeFieldValue4(uint32(iv[5]), uint32(d[10]|iv22), uint32(key[10]), uint32(key[28]))
s.lfsr[11] = makeFieldValue4(uint32(key[11]), uint32(d[11]|iv23), uint32(iv[6]), uint32(iv[13]))
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[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) {
k := len(key)
ivLen := len(iv)
state := &zucState32{}
switch k {
default:
return nil, fmt.Errorf("zuc: invalid key size %d, we support 16/32 now", k)
case 16: // ZUC-128
if ivLen != 16 {
return nil, fmt.Errorf("zuc: invalid iv size %d, expect 16 in bytes", ivLen)
}
state.loadKeyIV16(key, iv)
case 32: // ZUC-256
if ivLen != 23 {
return nil, fmt.Errorf("zuc: invalid iv size %d, expect 23 in bytes", ivLen)
}
state.loadKeyIV32(key, iv, zuc256_d0[:])
}
// initialization
@ -148,3 +201,12 @@ func (s *zucState32) genKeyword() uint32 {
s.enterWorkMode()
return z
}
func (s *zucState32) genKeywords(words []uint32) {
if len(words) == 0 {
return
}
for i := 0; i < len(words); i++ {
words[i] = s.genKeyword()
}
}

View File

@ -1,6 +1,7 @@
package zuc
import (
"reflect"
"testing"
)
@ -39,3 +40,62 @@ func Test_genKeyword_case3(t *testing.T) {
t.Errorf("expected=%x, result=%x\n", 0x3279c419, z2)
}
}
var zuc256Tests = []struct {
key []byte
iv []byte
expectedKeys []uint32
}{
{
[]byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
[]byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
[]uint32{
0x58d03ad6, 0x2e032ce2, 0xdafc683a, 0x39bdcb03, 0x52a2bc67,
0xf1b7de74, 0x163ce3a1, 0x01ef5558, 0x9639d75b, 0x95fa681b,
0x7f090df7, 0x56391ccc, 0x903b7612, 0x744d544c, 0x17bc3fad,
0x8b163b08, 0x21787c0b, 0x97775bb8, 0x4943c6bb, 0xe8ad8afd,
},
},
{
[]byte{
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
},
[]byte{
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
},
[]uint32{
0x3356cbae, 0xd1a1c18b, 0x6baa4ffe, 0x343f777c, 0x9e15128f,
0x251ab65b, 0x949f7b26, 0xef7157f2, 0x96dd2fa9, 0xdf95e3ee,
0x7a5be02e, 0xc32ba585, 0x505af316, 0xc2f9ded2, 0x7cdbd935,
0xe441ce11, 0x15fd0a80, 0xbb7aef67, 0x68989416, 0xb8fac8c2,
},
},
}
func Test_ZUC256(t *testing.T) {
for i, test := range zuc256Tests {
c, err := newZUCState(test.key, test.iv)
if err != nil {
t.Error(err)
}
words := make([]uint32, 20)
c.genKeywords(words)
if !reflect.DeepEqual(words, test.expectedKeys) {
t.Errorf("#%d: wrong output: got %x, expected %x", i, words, test.expectedKeys)
}
}
}