• Integrated Circuit Design - Chia sẻ kiến thức về vi mạch

    Vi mạch và Ứng dụng

  • Integrated Circuit Design - Chia sẻ kiến thức về vi mạch

    Vi mạch và Ứng dụng

  • Integrated Circuit Design - Chia sẻ kiến thức về vi mạch

    Vi mạch và Ứng dụng

Hiển thị các bài đăng có nhãn DES. Hiển thị tất cả bài đăng
Hiển thị các bài đăng có nhãn DES. Hiển thị tất cả bài đăng

Chủ Nhật, 27 tháng 8, 2017

[IP core] Lõi IP mã hóa giải mã DES

Bài viết phân tích và mô tả một thiết kế lõi IP thực hiện mã hóa và giải mã DES. Đầu tiên, chi tiết về bộ mã hóa sẽ được phân tích. Sau đó, những điểm khác biệt của bộ giải mã sẽ được phân tích để tích hợp bộ mã hóa để tạo ra một thiết kế đầy đủ chức năng mã hóa và giải mã DES. Thiết kế có thể được hiện thực trên FPGA hoặc ASIC.


Để hiểu rõ, các bạn hãy đọc từng bước được mô tả trong bài trên và so sánh với từng bước được phân tích trong bài này.

1. Lõi mã hóa DES
2.1 Sơ đồ tín hiệu
Hình 1. Tín hiệu giao tiếp của bộ mã hóa DES
Hình 2. Mô tả các tín hiệu giao tiếp của lõi mã hóa DES
Chú ý: Trong chuẩn DES, việc đánh số thứ tự của chuỗi bit được thực hiện từ trái qua phải. Một tín hiệu được khai báo theo thứ tự từ MSB đến LSB nên trong phần thiết kế, giá trị các bảng hoán vị được thay đổi lại theo thứ tự bit này.Ví dụ: một tín hiệu được khai báo [63:0] thì bit 1 trong chuẩn DES ứng với bit 63, bit 2 ứng trong chuẩn mã hóa ứng với bit 62, ... và bit 64 trong chuẩn DES ứng với bit 0.
Các bạn cần lưu ý kỹ điều này trước khi đọc tiếp những phần mô tả dưới đây.

2.2 Mạch tính toán khóa vòng - KS
Mạch sử dụng 2 thanh ghi để lưu lại giá trị Cn và Dn sau mỗi lần tính toán.

2.2.1 Tính hoán vị PC-1
Hoán vị thực chất là thay đổi trật tự sắp xếp các bit theo quy định của chuẩn. Như đã lưu ý, trong hoán vị PC-1 sau đây, tại bảng tạo ra c0, vị trí ô MSB là bit des_key_in[7] ứng với bit thứ 57 theo cách đánh số từ trái sang phải của chuẩn. Tương tự, ở bảng tạo ra d0, vị trí MSB là des_key_in[1] ứng với bit thứ 63 theo cách đánh số từ trái sang phải của chuẩn.
Hình 3. Tính hoán vị PC-1 - chỉ số trong từng ô vuông là vị trí bit của tín hiệu des_key_in[63:0]
Ví dụ về đoạn code thực hiện hoán vị tạo ra c0:
assign c0 = {des_key_in[7], des_key_in[15], des_key_in[23], des_key_in[31], des_key_in[39], des_key_in[47], des_key_in[55],
des_key_in[63], des_key_in[6], des_key_in[14], des_key_in[22], des_key_in[30], des_key_in[38], des_key_in[46],
des_key_in[54], des_key_in[62], des_key_in[5], des_key_in[13], des_key_in[21], des_key_in[29], des_key_in[37],
des_key_in[45], des_key_in[53], des_key_in[61], des_key_in[4], des_key_in[12], des_key_in[20], des_key_in[28]};
Đoạn code trên rất đơn giản là thực hiện sắp xếp lại các bit.

2.2.2 Phép dịch trái
Mạch này sử dụng 2 thanh ghi để lưu giá trị thứ n của C và D. Mạch này lấy đầu vào là:
  • Giá trị C0 và D0 từ phép tính hoán vị PC-1
  • Giá trị Cn-1 và Dn-1 từ 2 thanh ghi
Mạch sử dụng các tín hiệu điều khiển sau:
  • rkey_sel để lựa chọn khi nào sử dụng giá trị C0/D0 và khi nào sử dụng giá trị từ thanh ghi
  • shift_1 để xác định thời điểm dịch 1 bit và thời điểm dịch 2 bit
  • key_process để xác định thời điểm cần tính khóa vòng mới
