Giá trị của di số shift(r,Nb) phụ thuộc vào chỉ số dòng r và kích thước Nb của khối và được thể hiện trong Phép biến đổi ngược của thao tác SubBytes, ký hiệu là InvSubBytes, sự dụng bảng thay thế nghịch đảo của S-box trên GF(28), ký hiệu là S-box-1. Quá trình thay thế 1 byte y dựa vào S-box-1 bao gồm hai bước sau: 1. Áp dụng phép biến đổi affine (trên GF(2)) sau đối với y
Chương Giá trị di số shift(r,Nb) phụ thuộc vào số dịng r kích thước Nb khối thể Bảng 3.1 InvShiftRows(byte state[4,Nb]) begin byte t[Nb] for r = to for c = to Nb - t[(c + h[r,Nb]) mod Nb] = state[r,c] end for for c = to Nb – state[r,c] = t[c] end for end for end 3.6.2 Phép biến đổi InvSubBytes Phép biến đổi ngược thao tác SubBytes, ký hiệu InvSubBytes, dụng bảng thay nghịch đảo S-box GF(28), ký hiệu S-box-1 Quá trình thay byte y dựa vào S-box-1 bao gồm hai bước sau: Áp dụng phép biến đổi affine (trên GF(2)) sau y (có biểu diễn nhị phân {y7 y y5 y y3 y y1 y } ): 64 Phương pháp mã hóa Rijndael ⎡ x ⎤ ⎡0 ⎢x ⎥ ⎢ ⎢ ⎥ ⎢1 ⎢ x ⎥ ⎢0 ⎢ ⎥ ⎢ ⎢ x3 ⎥ = ⎢1 ⎢ x ⎥ ⎢0 ⎢ ⎥ ⎢ ⎢ x ⎥ ⎢0 ⎢ x ⎥ ⎢1 ⎢ 6⎥ ⎢ ⎣⎢ x7 ⎦⎥ ⎣⎢0 0 1 ⎤ ⎡ y ⎤ ⎡1 ⎤ ⎢ ⎥ 0 0 0⎥⎥ ⎢ y1 ⎥ ⎢⎢0⎥⎥ 0 0 ⎥ ⎢ y ⎥ ⎢1 ⎥ ⎥⎢ ⎥ ⎢ ⎥ 0 0⎥ ⎢ y ⎥ ⎢0⎥ + 1 0 0⎥ ⎢ y ⎥ ⎢0⎥ ⎥⎢ ⎥ ⎢ ⎥ 1 0 ⎥ ⎢ y ⎥ ⎢0⎥ 0 1 0⎥ ⎢ y ⎥ ⎢0⎥ ⎥⎢ ⎥ ⎢ ⎥ 0 1 0⎦⎥ ⎣⎢ y ⎦⎥ ⎣⎢0⎦⎥ (3.27) hay xi = y (i + ) mod ⊕ y (i +5) mod ⊕ y ( i + 7) mod ⊕ d i , với di bit thứ i giá trị {05},0 ≤ i ≤ (3.28) Rõ ràng phép biến đổi affine ngược phép biến đổi affine bước S-box Gọi x phần tử thuộc GF(28) có biểu diễn nhị phân {x7 x6 x5 x4 x3 x2 x1 x0 } Xác định phần tử nghịch đảo x-1 ∈ GF(28) với quy ước {00}-1 = {00} InvSubBytes(byte state[4,Nb]) begin for r = to for c = to Nb - state[r,c] = InvSbox[state[r,c]] end for end for end 65 Chương Bảng D.2 thể bảng thay nghịch đảo sử dụng phép biến đổi InvSubBytes 3.6.3 Phép biến đổi InvMixColumns InvMixColumns biến đổi ngược phép biến đổi MixColumns Mỗi cột trạng thái hành xem đa thức s(x) bậc có hệ số thuộc GF(28) nhân với đa thức a-1(x) nghịch đảo đa thức a(x) (modulo M(x)) sử dụng phép biến đổi MixColumns a-1(x) = {0b}x3 + {0d}x2 + {09}x + {0e} (3.29) Phép nhân s ′( x) = a −1 ( x ) ⊗ s ( x) biểu diễn dạng ma trận: ⎡ s 0' ,c ⎤ ⎡0e ⎢ ' ⎥ ⎢ ⎢ s1,c ⎥ = ⎢09 ⎢ s ' ⎥ ⎢0d ⎢ 2' ,c ⎥ ⎢ ⎢⎣ s3,c ⎥⎦ ⎣0b 0b 0d 09⎤ ⎡ s0,c ⎤ ⎥⎢ ⎥ 0e 0b 0d ⎥ ⎢ s1,c ⎥ với ≤ c < Nb 09 0e 0b⎥ ⎢ s 2,c ⎥ ⎥⎢ ⎥ 0d 09 0e⎦ ⎣⎢ s3,c ⎦⎥ (3.30) Trong đoạn mã chương trình đây, hàm FFmul(x, y) thực phép nhân (trên trường GF(28)) hai phần tử x y với InvMixColumns(byte block[4,Nb]) begin byte t[4] for c = to Nb – for r = to t[r] = block[r,c] end for for r = to 66 Phương pháp mã hóa Rijndael block[r,c] = FFmul(0x0e, t[r]) xor FFmul(0x0b, t[(r + 1) mod 4]) xor FFmul(0x0d, t[(r + 2) mod 4]) xor FFmul(0x09, t[(r + 3) mod 4]) end for end for end 3.6.4 Quy trình giải mã tương đương Nhận xét: Phép biến đổi InvSubBytes thao tác giá trị byte riêng biệt trạng thái hành, phép biến đổi InvShiftRows thực thao tác di chuyển byte mà không làm thay đổi giá trị chúng Do đó, thứ tự hai phép biến đổi quy trình mã hóa đảo ngược Với phép biến đổi tuyến tính A bất kỳ, ta có A( x + k ) = A( x) + A(k ) Từ đó, suy InvMixColumns(state XOR Round Key)= InvMixColumns(state) XOR InvMixColumns(Round Key) Như vậy, thứ tự phép biến đổi InvMixColumns AddRoundKey quy trình giải mã đảo ngược với điều kiện từ (4 byte) bảng mã khóa mở rộng sử dụng giải mã phải biến đổi InvMixColumns Do chu kỳ mã hóa cuối khơng thực thao tác MixColumns nên không 67 Chương cần thực thao tác InvMixColumns mã khóa chu kỳ giải mã chu kỳ giải mã cuối Vậy, quy trình giải mã Rijndael thực theo với trình tự phép biến đổi ngược hồn tồn tương đương với quy trình mã hóa EqInvCipher(byte in[4*Nb], byte out[4*Nb], word dw[Nb*(Nr+1)]) begin byte state[4,Nb] state = in AddRoundKey(state, dw + Nr * Nb) for round = Nr - downto InvSubBytes(state) InvShiftRows(state) InvMixColumns(state) AddRoundKey(state, dw + round * Nb) end for InvSubBytes(state) InvShiftRows(state) AddRoundKey(state, dw) out = state end Trong quy trình trên, bảng mã khóa mở rộng dw xây dựng từ bảng mã khóa w cách áp dụng phép biến đổi InvMixColumns lên từ (4 byte) w, ngoại trừ Nb từ cuối w 68 Phương pháp mã hóa Rijndael for i = to (Nr + 1) * Nb – dw[i] = w[i] end for for rnd = to Nr – InvMixColumns(dw + rnd * Nb) end for 3.7 Các vấn đề cài đặt thuật toán Gọi a trạng thái bắt đầu chu kỳ mã hóa Gọi b, c, d, e trạng thái kết đầu sau thực phép biến đổi SubBytes, ShiftRows, MixColumns AddRoundKey chu kỳ xét Quy ước: trạng thái s ( s = a, b, c, d , e ), cột thứ j kí hiệu sj, phần tử dịng i cột j kí hiệu si, j Sau biến đổi SubBytes: ⎡b0, j ⎤ ⎡ S [a 0, j ]⎤ ⎢ b ⎥ ⎢ S[a ] ⎥ ⎢ 1, j ⎥ = ⎢ 1, j ⎥ ⎢b2, j ⎥ ⎢ S [a 2, j ]⎥ ⎥ ⎥ ⎢ ⎢ ⎣⎢b3, j ⎦⎥ ⎣⎢ S [a 3, j ]⎦⎥ (3.31) Sau biến đổi ShiftRows: b0, j ⎤ ⎡c 0, j ⎤ ⎡ ⎥ ⎢c ⎥ ⎢ b ⎢ 1, j ⎥ = ⎢ 1,( j + shift (1, Nb )) mod Nb ⎥ ⎢ c , j ⎥ ⎢ b ,( j + shift (2 , Nb )) mod Nb ⎥ ⎥ ⎥ ⎢ ⎢ ⎢⎣ c 3, j ⎥⎦ ⎢⎣ b3 ,( j + shift (3, Nb )) mod Nb ⎥⎦ (3.32) Sau biến đổi MixColumns: ⎡d 0, j ⎤ ⎡02 ⎢d ⎥ ⎢ ⎢ 1, j ⎥ = ⎢ 01 ⎢d 2, j ⎥ ⎢ 01 ⎢ ⎥ ⎢ ⎣⎢ d 3, j ⎦⎥ ⎣03 (3.33) 03 01 01⎤ ⎡c0, j ⎤ ⎢ ⎥ 02 03 01⎥⎥ ⎢ c1, j ⎥ 01 02 03⎥ ⎢c 2, j ⎥ ⎥ ⎥⎢ 01 01 02⎦ ⎣⎢c3, j ⎦⎥ 69 Chương Sau biến đổi AddRoundKey: ⎡e0, j ⎤ ⎡ d 0, j ⎤ ⎡ k 0, j ⎤ ⎢e ⎥ ⎢d ⎥ ⎢k ⎥ ⎢ 1, j ⎥ = ⎢ 1, j ⎥ ⊕ ⎢ 1, j ⎥ ⎢e , j ⎥ ⎢ d , j ⎥ ⎢ k , j ⎥ ⎥ ⎥ ⎢ ⎢ ⎥ ⎢ ⎢⎣e3, j ⎥⎦ ⎢⎣ d 3, j ⎥⎦ ⎢⎣ k 3, j ⎥⎦ (3.34) Kết hợp kết trung gian phép biến đổi chu kỳ với nhau, ta có: ⎡e0, j ⎤ ⎡02 ⎢e ⎥ ⎢ ⎢ 1, j ⎥ = ⎢ 01 ⎢e2, j ⎥ ⎢ 01 ⎢ ⎥ ⎢ ⎣⎢e3, j ⎦⎥ ⎣03 S [ a 0, j ] 03 01 01⎤ ⎡ ⎢S a ⎥ 02 03 01⎥ ⎢ 1,( j + shift (1, Nb ))mod Nb 01 02 03⎥ ⎢ S a 2,( j + shift (2, Nb ))mod Nb ⎥⎢ 01 01 02⎦ ⎣⎢ S a3,( j + shift (3, Nb )) mod Nb [ [ [ ⎤ ⎡ k 0, j ⎤ ⎥ ⎢k ⎥ ⎥ ⊕ ⎢ 1, j ⎥ ⎥ ⎢ k 2, j ⎥ ⎥ ⎥ ⎢ ⎦⎥ ⎣⎢ k 3, j ⎦⎥ ] ] ] (3.35) Ký hiệu j[r ] = ( j + shift (r , Nb )) mod Nb , biểu thức (3.35) viết lại sau: ⎡e0, j ⎤ ⎡02 ⎢e ⎥ ⎢ ⎢ 1, j ⎥ = ⎢ 01 ⎢e2, j ⎥ ⎢ 01 ⎢ ⎥ ⎢ ⎣⎢ e3, j ⎦⎥ ⎣ 03 ⎡ S [a0, j [0] ] ⎤ ⎥ ⎡ k0, j ⎤ 03 01 01⎤ ⎢ ⎢ S ⎡ a1, j [1] ⎤ ⎥ ⎢ ⎥ ⎥ ⎦ ⎥ ⎢ k1, j ⎥ 02 03 01⎥ ⎢ ⎣ ⊕ ⎢ 01 02 03⎥ S ⎡ a2, j [ 2] ⎤ ⎥ ⎢ k2, j ⎥ ⎦⎥ ⎢ ⎥ ⎥⎢ ⎣ 01 01 02 ⎦ ⎢ ⎥ ⎣⎢ k3, j ⎦⎥ ⎡ ⎤ ⎢⎣ S ⎣ a3, j [3] ⎦ ⎥⎦ (3.36) Khai triển phép nhân ma trận, ta có: ⎡ e0, j ⎤ ⎡ 02 ⎤ ⎡ 03⎤ ⎡ 01⎤ ⎡ 01⎤ ⎡ k0, j ⎤ ⎢e ⎥ ⎢ 01⎥ ⎢ 02 ⎥ ⎢ 03⎥ ⎢ 01⎥ ⎢ k ⎥ ⎢ 1, j ⎥ = S ⎡ a ⎢ ⎥ ⊕ S ⎡a ⎤ ⎢ ⎥ ⊕ S ⎡a ⎢ ⎥ ⊕ S ⎡a ⎢ ⎥ ⊕ ⎢ 1, j ⎥ ⎤ ⎤ ⎤ ⎣ 0, j [0] ⎦ ⎢ 01⎥ ⎣ 1, j[1] ⎦ ⎢ 01⎥ ⎣ 2, j[2] ⎦ ⎢ 02 ⎥ ⎣ 3, j[3] ⎦ ⎢ 03⎥ ⎢ k 2, j ⎥ ⎢ e2, j ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ ⎢⎣ e3, j ⎥⎦ ⎣ 03⎦ ⎣ 01⎦ ⎣ 01⎦ ⎣ 02⎦ ⎢⎣ k3, j ⎥⎦ (3.37) 70 Phương pháp mã hóa Rijndael Định nghĩa bảng tra cứu T0, T1, T2, T3 sau: ⎡ S [a ] • 02⎤ ⎡S[a ] • 03⎤ ⎢ S [a ] ⎥ ⎢ ⎥ ⎥ , T [a ] = ⎢S[a ] • 02⎥ , T0 [a ] = ⎢ ⎢ S [a ] ⎥ ⎢ S[a ] ⎥ ⎢ ⎥ ⎢ ⎥ ⎣ S [a ] • 03⎦ ⎣ S[a ] ⎦ ⎡ S [a ] ⎤ ⎡ S [a ] ⎤ ⎢ S [a ] • 03⎥ ⎢ ⎥ ⎥ , T [a ] = ⎢ S [a ] ⎥ T2 [a ] = ⎢ ⎢ S [a ] • 02⎥ ⎢ S [a ] • 03⎥ ⎢ ⎥ ⎢ ⎥ ⎣ S [a ] ⎦ ⎣ S [a ] • 02⎦ (3.38) Khi đó, biểu thức (3.38) viết lại sau: [ ] ⎛ ⎞ e j = ⎜ ⊕ Ti , j[i ] ⎟ ⊕ wround *Nb + j ⎝ i =0 ⎠ (3.39) với round số thứ tự chu kỳ xét Như vậy, cột ej trạng thái kết sau thực chu kỳ mã hóa xác định bốn phép toán XOR số nguyên 32 bit sử dụng bốn bảng tra cứu T0, T1, T2 T3 Công thức (3.39) áp dụng cho Nr-1 chu kì đầu Do chu kỳ cuối khơng thực phép biến đổi MixColumns nên cần xây dựng bảng tra cứu riêng cho chu kì này: ⎡ S [a ]⎤ ⎡ ⎤ ⎡ ⎤ ⎡ ⎤ ⎢ ⎥ ⎢ S [a ]⎥ ⎢ ⎥ ⎢ ⎥ ⎥ , U [a ] = ⎢ ⎥ , U [a ] = ⎢ ⎥ , U [a ] = ⎢ ⎥ U [a ] = ⎢ ⎢ ⎥ ⎢ ⎥ ⎢ S [a ]⎥ ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ ⎣ ⎦ ⎣ ⎦ ⎣ ⎦ ⎣ S [a ]⎦ (3.40) 71 Chương 3.7.1 Nhận xét Kỹ thuật sử dụng bảng tra cứu giúp cải thiện tốc độ mã hóa giải mã cách đáng kể Ngoài ra, kỹ thuật giúp chống lại phương pháp phá mã dựa thời gian mã hóa sử dụng bảng tra cứu, thời gian mã hóa liệu Kỹ thuật sử dụng quy trình mã hóa quy trình giải mã tương đương tương ứng bước thực hai quy trình Khi đó, dùng chung quy trình cho việc mã hóa giải mã sử dụng bảng tra khác Trên thực tế, bảng tra cứu lưu trữ sẵn xây dựng trực tiếp dựa bảng thay S-Box với thông tin khuôn dạng tương ứng Trên vi xử lý 32-bit, thao tác biến đổi sử dụng quy trình mã hóa tối ưu hóa cách sử dụng bốn bảng tra cứu, bảng có 256 phần tử với kích thước phần tử byte Với phần tử a ∈ GF(28), đặt: ⎡ S [a ] • 02⎤ ⎡S[a ] • 03⎤ ⎢ S [a ] ⎥ ⎢ ⎥ ⎥ , T [a ] = ⎢S[a ] • 02⎥ , T0 [a ] = ⎢ ⎢ S [a ] ⎥ ⎢ S[a ] ⎥ ⎢ ⎥ ⎢ ⎥ ⎣ S [a ] • 03⎦ ⎣ S[a ] ⎦ ⎡ S [a ] ⎤ ⎡ S [a ] ⎤ ⎢ S [a ] • 03⎥ ⎢ ⎥ ⎥ , T [a ] = ⎢ S [a ] ⎥ T2 [a ] = ⎢ ⎢ S [a ] • 02⎥ ⎢ S [a ] • 03⎥ ⎢ ⎥ ⎢ ⎥ ⎣ S [a ] ⎦ ⎣ S [a ] • 02⎦ 72 (3.41) Phương pháp mã hóa Rijndael Nhận xét: Ti[a] = RotWord(Ti-1[a]) với i = 1, 2,3 Ký hiệu RotWordi hàm xử lý gồm i lần thực hàm RotWord, ta có: Ti [a ] = RotWord i (T0 [a ]) (3.42) Như vậy, thay dùng kilobyte để lưu trữ sẵn bốn bảng, cần tốn kilobyte để lưu bảng đầu tiên, bảng cịn lại phát sinh lại sử dụng Các hạn chế nhớ thường khơng đặt ra, trừ số trường hợp applet hay servlet Khi đó, thay lưu trữ sẵn bảng tra cứu, cần lưu đoạn mã xử lý phát sinh lại bảng Lúc đó, cơng thức (3.39) trở thành: e j = k j ⊕ Ti [ a i , j [i ] ] = k j ⊕ RotWord i (T0 [ a i , j [i ] ]) 3.8 3 i=0 i =0 (3.43) Kết thử nghiệm Bảng 3.2 Tốc độ xử lý phương pháp Rijndael Kích thước (bit) Khóa 128 192 256 Khối 128 128 128 Pentium 200 MHz C++ 69.4 58.0 50.1 C 70.5 59.8 51.3 Tốc độ xử lý (Mbit/giây) Pentium II Pentium III 400 MHz 733 MHz C++ 138.0 116.2 101.2 C 141.5 119.7 101.5 C++ 252.9 212.9 185.5 C 259.2 219.3 186.1 Pentium IV 2.4 GHz C++ 863.0 726.5 633.5 C 884.7 748.3 634.9 Kết thử nghiệm thuật toán Rijndael ghi nhận máy Pentium 200 MHz (sử dụng hệ điều hành Microsoft Windows 98), máy Pentium II 400 MHz, Pentium III 733 MHz (sử dụng hệ điều hành Microsoft Windows 2000 Professional), Pentium IV 2,4GHz (sử dụng hệ điều hành Microsoft Windows XP Service Pack 2) 73 Chương hệ thống máy tính Thế giới giải pháp vét cạn khơng khả thi Tuy nhiên, với phát triển ngày nhanh công nghệ thông tin, hệ máy tính đời với lực tốc độ xử lý ngày cao, thuật tốn Rijndael bị cơng phá tương lai Khi đó, thông tin quan trọng vốn bảo mật phương pháp Rijndael cần phải mã hóa lại phương pháp mã hóa an tồn Vấn đề tái tổ chức liệu quan trọng tích lũy sau nhiều thập niên hồn tồn khơng đơn giản Điều dẫn đến yêu cầu mở rộng để nâng cao độ an tồn thuật tốn, chẳng hạn tăng kích thước khóa kích thước khối xử lý Các phiên mở rộng 256/384/512-bit phiên mở rộng 512/768/1024-bit thuật toán Rijndael trình bày chúng tơi xây dựng sở lý thuyết thuật toán nguyên thủy có khả xử lý khóa khối liệu lớn nhiều lần so với phiên gốc 4.2 Phiên mở rộng 256/384/512-bit Trong thuật toán mở rộng 256/384/512-bit phương pháp Rijndael, từ gồm có Nw=8 byte Mỗi trạng thái biểu diễn dạng ma trận gồm dòng Nb cột với Nb với độ dài khối chia cho 64 Khóa biểu diễn dạng ma trận gồm dòng Nk cột với Nk với độ dài khóa chia cho 64 Ma trận biểu diễn trạng thái hay khóa khảo sát dạng mảng chiều từ (Nw byte), phần tử tương ứng với cột ma trận Số lượng chu kỳ, ký hiệu Nr, có giá trị Nr = max{Nb, Nk}+ 78 (4.1) Phương pháp Rijndael mở rộng 4.2.1 Quy trình mã hóa Trong quy trình mã hóa sử dụng phép biến đổi trình bày thuật tốn mã hóa Rijndael bản: AddRoundKey: cộng ( ⊕ ) mã khóa chu kỳ vào trạng thái hành Độ dài mã khóa chu kỳ với kích thước trạng thái SubBytes: thay phi tuyến byte trạng thái hành thông qua bảng thay (S-box) MixColumns: trộn thông tin cột trạng thái hành Mỗi cột xử lý độc lập ShiftRows: dịch chuyển xoay vòng dòng trạng thái hành với di số khác Mỗi phép biến đổi thao tác trạng thái hành S Kết S’ phép biến đổi trở thành đầu vào phép biến đổi quy trình mã hóa Trước tiên, tồn liệu đầu vào chép vào mảng trạng thái hành Sau thực thao tác cộng mã khóa đầu tiên, mảng trạng thái trải qua Nr = 10, 12 hay 14 chu kỳ biến đổi (tùy thuộc vào độ dài mã khóa độ dài khối xử lý) Nr − chu kỳ chu kỳ biến đổi bình thường hoàn toàn tương tự nhau, riêng chu kỳ biến đổi cuối có khác biệt so với Nr − chu kỳ trước Cuối cùng, nội dung mảng trạng thái chép lại vào mảng chứa liệu đầu 79 Chương Hình 4.1 thể kiến trúc chu kỳ biến đổi thuật toán Rijndael mở rộng 256/384/512-bit với Nb = Quy trình mã hóa Rijndael mở rộng tóm tắt lại sau: Thực thao tác AddRoundKey trước thực chu kỳ mã hóa Nr–1 chu kỳ mã hóa bình thường: chu kỳ bao gồm bước biến đổi liên tiếp nhau: SubBytes, ShiftRows, MixColumns, AddRoundKey Thực chu kỳ mã hóa cuối cùng: chu kỳ thao tác MixColumns bỏ qua Hình 4.1 Kiến trúc chu kỳ biến đổi thuật toán Rijndael mở rộng 256/384/512-bit với Nb = Trong thuật toán đây, mảng w[] chứa bảng mã khóa mở rộng; mảng in[] out[] chứa liệu vào kết thuật tốn mã hóa 80 Phương pháp Rijndael mở rộng Cipher(byte in[8 * Nb], byte out[8 * Nb], word w[Nb * (Nr + 1)]) begin byte state[8,Nb] state = in AddRoundKey(state, w) // Xem phần 4.2.1.4 for round = to Nr – SubBytes(state) // Xem phần 4.2.1.1 ShiftRows(state) // Xem phần 4.2.1.2 MixColumns(state) // Xem phần 4.2.1.3 AddRoundKey(state, w + round * Nb) end for SubBytes(state) ShiftRows(state) AddRoundKey(state, w + Nr * Nb) out = state end 4.2.1.1 Phép biến đổi SubBytes Thao tác biến đổi SubBytes phép thay byte phi tuyến tác động cách độc lập lên byte trạng thái hành Bảng thay (S-box) có tính khả nghịch q trình thay byte x dựa vào S-box bao gồm hai bước: Xác định phần tử nghịch đảo x−1 ∈ GF(28) Quy ước {00}−1 = {00} 81 Chương Áp dụng phép biến đổi affine (trên GF(2)) x−1 (giả sử x−1 có biểu diễn nhị phân {x7 x6 x5 x4 x3 x2 x1 x0 } ): yi = xi ⊕ x(i +4) mod ⊕ x(i +5) mod ⊕ x(i +6) mod ⊕ x (i +7) mod ⊕ ci (4.2) với ci bit thứ i {63}, ≤ i ≤ Phép biến đổi SubBytes thể dạng mã giả: SubBytes(byte state[8,Nb]) begin for r = to for c = to Nb - state[r,c] = Sbox[state[r,c]] end for end for end Bảng D.2 thể bảng thay nghịch đảo sử dụng phép biến đổi SubBytes 4.2.1.2 Phép biến đổi ShiftRows Trong thao tác biến đổi ShiftRows, dòng trạng thái hành dịch chuyển xoay vòng với độ dời khác Byte Sr,c dòng r cột c dịch chuyển đến cột (c - shift(r, Nb)) mod Nb hay: s r' ,c = s r ,(c + shift (r , Nb )) mod Nb với < r < ≤ c < Nb (4.3) shift (r , Nb ) = r mod Nb (4.4) với 82 Phương pháp Rijndael mở rộng Phép biến đổi ShiftRows thể dạng mã giả: ShiftRows(byte state[8,Nb]) begin byte t[Nb] for r = to for c = to Nb - t[c] = state[r, (c + shift[r,Nb]) mod Nb] end for for c = to Nb – state[r,c] = t[c] end for end for end 4.2.1.3 Phép biến đổi MixColumns Trong thao tác biến đổi MixColumns, cột trạng thái hành biểu diễn dạng đa thức s(x) có hệ số GF(28) Thực phép nhân: s ' ( x ) = a ( x ) ⊗ s ( x ) với a(x ) = ∑a x i i , a i ∈ GF(28) (4.5) i =0 Đặt ⎡α ⎢α ⎢ ⎢α ⎢ α Ma = ⎢ ⎢α ⎢ ⎢α ⎢α ⎢ ⎢⎣α α7 α0 α1 α2 α3 α4 α5 α6 α6 α7 α0 α1 α2 α3 α4 α5 α5 α6 α7 α0 α1 α2 α3 α4 α4 α5 α6 α7 α0 α1 α2 α3 α3 α4 α5 α6 α7 α0 α1 α2 α2 α3 α4 α5 α6 α7 α0 α1 α1 ⎤ α ⎥⎥ α3 ⎥ ⎥ α4 ⎥ α5 ⎥ ⎥ α6 ⎥ α7 ⎥ ⎥ α ⎥⎦ (4.6) 83 Chương Ta có: ⎡ s ' 0, c ⎤ ⎡ s 0, c ⎤ ⎢ ⎥ ⎢ ⎥ ⎢ s '1,c ⎥ ⎢ s1,c ⎥ ⎢ s ' 2, c ⎥ ⎢ s ,c ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ s ' 3,c ⎥ = M ⎢ s 3,c ⎥ , 0≤ c≤ Nb a⎢ ⎢s' ⎥ s ⎥ ⎢ 4, c ⎥ ⎢ ,c ⎥ ⎢ s ' ,c ⎥ ⎢ s 5, c ⎥ ⎢s' ⎥ ⎢s ⎥ ⎢ 6, c ⎥ ⎢ 6, c ⎥ ⎢⎣ s ' 7,c ⎥⎦ ⎢⎣ s 7,c ⎥⎦ (4.7) Chúng ta có nhiều khả chọn lựa đa thức a(x) khác mà đảm bảo tính hiệu độ an tồn thuật tốn Để đảm bảo tính chất an tồn mình, hệ số ma trận phải thỏa tính chất sau: Khả nghịch Tuyến tính GF(2) Các phần tử ma trận (các hệ số) có giá trị nhỏ tốt Khả chống lại cơng thuật tốn (xem 4.4 - Phân tích mật mã vi phân phân tích mật mã tuyến tính) Đoạn mã chương trình thể thao tác biến đổi MixColumns với đa thức trình bày cơng thức (2.6) Trong đoạn chương trình này, hàm FFmul(x,y) thực phép nhân (trên trường GF(2 )) hai phần tử x y với 84 Phương pháp Rijndael mở rộng MixColumns(byte state[8, Nb]) begin byte t[8] for c = to Nb – for r = to t[r] = state[r,c] end for for r = to state[r,c] = FFmul(0x01, t[r]) xor FFmul(0x05, t[(r + 1) mod 8]) xor FFmul(0x03, t[(r + 2) mod 8]) xor FFmul(0x05, t[(r + 3) mod 8]) xor FFmul(0x04, t[(r + 4) mod 8]) xor FFmul(0x03, t[(r + 5) mod 8]) xor FFmul(0x02, t[(r + 6) mod 8]) xor FFmul(0x02, t[(r + 7) mod 8]) xor end for end for end 4.2.1.4 Thao tác AddRoundKey Mã khóa chu kỳ biểu diễn ma trận gồm dòng Nb cột Mỗi cột trạng thái hành XOR với cột tương ứng mã khóa chu kỳ xét: [ s ' 0,c , s '1,c , s ' 2,c , s '3,c , s ' 4,c , s '5,c , s ' 6,c , s ' 7,c ] = [ s 0,c , s1,c , s 2,c , s3,c , s 4,c , s5,c , s 6,c , s 7,c ] ⊕ [ wround ∗ Nb +c ] với ≤ c < Nb, (4.8) 85 Chương Nhận xét: Thao tác biến đổi ngược AddRoundKey thao tác AddRoundKey Trong đoạn chương trình đây, hàm xbyte(r, w) thực việc lấy byte thứ r từ w AddRoundKey(byte state[8,Nb], word rk[]) // rk = w + round * Nb begin for c = to Nb – for r = to state[r,c] = state[r,c] xor xbyte(r, rk[c]) end for end for end 4.2.2 Phát sinh khóa chu kỳ Quy trình phát sinh khóa cho chu kỳ bao gồm hai giai đoạn: Mở rộng khóa thành bảng mã khóa mở rộng, Chọn khóa cho chu kỳ từ bảng mã khóa mở rộng 4.2.2.1 Xây dựng bảng khóa mở rộng Bảng khóa mở rộng mảng chiều chứa từ (có độ dài byte), ký hiệu w[Nb*(Nr + 1)] Hàm phát sinh bảng khóa mở rộng phụ thuộc vào giá trị Nk, tức phụ thuộc vào độ dài mã khóa 86 Phương pháp Rijndael mở rộng Hàm SubWord(W) thay (sử dụng S-box) byte thành phần từ (có độ dài byte) Hàm RotWord(W) thực việc dịch chuyển xoay vòng byte thành phần (b0, b1, b 2, b 3, b 4, b 5, b 6, b7) từ đưa vào Kết trả hàm RotWord từ gồm byte thành phần (b1, b 2, b 3, b 4, b 5, b 6, b7, b0) KeyExpansion(byte key[8 * Nk], word w[Nb * (Nr + 1)], Nk) begin i = while (i < Nk) w[i]=word[ key[8*i] , key[8*i+1], key[8*i+2], key[8*i+3], key[8*i+4], key[8*i+5], key[8*i+6], key[8*i+7]] i = i + end while i = Nk while (i < Nb * (Nr + 1)) word temp = w[i - 1] if (i mod Nk = 0) then temp = SubWord(RotWord(temp)) xor Rcon[i / Nk] else if ((Nk = 8) and (i mod Nk = 4)) then temp = SubWord(temp) end if end if w[i] = w[i - Nk] xor temp i = i + end while end Các số chu kỳ hoàn toàn độc lập với giá trị Nk xác định Rcon[i] = (xi−1, 0, 0, 0, 0, 0, 0, 0), i ≥ 87 Chương 4.2.2.2 Xác định khóa chu kỳ Mã khóa chu kỳ thứ i xác định bao gồm từ (8 byte) có số từ Nb * i đến Nb * (i + 1) − bảng mã khóa mở rộng Như vậy, mã khóa chu kỳ thứ i bao gồm phần tử w[ Nb * i ] , w[ Nb * i + 1] , …, w[ Nb * (i + 1) − 1] w0 w1 w2 w3 w4 w5 w6 w7 w8 w9 w10 w11 w12 w13 w14 w15 w16 w17 Mã khóa chu kỳ Mã khóa chu kỳ Mã khó a chu kỳ Hình 4.2 Bảng mã khóa mở rộng cách xác định mã khóa chu kỳ (với Nb = Nk = 4) 4.2.3 Quy trình giải mã Quy trình giải mã thực qua giai đoạn sau: Thực thao tác AddRoundKey trước thực chu kỳ giải mã Nr – chu kỳ giải mã bình thường: chu kỳ bao gồm bốn bước biến đổi liên tiếp nhau: InvShiftRows, InvSubBytes, AddRoundKey, InvMixColumns Thực chu kỳ giải mã cuối Trong chu kỳ này, InvMixColumns bỏ qua 88 thao tác Phương pháp Rijndael mở rộng InvCipher( byte in[8 * Nb], byte out[8 * Nb], word w[Nb * (Nr + 1)]) begin byte state[8,Nb] state = in AddRoundKey(state, w + Nr * Nb) // Xem phần for round = Nr - downto InvShiftRows(state) // Xem phần 4.2.3.1 InvSubBytes(state) // Xem phần AddRoundKey(state, w + round * Nb) InvMixColumns(state) // Xem phần end for InvShiftRows(state) InvSubBytes(state) AddRoundKey(state, w) out = state end 4.2.3.1 Phép biến đổi InvShiftRows InvShiftRows biến đổi ngược biến đổi ShiftRows Mỗi dòng trạng thái dịch chuyển xoay vòng theo chiều ngược với biến đổi ShiftRows với độ dời Nb–shift (r, Nb) khác Các byte cuối dòng đưa vòng lên đầu dịng byte cịn lại có khuynh hướng di chuyển cuối dòng s r' ,(c + shift ( r , Nb)) mod Nb = s r ,c với < r < ≤ c < Nb (4.9) 89 Chương InvShiftRows(byte state[8,Nb]) begin byte t[Nb] for r = to for c = to Nb - t[(c + shift[r,Nb]) mod Nb] = state[r,c] end for for c = to Nb – state[r,c] = t[c] end for end for end 4.2.3.2 Phép biến đổi InvSubBytes Phép biến đổi ngược thao tác SubBytes, ký hiệu InvSubBytes, sử dụng bảng thay nghịch đảo S-box GF(28) ký hiệu S-box-1 Quá trình thay byte y dựa vào S-box-1 bao gồm hai bước sau: Áp dụng phép biến đổi affine (trên GF(2)) sau y (có biểu diễn nhị phân {y y y5 y y3 y y1 y } ): xi = y (i + ) mod ⊕ y (i +5) mod ⊕ y ( i + 7) mod ⊕ d i , với di bit thứ i giá trị {05},0 ≤ i ≤ (4.10) Đây phép biến đổi affine ngược phép biến đổi affine bước S-box 90 Phương pháp Rijndael mở rộng Gọi x phần tử thuộc GF(28) có biểu diễn nhị phân {x7 x6 x5 x4 x3 x2 x1 x0 } Xác định phần tử nghịch đảo x-1 ∈ GF(28) với quy ước {00}-1 = {00} Bảng D.2 thể bảng thay nghịch đảo sử dụng phép biến đổi InvSubBytes InvSubBytes(byte state[8,Nb]) begin for r = to for c = to Nb - state[r,c] = InvSbox[state[r,c]] end for end for end 4.2.3.3 Phép biến đổi InvMixColumns InvMixColumns biến đổi ngược phép biến đổi MixColumns Mỗi cột trạng thái hành xem đa thức s(x) bậc có hệ số thuộc GF(28) nhân với đa thức a−1(x) nghịch đảo đa thức a(x) (modulo M ( x ) = x + ) sử dụng phép biến đổi MixColumns Với a(x) = {05}x7 + {03}x6 + {05}x5 + {04}x4+ {03}x3 + {02}x2 + {02}x + {01} (4.11) ta có: a-1(x) = {b3}x7 + {39}x6 + {9a}x5 + {a1}x4+ {db}x3 + {54}x2 + {46}x + {2a} (4.12) 91 Chương −1 Phép nhân s′( x) = a ( x) ⊗ s( x) biểu diễn dạng ma trận sau: ⎡ s ' 0, c ⎤ ⎡ s 0, c ⎤ ⎢ ⎥ ⎢ ⎥ ⎢ s '1,c ⎥ ⎢ s1,c ⎥ ⎢ s ' 2, c ⎥ ⎢ s 2, c ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ s ' 3,c ⎥ = M ⎢ s 3,c ⎥ , 0≤ c≤ Nb −1 a ⎢s ⎢s' ⎥ ⎥ ⎢ 4, c ⎥ ⎢ 4, c ⎥ ⎢ s ' ,c ⎥ ⎢ s 5, c ⎥ ⎢s' ⎥ ⎢s ⎥ ⎢ 6, c ⎥ ⎢ 6, c ⎥ ⎢⎣ s ' 7,c ⎥⎦ ⎢⎣ s 7,c ⎥⎦ (4.13) Đoạn chương trình sau thể thao tác InvMixColumns sử dụng đa thức a-1(x) công thức (4.12) InvMixColumns(byte block[8,Nb]) begin byte t[8] for c = to Nb – for r = to t[r] = block[r,c] end for for r = to block[r,c] = FFmul(0x2a, t[r]) xor FFmul(0xb3, t[(r + 1) mod 8]) xor FFmul(0x39, t[(r + 2) mod 8]) xor FFmul(0x9a, t[(r + 3) mod 8]) xor FFmul(0xa1, t[(r + 4) mod 8]) xor FFmul(0xdb, t[(r + 5) mod 8]) xor FFmul(0x54, t[(r + 6) mod 8]) xor 92 ... II Pentium III 400 MHz 733 MHz C++ 138 .0 116 .2 101 .2 C 141.5 119.7 101.5 C++ 25 2.9 21 2.9 185.5 C 25 9 .2 219 .3 186.1 Pentium IV 2. 4 GHz C++ 8 63. 0 726 .5 633 .5 C 884.7 748 .3 634 .9 Kết thử nghiệm thuật... 02 ⎥ ⎣ 3, j [3] ⎦ ⎢ 03? ?? ⎢ k 2, j ⎥ ⎢ e2, j ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ ⎢⎣ e3, j ⎥⎦ ⎣ 03? ?? ⎣ 01⎦ ⎣ 01⎦ ⎣ 02? ?? ⎢⎣ k3, j ⎥⎦ (3. 37) 70 Phương pháp mã hóa Rijndael Định nghĩa bảng tra cứu T0, T1, T2, T3... w1 w2 w3 w4 w5 w6 w7 w8 w9 w10 w11 w 12 w 13 w14 w15 w16 w17 Mã khóa chu kỳ Mã khóa chu kỳ Mã khó a chu kỳ Hình 4 .2 Bảng mã khóa mở rộng cách xác định mã khóa chu kỳ (với Nb = Nk = 4) 4 .2. 3 Quy