III. Thuật toán AES - thực hiện (tiếp)
7. MixColumns (tiếp)
Giải đáp bài tập phần trước: Công thức tính phần tử ở cột trong mỗi hàng lúc này có thể rút gọn lại thành:
Ví dụ, với state table:
Dựa theo công thức trên chúng ta có:
Tương tự chúng ta tính được state table mới:
Tiếp theo chúng ta cùng phân tích cách thực hiện quá trình MixColumns trong lập trình. Đối với phép toán có thể dễ dàng thực hiện bằng toán tử ^
trong Python. Có thể thấy việc biểu diễn phép toán sau qua ngôn ngữ lập trình đóng vai trò then chốt:
Đặt đại diện cho tham số truyền vào. Để ý một chút, chúng ta có hai trường hợp:
- : Loại bỏ bit và bổ sung vào bên phải bit đối với .
- . Loại bỏ bit và bổ sung vào bên phải bit đối với rồi mang kết quả thực hiện phép toán với (hay
0x1B
).
(Bạn đọc cần lưu ý giá trị KHÔNG PHẢI là kết quả của phép dịch trái một bit, do dịch trái một bit chúng ta thu được kết quả )
Định nghĩa hàm xtime()
như sau:
def xtime1(x): if (x & 0x80): return (((x << 1) ^ 0x1B) & 0xFF) else: return (x << 1)
Kiểm tra điều kiện trường hợp bằng cách thực hiện phép &
với số 0x80
(1000 0000
), phép toán &
với số 0xFF
(1111 1111
) nhằm đảm bảo kết quả trong phạm vi bit (Do x << 1
đã tăng số lượng bit lên một). Đối với trường hợp còn lại chúng ta chỉ cần thực hiện phép dịch bit sang trái một đơn vị bởi bit đầu tiên sẽ không ảnh hưởng đến kết quả.
Ngoài ra, do đây là một hàm đơn giản nên các bạn cũng có thể sử dụng hàm nặc danh lambda định nghĩa:
xtime = lambda x: (((x << 1) ^ 0x1B) & 0xFF) if (x & 0x80) else (x << 1)
Từ đây, phép tính có thể biểu diễn thành: xtime(x) ^ x
Xét a
là một cột bất kỳ của state table trước khi tiến hành MixColumns, dựa vào công thức:
Chúng ta có:
Với . Từ đó biểu diễn bằng ngôn ngữ Python có: a[0] ^= t ^ xtime(a[0] ^ a[1])
Tương tự biến đổi như trên, xây dựng được hàm mix_single_column()
thực hiện MixColumns cho một cột bất kỳ và hàm mix_columns()
thực hiện cho toàn bộ state table có dạng:
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])
Cần sử dụng thêm biến u = a[0]
để bước tính a[3]
không bị ảnh hưởng bởi giá trị của a[0]
đã thay đổi.
Tiếp theo chúng ta cần giải quyết vấn đề InvMixColumns. Dựa theo quy tắc "nhân" ma trận với các phép toán được quy ước trong GF(2^8), xét các phép tính đặc biệt sau:
Biểu diễn dạng ma trận:
\left[\begin{array}\\ 0x01 & 0x00 & 0x00 & 0x00\\ 0x00 & 0x01 & 0x00 & 0x00\\ 0x00 & 0x00 & 0x01 & 0x00\\ 0x00 & 0x00 & 0x00 & 0x01\\ \end{array}\right] \left[\begin{array}\\ S_{0,0} & S_{0,1} & S_{0,2} & S_{0,3}\\ S_{1,0} & S_{1,1} & S_{1,2} & S_{1,3}\\ S_{2,0} & S_{2,1} & S_{2,2} & S_{2,3}\\ S_{3,0} & S_{3,1} & S_{3,2} & S_{3,3}\\ \end{array}\right] \ =\ \left[\begin{array}\\ S_{0,0} & S_{0,1} & S_{0,2} & S_{0,3}\\ S_{1,0} & S_{1,1} & S_{1,2} & S_{1,3}\\ S_{2,0} & S_{2,1} & S_{2,2} & S_{2,3}\\ S_{3,0} & S_{3,1} & S_{3,2} & S_{3,3}\\ \end{array}\right]Như vậy, nếu ta có thể tìm được một ma trận thỏa mãn phương trình ma trận X:
\left[\begin{array}\\ X_{0,0} & X_{0,1} & X_{0,2} & X_{0,3}\\ X_{1,0} & X_{1,1} & X_{1,2} & X_{1,3}\\ X_{2,0} & X_{2,1} & X_{2,2} & X_{2,3}\\ X_{3,0} & X_{3,1} & X_{3,2} & X_{3,3}\\ \end{array}\right] \left[\begin{array}\\ 0x02 & 0x03 & 0x01 & 0x01\\ 0x01 & 0x02 & 0x03 & 0x01\\ 0x01 & 0x01 & 0x02 & 0x03\\ 0x03 & 0x01 & 0x01 & 0x02\\ \end{array}\right] \ =\ \left[\begin{array}\\ 0x01 & 0x00 & 0x00 & 0x00\\ 0x00 & 0x01 & 0x00 & 0x00\\ 0x00 & 0x00 & 0x01 & 0x00\\ 0x00 & 0x00 & 0x00 & 0x01\\ \end{array}\right]Thì ta có thể biến đổi:
\left[\begin{array}\\ X_{0,0} & X_{0,1} & X_{0,2} & X_{0,3}\\ X_{1,0} & X_{1,1} & X_{1,2} & X_{1,3}\\ X_{2,0} & X_{2,1} & X_{2,2} & X_{2,3}\\ X_{3,0} & X_{3,1} & X_{3,2} & X_{3,3}\\ \end{array}\right] \left[\begin{array}\\ S'_{0,0} & S'_{0,1} & S'_{0,2} & S'_{0,3}\\ S'_{1,0} & S'_{1,1} & S'_{1,2} & S'_{1,3}\\ S'_{2,0} & S'_{2,1} & S'_{2,2} & S'_{2,3}\\ S'_{3,0} & S'_{3,1} & S'_{3,2} & S'_{3,3}\\ \end{array}\right] \ = \left[\begin{array}\\ X_{0,0} & X_{0,1} & X_{0,2} & X_{0,3}\\ X_{1,0} & X_{1,1} & X_{1,2} & X_{1,3}\\ X_{2,0} & X_{2,1} & X_{2,2} & X_{2,3}\\ X_{3,0} & X_{3,1} & X_{3,2} & X_{3,3}\\ \end{array}\right] \left[\begin{array}\\ 0x02 & 0x03 & 0x01 & 0x01\\ 0x01 & 0x02 & 0x03 & 0x01\\ 0x01 & 0x01 & 0x02 & 0x03\\ 0x03 & 0x01 & 0x01 & 0x02\\ \end{array}\right] \left[\begin{array}\\ S_{0,0} & S_{0,1} & S_{0,2} & S_{0,3}\\ S_{1,0} & S_{1,1} & S_{1,2} & S_{1,3}\\ S_{2,0} & S_{2,1} & S_{2,2} & S_{2,3}\\ S_{3,0} & S_{3,1} & S_{3,2} & S_{3,3}\\ \end{array}\right] \ = \left[\begin{array}\\ 0x01 & 0x00 & 0x00 & 0x00\\ 0x00 & 0x01 & 0x00 & 0x00\\ 0x00 & 0x00 & 0x01 & 0x00\\ 0x00 & 0x00 & 0x00 & 0x01\\ \end{array}\right] \left[\begin{array}\\ S_{0,0} & S_{0,1} & S_{0,2} & S_{0,3}\\ S_{1,0} & S_{1,1} & S_{1,2} & S_{1,3}\\ S_{2,0} & S_{2,1} & S_{2,2} & S_{2,3}\\ S_{3,0} & S_{3,1} & S_{3,2} & S_{3,3}\\ \end{array}\right] \ = \left[\begin{array}\\ S_{0,0} & S_{0,1} & S_{0,2} & S_{0,3}\\ S_{1,0} & S_{1,1} & S_{1,2} & S_{1,3}\\ S_{2,0} & S_{2,1} & S_{2,2} & S_{2,3}\\ S_{3,0} & S_{3,1} & S_{3,2} & S_{3,3}\\ \end{array}\right]Giải phương trình ma trận X chúng ta thu được kết quả:
\left[\begin{array}\\ 0x0E & 0x0B & 0x0D & 0x09\\ 0x09 & 0x0E & 0x0B & 0x0D\\ 0x0D & 0x09 & 0x0E & 0x0B\\ 0x0B & 0x0D & 0x09 & 0x0E\\ \end{array}\right]Do thực hiện phép tính với ma trận khá phức tạp nên chúng ta có thể tận dụng hàm MixColumns bằng cách biến đổi:
\left[\begin{array}\\ 0x0E & 0x0B & 0x0D & 0x09\\ 0x09 & 0x0E & 0x0B & 0x0D\\ 0x0D & 0x09 & 0x0E & 0x0B\\ 0x0B & 0x0D & 0x09 & 0x0E\\ \end{array}\right] \ = \left[\begin{array}\\ 0x02 & 0x03 & 0x01 & 0x01\\ 0x01 & 0x02 & 0x03 & 0x01\\ 0x01 & 0x01 & 0x02 & 0x03\\ 0x03 & 0x01 & 0x01 & 0x02\\ \end{array}\right] \left[\begin{array}\\ 0x05 & 0x00 & 0x04 & 0x00\\ 0x00 & 0x05 & 0x00 & 0x04\\ 0x04 & 0x00 & 0x05 & 0x00\\ 0x00 & 0x04 & 0x00 & 0x05\\ \end{array}\right]Như vậy, công việc trở nên đơn giản hơn là lập trình phép tính ma trận dưới, sau đó thực hiện hàm MixColumns trước đó:
\left[\begin{array}\\ 0x05 & 0x00 & 0x04 & 0x00\\ 0x00 & 0x05 & 0x00 & 0x04\\ 0x04 & 0x00 & 0x05 & 0x00\\ 0x00 & 0x04 & 0x00 & 0x05\\ \end{array}\right] \left[\begin{array}\\ S'_{0,0} & S'_{0,1} & S'_{0,2} & S'_{0,3}\\ S'_{1,0} & S'_{1,1} & S'_{1,2} & S'_{1,3}\\ S'_{2,0} & S'_{2,1} & S'_{2,2} & S'_{2,3}\\ S'_{3,0} & S'_{3,1} & S'_{3,2} & S'_{3,3}\\ \end{array}\right]Bạn đọc có thể tham khảo hàm inv_mix_columns()
dưới đây và đường dẫn thực hiện https://cs.ru.nl/~joan/papers/JDA_VRI_Rijndael_2002.pdf mục
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)