Các tín hiệu trên sẽ được tạo ra từ các mạch khác và được mô tả trong các phần tiếp theo của bài này.
Hình 4. Mạch dịch trái 
2.2.3 Tính hoán vị PC-2
Ngõ ra mạch dịch trái trên đây được hoán vị theo bảng PC_2 như sau để tạo ra khóa vòng.
Hình 5. Mạch hoán vị PC-2
2.3 Mạch tính hàm mã hóa f(R,K)
2.3.1 Tính hoán vị E
Hoán vị E sẽ tạo ra giá trị đầu vào cho các bảng S.
Hình 6. Hoán vị E và XOR với khóa vòng, kết quả được chia thành 8 nhóm 6 bit để dùng cho 8 bảng S
2.3.2 Thực thi tra bảng S
Tra bảng S thực chất là thay thế giá trị đầu vào bằng một giá trị khác được quy định trong bảng.
Hình 6. Thực thi tra bảng S
Một đoạn code RTL thực thi tra bảng S1 sẽ được thể hiện dưới đây. Trong đó, mỗi phát biểu case(s1_in[4:1]) tương ứng với việc tra 1 hàng của bảng S1:
always @ (*) begin
case ({s1_in[5], s1_in[0]})
2'b00: begin
case (s1_in[4:1])
4'd0: s1_out = 4'd14;
4'd1: s1_out = 4'd4;
4'd2: s1_out = 4'd13;
4'd3: s1_out = 4'd1;
4'd4: s1_out = 4'd2;
4'd5: s1_out = 4'd15;
4'd6: s1_out = 4'd11;
4'd7: s1_out = 4'd8;
4'd8: s1_out = 4'd3;
4'd9: s1_out = 4'd10;
4'd10: s1_out = 4'd6;
4'd11: s1_out = 4'd12;
4'd12: s1_out = 4'd5;
4'd13: s1_out = 4'd9;
4'd14: s1_out = 4'd0;
default: s1_out = 4'd7;
endcase
end
2'b01: begin
case (s1_in[4:1])
4'd0: s1_out = 4'd0;
4'd1: s1_out = 4'd15;
4'd2: s1_out = 4'd7;
4'd3: s1_out = 4'd4;
4'd4: s1_out = 4'd14;
4'd5: s1_out = 4'd2;
4'd6: s1_out = 4'd13;
4'd7: s1_out = 4'd1;
4'd8: s1_out = 4'd10;
4'd9: s1_out = 4'd6;
4'd10: s1_out = 4'd12;
4'd11: s1_out = 4'd11;
4'd12: s1_out = 4'd9;
4'd13: s1_out = 4'd5;
4'd14: s1_out = 4'd3;
default: s1_out = 4'd8;
endcase
end
2'b10: begin
case (s1_in[4:1])
4'd0: s1_out = 4'd4;
4'd1: s1_out = 4'd1;
4'd2: s1_out = 4'd14;
4'd3: s1_out = 4'd8;
4'd4: s1_out = 4'd13;
4'd5: s1_out = 4'd6;
4'd6: s1_out = 4'd2;
4'd7: s1_out = 4'd11;
4'd8: s1_out = 4'd15;
4'd9: s1_out = 4'd12;
4'd10: s1_out = 4'd9;
4'd11: s1_out = 4'd7;
4'd12: s1_out = 4'd3;
4'd13: s1_out = 4'd10;
4'd14: s1_out = 4'd5;
default: s1_out = 4'd0;
endcase
end
default: begin
case (s1_in[4:1])
4'd0: s1_out = 4'd15;
4'd1: s1_out = 4'd12;
4'd2: s1_out = 4'd8;
4'd3: s1_out = 4'd2;
4'd4: s1_out = 4'd4;
4'd5: s1_out = 4'd9;
4'd6: s1_out = 4'd1;
4'd7: s1_out = 4'd7;
4'd8: s1_out = 4'd5;
4'd9: s1_out = 4'd11;
4'd10: s1_out = 4'd3;
4'd11: s1_out = 4'd14;
4'd12: s1_out = 4'd10;
4'd13: s1_out = 4'd0;
4'd14: s1_out = 4'd6;
default: s1_out = 4'd13;
endcase
end
endcase
end
2.3.3 Hoán vị P

Sau khi tra các bảng S, giá trị sẽ được hoán vị theo bảng P để tạo ra giá trị hàm f(R,K).
Hình 8. Hoán vị P để tạo giá trị hàm f(R,K)

