mirror of
https://github.com/emmansun/gmsm.git
synced 2025-10-14 15:20:45 +08:00
internal/zuc: support fast forward
This commit is contained in:
parent
47b23bc827
commit
a0912994f3
@ -276,6 +276,21 @@ func (c *eea) reset(offset uint64) {
|
|||||||
c.used = n * uint64(c.bucketSize)
|
c.used = n * uint64(c.bucketSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *eea) fastForward(offset uint64) {
|
||||||
|
// fast forward, check and adjust state if needed
|
||||||
|
var n uint64
|
||||||
|
if c.bucketSize > 0 {
|
||||||
|
n = offset / uint64(c.bucketSize)
|
||||||
|
expectedStateIndex := int(n)
|
||||||
|
if expectedStateIndex > c.stateIndex && expectedStateIndex < len(c.states) {
|
||||||
|
c.stateIndex = int(n)
|
||||||
|
c.zucState32 = *c.states[n]
|
||||||
|
c.xLen = 0
|
||||||
|
c.used = n * uint64(c.bucketSize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// seek sets the offset for the next XORKeyStream operation.
|
// seek sets the offset for the next XORKeyStream operation.
|
||||||
//
|
//
|
||||||
// If the offset is less than the current offset, the state will be reset to the initial state.
|
// If the offset is less than the current offset, the state will be reset to the initial state.
|
||||||
@ -283,6 +298,7 @@ func (c *eea) reset(offset uint64) {
|
|||||||
// If the offset is greater than the current offset, the function will forward the state to the offset.
|
// If the offset is greater than the current offset, the function will forward the state to the offset.
|
||||||
// Note: This method is not thread-safe.
|
// Note: This method is not thread-safe.
|
||||||
func (c *eea) seek(offset uint64) {
|
func (c *eea) seek(offset uint64) {
|
||||||
|
c.fastForward(offset)
|
||||||
if offset < c.used {
|
if offset < c.used {
|
||||||
c.reset(offset)
|
c.reset(offset)
|
||||||
}
|
}
|
||||||
|
@ -275,7 +275,7 @@ func TestEEAXORKeyStreamAtWithBucketSize(t *testing.T) {
|
|||||||
}
|
}
|
||||||
clear(dst)
|
clear(dst)
|
||||||
bucketCipher.XORKeyStreamAt(dst[513:768], src[513:768], 513)
|
bucketCipher.XORKeyStreamAt(dst[513:768], src[513:768], 513)
|
||||||
if bucketCipher.stateIndex != 0 {
|
if bucketCipher.stateIndex != 4 {
|
||||||
t.Fatalf("expected=%d, result=%d\n", 0, bucketCipher.stateIndex)
|
t.Fatalf("expected=%d, result=%d\n", 0, bucketCipher.stateIndex)
|
||||||
}
|
}
|
||||||
if len(bucketCipher.states) != 7 {
|
if len(bucketCipher.states) != 7 {
|
||||||
@ -296,6 +296,29 @@ func TestEEAXORKeyStreamAtWithBucketSize(t *testing.T) {
|
|||||||
t.Fatalf("expected=%x, result=%x\n", expected[512:768], dst[512:768])
|
t.Fatalf("expected=%x, result=%x\n", expected[512:768], dst[512:768])
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("Rotate end to start, end to start", func(t *testing.T) {
|
||||||
|
bucketCipher, err := NewEEACipherWithBucketSize(key, zucEEATests[0].count, zucEEATests[0].bearer, zucEEATests[0].direction, 128)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
clear(dst)
|
||||||
|
for i := len(src) - RoundBytes; i >= 0; i -= RoundBytes {
|
||||||
|
offset := i
|
||||||
|
bucketCipher.XORKeyStreamAt(dst[offset:offset+RoundBytes], src[offset:offset+RoundBytes], uint64(offset))
|
||||||
|
if !bytes.Equal(expected[offset:offset+RoundBytes], dst[offset:offset+RoundBytes]) {
|
||||||
|
t.Fatalf("at %d, expected=%x, result=%x\n", offset, expected[offset:offset+RoundBytes], dst[offset:offset+RoundBytes])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clear(dst)
|
||||||
|
for i := len(src) - RoundBytes; i >= 0; i -= RoundBytes {
|
||||||
|
offset := i
|
||||||
|
bucketCipher.XORKeyStreamAt(dst[offset:offset+RoundBytes], src[offset:offset+RoundBytes], uint64(offset))
|
||||||
|
if !bytes.Equal(expected[offset:offset+RoundBytes], dst[offset:offset+RoundBytes]) {
|
||||||
|
t.Fatalf("at %d, expected=%x, result=%x\n", offset, expected[offset:offset+RoundBytes], dst[offset:offset+RoundBytes])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMarshalUnmarshalBinary(t *testing.T) {
|
func TestMarshalUnmarshalBinary(t *testing.T) {
|
||||||
@ -394,7 +417,7 @@ func TestUnmarshalBinary_InvalidRemainingBytes(t *testing.T) {
|
|||||||
data[xLenOffset+3] = 8 // xLen = 8
|
data[xLenOffset+3] = 8 // xLen = 8
|
||||||
|
|
||||||
// Truncate data so remaining bytes < xLen
|
// Truncate data so remaining bytes < xLen
|
||||||
truncated := data[:minMarshaledSize + 4]
|
truncated := data[:minMarshaledSize+4]
|
||||||
|
|
||||||
c2 := NewEmptyCipher()
|
c2 := NewEmptyCipher()
|
||||||
err = c2.UnmarshalBinary(truncated)
|
err = c2.UnmarshalBinary(truncated)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user