github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/sm4/sm4_gcm_test.go (about) 1 //go:build amd64 || arm64 2 // +build amd64 arm64 3 4 package sm4 5 6 import ( 7 "encoding/hex" 8 "fmt" 9 "testing" 10 ) 11 12 func genPrecomputeTable() *gcmAsm { 13 key := []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10} 14 c := &sm4CipherAsm{sm4Cipher{make([]uint32, rounds), make([]uint32, rounds)}, 4, 64} 15 expandKey(key, c.enc, c.dec) 16 c1 := &sm4CipherGCM{c} 17 g := &gcmAsm{} 18 g.cipher = c1.sm4CipherAsm 19 gcmSm4InitInst(&g.bytesProductTable, g.cipher.enc) 20 return g 21 } 22 23 /* 24 amd64 result = { 25 0xEF, 0xE0, 0x28, 0x75, 0x21, 0x1F, 0x10, 0x4B, 0x6C, 0xC6, 0x39, 0x8A, 0x88, 0xE0, 0x26, 0x16, 26 0x83, 0x26, 0x11, 0xFF, 0xA9, 0xFF, 0x36, 0x5D, 0x83, 0x26, 0x11, 0xFF, 0xA9, 0xFF, 0x36, 0x5D, 27 0xD1, 0x99, 0x07, 0x39, 0xBA, 0x15, 0x68, 0xA7, 0xB8, 0x50, 0xC2, 0xB3, 0xD6, 0xFA, 0xA7, 0x02, 28 0x69, 0xC9, 0xC5, 0x8A, 0x6C, 0xEF, 0xCF, 0xA5, 0x69, 0xC9, 0xC5, 0x8A, 0x6C, 0xEF, 0xCF, 0xA5, 29 0xC4, 0x65, 0xCA, 0xCA, 0x55, 0x7F, 0x2B, 0x72, 0xB1, 0xA4, 0x14, 0x62, 0xDE, 0xBD, 0x1B, 0x00, 30 0x75, 0xC1, 0xDE, 0xA8, 0x8B, 0xC2, 0x30, 0x72, 0x75, 0xC1, 0xDE, 0xA8, 0x8B, 0xC2, 0x30, 0x72, 31 0x85, 0xF6, 0x58, 0x15, 0x09, 0x45, 0xB9, 0x72, 0x00, 0x30, 0xAB, 0x91, 0x2A, 0x73, 0xB7, 0x1C, 32 0x85, 0xC6, 0xF3, 0x84, 0x23, 0x36, 0x0E, 0x6E, 0x85, 0xC6, 0xF3, 0x84, 0x23, 0x36, 0x0E, 0x6E, 33 0x70, 0xD7, 0xD2, 0x6D, 0x60, 0xBA, 0x5E, 0x2E, 0x43, 0x4C, 0x4A, 0xCF, 0xFA, 0xE2, 0xF1, 0x5B, 34 0x33, 0x9B, 0x98, 0xA2, 0x9A, 0x58, 0xAF, 0x75, 0x33, 0x9B, 0x98, 0xA2, 0x9A, 0x58, 0xAF, 0x75, 35 0xED, 0xEB, 0x6C, 0xD4, 0x1B, 0x6C, 0x86, 0x6A, 0xA1, 0x16, 0xA5, 0xFF, 0x33, 0xDC, 0xBB, 0xC0, 36 0x4C, 0xFD, 0xC9, 0x2B, 0x28, 0xB0, 0x3D, 0xAA, 0x4C, 0xFD, 0xC9, 0x2B, 0x28, 0xB0, 0x3D, 0xAA, 37 0xBF, 0x7C, 0x2D, 0x4E, 0xFD, 0xDD, 0x55, 0x77, 0x1C, 0x7E, 0x73, 0xC7, 0xAA, 0x8B, 0x73, 0x2F, 38 0xA3, 0x02, 0x5E, 0x89, 0x57, 0x56, 0x26, 0x58, 0xA3, 0x02, 0x5E, 0x89, 0x57, 0x56, 0x26, 0x58, 39 0x54, 0x44, 0xA9, 0xB7, 0x20, 0x66, 0xAA, 0x2E, 0x99, 0x45, 0x82, 0x13, 0xD6, 0xE8, 0xEF, 0x4C, 40 0xCD, 0x01, 0x2B, 0xA4, 0xF6, 0x8E, 0x45, 0x62, 0xCD, 0x01, 0x2B, 0xA4, 0xF6, 0x8E, 0x45, 0x62, } 41 arm64 result = { 42 0x6C, 0xC6, 0x39, 0x8A, 0x88, 0xE0, 0x26, 0x16, 0xEF, 0xE0, 0x28, 0x75, 0x21, 0x1F, 0x10, 0x4B, 43 0x83, 0x26, 0x11, 0xFF, 0xA9, 0xFF, 0x36, 0x5D, 0x83, 0x26, 0x11, 0xFF, 0xA9, 0xFF, 0x36, 0x5D, 44 0xB8, 0x50, 0xC2, 0xB3, 0xD6, 0xFA, 0xA7, 0x02, 0xD1, 0x99, 0x07, 0x39, 0xBA, 0x15, 0x68, 0xA7, 45 0x69, 0xC9, 0xC5, 0x8A, 0x6C, 0xEF, 0xCF, 0xA5, 0x69, 0xC9, 0xC5, 0x8A, 0x6C, 0xEF, 0xCF, 0xA5, 46 0xB1, 0xA4, 0x14, 0x62, 0xDE, 0xBD, 0x1B, 0x00, 0xC4, 0x65, 0xCA, 0xCA, 0x55, 0x7F, 0x2B, 0x72, 47 0x75, 0xC1, 0xDE, 0xA8, 0x8B, 0xC2, 0x30, 0x72, 0x75, 0xC1, 0xDE, 0xA8, 0x8B, 0xC2, 0x30, 0x72, 48 0x00, 0x30, 0xAB, 0x91, 0x2A, 0x73, 0xB7, 0x1C, 0x85, 0xF6, 0x58, 0x15, 0x09, 0x45, 0xB9, 0x72, 49 0x85, 0xC6, 0xF3, 0x84, 0x23, 0x36, 0x0E, 0x6E, 0x85, 0xC6, 0xF3, 0x84, 0x23, 0x36, 0x0E, 0x6E, 50 0x43, 0x4C, 0x4A, 0xCF, 0xFA, 0xE2, 0xF1, 0x5B, 0x70, 0xD7, 0xD2, 0x6D, 0x60, 0xBA, 0x5E, 0x2E, 51 0x33, 0x9B, 0x98, 0xA2, 0x9A, 0x58, 0xAF, 0x75, 0x33, 0x9B, 0x98, 0xA2, 0x9A, 0x58, 0xAF, 0x75, 52 0xA1, 0x16, 0xA5, 0xFF, 0x33, 0xDC, 0xBB, 0xC0, 0xED, 0xEB, 0x6C, 0xD4, 0x1B, 0x6C, 0x86, 0x6A, 53 0x4C, 0xFD, 0xC9, 0x2B, 0x28, 0xB0, 0x3D, 0xAA, 0x4C, 0xFD, 0xC9, 0x2B, 0x28, 0xB0, 0x3D, 0xAA, 54 0x1C, 0x7E, 0x73, 0xC7, 0xAA, 0x8B, 0x73, 0x2F, 0xBF, 0x7C, 0x2D, 0x4E, 0xFD, 0xDD, 0x55, 0x77, 55 0xA3, 0x02, 0x5E, 0x89, 0x57, 0x56, 0x26, 0x58, 0xA3, 0x02, 0x5E, 0x89, 0x57, 0x56, 0x26, 0x58, 56 0x99, 0x45, 0x82, 0x13, 0xD6, 0xE8, 0xEF, 0x4C, 0x54, 0x44, 0xA9, 0xB7, 0x20, 0x66, 0xAA, 0x2E, 57 0xCD, 0x01, 0x2B, 0xA4, 0xF6, 0x8E, 0x45, 0x62, 0xCD, 0x01, 0x2B, 0xA4, 0xF6, 0x8E, 0x45, 0x62, 58 } 59 */ 60 func TestGcmSm4Init(t *testing.T) { 61 g := genPrecomputeTable() 62 for i := 0; i < 16; i++ { 63 for j := 0; j < 16; j++ { 64 fmt.Printf("0x%02X, ", g.bytesProductTable[i*16+j]) 65 } 66 fmt.Println() 67 } 68 } 69 70 /* 71 amd64 result = { 72 7D 13 81 A2 78 ED 2D 5E 91 3E 7F 9A 15 2C 76 DA 73 } 74 75 arm64 result = { 76 91 3E 7F 9A 15 2C 76 DA 7D 13 81 A2 78 ED 2D 5E 77 } 78 */ 79 func TestGcmSm4Data(t *testing.T) { 80 g := genPrecomputeTable() 81 var counter [gcmBlockSize]byte 82 nonce := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} 83 gcmSm4Data(&g.bytesProductTable, nonce, &counter) 84 for j := 0; j < 16; j++ { 85 fmt.Printf("%02X ", counter[j]) 86 } 87 fmt.Println() 88 } 89 90 /* 91 amd64 result = { 92 8F F3 05 10 EA 99 A8 D7 41 D9 E3 BA 67 D6 18 EE 93 } 94 arm64 result = { 95 8F F3 05 10 EA 99 A8 D7 41 D9 E3 BA 67 D6 18 EE 96 } 97 */ 98 func TestGcmSm4Finish(t *testing.T) { 99 g := genPrecomputeTable() 100 var counter, tagMask [gcmBlockSize]byte 101 nonce := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} 102 gcmSm4Data(&g.bytesProductTable, nonce, &counter) 103 gcmSm4Finish(&g.bytesProductTable, &tagMask, &counter, uint64(len(nonce)), uint64(0)) 104 for j := 0; j < 16; j++ { 105 fmt.Printf("%02X ", counter[j]) 106 } 107 fmt.Println() 108 } 109 110 /* 111 amd64 result= { 112 71 F0 B5 6E B6 6A 89 11 98 01 23 72 4B F6 0D 0C 113 5B 36 17 D5 95 7E B6 42 8C 6A C7 E1 80 76 70 B6 114 16 3E 35 A0 B7 51 62 AA 1D AF C1 15 2D C4 3B 9D 115 } 116 arm64 result = { 117 98 01 23 72 4B F6 0D 0C 71 F0 B5 6E B6 6A 89 11 118 8C 6A C7 E1 80 76 70 B6 5B 36 17 D5 95 7E B6 42 119 16 3E 35 A0 B7 51 62 AA 1D AF C1 15 2D C4 3B 9D 120 } 121 */ 122 func TestBothDataPlaintext(t *testing.T) { 123 g := genPrecomputeTable() 124 var tagOut, tagMask [gcmBlockSize]byte 125 data := []byte("emmansun") 126 gcmSm4Data(&g.bytesProductTable, data, &tagOut) 127 for j := 0; j < 16; j++ { 128 tagMask[j] = byte(j) 129 } 130 for j := 0; j < 16; j++ { 131 fmt.Printf("%02X ", tagOut[j]) 132 } 133 fmt.Println() 134 gcmSm4Data(&g.bytesProductTable, []byte("emmansunemmansunemmansunemmansun"), &tagOut) 135 for j := 0; j < 16; j++ { 136 fmt.Printf("%02X ", tagOut[j]) 137 } 138 fmt.Println() 139 gcmSm4Finish(&g.bytesProductTable, &tagMask, &tagOut, uint64(32), uint64(8)) 140 for j := 0; j < 16; j++ { 141 fmt.Printf("%02X ", tagOut[j]) 142 } 143 fmt.Println() 144 } 145 146 func createGcm() *gcmAsm { 147 key := []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10} 148 c := &sm4CipherAsm{sm4Cipher{make([]uint32, rounds), make([]uint32, rounds)}, 4, 64} 149 expandKey(key, c.enc, c.dec) 150 c1 := &sm4CipherGCM{c} 151 g := &gcmAsm{} 152 g.cipher = c1.sm4CipherAsm 153 g.tagSize = 16 154 gcmSm4InitInst(&g.bytesProductTable, g.cipher.enc) 155 return g 156 } 157 158 var sm4GCMTests = []struct { 159 plaintext string 160 }{ 161 { // case 0: < 16 162 "abcdefg", 163 }, 164 { // case 1: = 16 165 "abcdefgabcdefghg", 166 }, 167 { // case 2: > 16 , < 64 168 "abcdefgabcdefghgabcdefgabcdefghgaaa", 169 }, 170 { // case 3: = 64 171 "abcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghg", 172 }, 173 { // case 4: > 64, < 128 174 "abcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgaaa", 175 }, 176 { // case 5: = 128 177 "abcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghg", 178 }, 179 { // case 6: 227 > 128, < 256, 128 + 64 + 35 180 "abcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgaaa", 181 }, 182 { // case 7: = 256 183 "abcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghg", 184 }, 185 { // case 8: > 256, = 355 186 "abcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgabcdefgabcdefghgaaa", 187 }, 188 } 189 190 func initCounter(i byte, counter *[16]byte) { 191 copy(counter[:], []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}) 192 counter[gcmBlockSize-1] = i 193 } 194 195 func resetTag(tag *[16]byte) { 196 for j := 0; j < 16; j++ { 197 tag[j] = 0 198 } 199 } 200 201 func TestGcmSm4Enc(t *testing.T) { 202 var counter1, counter2 [16]byte 203 gcm := createGcm() 204 var tagOut1, tagOut2 [gcmTagSize]byte 205 206 for i, test := range sm4GCMTests { 207 initCounter(2, &counter1) 208 initCounter(1, &counter2) 209 210 gcmSm4Data(&gcm.bytesProductTable, []byte("emmansun"), &tagOut1) 211 out1 := make([]byte, len(test.plaintext)+gcm.tagSize) 212 gcm.counterCrypt(out1, []byte(test.plaintext), &counter1) 213 gcmSm4Data(&gcm.bytesProductTable, out1[:len(test.plaintext)], &tagOut1) 214 215 out2 := make([]byte, len(test.plaintext)+gcm.tagSize) 216 gcmSm4Data(&gcm.bytesProductTable, []byte("emmansun"), &tagOut2) 217 gcmSm4EncInst(&gcm.bytesProductTable, out2, []byte(test.plaintext), &counter2, &tagOut2, gcm.cipher.enc) 218 if hex.EncodeToString(out1) != hex.EncodeToString(out2) { 219 t.Errorf("#%d: out expected %s, got %s", i, hex.EncodeToString(out1), hex.EncodeToString(out2)) 220 } 221 if hex.EncodeToString(tagOut1[:]) != hex.EncodeToString(tagOut2[:]) { 222 t.Errorf("#%d: tag expected %s, got %s", i, hex.EncodeToString(tagOut1[:]), hex.EncodeToString(tagOut2[:])) 223 } 224 resetTag(&tagOut1) 225 resetTag(&tagOut2) 226 } 227 } 228 229 func TestGcmSm4Dec(t *testing.T) { 230 var counter1, counter2 [16]byte 231 gcm := createGcm() 232 var tagOut1, tagOut2 [gcmTagSize]byte 233 234 for i, test := range sm4GCMTests { 235 initCounter(2, &counter1) 236 initCounter(1, &counter2) 237 238 gcmSm4Data(&gcm.bytesProductTable, []byte("emmansun"), &tagOut1) 239 out1 := make([]byte, len(test.plaintext)+gcm.tagSize) 240 gcm.counterCrypt(out1, []byte(test.plaintext), &counter1) 241 gcmSm4Data(&gcm.bytesProductTable, out1[:len(test.plaintext)], &tagOut1) 242 243 out1 = out1[:len(test.plaintext)] 244 245 out2 := make([]byte, len(test.plaintext)+gcm.tagSize) 246 gcmSm4Data(&gcm.bytesProductTable, []byte("emmansun"), &tagOut2) 247 gcmSm4DecInst(&gcm.bytesProductTable, out2, out1, &counter2, &tagOut2, gcm.cipher.enc) 248 249 if hex.EncodeToString([]byte(test.plaintext)) != hex.EncodeToString(out2[:len(test.plaintext)]) { 250 t.Errorf("#%d: out expected %s, got %s", i, hex.EncodeToString([]byte(test.plaintext)), hex.EncodeToString(out2[:len(test.plaintext)])) 251 } 252 if hex.EncodeToString(tagOut1[:]) != hex.EncodeToString(tagOut2[:]) { 253 t.Errorf("#%d: tag expected %s, got %s", i, hex.EncodeToString(tagOut1[:]), hex.EncodeToString(tagOut2[:])) 254 } 255 resetTag(&tagOut1) 256 resetTag(&tagOut2) 257 } 258 }