Đoạn RTL code thực hiện hoán vị P:
assign p_in = {s1_out, s2_out, s3_out, s4_out, s5_out, s6_out, s7_out, s8_out};
assign f_value = {p_in[16], p_in[25], p_in[12], p_in[11],
p_in[3], p_in[20], p_in[4], p_in[15],
p_in[31], p_in[17], p_in[9], p_in[6],
p_in[27], p_in[14], p_in[1], p_in[22],
p_in[30], p_in[24], p_in[8], p_in[18],
p_in[0], p_in[5], p_in[29], p_in[23],
p_in[13], p_in[19], p_in[2], p_in[26],
p_in[10], p_in[21], p_in[28], p_in[7]};

2.4 Mạch thực hiện thuật toán mã hóa DES
2.4.1 Hoán vị đầu vào - IP và lựa chọn giá trị cho mỗi vòng lặp mã hóa
Hình 9. Thực hiện hoán vị đầu vào và lựa chọn giá trị
Hoán vị đầu vào tạo ra giá trị ngõ vào đầu tiên l0 và r0. Mạch sử dụng một tín hiệu điều khiển cipher_sel để chọn giá trị tính toán là l0-r0 hoặc giá trị ln-rn (đây là gí trị lưu trong thanh ghi).
Đoạn RTL code thực hiện hoán vị đầu vào và lựa chọn giá trị cho mỗi vòng lặp mã hóa như sau:
assign ip_input = {des_data[6], des_data[14], des_data[22], des_data[30], des_data[38], des_data[46], des_data[54], des_data[62],
des_data[4], des_data[12], des_data[20], des_data[28], des_data[36], des_data[44], des_data[52], des_data[60],
des_data[2], des_data[10], des_data[18], des_data[26], des_data[34], des_data[42], des_data[50], des_data[58],
des_data[0], des_data[8], des_data[16], des_data[24], des_data[32], des_data[40], des_data[48], des_data[56],
des_data[7], des_data[15], des_data[23], des_data[31], des_data[39], des_data[47], des_data[55], des_data[63],
des_data[5], des_data[13], des_data[21], des_data[29], des_data[37], des_data[45], des_data[53], des_data[61],
des_data[3], des_data[11], des_data[19], des_data[27], des_data[35], des_data[43], des_data[51], des_data[59],
des_data[1], des_data[9], des_data[17], des_data[25], des_data[33], des_data[41], des_data[49], des_data[57]};
assign l0 = ip_input[63:32];
assign r0 = ip_input[31:0];
assign l_input = (cipher_sel)? l0: ln;
assign r_input = (cipher_sel)? r0: rn;
2.4.2 Lưu giá trị Ln và Rn, thực hiện hoán vị đảo IP-1
Hình 10. Tính, lưu giá trị ln-rn và thực hiện hoán vị đảo IP-1
Ngõ ra l_input[31:0] từ mạch hoán vị và lựa chọn mục 2.4.1 được XOR với giá trị hàm f(R,K) trước khi lưu vào thanh ghi ln[31:0]. Giá trị 2 thanh ghi được ghép lại thành giá trị ngõ vào của hoán vị IP-1. Sau hoán vị IP-1, desc_ciphertext[63:0] là giá trị của mỗi vòng lặp mã hóa và là giá trị mã hóa nếu bộ mã hóa đang ở vòng lặp cuối cùng.
RTL code của thanh ghi ln và rn như sau:
always @ (posedge clk) begin
if (cipher_process) begin
ln <= `DELAY r_input;
rn <= `DELAY l_input ^ f_value;
end
end
RTL code của hoán vị đảo IP-1:
assign inv_p_input = {rn, ln};
assign desc_ciphertext = {inv_p_input[24], inv_p_input[56], inv_p_input[16], inv_p_input[48], inv_p_input[8], inv_p_input[40], inv_p_input[0], inv_p_input[32],
inv_p_input[25], inv_p_input[57], inv_p_input[17], inv_p_input[49], inv_p_input[9], inv_p_input[41], inv_p_input[1], inv_p_input[33],
inv_p_input[26], inv_p_input[58], inv_p_input[18], inv_p_input[50], inv_p_input[10], inv_p_input[42], inv_p_input[2], inv_p_input[34],
inv_p_input[27], inv_p_input[59], inv_p_input[19], inv_p_input[51], inv_p_input[11], inv_p_input[43], inv_p_input[3], inv_p_input[35],
inv_p_input[28], inv_p_input[60], inv_p_input[20], inv_p_input[52], inv_p_input[12], inv_p_input[44], inv_p_input[4], inv_p_input[36],
inv_p_input[29], inv_p_input[61], inv_p_input[21], inv_p_input[53], inv_p_input[13], inv_p_input[45], inv_p_input[5], inv_p_input[37],
inv_p_input[30], inv_p_input[62], inv_p_input[22], inv_p_input[54], inv_p_input[14], inv_p_input[46], inv_p_input[6], inv_p_input[38],
inv_p_input[31], inv_p_input[63], inv_p_input[23], inv_p_input[55], inv_p_input[15], inv_p_input[47], inv_p_input[7], inv_p_input[39]};
2.5 Mạch giám sát quá trình mã hóa

