From a689dccc34edcc6b955c9b522bb141e32c871add Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20Stro=CC=88mbergson?= Date: Tue, 22 May 2018 11:18:35 +0200 Subject: Combined all AES round operations into a single operation for a round. --- README.md | 11 ++--- src/rtl/aes_decipher_block.v | 102 ++++++++++------------------------------- src/rtl/aes_encipher_block.v | 99 ++++++++++----------------------------- src/tb/tb_aes.v | 1 + src/tb/tb_aes_decipher_block.v | 5 +- src/tb/tb_aes_encipher_block.v | 9 ++-- 6 files changed, 61 insertions(+), 166 deletions(-) diff --git a/README.md b/README.md index 6ce5f4b..aa2e14e 100644 --- a/README.md +++ b/README.md @@ -40,10 +40,11 @@ the total number of S-boxes is 20. ## Performance comparison Number of cycles for the old Cryptech AES core: - AES-128 Encipher one block with key expansion: 57 - +- AES-256 Decipher one block with key expansion: 77 Number of cycles for the Cryptech AES speed core: -- AES-128 Encipher with key expansion: 27 +- AES-128 Encipher one block with key expansion: 17 +- AES-255 Decipher one block with key expansion: 21 ## Implementation comparison @@ -56,8 +57,6 @@ Old Cryptech AES core: Cryptec AES speed core: -- 2019 slices +- 2076 slices - 2984 regs -- 131 MHz. (7.58ns) - -Surprisingly, the number of slices actually decreases. +- 117 MHz. (8.54ns) diff --git a/src/rtl/aes_decipher_block.v b/src/rtl/aes_decipher_block.v index c2304d6..ce34cc8 100644 --- a/src/rtl/aes_decipher_block.v +++ b/src/rtl/aes_decipher_block.v @@ -72,9 +72,8 @@ module aes_decipher_block( localparam CTRL_IDLE = 3'h0; localparam CTRL_INIT = 3'h1; - localparam CTRL_SBOX = 3'h2; - localparam CTRL_MAIN = 3'h3; - localparam CTRL_FINAL = 3'h4; + localparam CTRL_MAIN = 3'h2; + localparam CTRL_FINAL = 3'h3; //---------------------------------------------------------------- @@ -192,22 +191,16 @@ module aes_decipher_block( //---------------------------------------------------------------- // Registers including update variables and write enable. //---------------------------------------------------------------- + reg [127 : 0] block_reg; + reg [127 : 0] block_new; + reg block_we; + reg [3 : 0] round_ctr_reg; reg [3 : 0] round_ctr_new; reg round_ctr_we; reg round_ctr_set; reg round_ctr_dec; - reg [127 : 0] block_new; - reg [31 : 0] block_w0_reg; - reg [31 : 0] block_w1_reg; - reg [31 : 0] block_w2_reg; - reg [31 : 0] block_w3_reg; - reg block_w0_we; - reg block_w1_we; - reg block_w2_we; - reg block_w3_we; - reg ready_reg; reg ready_new; reg ready_we; @@ -243,8 +236,8 @@ module aes_decipher_block( //---------------------------------------------------------------- // Concurrent connectivity for ports etc. //---------------------------------------------------------------- + assign new_block = block_reg; assign round = round_ctr_reg; - assign new_block = {block_w0_reg, block_w1_reg, block_w2_reg, block_w3_reg}; assign ready = ready_reg; @@ -259,27 +252,15 @@ module aes_decipher_block( begin: reg_update if (!reset_n) begin - block_w0_reg <= 32'h0; - block_w1_reg <= 32'h0; - block_w2_reg <= 32'h0; - block_w3_reg <= 32'h0; + block_reg <= 128'h0; round_ctr_reg <= 4'h0; ready_reg <= 1'b1; dec_ctrl_reg <= CTRL_IDLE; end else begin - if (block_w0_we) - block_w0_reg <= block_new[127 : 096]; - - if (block_w1_we) - block_w1_reg <= block_new[095 : 064]; - - if (block_w2_we) - block_w2_reg <= block_new[063 : 032]; - - if (block_w3_we) - block_w3_reg <= block_new[031 : 000]; + if (block_we) + block_reg <= block_new; if (round_ctr_we) round_ctr_reg <= round_ctr_new; @@ -300,68 +281,43 @@ module aes_decipher_block( //---------------------------------------------------------------- always @* begin : round_logic - reg [127 : 0] old_block, inv_shiftrows_block, inv_mixcolumns_block; + reg [127 : 0] subbytes_block, inv_shiftrows_block, inv_mixcolumns_block; reg [127 : 0] addkey_block; inv_shiftrows_block = 128'h0; inv_mixcolumns_block = 128'h0; addkey_block = 128'h0; block_new = 128'h0; - block_w0_we = 1'b0; - block_w1_we = 1'b0; - block_w2_we = 1'b0; - block_w3_we = 1'b0; + block_we = 1'b0; - sboxw0 = block_w0_reg; - sboxw1 = block_w1_reg; - sboxw2 = block_w2_reg; - sboxw3 = block_w3_reg; + sboxw0 = block_reg[127 : 96]; + sboxw1 = block_reg[95 : 64]; + sboxw2 = block_reg[63 : 32]; + sboxw3 = block_reg[31 : 0]; + subbytes_block = {new_sboxw0, new_sboxw1, new_sboxw2, new_sboxw3}; - old_block = {block_w0_reg, block_w1_reg, block_w2_reg, block_w3_reg}; - - // Update based on update type. case (update_type) - // InitRound INIT_UPDATE: begin - old_block = block; - addkey_block = addroundkey(old_block, round_key); + addkey_block = addroundkey(block, round_key); inv_shiftrows_block = inv_shiftrows(addkey_block); block_new = inv_shiftrows_block; - block_w0_we = 1'b1; - block_w1_we = 1'b1; - block_w2_we = 1'b1; - block_w3_we = 1'b1; - end - - SBOX_UPDATE: - begin - block_new = {new_sboxw0, new_sboxw1, new_sboxw2, new_sboxw3}; - block_w0_we = 1'b1; - block_w1_we = 1'b1; - block_w2_we = 1'b1; - block_w3_we = 1'b1; + block_we = 1'b1; end MAIN_UPDATE: begin - addkey_block = addroundkey(old_block, round_key); + addkey_block = addroundkey(subbytes_block, round_key); inv_mixcolumns_block = inv_mixcolumns(addkey_block); inv_shiftrows_block = inv_shiftrows(inv_mixcolumns_block); block_new = inv_shiftrows_block; - block_w0_we = 1'b1; - block_w1_we = 1'b1; - block_w2_we = 1'b1; - block_w3_we = 1'b1; + block_we = 1'b1; end FINAL_UPDATE: begin - block_new = addroundkey(old_block, round_key); - block_w0_we = 1'b1; - block_w1_we = 1'b1; - block_w2_we = 1'b1; - block_w3_we = 1'b1; + block_new = addroundkey(subbytes_block, round_key); + block_we = 1'b1; end default: @@ -431,15 +387,8 @@ module aes_decipher_block( CTRL_INIT: begin - update_type = INIT_UPDATE; - dec_ctrl_new = CTRL_SBOX; - dec_ctrl_we = 1'b1; - end - - CTRL_SBOX: - begin - update_type = SBOX_UPDATE; round_ctr_dec = 1'b1; + update_type = INIT_UPDATE; dec_ctrl_new = CTRL_MAIN; dec_ctrl_we = 1'b1; end @@ -448,9 +397,8 @@ module aes_decipher_block( begin if (round_ctr_reg > 0) begin + round_ctr_dec = 1'b1; update_type = MAIN_UPDATE; - dec_ctrl_new = CTRL_SBOX; - dec_ctrl_we = 1'b1; end else begin diff --git a/src/rtl/aes_encipher_block.v b/src/rtl/aes_encipher_block.v index f0e42f9..8cac95f 100644 --- a/src/rtl/aes_encipher_block.v +++ b/src/rtl/aes_encipher_block.v @@ -66,9 +66,8 @@ module aes_encipher_block( localparam NO_UPDATE = 3'h0; localparam INIT_UPDATE = 3'h1; - localparam SBOX_UPDATE = 3'h2; - localparam MAIN_UPDATE = 3'h3; - localparam FINAL_UPDATE = 3'h4; + localparam MAIN_UPDATE = 3'h2; + localparam FINAL_UPDATE = 3'h3; localparam CTRL_IDLE = 3'h0; localparam CTRL_INIT = 3'h1; @@ -156,22 +155,16 @@ module aes_encipher_block( //---------------------------------------------------------------- // Registers including update variables and write enable. //---------------------------------------------------------------- + reg [127 : 0] block_reg; + reg [127 : 0] block_new; + reg block_we; + reg [3 : 0] round_ctr_reg; reg [3 : 0] round_ctr_new; reg round_ctr_we; reg round_ctr_rst; reg round_ctr_inc; - reg [127 : 0] block_new; - reg [31 : 0] block_w0_reg; - reg [31 : 0] block_w1_reg; - reg [31 : 0] block_w2_reg; - reg [31 : 0] block_w3_reg; - reg block_w0_we; - reg block_w1_we; - reg block_w2_we; - reg block_w3_we; - reg ready_reg; reg ready_new; reg ready_we; @@ -199,8 +192,8 @@ module aes_encipher_block( //---------------------------------------------------------------- // Concurrent connectivity for ports etc. //---------------------------------------------------------------- + assign new_block = block_reg; assign round = round_ctr_reg; - assign new_block = {block_w0_reg, block_w1_reg, block_w2_reg, block_w3_reg}; assign ready = ready_reg; @@ -224,27 +217,15 @@ module aes_encipher_block( begin: reg_update if (!reset_n) begin - block_w0_reg <= 32'h0; - block_w1_reg <= 32'h0; - block_w2_reg <= 32'h0; - block_w3_reg <= 32'h0; + block_reg <= 128'h0; round_ctr_reg <= 4'h0; ready_reg <= 1'b1; enc_ctrl_reg <= CTRL_IDLE; end else begin - if (block_w0_we) - block_w0_reg <= block_new[127 : 096]; - - if (block_w1_we) - block_w1_reg <= block_new[095 : 064]; - - if (block_w2_we) - block_w2_reg <= block_new[063 : 032]; - - if (block_w3_we) - block_w3_reg <= block_new[031 : 000]; + if (block_we) + block_reg <= block_new; if (round_ctr_we) round_ctr_reg <= round_ctr_new; @@ -265,22 +246,19 @@ module aes_encipher_block( //---------------------------------------------------------------- always @* begin : round_logic - reg [127 : 0] old_block, shiftrows_block, mixcolumns_block; + reg [127 : 0] subbytes_block, shiftrows_block, mixcolumns_block; reg [127 : 0] addkey_init_block, addkey_main_block, addkey_final_block; - block_new = 128'h0; - block_w0_we = 1'b0; - block_w1_we = 1'b0; - block_w2_we = 1'b0; - block_w3_we = 1'b0; + block_new = 128'h0; + block_we = 1'b0; - sboxw0 = block_w0_reg; - sboxw1 = block_w1_reg; - sboxw2 = block_w2_reg; - sboxw3 = block_w3_reg; + sboxw0 = block_reg[127 : 96]; + sboxw1 = block_reg[95 : 64]; + sboxw2 = block_reg[63 : 32]; + sboxw3 = block_reg[31 : 0]; - old_block = {block_w0_reg, block_w1_reg, block_w2_reg, block_w3_reg}; - shiftrows_block = shiftrows(old_block); + subbytes_block = {new_sboxw0, new_sboxw1, new_sboxw2, new_sboxw3}; + shiftrows_block = shiftrows(subbytes_block); mixcolumns_block = mixcolumns(shiftrows_block); addkey_init_block = addroundkey(block, round_key); addkey_main_block = addroundkey(mixcolumns_block, round_key); @@ -289,38 +267,20 @@ module aes_encipher_block( case (update_type) INIT_UPDATE: begin - block_new = addkey_init_block; - block_w0_we = 1'b1; - block_w1_we = 1'b1; - block_w2_we = 1'b1; - block_w3_we = 1'b1; - end - - SBOX_UPDATE: - begin - block_new = {new_sboxw0, new_sboxw1, new_sboxw2, new_sboxw3}; - block_w0_we = 1'b1; - block_w1_we = 1'b1; - block_w2_we = 1'b1; - block_w3_we = 1'b1; + block_new = addkey_init_block; + block_we = 1'b1; end MAIN_UPDATE: begin - block_new = addkey_main_block; - block_w0_we = 1'b1; - block_w1_we = 1'b1; - block_w2_we = 1'b1; - block_w3_we = 1'b1; + block_new = addkey_main_block; + block_we = 1'b1; end FINAL_UPDATE: begin - block_new = addkey_final_block; - block_w0_we = 1'b1; - block_w1_we = 1'b1; - block_w2_we = 1'b1; - block_w3_we = 1'b1; + block_new = addkey_final_block; + block_we = 1'b1; end default: @@ -392,13 +352,6 @@ module aes_encipher_block( begin round_ctr_inc = 1'b1; update_type = INIT_UPDATE; - enc_ctrl_new = CTRL_SBOX; - enc_ctrl_we = 1'b1; - end - - CTRL_SBOX: - begin - update_type = SBOX_UPDATE; enc_ctrl_new = CTRL_MAIN; enc_ctrl_we = 1'b1; end @@ -409,8 +362,6 @@ module aes_encipher_block( if (round_ctr_reg < num_rounds) begin update_type = MAIN_UPDATE; - enc_ctrl_new = CTRL_SBOX; - enc_ctrl_we = 1'b1; end else begin diff --git a/src/tb/tb_aes.v b/src/tb/tb_aes.v index bd51ec8..35fc1d9 100644 --- a/src/tb/tb_aes.v +++ b/src/tb/tb_aes.v @@ -305,6 +305,7 @@ module tb_aes(); end endtask // read_word + //---------------------------------------------------------------- // wait_ready // diff --git a/src/tb/tb_aes_decipher_block.v b/src/tb/tb_aes_decipher_block.v index 0475cf5..13b9949 100644 --- a/src/tb/tb_aes_decipher_block.v +++ b/src/tb/tb_aes_decipher_block.v @@ -158,10 +158,9 @@ module tb_aes_decipher_block(); $display("Internal data values"); $display("round_key = 0x%016x", dut.round_key); - $display("block_w0_reg = 0x%08x, block_w1_reg = 0x%08x, block_w2_reg = 0x%08x, block_w3_reg = 0x%08x", - dut.block_w0_reg, dut.block_w1_reg, dut.block_w2_reg, dut.block_w3_reg); + $display("block_reg = 0x%016x", dut.block_reg); $display(""); - $display("old_block = 0x%08x", dut.round_logic.old_block); + $display("subbytes_block = 0x%08x", dut.round_logic.subbytes_block); $display("inv_shiftrows_block = 0x%08x", dut.round_logic.inv_shiftrows_block); $display("inv_mixcolumns_block = 0x%08x", dut.round_logic.inv_mixcolumns_block); $display("addkey_block = 0x%08x", dut.round_logic.addkey_block); diff --git a/src/tb/tb_aes_encipher_block.v b/src/tb/tb_aes_encipher_block.v index 87bab2c..0606d95 100644 --- a/src/tb/tb_aes_encipher_block.v +++ b/src/tb/tb_aes_encipher_block.v @@ -159,18 +159,15 @@ module tb_aes_encipher_block(); $display("Internal data values"); $display("round_key = 0x%016x", dut.round_key); - $display("block_w0_reg = 0x%08x, block_w1_reg = 0x%08x, block_w2_reg = 0x%08x, block_w3_reg = 0x%08x", - dut.block_w0_reg, dut.block_w1_reg, dut.block_w2_reg, dut.block_w3_reg); + $display("block_reg = 0x%016x", dut.block_reg); $display(""); - $display("old_block = 0x%08x", dut.round_logic.old_block); + $display("subbytes_block = 0x%08x", dut.round_logic.subbytes_block); $display("shiftrows_block = 0x%08x", dut.round_logic.shiftrows_block); $display("mixcolumns_block = 0x%08x", dut.round_logic.mixcolumns_block); $display("addkey_init_block = 0x%08x", dut.round_logic.addkey_init_block); $display("addkey_main_block = 0x%08x", dut.round_logic.addkey_main_block); $display("addkey_final_block = 0x%08x", dut.round_logic.addkey_final_block); - $display("block_w0_new = 0x%08x, block_w1_new = 0x%08x, block_w2_new = 0x%08x, block_w3_new = 0x%08x", - dut.block_new[127 : 096], dut.block_new[095 : 064], - dut.block_new[063 : 032], dut.block_new[031 : 000]); + $display("block_new = 0x%08x", dut.block_new); $display(""); end endtask // dump_dut_state -- cgit v1.2.3