mirror of
https://github.com/emmansun/gmsm.git
synced 2025-04-21 17:56:19 +08:00
101 lines
2.5 KiB
Go
101 lines
2.5 KiB
Go
package cipher_test
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/rand"
|
|
"encoding/hex"
|
|
"io"
|
|
mrand "math/rand"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/emmansun/gmsm/cipher"
|
|
"github.com/emmansun/gmsm/internal/cryptotest"
|
|
"github.com/emmansun/gmsm/sm4"
|
|
)
|
|
|
|
var bcSM4TestVectors = []struct {
|
|
key string
|
|
iv string
|
|
plaintext string
|
|
ciphertext string
|
|
}{
|
|
{
|
|
"2B7E151628AED2A6ABF7158809CF4F3C",
|
|
"000102030405060708090A0B0C0D0E0F",
|
|
"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710",
|
|
"AC529AF989A62FCE9CDDC5FFB84125CAFB8CDE77339FFE481D113C40BBD5B6786FFC9916F98F94FF12D78319707E240428718707605BC1EAC503153EBAA0FB1D",
|
|
},
|
|
}
|
|
|
|
func TestBC(t *testing.T) {
|
|
for i, test := range bcSM4TestVectors {
|
|
key, _ := hex.DecodeString(test.key)
|
|
iv, _ := hex.DecodeString(test.iv)
|
|
plaintext, _ := hex.DecodeString(test.plaintext)
|
|
ciphertext, _ := hex.DecodeString(test.ciphertext)
|
|
got := make([]byte, len(plaintext))
|
|
c, err := sm4.NewCipher(key)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
encrypter := cipher.NewBCEncrypter(c, iv)
|
|
encrypter.CryptBlocks(got, plaintext)
|
|
if !bytes.Equal(got, ciphertext) {
|
|
t.Fatalf("%v case encrypt failed, got %x\n", i+1, got)
|
|
}
|
|
|
|
decrypter := cipher.NewBCDecrypter(c, iv)
|
|
decrypter.CryptBlocks(got, ciphertext)
|
|
if !bytes.Equal(got, plaintext) {
|
|
t.Fatalf("%v case decrypt failed, got %x\n", i+1, got)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSM4BCRandom(t *testing.T) {
|
|
key, _ := hex.DecodeString(bcSM4TestVectors[0].key)
|
|
iv := []byte("0123456789ABCDEF")
|
|
c, err := sm4.NewCipher(key)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
encrypter := cipher.NewBCEncrypter(c, iv)
|
|
decrypter := cipher.NewBCDecrypter(c, iv)
|
|
for i := 1; i <= 50; i++ {
|
|
plaintext := make([]byte, i*16)
|
|
ciphertext := make([]byte, i*16)
|
|
got := make([]byte, i*16)
|
|
io.ReadFull(rand.Reader, plaintext)
|
|
encrypter.CryptBlocks(ciphertext, plaintext)
|
|
decrypter.CryptBlocks(got, ciphertext)
|
|
if !bytes.Equal(got, plaintext) {
|
|
t.Errorf("test %v blocks failed", i)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Test BC Blockmode against the general cipher.BlockMode interface tester
|
|
func TestBCBlockMode(t *testing.T) {
|
|
t.Run("SM4", func(t *testing.T) {
|
|
rng := newRandReader(t)
|
|
|
|
key := make([]byte, 16)
|
|
rng.Read(key)
|
|
|
|
block, err := sm4.NewCipher(key)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
cryptotest.TestBlockMode(t, block, cipher.NewBCEncrypter, cipher.NewBCDecrypter)
|
|
})
|
|
}
|
|
|
|
func newRandReader(t *testing.T) io.Reader {
|
|
seed := time.Now().UnixNano()
|
|
t.Logf("Deterministic RNG seed: 0x%x", seed)
|
|
return mrand.New(mrand.NewSource(seed))
|
|
}
|