Phần mạch này tạo ra các tín hiệu điều khiển cho các mạch đã trình bày ở trên. Để giám sát quá trình mã hóa một bộ đếm 4 bit được sử dụng để xác định số lần lặp mã hóa. Đồng thời giá trị bộ đếm này được sử dụng để tạo thêm tín hiệu điều khiển khác. Ví dụ, tín hiệu shift_1 tích cực tại 4 vị trí ứng với lần lặp thứ 1 (bộ đếm bằng 0), thứ 2 (Bộ đếm bằng 1), thứ 9 (bộ đếm bằng 8) và thứ 16 (Bộ đếm bằng 15).
Hình 11. Bộ đếm giám sát quá trình mã hóa và tín hiệu xác định quá trình tính khóa vòng key_process
3. Bộ giải mã DES
Bộ giải mã được thực hiện dựa trên cấu trúc bộ mã hóa. Phần này chỉ nhấn mạnh các điểm được điều chỉnh để tích hợp phần giải mã vào mạch mã hóa để tạo ra một thiết kế có chức năng mã háo và giải mã hoàn chỉnh.
3.1 Tín hiệu giao tiếp
Tín hiệu giao tiếp được điều chỉnh như sau:
  • Tách tín hiệu des_cipher_en thành 2 tín hiệu:
    • des_encipher_en: Khởi động quá trình mã hóa
    • des_decipher_en: Khởi động quá trình giải mã
  • Tín hiệu des_ciphertext[63:0] được chuyển thành des_result[63:0] và tín hiệu này sẽ là giá trị bản mã của quá trình mã hóa hoặc bản rõ của quá trình giải mã
Hình 12. Sơ đồ tín hiệu giao tiếp của lõi tích hợp chức năng giải mã
3.2 Mạch tính khóa vòng
Mạch này điều chỉnh:
  • Tín hiệu rkey_sel ở mạch tạo cin và din
  • Điều chỉnh mạch của thanh ghi cn và dn
Hình 13. Mạch tính khóa vòng

3.3 Mạch tính hàm mã hóa f(R,K)

Không có sự thay đổi

3.4 Mạch thực hiện thuật toán giải mã

Điều chỉnh mạch tạo l_input[31:0] và r_input[31:0].
Hình 14. Mạch tạo ngõ vào cho bảng hoán vị IP-1
3.5 Mạch tạo giá trị ngõ ra bộ mã hóa và giải mã DES
Điều chỉnh thêm cổng OR ở mạch MUX tạo ngõ vào bảng hoán vị IP-1.
Hình 15. Mạch tạo ngõ ra bộ mã hóa và giải mã DES
3.6 Mạch giám sát quá trình giải mã và mã hóa
Mạch này có nhiều thay đổi để tách quá trình mã hóa và giải mã riêng. bạn đọc có thể so sánh và tự tìm hiểu.
Hình 16. Mạch giám sát quá trình mã hóa và giải mã
Một điểm khác biệt là, khi quá trình giải mã được khởi động, quá trình tính khóa vòng sẽ chạy để tính ra khóa vòng K16. Sau đó, quá trình giải mã mới thực sự được khởi động.

4. RTL code và testbench


pass (nếu có): nguyenquanicd

Mọi ý kiến trao đổi cá bạn có thể post dưới bài viết.

Thứ Bảy, 26 tháng 8, 2017

[DES] Thuật toán mã hóa và giải mã DES

Bài viết này giới thiệu về thuật toán mã hóa và giải mã dữ liệu DES (Data Encryption Standard). Đây là thuật toán mã hóa dữ liệu được công bố 25/10/1999 trong tài liệu về chuẩn xử lý thông tin liên bang Hoa Kỳ FIPS 46-3.

