github.com/emmansun/gmsm@v0.29.1/cipher/bc_test.go (about) 1 package cipher_test 2 3 import ( 4 "bytes" 5 "crypto/rand" 6 "encoding/hex" 7 "io" 8 mrand "math/rand" 9 "testing" 10 "time" 11 12 "github.com/emmansun/gmsm/cipher" 13 "github.com/emmansun/gmsm/internal/cryptotest" 14 "github.com/emmansun/gmsm/sm4" 15 ) 16 17 var bcSM4TestVectors = []struct { 18 key string 19 iv string 20 plaintext string 21 ciphertext string 22 }{ 23 { 24 "2B7E151628AED2A6ABF7158809CF4F3C", 25 "000102030405060708090A0B0C0D0E0F", 26 "6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710", 27 "AC529AF989A62FCE9CDDC5FFB84125CAFB8CDE77339FFE481D113C40BBD5B6786FFC9916F98F94FF12D78319707E240428718707605BC1EAC503153EBAA0FB1D", 28 }, 29 } 30 31 func TestBC(t *testing.T) { 32 for i, test := range bcSM4TestVectors { 33 key, _ := hex.DecodeString(test.key) 34 iv, _ := hex.DecodeString(test.iv) 35 plaintext, _ := hex.DecodeString(test.plaintext) 36 ciphertext, _ := hex.DecodeString(test.ciphertext) 37 got := make([]byte, len(plaintext)) 38 c, err := sm4.NewCipher(key) 39 if err != nil { 40 t.Fatal(err) 41 } 42 43 encrypter := cipher.NewBCEncrypter(c, iv) 44 encrypter.CryptBlocks(got, plaintext) 45 if !bytes.Equal(got, ciphertext) { 46 t.Fatalf("%v case encrypt failed, got %x\n", i+1, got) 47 } 48 49 decrypter := cipher.NewBCDecrypter(c, iv) 50 decrypter.CryptBlocks(got, ciphertext) 51 if !bytes.Equal(got, plaintext) { 52 t.Fatalf("%v case decrypt failed, got %x\n", i+1, got) 53 } 54 } 55 } 56 57 func TestSM4BCRandom(t *testing.T) { 58 key, _ := hex.DecodeString(bcSM4TestVectors[0].key) 59 iv := []byte("0123456789ABCDEF") 60 c, err := sm4.NewCipher(key) 61 if err != nil { 62 t.Fatal(err) 63 } 64 encrypter := cipher.NewBCEncrypter(c, iv) 65 decrypter := cipher.NewBCDecrypter(c, iv) 66 for i := 1; i <= 50; i++ { 67 plaintext := make([]byte, i*16) 68 ciphertext := make([]byte, i*16) 69 got := make([]byte, i*16) 70 io.ReadFull(rand.Reader, plaintext) 71 encrypter.CryptBlocks(ciphertext, plaintext) 72 decrypter.CryptBlocks(got, ciphertext) 73 if !bytes.Equal(got, plaintext) { 74 t.Errorf("test %v blocks failed", i) 75 } 76 } 77 } 78 79 // Test BC Blockmode against the general cipher.BlockMode interface tester 80 func TestBCBlockMode(t *testing.T) { 81 t.Run("SM4", func(t *testing.T) { 82 rng := newRandReader(t) 83 84 key := make([]byte, 16) 85 rng.Read(key) 86 87 block, err := sm4.NewCipher(key) 88 if err != nil { 89 panic(err) 90 } 91 92 cryptotest.TestBlockMode(t, block, cipher.NewBCEncrypter, cipher.NewBCDecrypter) 93 }) 94 } 95 96 func newRandReader(t *testing.T) io.Reader { 97 seed := time.Now().UnixNano() 98 t.Logf("Deterministic RNG seed: 0x%x", seed) 99 return mrand.New(mrand.NewSource(seed)) 100 }