github.com/emmansun/gmsm@v0.29.1/cipher/cfb_sm4_test.go (about) 1 package cipher_test 2 3 import ( 4 "bytes" 5 "crypto/cipher" 6 "crypto/rand" 7 "encoding/hex" 8 "testing" 9 10 "github.com/emmansun/gmsm/internal/cryptotest" 11 "github.com/emmansun/gmsm/sm4" 12 ) 13 14 var cfbTests = []struct { 15 key, iv, plaintext, ciphertext string 16 }{ 17 { 18 "2b7e151628aed2a6abf7158809cf4f3c", 19 "000102030405060708090a0b0c0d0e0f", 20 "6bc1bee22e409f96e93d7e117393172a", 21 "bc710d762d070b26361da82b54565e46", 22 }, 23 { 24 "2b7e151628aed2a6abf7158809cf4f3c", 25 "3B3FD92EB72DAD20333449F8E83CFB4A", 26 "ae2d8a571e03ac9c9eb76fac45af8e51", 27 "945fc8a8241b340d496be6b772d04ee3", 28 }, 29 { 30 "2b7e151628aed2a6abf7158809cf4f3c", 31 "C8A64537A0B3A93FCDE3CDAD9F1CE58B", 32 "30c81c46a35ce411e5fbc1191a0a52ef", 33 "ebe17f4c9b41ebe026d99ccdbb1e1e0d", 34 }, 35 { 36 "2b7e151628aed2a6abf7158809cf4f3c", 37 "26751F67A3CBB140B1808CF187A4F4DF", 38 "f69f2445df4f9b17ad2b417be66c3710", 39 "422994eb51eb089f1def710f07324be5", 40 }, 41 } 42 43 func TestCFBVectors(t *testing.T) { 44 for i, test := range cfbTests { 45 key, err := hex.DecodeString(test.key) 46 if err != nil { 47 t.Fatal(err) 48 } 49 iv, err := hex.DecodeString(test.iv) 50 if err != nil { 51 t.Fatal(err) 52 } 53 plaintext, err := hex.DecodeString(test.plaintext) 54 if err != nil { 55 t.Fatal(err) 56 } 57 expected, err := hex.DecodeString(test.ciphertext) 58 if err != nil { 59 t.Fatal(err) 60 } 61 62 block, err := sm4.NewCipher(key) 63 if err != nil { 64 t.Fatal(err) 65 } 66 67 ciphertext := make([]byte, len(plaintext)) 68 cfb := cipher.NewCFBEncrypter(block, iv) 69 cfb.XORKeyStream(ciphertext, plaintext) 70 71 if !bytes.Equal(ciphertext, expected) { 72 t.Errorf("#%d: wrong output: got %x, expected %x", i, ciphertext, expected) 73 } 74 75 cfbdec := cipher.NewCFBDecrypter(block, iv) 76 plaintextCopy := make([]byte, len(ciphertext)) 77 cfbdec.XORKeyStream(plaintextCopy, ciphertext) 78 79 if !bytes.Equal(plaintextCopy, plaintext) { 80 t.Errorf("#%d: wrong plaintext: got %x, expected %x", i, plaintextCopy, plaintext) 81 } 82 } 83 } 84 85 func TestCFBInverse(t *testing.T) { 86 block, err := sm4.NewCipher([]byte{0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}) 87 if err != nil { 88 t.Error(err) 89 return 90 } 91 92 plaintext := []byte("this is the plaintext. this is the plaintext.") 93 iv := make([]byte, block.BlockSize()) 94 rand.Reader.Read(iv) 95 cfb := cipher.NewCFBEncrypter(block, iv) 96 ciphertext := make([]byte, len(plaintext)) 97 copy(ciphertext, plaintext) 98 cfb.XORKeyStream(ciphertext, ciphertext) 99 100 cfbdec := cipher.NewCFBDecrypter(block, iv) 101 plaintextCopy := make([]byte, len(plaintext)) 102 copy(plaintextCopy, ciphertext) 103 cfbdec.XORKeyStream(plaintextCopy, plaintextCopy) 104 105 if !bytes.Equal(plaintextCopy, plaintext) { 106 t.Errorf("got: %x, want: %x", plaintextCopy, plaintext) 107 } 108 } 109 110 func TestCFBStream(t *testing.T) { 111 t.Run("SM4", func(t *testing.T) { 112 rng := newRandReader(t) 113 114 key := make([]byte, 16) 115 rng.Read(key) 116 117 block, err := sm4.NewCipher(key) 118 if err != nil { 119 panic(err) 120 } 121 122 t.Run("Encrypter", func(t *testing.T) { 123 cryptotest.TestStreamFromBlock(t, block, cipher.NewCFBEncrypter) 124 }) 125 t.Run("Decrypter", func(t *testing.T) { 126 cryptotest.TestStreamFromBlock(t, block, cipher.NewCFBDecrypter) 127 }) 128 }) 129 }