1. Một số thuật ngữ sử dụng
  • Encipher - Bộ mã hóa
  • Decipher - Bộ giải mã
  • Plaintext - Bản rõ là dữ liệu gốc chưa được mã hóa
  • Ciphertext - Bản mã là dữ liệu đã dược mã hóa
  • Key - khóa mã là một giá trị được sử dụng để mã hóa và giải mã
  • Round key - khóa vòng là những giá trị trung gian được tạo ra từ khóa mã trong suốt quá trình mã hóa và giải mã
2. Thuật toán mã hóa dữ liệu DES – Encipher
2.1 Lưu đồ thuật toán mã hóa
Thuật toán DES được sử dụng để mã hóa và giải mã các block (khối) dữ liệu 64 bit dựa trên một key (khóa mã) 64 bit. Chú ý, các block được đánh số thứ tự bit từ trái sang phải và bắt đầu từ 1, bit đầu tiên bên trái là bit số 1 và bit cuối cùng bên phải là bit số 64. Quá trình giải mã và mã hóa sử dụng cùng một key nhưng thứ tự phân phối các giá trị các bit key của quá trình giải mã ngược với quá trình mã hóa.
Một block dữ liệu sẽ được hoán vị khởi tạo (Initial Permutation) IP trước khi thực hiện tính toán mã hóa với key. Cuối cùng, kết quả tính toán với key sẽ được hoán vị lần nữa để tạo ra , đây là hoán vị đảo của hoán vị khởi tạo gọi là (Inverse Initial Permutation) IP-1. Việc tính toán dựa trên key được định nghĩa đơn giản trong một hàm f, gọi là hàm mã hóa, và một hàm KS, gọi là hàm phân phối key (key schedule). Hàm KS là hàm tạo ra các khóa vòng (round key) cho các lần lặp mã hóa. Có tất cả 16 khóa vòng từ K1 đến K16.
Hình 1. Giải thuật mã hóa DES
2.2 Hoán vị khởi tạo - IP
Hoán vị là thay đổi ví trí các bit trong một chuỗi giá trị nhưng không làm thay đổi giá trị của các bit này. Đây là bước đầu tiên trong quy trình mã hóa dữ liệu. 64 bit dữ liệu đầu vào, gọi là plaintext, sẽ được hoán vị theo bảng mô tả sau đây.
Hình 2. Sơ đồ hoán vị khởi tạo, ký hiệu IP
Chuỗi bit đầu vào được đánh số từ 1 đến 64 (tính từ trái qua phải). Sau đó, các bit này được thay đổi vị trí như sơ đồ IP, bit số 58 được đặt vào vị trí đầu tiên, bit số 50 được đặt vào vị trí thứ 2. Cứ như vậy, bit thứ 7 được đặt vào vị trí cuối cùng. 
Sau hoán vị, chuỗi bit mới được phân ra làm hai đoạn, mỗi đoạn 32 bit để bắt đầu vào quy trình tính toán mã hóa với key. Đoạn bên trái ký hiệu là L, đoạn bên phải ký hiệu là R. Đoạn L gồm các bit từ bit số 1 đến bit số 32, đoạn R gồm các bit từ bit số 33 đến bit số 64. Đoạn L của lần tính toán sau sẽ chính là đoạn R của lần tính toán trước. Đoạn R của lần tính toán sau sẽ được tính từ đoạn R trước đó qua hàm mã hóa f(R, K) rồi XOR với đoạn L của lần tính trước đó.

