init: v1.0.0

This commit is contained in:
yaole
2026-05-27 23:03:00 +08:00
commit 8d97f750eb
466 changed files with 80067 additions and 0 deletions
+187
View File
@@ -0,0 +1,187 @@
package blockmode_test
import (
"bytes"
"crypto/cipher"
"encoding/hex"
"fmt"
"testing"
"time"
"github.com/stretchr/testify/assert"
"xdx.jelly/xgcl/grand"
"xdx.jelly/xgcl/sm/sm4"
"xdx.jelly/xgcl/utils/blockmode"
)
type noopBlock int
func (b noopBlock) BlockSize() int { return int(b) }
func (noopBlock) Encrypt(dst, src []byte) { copy(dst, src) }
func (noopBlock) Decrypt(dst, src []byte) { copy(dst, src) }
func inc(b []byte) {
for i := len(b) - 1; i >= 0; i++ {
b[i]++
if b[i] != 0 {
break
}
}
}
func xor(a, b []byte) {
for i := range a {
a[i] ^= b[i]
}
}
func TestCTR(t *testing.T) {
for size := 64; size <= 1024; size *= 2 {
iv := make([]byte, size)
ctr := cipher.NewCTR(noopBlock(size), iv)
src := make([]byte, 1024)
for i := range src {
src[i] = 0xff
}
want := make([]byte, 1024)
copy(want, src)
counter := make([]byte, size)
for i := 1; i < len(want)/size; i++ {
inc(counter)
xor(want[i*size:(i+1)*size], counter)
}
dst := make([]byte, 1024)
ctr.XORKeyStream(dst, src)
if !bytes.Equal(dst, want) {
t.Errorf("for size %d\nhave %x\nwant %x", size, dst, want)
}
}
}
func FuzzSm4Ctr(f *testing.F) {
iv := grand.GetRandom(16)
key := grand.GetRandom(16)
key, _ = hex.DecodeString("70fe9d4cdf29d1db1549a44d70bf28fb")
iv, _ = hex.DecodeString("edf1631376519ddc9654cec2900060de")
block, _ := sm4.NewCipher(key)
mode := blockmode.Wrap(block)
f.Add([]byte{}, []byte{})
f.Fuzz(func(t *testing.T, plaintext, ad []byte) {
stdctr := cipher.NewCTR(block, iv)
ctr, err := blockmode.NewCTR(mode, iv)
if err != nil {
t.Fatal(err)
}
stdct := make([]byte, len(plaintext))
stdctr.XORKeyStream(stdct, plaintext)
ct1 := make([]byte, len(plaintext))
ctr.XORKeyStream(ct1, plaintext)
if bytes.Compare(ct1, stdct) != 0 {
t.Errorf("XORKeyStream failed")
}
if err := ctr.EncryptInit(iv); err != nil {
t.Fatal(err)
}
ct2, err := ctr.EncryptUpdate(nil, plaintext[:len(plaintext)/2])
if err != nil {
t.Fatal(err)
}
if ct2, err = ctr.EncryptUpdate(ct2, plaintext[len(plaintext)/2:]); err != nil {
t.Fatal(err)
}
ct2, err = ctr.EncryptFinal(ct2)
if err != nil {
t.Fatal(err)
}
if bytes.Compare(ct2, stdct) != 0 {
t.Errorf("Encrypt failed")
}
if err := ctr.DecryptInit(iv); err != nil {
t.Fatal(err)
}
pt2, err := ctr.DecryptUpdate(nil, ct2[:len(ct2)/2])
if err != nil {
t.Fatal(err)
}
if pt2, err = ctr.DecryptUpdate(pt2, ct2[len(ct2)/2:]); err != nil {
t.Fatal(err)
}
pt2, err = ctr.DecryptFinal(pt2)
if err != nil {
t.Fatal(err)
}
if bytes.Compare(pt2, plaintext) != 0 {
t.Errorf("Decrypt failed")
}
})
}
func TestCTRData(t *testing.T) {
size := 1024
key := []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}
iv := []byte{0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF}
src := make([]byte, size)
b, err := sm4.NewCipher(key)
assert.Nil(t, err)
ctr, err := blockmode.NewCTR(blockmode.Wrap(b), iv)
for i := range src {
src[i] = byte(i)
}
ctr.EncryptInit(iv)
dst, err := ctr.EncryptUpdate(nil, src)
assert.Nil(t, err)
dst, err = ctr.EncryptFinal(dst)
assert.Nil(t, err)
fmt.Println("src:")
for i := range src {
fmt.Printf("0x%02x, ", src[i])
if (i+1)%32 == 0 {
fmt.Println("")
}
}
fmt.Println("dst:")
for i := range dst {
fmt.Printf("0x%02x, ", dst[i])
if (i+1)%32 == 0 {
fmt.Println("")
}
}
}
func TestCTRSpeed(t *testing.T) {
size := 1024
key := []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}
iv := []byte{0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF}
src := make([]byte, size)
b, err := sm4.NewCipher(key)
assert.Nil(t, err)
ctr, err := blockmode.NewCTR(blockmode.Wrap(b), iv)
for i := range src {
src[i] = byte(i)
}
assert.Nil(t, err)
start := time.Now()
times := 10000
for i := 0; i < times; i++ {
ctr.EncryptInit(iv)
dst, _ := ctr.EncryptUpdate(nil, src)
dst, _ = ctr.EncryptFinal(dst)
}
end := time.Now()
elapsed := end.Sub(start)
t.Log("SM4 Encrypt: ", int(float64(times*len(src))/float64(1024*1024)/elapsed.Seconds()), "MBps")
}