diff --git a/Efficient-Software-Implementations-of-ZUC.md b/Efficient-Software-Implementations-of-ZUC.md index 33eee73..bb5633f 100644 --- a/Efficient-Software-Implementations-of-ZUC.md +++ b/Efficient-Software-Implementations-of-ZUC.md @@ -368,6 +368,167 @@ M2= 0x95 ,0x45 ,0x66 ,0xf5 ,0x9d ,0xe7 ,0x84 ,0x15 , C2= 0xec M1= 0x6a ,0x42 ,0xb4 ,0x16 ,0xec ,0x0a ,0xf4 ,0xa7 , C1= 0x0 M2= 0x62 ,0xf2 ,0xa0 ,0xcd ,0xec ,0xae ,0xbc ,0xeb , C2= 0xb7 ``` + +## 计算查找表 +```python +from pyfinite import genericmatrix + +def XOR(x, y): return x ^ y +def AND(x, y): return x & y +def DIV(x, y): return x + +def genCMatrix(c): + Imatrix = genericmatrix.GenericMatrix(size=(8, 1), zeroElement=0, identityElement=1, add=XOR, mul=AND, sub=XOR, div=DIV) + for j in range (8): + Imatrix.SetRow(j, [(0x63 >> (7 - j)) & 1]) + return Imatrix + +def matrix_from_cols(cols): + m = genericmatrix.GenericMatrix(size=(8, 8), zeroElement=0, identityElement=1, add=XOR, mul=AND, sub=XOR, div=DIV) + for i in range (8): + k = 7 - i + j = 1 << k + m.SetRow(i, [(cols[0] & j) >> k, (cols[1] & j) >> k, (cols[2] & j) >> k, (cols[3] & j) >> k, (cols[4] & j) >> k, (cols[5] & j) >> k, (cols[6] & j) >> k, (cols[7] & j) >> k]) + + return m + +def gen_matrix_based_table(table): + return matrix_from_cols([table[0x80] ^ table[0], table[0x40] ^ table[0], table[0x20] ^ table[0], table[0x10] ^ table[0], table[0x08] ^ table[0], table[0x04] ^ table[0], table[0x02] ^ table[0], table[0x01] ^ table[0]]) + +def gen_matrix_based_high_low(high, low): + table = [] + for i in range(16): + for j in range(16): + table.append(high[i] ^ low[j]) + return gen_matrix_based_table(table) + +def matrix_col_byte(c): + return (c[0] << 7) ^ (c[1] << 6) ^ (c[2] << 5) ^ (c[3] << 4) ^ (c[4] << 3) ^ (c[5] << 2) ^ (c[6] << 1) ^ (c[7] << 0) + +def gen_lookup(m, c): + table = [] + for i in range(256): + Imatrix = genericmatrix.GenericMatrix(size=(8, 1), zeroElement=0, identityElement=1, add=XOR, mul=AND, sub=XOR, div=DIV) + for j in range (8): + Imatrix.SetRow(j, [(i >> (7 - j)) & 1]) + tmp = m * Imatrix + table.append(matrix_col_byte(tmp.GetColumn(0)) ^ c) + return table + +def gen_lookup_low(m, c): + table = [] + for i in range(256): + Imatrix = genericmatrix.GenericMatrix(size=(8, 1), zeroElement=0, identityElement=1, add=XOR, mul=AND, sub=XOR, div=DIV) + for j in range (8): + if j < 4: + Imatrix.SetRow(j, [0]) + else: + Imatrix.SetRow(j, [(i >> (7 - j)) & 1]) + tmp = m * Imatrix + table.append(matrix_col_byte(tmp.GetColumn(0)) ^ c) + return table + +def gen_lookup_high(m, c): + table = [] + for i in range(256): + Imatrix = genericmatrix.GenericMatrix(size=(8, 1), zeroElement=0, identityElement=1, add=XOR, mul=AND, sub=XOR, div=DIV) + for j in range (8): + if j < 4: + Imatrix.SetRow(j, [(i >> (7 - j)) & 1]) + else: + Imatrix.SetRow(j, [0]) + tmp = m * Imatrix + table.append(matrix_col_byte(tmp.GetColumn(0)) ^ c) + return table + +def print_table(table): + for i, s in enumerate(table): + print(f'0x%02X'%s,',', end='') + if (i+1) % 16 == 0: + print() + +def print_high(table): + for i, s in enumerate(table): + if i % 16 == 0: + print(f'0x%02X'%s,',', end='') + print() + +def print_low(table): + for i, s in enumerate(table): + if i < 16: + print(f'0x%02X'%s,',', end='') + print() + +def to_matrix(x): + m = genericmatrix.GenericMatrix(size=(8,8), zeroElement=0, identityElement=1, add=XOR, mul=AND, sub=XOR, div=DIV) + for i in range(8): + m.SetRow(i, [(x[i] & 0x80) >> 7, (x[i] & 0x40) >> 6, (x[i] & 0x20) >> 5, (x[i] & 0x10) >> 4, (x[i] & 0x08) >> 3, (x[i] & 0x04) >> 2, (x[i] & 0x02) >> 1, (x[i] & 0x01) >> 0]) + return m + +def gen_intel_c(m, c): + Cmatrix = genCMatrix(0x63) + c1 = m*Cmatrix + return matrix_col_byte(c1.GetColumn(0)) ^ c + +Mmatrix = to_matrix([0x3a ,0xd4 ,0x1e ,0xad ,0xb2 ,0x99 ,0x1a ,0x3c]) +print('High') +print_high(gen_lookup_high(Mmatrix, 0x55)) +print() +print('Low for AMD64 wich use Cancel AES 0x63') +print_low(gen_lookup_low(Mmatrix, 0x00)) +print() +print('Low for ARM64') +print_low(gen_lookup_low(Mmatrix, 0x32^0x55)) +``` + +结果: +``` +High +0x55 ,0xBA ,0xCC ,0x23 ,0x15 ,0xFA ,0x8C ,0x63 ,0x09 ,0xE6 ,0x90 ,0x7F ,0x49 ,0xA6 ,0xD0 ,0x3F , + +Low for AMD64 wich use Cancel AES 0x63 +0x00 ,0x14 ,0xAA ,0xBE ,0x71 ,0x65 ,0xDB ,0xCF ,0xB7 ,0xA3 ,0x1D ,0x09 ,0xC6 ,0xD2 ,0x6C ,0x78 , + +Low for ARM64 +0x67 ,0x73 ,0xCD ,0xD9 ,0x16 ,0x02 ,0xBC ,0xA8 ,0xD0 ,0xC4 ,0x7A ,0x6E ,0xA1 ,0xB5 ,0x0B ,0x1F , +``` + +当然,ARM64的外层查找表也可以写成: +```python +Mmatrix = to_matrix([0x3a ,0xd4 ,0x1e ,0xad ,0xb2 ,0x99 ,0x1a ,0x3c]) +print('High') +print_high(gen_lookup_high(Mmatrix, 0x00)) +print() +print('Low for ARM64') +print_low(gen_lookup_low(Mmatrix, 0x32)) +``` + +结果: +``` +High +0x00 ,0xEF ,0x99 ,0x76 ,0x40 ,0xAF ,0xD9 ,0x36 ,0x5C ,0xB3 ,0xC5 ,0x2A ,0x1C ,0xF3 ,0x85 ,0x6A , + +Low for ARM64 +0x32 ,0x26 ,0x98 ,0x8C ,0x43 ,0x57 ,0xE9 ,0xFD ,0x85 ,0x91 ,0x2F ,0x3B ,0xF4 ,0xE0 ,0x5E ,0x4A , +``` + +内层查找表: +```python +Mmatrix = to_matrix([0x96 ,0x50 ,0x48 ,0xd4 ,0xe4 ,0xdc ,0x06 ,0x11]) +print('High') +print_high(gen_lookup_high(Mmatrix, 0x00)) +print() +print('Low') +print_low(gen_lookup_low(Mmatrix, 0x00)) +``` +结果: +``` +High +0x00 ,0xD5 ,0x08 ,0xDD ,0x7C ,0xA9 ,0x74 ,0xA1 ,0x9C ,0x49 ,0x94 ,0x41 ,0xE0 ,0x35 ,0xE8 ,0x3D , + +Low +0x00 ,0x01 ,0x82 ,0x83 ,0x9E ,0x9F ,0x1C ,0x1D ,0x24 ,0x25 ,0xA6 ,0xA7 ,0xBA ,0xBB ,0x38 ,0x39 , +``` ## 参考: 1. [zuc sbox with aesni](https://gist.github.com/emmansun/ae4677d71c75ff8407d5f5b3a884f5d2), This is the pure golang code to study ZUC implementation with AESENCLAST/AESE instruction.