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.
Tham khảo bài: http://nguyenquanicd.blogspot.com/2017/08/background-thuat-toan-ma-hoa-va-giai-ma.html
Để 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
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.
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 |
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.
Ví dụ về đoạn code thực hiện hoán vị tạo ra c0:
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] |
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
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.
2.3 Mạch tính hàm mã hóa f(R,K)
Hình 5. Mạch hoán vị PC-2 |
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.
2.3.2 Thực thi tra 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 |
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.
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:
Hình 6. Thực thi tra bảng S |
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).
Đoạn RTL code thực hiện hoán vị P:
2.4 Mạch thực hiện thuật toán mã hóa DES
Hình 8. Hoán vị P để tạo giá trị hàm f(R,K) |
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
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).
Hình 9. Thực hiện hoán vị đầu vào và lựa chọn giá trị |
Đ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],2.4.2 Lưu giá trị Ln và Rn, thực hiện hoán vị đảo IP-1
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;
Hình 10. Tính, lưu giá trị ln-rn và thực hiện hoán vị đảo IP-1 |
RTL code của thanh ghi ln và rn như sau:
always @ (posedge clk) beginRTL code của hoán vị đảo IP-1:
if (cipher_process) begin
ln <= `DELAY r_input;
rn <= `DELAY l_input ^ f_value;
end
end
assign inv_p_input = {rn, ln};2.5 Mạch giám sát quá trình mã hóa
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]};
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).
3. Bộ giải mã DES
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 |
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].
3.5 Mạch tạo giá trị ngõ ra bộ mã hóa và giải mã DES
Hình 14. Mạch tạo ngõ vào cho bảng hoán vị IP-1 |
Điều chỉnh thêm cổng OR ở mạch MUX tạo ngõ vào bảng hoán vị IP-1.
3.6 Mạch giám sát quá trình giải mã và mã hóa
Hình 15. Mạch tạo ngõ ra bộ mã hóa và giải mã DES |
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.
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.
Hình 16. Mạch giám sát quá trình mã hóa và giải mã |
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.
i cannot find .h file...
Trả lờiXóa.h is really the empty file in this case. It is not used for anything. You can comment the include line. Please check it again.
Xóacho em hỏi chạy code nó bị lỗi này là sao ạ
Trả lờiXóaline 793 Macro reference `DELAY is not defined
Hi,
XóaTrong RTL có dòng này "`include "des_defines.h".
Em tạo thêm 1 file des_defines.h.
Trong file trên em thêm dòng "`define DELAY #0.01"
cho em hỏi lỗi này là sao ạ
Trả lờiXóaMacro is not defined.
Lỗi này anh đã có chỉ cách sửa ở comment phía trên. Nó báo thiếu macro (define) nào thì em thêm define đó vào tưởng tự như hướng dẫn phía trên đây
Xóacái này mình không cần lưu đồ giải thuật hả anh
Trả lờiXóaVề lý thuyết, giải thuật mã hóa DES, em có thể thao khảo các bài trước đó http://nguyenquanicd.blogspot.com/2017/08/background-thuat-toan-ma-hoa-va-giai-ma.html
XóaDựa trên lý thuyết này, các logic được phân tích chi tiết như trong bài này để thực hiện được giải thuật DES