2.3 Hàm mã hóa f(R,K)
Hình 3. Tính toán hàm mã hóa f(R,K)
Đầu tiên, 32 bit của đoạn R được đánh số từ 1 đến 32 theo thứ tự từ trái qua phải. Giá trị này sẽ được chuyển đổi thông qua bảng tra E để tạo thành một giá trị 48 bit. Bit đầu tiên trong chuỗi giá trị 48 bit là bit số 32 của R, bit thứ 2 là bit số 1 của R, bit thứ 3 là bit số 2 của R và bit cuối cùng là bit số 1 của R.
Hình 4. Bảng tra E
Sau khi tra bảng E, giá trị 48 bit được XOR với 48 bit của khóa vòng (cách tạo ra khóa vòng 48 bit sẽ được trình bày sau). Kết quả phép XOR được chia làm 8 block được đánh số từ 1 đến 8 theo thứ tự từ trái qua phải, mỗi block 6 bit. Mỗi block sẽ được biến đổi thông qua các hàm lựa chọn riêng biệt. Tương ứng với 8 block sẽ có 8 hàm chuyển đổi (selection function) riêng biệt là S1, S2, S3, S4, S5, S6, S7 và S8.
Hình 5. Các hàm S (selection fuction)
Việc chuyển đổi giá trị của các hàm S1, S2, ..., S8 được thực hiện bằng cách tách block 6 bit thành hai phần. Phần thứ nhất là tổ hợp của bit đầu tiên và bit cuối cùng của block để tạo thành 2 bit chọn hàng của bảng S, bảng S có 4 hàng được đánh số từ 0 đến 3 theo thứ tự từ trên xuống. Phần thứ 2 là 4 bit còn lại dùng để chọn cột của bảng S, bảng S có 16 cột được đánh số từ 0 đến 15 theo thứ tự từ trái qua phải. Như vậy, với mỗi block 8 bit ta chọn được 1 giá trị trong bảng S. Giá trị này nằm trong khoảng từ 0 đến 15 sẽ được quy đổi thành chuỗi nhị phân 4 bit tương ứng. Các chuỗi nhị phân có được sau khi chuyển đổi từ S1 đến S8 sẽ được ghép lại theo thứ tự từ trái qua phải để tạo thành một giá trị 32 bit.
Ví dụ về việc thực hiện chuyển đổi hàm S, giả sử, giá trị block 6 bit đầu tiên là 011011. Ta tách chuỗi này ra làm hai tổ hợp giá trị là 01 (bit đầu tiên và bit cuối cùng) và 1101 (4 bit ở giữa). Hai tổ hợp này được dùng để chọn hàng và cột tương ứng như hình minh họa sau:
Hình 6. Minh họa việc sử dụng hàm S1
Tổ hợp 01 sẽ chọn hàng 1, tổ hợp 1101 sẽ chọn cột 13 và kết quả trả về là 5 có giá trị nhị phân 4 bit là 0101.
Qua bước chuyển đổi với các hàm lựa chọn S, kết quả thu được là một giá trị 32 bit. Giá trị này được đưa qua một hàm hoán vị P để tạo ra giá trị hàm f.
Hình 7. Hoán vị P trong thuật toán tính hàm mã hóa f(R,K)

Giá trị 32 bit thu được từ các chuyển đổi với hàm lựa chọn S sẽ được đánh số từ 1 đến 32 theo thứ tự từ trái qua phải.
Theo bảng hoán vị P, bit đầu tiên sau hoán vị sẽ là bit số 16, bit thứ 2 sẽ là bit số 7 và bit cuối cùng sẽ là bit số 25. Hàm tính toán mã hóa f(R, K) được định nghĩa như sau:

Trong đó: 
  • P(): là phép hoán vị P 
  • Sn: là phép chuyển đổi block n (n chạy từ 1 đến 8) với hàm lựa chọn S 
  • Bn: là block 6 bit thứ n (n chạy từ 1 đến 8). Block này lấy từ phép toán XOR giữa khóa vòng K và giá trị hàm E(R)
  • E(R): là hàm chuyển đổi giá trị R 32 bit thành giá trị 48 bit
2.4 Tính khóa vòng - KS
Một key có 64 bit nhưng chỉ có 56 bit được sử dụng để thực hiện tính toán giá trị khóa vòng. Key được chia làm 8 byte. Các bit ở vị trí 8, 16, 32, 40, 48, 56 và 64 là các bit parity được sử dụng để kiểm tra độ chính xác của key theo từng byte vì khi key được phân phối trên đường truyền đến bộ mã hóa giải mã thì có thể xảy ra lỗi. Parity được sử dụng là parity lẻ (odd parity).
Hình 8. Thuật toán tính khóa vòng
Key gốc sẽ được thực hiện hoán vị lựa chọn PC-1. Key được đánh số từ 1 đến 64 theo thứ tự từ trái qua phải.
Hình 9. Bảng hoán vị lựa chọn PC-1
Bảng hoán vị lựa chọn PC-1 có hai phần. Phần đầu dùng để xác định giá trị C0 và phần sau dùng để xác định giá trị D0. Theo bảng trên thì C0 là chuỗi bit có thứ tự là 57, 49, 41, ..., 36 lấy từ key gốc, D0 là chuỗi bit có thứ tự là 63, 55, 47, ..., 4 lấy từ key gốc.
Sau khi xác định được giá trị ban đầu để tính key là C0 và D0 thì các khóa vòng Kn (với n từ 1 đến 16) sẽ được tính theo nguyên tắc giá trị của khóa vòng thứ n sẽ được tính từ giá trị khóa vòng thứ n-1.

