diff --git a/rtl/gift.sv b/rtl/gift.sv index 0eeb2da9..ee353758 100644 --- a/rtl/gift.sv +++ b/rtl/gift.sv @@ -37,15 +37,19 @@ module gift ( logic data_we, key_we; // Inter-module signal declaration + logic [63:0] data_after_middle_rounds; logic [127:0] key_after_middle_rounds; round_index_e current_round_base; - // Middle and output modules instantiation + // Middle module instantiation gift_middle_rounds gift_middle_rounds_i ( - .data_i(data_q), - .key_i(key_q), + .in_data_i(data_i), + .in_key_i(key_i), + + .state_data_i(data_q), + .state_key_i(key_q), .round_base_i(current_round_base), @@ -53,13 +57,6 @@ module gift ( .key_o(key_after_middle_rounds) ); - gift_output_round gift_output_round_i ( - .data_i(data_q), - .key_i(key_q), - - .data_o(data_o) - ); - // Flip-flop always_ff @(posedge clk_i or negedge rst_ni) begin if (!rst_ni) begin @@ -80,18 +77,13 @@ module gift ( // FSM always_comb begin : gift_cipher_fsm - // Key management - key_we = 1'b0; - key_d = key_q; - // Data write enable + // Key and data write enable + key_we = 1'b0; data_we = 1'b0; - // Stored signals, arbitrarily set by default to the rectangle output - data_d = data_q; - // Gift rectangle-specific signals - current_round_base = BASE_1; + current_round_base = BASE_INPUT; // Handshake signals in_ready_o = 1'b0; @@ -104,10 +96,9 @@ module gift ( // Take the new key, tweak and data into account key_we = 1'b1; - key_d = key_i; - data_we = 1'b1; - data_d = data_i; + + current_round_base = BASE_INPUT; // In this state, the cipher is ready to get data in_ready_o = 1'b1; @@ -123,15 +114,9 @@ module gift ( ROUNDS_INTERNAL_1: begin // Key update - key_we = 1'b1; - key_d = key_after_middle_rounds; - data_we = 1'b1; - // Take middle rounds outputs into account - data_d = data_after_middle_rounds; - // Gift rectangle-specific signals current_round_base = BASE_1; @@ -143,13 +128,8 @@ module gift ( // Key update key_we = 1'b1; - key_d = key_after_middle_rounds; - data_we = 1'b1; - // Take middle rounds outputs into account - data_d = data_after_middle_rounds; - // Gift rectangle-specific signals current_round_base = BASE_2; @@ -161,13 +141,8 @@ module gift ( // Key update key_we = 1'b1; - key_d = key_after_middle_rounds; - data_we = 1'b1; - // Take middle rounds outputs into account - data_d = data_after_middle_rounds; - // Gift rectangle-specific signals current_round_base = BASE_3; @@ -195,18 +170,18 @@ module gift ( in_ready_o = 1'b1; if (in_valid_i) begin - // Select register input + + current_round_base = BASE_INPUT; + key_we = 1'b1; data_we = 1'b1; - data_d = data_i; - key_d = key_i; - // State transition state_d = ROUNDS_INTERNAL_1; end else begin // Register input does not matter, keep its value + key_we = 1'b0; data_we = 1'b0; @@ -230,4 +205,8 @@ module gift ( end end + assign data_d = data_after_middle_rounds; + assign key_d = key_after_middle_rounds; + assign data_o = data_q; + endmodule diff --git a/rtl/gift_middle_rounds.sv b/rtl/gift_middle_rounds.sv index 9fa2ce44..312c9154 100644 --- a/rtl/gift_middle_rounds.sv +++ b/rtl/gift_middle_rounds.sv @@ -5,8 +5,14 @@ import gift_pkg::*; module gift_middle_rounds ( - input logic [63:0] data_i, - input logic [127:0] key_i, + + // Data and key coming directly from the cipher input + input logic [63:0] in_data_i, + input logic [127:0] in_key_i, + + // Data and key coming from the state register + input logic [63:0] state_data_i, + input logic [127:0] state_key_i, input round_index_e round_base_i, @@ -19,41 +25,76 @@ module gift_middle_rounds ( logic [9:0][63:0] data_states; logic [9:0][127:0] key_states; - logic [8:0][5:0] roundcsts; + logic [7:0][5:0] roundcsts; - assign data_states[0] = data_i; - assign key_states[0] = key_i; + assign data_states[0] = state_data_i; + assign key_states[0] = state_key_i; // Round constant management always_comb begin unique case (round_base_i) + BASE_INPUT: begin + // The first 4 rounds are not used in this case. + for (int k = 0; k < 4; k++) begin + roundcsts[k] = RC[4 + k]; + end + for (int k = 0; k < 4; k++) begin + roundcsts[k + 4] = RC[k]; + end + end BASE_1: begin - for (int k = 0; k < 9; k++) begin - roundcsts[k] = RC[k]; + for (int k = 0; k < 8; k++) begin + roundcsts[k] = RC[4 + k]; end end BASE_2: begin - for (int k = 0; k < 9; k++) begin - roundcsts[k] = RC[9 + k]; + for (int k = 0; k < 8; k++) begin + roundcsts[k] = RC[12 + k]; end end default: begin - for (int k = 0; k < 9; k++) begin - roundcsts[k] = RC[18 + k]; + for (int k = 0; k < 8; k++) begin + roundcsts[k] = RC[20 + k]; end end endcase end // Round instantiation - for (genvar i = 0; i < 9; i++) begin : gen_rounds + for (genvar k = 0; k < 4; k++) begin : gen_pre_inject_rounds gift_round gift_round_i ( - .data_i(data_states[i]), - .key_i(key_states[i]), - .RC_i(roundcsts[i]), + .data_i(data_states[k]), + .key_i(key_states[k]), + .RC_i(roundcsts[k]), - .data_o(data_states[i+1]), - .key_o(key_states[i+1]) + .data_o(data_states[k+1]), + .key_o(key_states[k+1]) + ); + end + + // Input data injection management + always_comb begin + unique case (round_base_i) + BASE_INPUT: begin + data_states[5] = in_data_i; + key_states[5] = in_key_i; + end + default: begin + data_states[5] = data_states[4]; + key_states[5] = key_states[4]; + end + endcase + end + + + for (genvar k = 4; k < 8; k++) begin : gen_post_inject_rounds + gift_round gift_round_i ( + .data_i(data_states[k + 1]), + .key_i(key_states[k + 1]), + .RC_i(roundcsts[k]), + + .data_o(data_states[k + 2]), + .key_o(key_states[k + 2]) ); end diff --git a/rtl/gift_output_round.sv b/rtl/gift_output_round.sv deleted file mode 100644 index b2d64084..00000000 --- a/rtl/gift_output_round.sv +++ /dev/null @@ -1,51 +0,0 @@ -module gift_output_round ( - input logic [63:0] data_i, - input logic [127:0] key_i, - - output logic [63:0] data_o -); - - import gift_pkg::*; - - logic [63:0] data_after_sbox; - logic [63:0] data_after_permut; - logic [63:0] data_after_key; - - logic [63:0] data_state; - - always_comb begin : p_gift_round - - data_state = data_i; - - data_state = sbox_layer(data_state); - - data_after_sbox = data_state; - - data_state = permut_layer(data_after_sbox); - - data_after_permut = data_state; - - // Add round key - - for (int k = 0; k < 16; k++) begin - data_state[4 * k] ^= key_i[k]; - data_state[4 * k + 1] ^= key_i[k + 16]; - end - - data_after_key = data_state; - - // Add round constant - - data_state[63] ^= 1; - data_state[23] ^= RC[27][5]; - data_state[19] ^= RC[27][4]; - data_state[15] ^= RC[27][3]; - data_state[11] ^= RC[27][2]; - data_state[7] ^= RC[27][1]; - data_state[3] ^= RC[27][0]; - - end - - assign data_o = data_state; - -endmodule diff --git a/rtl/gift_pkg.sv b/rtl/gift_pkg.sv index 4aeb596a..4ee76d17 100644 --- a/rtl/gift_pkg.sv +++ b/rtl/gift_pkg.sv @@ -25,6 +25,7 @@ package gift_pkg; }; typedef enum logic [1:0] { + BASE_INPUT, BASE_1, BASE_2, BASE_3