III. Thuật Toán AES - Thực Hiện (Tiếp Theo)
7. Giai Đoạn MixColumns (Tiếp)
Bài tập của phần trước đã được giải thích. Các công thức tính toán cho phần tử ở cột j trong mỗi hàng có thể được đơn giản hóa như sau:
- S0,j′ = (0x02 * S0,j) ⊕ (0x03 * S1,j) ⊕ S2,j ⊕ S3,j
- S1,j′ = S0,j ⊕ (0x02 * S1,j) ⊕ (0x03 * S2,j) ⊕ S3,j
- S2,j′ = S0,j ⊕ S1,j ⊕ (0x02 * S2,j) ⊕ (0x03 * S3,j)
- S3,j′ = (0x03 * S0,j) ⊕ S1,j ⊕ S2,j ⊕ (0x02 * S3,j)
Ví dụ với state table:
Dựa theo công thức trên, chúng ta có:
S0,0′ = (0x02 * S0,0) ⊕ (0x03 * S1,0) ⊕ S2,0 ⊕ S3,0 = (0x02 * 0xC9) ⊕ (0x03 * 0x7A) ⊕ 0x63 ⊕ 0xB0.
Chúng ta tính toán các bước chi tiết để tìm ra giá trị cuối cùng của S0,0′.
Tiếp theo, chúng ta sẽ xem xét cách để thực hiện quá trình MixColumns trong lập trình. Đối với phép toán XOR (⊕), trong Python, bạn có thể sử dụng toán tử ^
để thực hiện. Việc chuyển thể công thức toán học sang ngôn ngữ lập trình rất quan trọng:
- Thực hiện phép nhân trong GF(2^8):
- (0000 0010) * (a7a6a5a4 a3a2a1a0) =
- Nếu a7 = 0: không thay đổi.
- Nếu a7 = 1: thêm phép XOR với 0001 1011 (hoặc
0x1B
).
- (0000 0010) * (a7a6a5a4 a3a2a1a0) =
Chúng ta định nghĩa hàm xtime()
như sau:
python
def xtime1(x):
if (x & 0x80):
return (((x << 1) ^ 0x1B) & 0xFF)
else:
return (x << 1)
Kiểm tra điều kiện 111 thông qua phép & với 0x80 và đảm bảo rằng kết quả vẫn nằm trong phạm vi 8 bit. Với a7 = 0, chúng ta chỉ cần dịch bit trái một lần.
Chúng ta cũng có thể sử dụng hàm nặc danh lambda:
python
xtime = lambda x: (((x << 1) ^ 0x1B) & 0xFF) if (x & 0x80) else (x << 1)
Từ đây, phép tính (0000 0011) * (a7a6a5a4 a3a2a1a0) có thể biểu diễn bằng: xtime(x) ^ x
.
Bây giờ, xét một cột bất kỳ trong state table trước khi thực hiện MixColumns, chúng ta có:
- a'0[0] = xtime(a[0]) ⊕ (xtime(a[1]) ⊕ a[1]) ⊕ a[2] ⊕ a[3]
- a'0[0] = xtime(a[0] ⊕ a[1]) ⊕ a[1] ⊕ a[2] ⊕ a[3]
Chúng ta cũng xây dựng hàm mix_single_column()
để thực hiện MixColumns cho một cột và hàm mix_columns()
cho toàn bộ state table:
python
def mix_single_column(a):
t = a[0] ^ a[1] ^ a[2] ^ a[3]
u = a[0]
a[0] ^= t ^ xtime(a[0] ^ a[1])
a[1] ^= t ^ xtime(a[1] ^ a[2])
a[2] ^= t ^ xtime(a[2] ^ a[3])
a[3] ^= t ^ xtime(a[3] ^ u)
def mix_columns(s):
for i in range(4):
mix_single_column(s[i])
Chúng ta cũng cần thực hiện InvMixColumns. Với quy tắc nhân ma trận và phép toán trong GF(2^8), chúng ta cần tìm ma trận X thỏa mãn một số phương trình. Sau đó, bằng cách sử dụng hàm MixColumns, chúng ta có thể đơn giản hóa các phép toán này.
Hàm inv_mix_columns()
có thể được triển khai như sau:
python
def inv_mix_columns(s):
for i in range(4):
u = xtime(xtime(s[i][0] ^ s[i][2]))
v = xtime(xtime(s[i][1] ^ s[i][3]))
s[i][0] ^= u
s[i][1] ^= v
s[i][2] ^= u
s[i][3] ^= v
mix_columns(s)
Tài Liệu Tham Khảo
- Wikipedia - Advanced Encryption Standard
- GeeksforGeeks - AES
- NIST FIPS Publication 197
- Joan Daemen Paper
source: viblo