Trong đó Cn và Dn được tạo từ Cn-1 và Dn-1 bằng cách dịch trái các giá trị này với số bit được quy định trong bảng sau đây:
Hình 10. Bảng quy định số bit dịch trái khi tính khóa vòng
Ví dụ, theo bảng trên, C3 và D3 có được từ C2 và D2 bằng cách dịch trái 2 bit. Hay C16 và D16 có được từ C15 và D15 bằng cách dịch trái 1 bit. Dịch trái ở đây được hiểu là quay trái như minh họa sau đây:
Hình 11. Minh họa phép dịch trái khi tính khóa vòng

Sau khi tính được Cn và Dn thì chuỗi CnDn sẽ được đánh số từ 1 đến 56 theo thứ tự từ trái sang phải và được hoán vị lựa chọn lần 2 theo bảng hoán vị PC-2.
Hình 12. Bảng hoán vị lựa chọn PC-2
Như vậy bit đầu tiên của khóa vòng Kn là bit số 14 của chuỗi CnDn, bit thứ 2 là bit số 17 của chuỗi CnDn và bit cuối cùng là bit số 32 của chuỗi CnDn.

2.5 Hoán vị khởi tạo đảo IP-1
Đây là bước cuối cùng để tạo ra giá trị mã hóa. Giá trị của lần lặp mã hóa cuối cùng sẽ được hoán vị khởi tạo đảo IP-1 và tạo ra giá trị mã hóa plaintext.
Hình 13. Bảng hoán vị khởi tạo đảo IP-1
2.6 Ví dụ về mã hóa DES
Giả sử ta có dữ liệu cần mã hóa và key là: 
  • M = 00123456789abcde (Hex) = 0000 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1111 
  • K = 0133457799bbcdff (Hex) = 0000 0001 0011 0011 0100 0101 0111 0111 1001 10001 1011 1011 1100 1100 1111 1111
Từ hai đầu vào này, giá trị của từng bước tính toán mã hóa DES sẽ được minh họa chi tiết sau đây.

2.6.1 Hoán vị khởi tạo – IP
Thông điệp M được đánh số vị trí bit từ trái qua phải như sau:

Sắp xếp lại thứ tự các bit của M theo bảng hoán vị IP, kết quả có được sau bước này là:

IP(M) = 98fecc00e054f0aa (Hex) = 1001 1000 1111 1110 1100 1100 0000 0000 1110 0000 0101 0100 1111 0000 1010 1010

2.6.2 Tính toán giá trị các khóa vòng – KS
Để tính toán hàm mã hóa f, chúng ta cần có giá trị khóa cho từng lần lặp mã hóa. Key ban đầu được đánh số thứ tự bit từ trái qua phải như sau:


Sau khi sắp xếp các bit theo bảng hoán vị PC-1 ở Hình 1‑8, kết quả thu được là hai giá trị đầu như sau: 
  • C0 = f0ccaab (Hex) = 1111 0000 1100 1100 1010 1010 1011 
  • D0 = aaccf0a (Hex) = 1010 1010 1100 1100 1111 0000 1010 
Để tính khóa vòng đầu tiên K1 thì C0 và D0 sẽ được dịch (quay) trái 1 bit. Giá trị thu được sau khi dịch trái là: 
  • C1 = e199557 (Hex) = 1110 0001 1001 1001 0101 0101 0111 
  • D1 = 5599e15 (Hex) = 0101 0101 1001 1001 1110 0001 0101 
Hai chuỗi C1 và D1 được ghép lài thành một chuỗi 56 bit là e1995575599e15. Chuỗi này được hoán vị bằng bảng PC-2 ở Hình 1‑11 để được giá trị khóa vòng 48 bit thứ nhất K1. 
  • K1 = 1b02efdb49a5 (Hex) 
Để tính khóa vòng K2 thì lấy C1 và D1 dịch trái với số lượng bit theo bảng ở Hình 1‑9, rồi lấy kết quả hoán vị theo bảng PC-2. Quá trình cứ tiếp tục cho đến khóa vòng cuối cùng là K16. Kết quả các khóa vòng 48 bit thu được là:
  • K2 = 69aed925ae66 (Hex) 
  • K3 = 55fc8ab4acd2 
  • K4 = 72add2ad8657 
  • K5 = 7cec071fe6c2 
  • K6 = 63a51e3cc545 
  • K7 = 6c84b78ae4c6 
  • K8 = f7883aece781 
  • K9 = c0dbeb27b839 
  • K10 = b1f347631d76 
  • K11 = 215fc30d89be 
  • K12 = 7171f5455cd5 
  • K13 = 95c5d14b80fd 
  • K14 = 5743b783đ8d 
  • K15 = bf91850a17b5 K16 = cb3d0bbc7072
