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  }