2.6.3 Tính hàm mã hóa f(R,K)
Sau bước hoán vị khởi tạo IP, giá trị IP(M) sẽ được tách làm hai phần là: 
  • R0 = e054f0aa (Hex) = 1110 0000 0101 0100 1111 0000 1010 1010 
  • L0 = 98fecc00 (Hex) = 1001 1000 1111 1110 1100 1100 0000 0000 
Giá trị 32 bit của R0 được tra qua bảng E để tạo ra một giá trị 48 bit. 
  • E(R0) = 7002a97a1555 (Hex) 
Giá trị này được XOR với khóa vòng thứ nhất K1 và được kết quả 
  • XOR(E(R0), K1) = 6b0046a15cf0 (Hex)
Giá trị trên được chia thành 8 nhóm theo thứ tự từ trái qua phải, mỗi nhóm 6 bit để đưa đến các bảng S.
Hình 14. Ví dụ về tra bảng S
Các giá trị đầu ra sau bước tra các bảng S sẽ được ghép lại theo thứ tự từ S1 đến S8 để được 1 giá trị 32 bit. 
  • S1()S2()S3()S4()S5()S6()S7()S8() = 10010101110100111010110101010000 = 95d3ad50 (Hex) 
Giá trị này được hoán vị bằng bảng P để cho ra giá trị của hàm f. 
  • f(R0,K1) = 97d1619a (Hex) = 1001 0111 1101 0001 0110 0001 1001 1010 
Tương tự, ta có giá trị hàm f tại các vòng lặp mã hóa còn lại như sau: 
  • f(R1,K2) = 88488d0b (Hex) 
  • f(R2,K3) = da3b2692 
  • f(R3,K4) = f44950b2 
  • f(R4,K5) = d83237fd 
  • f(R5,K6) = afc43b25 
  • f(R6,K7) = 4e5123a2 
  • f(R7,K8) = 6cfdecb8 
  • f(R8,K9) = fb0600b1 
  • f(R9,K10) = d51508e4 
  • f(R10,K11) = fcf67146 
  • f(R11,K12) = 704fa3a5 
  • f(R12,K13) = 7bfe2806 
  • f(R13,K14) = 65fc7a48 
  • f(R14,K15) = 513f1d11 f(R15,K16) = cbf5252d
2.6.4 Giá trị tại mỗi vòng lặp mã hóa

Giá trị của hàm f(R,K) được sử dụng để tính giá trị Rn và Ln tại mỗi vòng lặp mã hóa theo công thức:

Thay vào công thức trên ta có các kết quả như sau:

2.6.5 Hoán vị khởi tạo đảo IP-1 
Giá trị R16 và L16 của vòng lặp mã hóa cuối cùng sẽ được ghép lại thành một chuỗi 64 bit để thực hiện hoán vị theo bảng IP-1.
Kết quả của phép hoán vị này chính là giá trị mã hóa (ciphertext) cần tính.

IP-1(R16, L16) = 1abff69d5a93e80b (Hex) = 0001 1010 1011 1111 1111 0110 1001 1101 0101 1010 1001 0011 1110 1000 0000 1011

3. Thuật toán giải mã dữ liệu DES

Các bước của quá trình giải mã dữ liệu được thực hiện tương tự như quá trình mã hóa dữ liệu. Trong quá trình giải mã có một số thay đổi như sau: 
  • Đầu vào lúc này là dữ liệu cần giải mã (ciphertext) và đầu ra là kết quả giải mã được (plaintext).
  • Khóa vòng sử dụng trong các vòng lặp giải mã có thứ tự ngược với quá trình mã hóa. Nghĩa là, tại vòng lặp giải mã đầu tiên, khóa vòng được sử dụng là K16. Tại vòng lặp giải mã thứ 2, khóa vòng được sử dụng là K15, và tại vòng lặp giải mã cuối cùng thì khóa vòng được sử dụng là K1.
Hình 16. Quá trình giải mã dữ liệu DES

Các bạn có thể trao đổi thêm ở dưới vài viết hoặc thông qua mục liên hệ ở cột ngoài cùng bên phải của trang.

Lịch sử cập nhật:
1) 2019.10.21 - Sửa link các hình ảnh
2) 2020.04.19 - Sửa chuỗi binary (4 bit cuối) của C1 từ 1110 thành 0111 như góp ý dưới comment