Line Coverage for Module :
prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=1,UseOldKeySched=0,HalfwayDataReg=0,HalfwayKeyReg=0 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 35 | 35 | 100.00 |
ALWAYS | 56 | 7 | 7 | 100.00 |
ALWAYS | 75 | 3 | 3 | 100.00 |
CONT_ASSIGN | 99 | 1 | 1 | 100.00 |
CONT_ASSIGN | 100 | 1 | 1 | 100.00 |
CONT_ASSIGN | 101 | 1 | 1 | 100.00 |
ALWAYS | 114 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
ALWAYS | 154 | 3 | 3 | 100.00 |
CONT_ASSIGN | 186 | 1 | 1 | 100.00 |
CONT_ASSIGN | 187 | 1 | 1 | 100.00 |
CONT_ASSIGN | 190 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 227 | 3 | 3 | 100.00 |
55 always_comb begin : p_key_expansion
56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]};
Tests: T1 T2 T3
58 1/1 k1_d = key_i[DataWidth-1:0];
Tests: T1 T2 T3
59
60 // modify key for decryption
61 1/1 if (dec_i) begin
Tests: T1 T2 T3
62 1/1 k0 = k0_prime_d;
Tests: T1 T2 T3
63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
65 end
MISSING_ELSE
66 end
67
68 if (UseOldKeySched) begin : gen_legacy_keyschedule
69 // In this case we constantly use k1.
70 assign k0_new_d = k1_d;
71 end else begin : gen_new_keyschedule
72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
73 // In this case we alternate between k1 and k0.
74 always_comb begin : p_new_keyschedule_k0_alpha
75 1/1 k0_new_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode.
77 1/1 if (dec_i) begin
Tests: T1 T2 T3
78 1/1 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
79 end
MISSING_ELSE
80 end
81 end
82
83 if (HalfwayKeyReg) begin : gen_key_reg
84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg
85 if (!rst_ni) begin
86 k1_q <= '0;
87 k0_prime_q <= '0;
88 k0_new_q <= '0;
89 end else begin
90 if (valid_i) begin
91 k1_q <= k1_d;
92 k0_prime_q <= k0_prime_d;
93 k0_new_q <= k0_new_d;
94 end
95 end
96 end
97 end else begin : gen_no_key_reg
98 // just pass the key through in this case
99 1/1 assign k1_q = k1_d;
Tests: T1 T2 T3
100 1/1 assign k0_prime_q = k0_prime_d;
Tests: T1 T2 T3
101 1/1 assign k0_new_q = k0_new_d;
Tests: T1 T2 T3
102 end
103
104 //////////////
105 // datapath //
106 //////////////
107
108 // State variable for holding the rounds
109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo;
110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi;
111
112 // pre-round XOR
113 always_comb begin : p_pre_round_xor
114 1/1 data_state_lo[0] = data_i ^ k0;
Tests: T1 T2 T3
115 1/1 data_state_lo[0] ^= k1_d;
Tests: T1 T2 T3
116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0];
Tests: T1 T2 T3
117 end
118
119 // forward pass
120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass
121 logic [DataWidth-1:0] data_state_round;
122 if (DataWidth == 64) begin : gen_fwd_d64
123 always_comb begin : p_fwd_d64
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
129 end
130 end else begin : gen_fwd_d32
131 always_comb begin : p_fwd_d32
132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1],
133 prim_cipher_pkg::PRINCE_SBOX4);
134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round);
135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round,
136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
137 end
138 end
139 logic [DataWidth-1:0] data_state_xor;
140 1/1 assign data_state_xor = data_state_round ^
Tests: T1 T2 T3
141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0];
142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
143 if (k % 2 == 1) begin : gen_fwd_key_odd
144 1/1 assign data_state_lo[k] = data_state_xor ^ k0_new_d;
Tests: T1 T2 T3
145 end else begin : gen_fwd_key_even
146 assign data_state_lo[k] = data_state_xor ^ k1_d;
147 end
148 end
149
150 // middle part
151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle;
152 if (DataWidth == 64) begin : gen_middle_d64
153 always_comb begin : p_middle_d64
154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf],
Tests: T1 T2 T3
155 prim_cipher_pkg::PRINCE_SBOX4);
156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q);
Tests: T1 T2 T3
157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle,
Tests: T1 T2 T3
158 prim_cipher_pkg::PRINCE_SBOX4_INV);
159 end
160 end else begin : gen_middle_d32
161 always_comb begin : p_middle_d32
162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf],
163 prim_cipher_pkg::PRINCE_SBOX4);
164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q);
165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle,
166 prim_cipher_pkg::PRINCE_SBOX4_INV);
167 end
168 end
169
170 if (HalfwayDataReg) begin : gen_data_reg
171 logic valid_q;
172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg
173 if (!rst_ni) begin
174 valid_q <= 1'b0;
175 data_state_middle_q <= '0;
176 end else begin
177 valid_q <= valid_i;
178 if (valid_i) begin
179 data_state_middle_q <= data_state_middle_d;
180 end
181 end
182 end
183 assign valid_o = valid_q;
184 end else begin : gen_no_data_reg
185 // just pass data through in this case
186 1/1 assign data_state_middle_q = data_state_middle_d;
Tests: T1 T2 T3
187 1/1 assign valid_o = valid_i;
Tests: T1 T2 T3
188 end
189
190 1/1 assign data_state_hi[0] = data_state_middle;
Tests: T1 T2 T3
191
192 // backward pass
193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass
194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1;
195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd
197 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q;
Tests: T1 T2 T3
198 end else begin : gen_bkwd_key_even
199 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q;
200 end
201 // the construction is reflective, hence the subtraction with NumRoundsHalf
202 1/1 assign data_state_xor1 = data_state_xor0 ^
Tests: T1 T2 T3
203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0];
204
205 logic [DataWidth-1:0] data_state_bwd;
206 if (DataWidth == 64) begin : gen_bwd_d64
207 always_comb begin : p_bwd_d64
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
212 prim_cipher_pkg::PRINCE_SBOX4_INV);
213 end
214 end else begin : gen_bwd_d32
215 always_comb begin : p_bwd_d32
216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1,
217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd);
219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd,
220 prim_cipher_pkg::PRINCE_SBOX4_INV);
221 end
222 end
223 end
224
225 // post-rounds
226 always_comb begin : p_post_round_xor
227 1/1 data_o = data_state_hi[NumRoundsHalf] ^
Tests: T1 T2 T3
228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0];
229 1/1 data_o ^= k1_q;
Tests: T1 T2 T3
230 1/1 data_o ^= k0_prime_q;
Tests: T1 T2 T3
Line Coverage for Module :
prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=2,UseOldKeySched=0,HalfwayDataReg=0,HalfwayKeyReg=0 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 45 | 45 | 100.00 |
ALWAYS | 56 | 7 | 7 | 100.00 |
ALWAYS | 75 | 3 | 3 | 100.00 |
CONT_ASSIGN | 99 | 1 | 1 | 100.00 |
CONT_ASSIGN | 100 | 1 | 1 | 100.00 |
CONT_ASSIGN | 101 | 1 | 1 | 100.00 |
ALWAYS | 114 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 146 | 1 | 1 | 100.00 |
ALWAYS | 154 | 3 | 3 | 100.00 |
CONT_ASSIGN | 186 | 1 | 1 | 100.00 |
CONT_ASSIGN | 187 | 1 | 1 | 100.00 |
CONT_ASSIGN | 190 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 227 | 3 | 3 | 100.00 |
55 always_comb begin : p_key_expansion
56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]};
Tests: T1 T2 T3
58 1/1 k1_d = key_i[DataWidth-1:0];
Tests: T1 T2 T3
59
60 // modify key for decryption
61 1/1 if (dec_i) begin
Tests: T1 T2 T3
62 1/1 k0 = k0_prime_d;
Tests: T1 T2 T3
63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
65 end
MISSING_ELSE
66 end
67
68 if (UseOldKeySched) begin : gen_legacy_keyschedule
69 // In this case we constantly use k1.
70 assign k0_new_d = k1_d;
71 end else begin : gen_new_keyschedule
72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
73 // In this case we alternate between k1 and k0.
74 always_comb begin : p_new_keyschedule_k0_alpha
75 1/1 k0_new_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode.
77 1/1 if (dec_i) begin
Tests: T1 T2 T3
78 1/1 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
79 end
MISSING_ELSE
80 end
81 end
82
83 if (HalfwayKeyReg) begin : gen_key_reg
84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg
85 if (!rst_ni) begin
86 k1_q <= '0;
87 k0_prime_q <= '0;
88 k0_new_q <= '0;
89 end else begin
90 if (valid_i) begin
91 k1_q <= k1_d;
92 k0_prime_q <= k0_prime_d;
93 k0_new_q <= k0_new_d;
94 end
95 end
96 end
97 end else begin : gen_no_key_reg
98 // just pass the key through in this case
99 1/1 assign k1_q = k1_d;
Tests: T1 T2 T3
100 1/1 assign k0_prime_q = k0_prime_d;
Tests: T1 T2 T3
101 1/1 assign k0_new_q = k0_new_d;
Tests: T1 T2 T3
102 end
103
104 //////////////
105 // datapath //
106 //////////////
107
108 // State variable for holding the rounds
109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo;
110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi;
111
112 // pre-round XOR
113 always_comb begin : p_pre_round_xor
114 1/1 data_state_lo[0] = data_i ^ k0;
Tests: T1 T2 T3
115 1/1 data_state_lo[0] ^= k1_d;
Tests: T1 T2 T3
116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0];
Tests: T1 T2 T3
117 end
118
119 // forward pass
120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass
121 logic [DataWidth-1:0] data_state_round;
122 if (DataWidth == 64) begin : gen_fwd_d64
123 always_comb begin : p_fwd_d64
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 1
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
129 end
130 end else begin : gen_fwd_d32
131 always_comb begin : p_fwd_d32
132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1],
133 prim_cipher_pkg::PRINCE_SBOX4);
134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round);
135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round,
136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
137 end
138 end
139 logic [DataWidth-1:0] data_state_xor;
140 2/2 assign data_state_xor = data_state_round ^
Tests: T1 T2 T3 | T1 T2 T3
141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0];
142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
143 if (k % 2 == 1) begin : gen_fwd_key_odd
144 1/1 assign data_state_lo[k] = data_state_xor ^ k0_new_d;
Tests: T1 T2 T3
145 end else begin : gen_fwd_key_even
146 1/1 assign data_state_lo[k] = data_state_xor ^ k1_d;
Tests: T1 T2 T3
147 end
148 end
149
150 // middle part
151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle;
152 if (DataWidth == 64) begin : gen_middle_d64
153 always_comb begin : p_middle_d64
154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf],
Tests: T1 T2 T3
155 prim_cipher_pkg::PRINCE_SBOX4);
156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q);
Tests: T1 T2 T3
157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle,
Tests: T1 T2 T3
158 prim_cipher_pkg::PRINCE_SBOX4_INV);
159 end
160 end else begin : gen_middle_d32
161 always_comb begin : p_middle_d32
162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf],
163 prim_cipher_pkg::PRINCE_SBOX4);
164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q);
165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle,
166 prim_cipher_pkg::PRINCE_SBOX4_INV);
167 end
168 end
169
170 if (HalfwayDataReg) begin : gen_data_reg
171 logic valid_q;
172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg
173 if (!rst_ni) begin
174 valid_q <= 1'b0;
175 data_state_middle_q <= '0;
176 end else begin
177 valid_q <= valid_i;
178 if (valid_i) begin
179 data_state_middle_q <= data_state_middle_d;
180 end
181 end
182 end
183 assign valid_o = valid_q;
184 end else begin : gen_no_data_reg
185 // just pass data through in this case
186 1/1 assign data_state_middle_q = data_state_middle_d;
Tests: T1 T2 T3
187 1/1 assign valid_o = valid_i;
Tests: T1 T2 T3
188 end
189
190 1/1 assign data_state_hi[0] = data_state_middle;
Tests: T1 T2 T3
191
192 // backward pass
193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass
194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1;
195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd
197 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q;
Tests: T1 T2 T3
198 end else begin : gen_bkwd_key_even
199 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q;
Tests: T1 T2 T3
200 end
201 // the construction is reflective, hence the subtraction with NumRoundsHalf
202 2/2 assign data_state_xor1 = data_state_xor0 ^
Tests: T1 T2 T3 | T1 T2 T3
203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0];
204
205 logic [DataWidth-1:0] data_state_bwd;
206 if (DataWidth == 64) begin : gen_bwd_d64
207 always_comb begin : p_bwd_d64
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 2
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
212 prim_cipher_pkg::PRINCE_SBOX4_INV);
213 end
214 end else begin : gen_bwd_d32
215 always_comb begin : p_bwd_d32
216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1,
217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd);
219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd,
220 prim_cipher_pkg::PRINCE_SBOX4_INV);
221 end
222 end
223 end
224
225 // post-rounds
226 always_comb begin : p_post_round_xor
227 1/1 data_o = data_state_hi[NumRoundsHalf] ^
Tests: T1 T2 T3
228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0];
229 1/1 data_o ^= k1_q;
Tests: T1 T2 T3
230 1/1 data_o ^= k0_prime_q;
Tests: T1 T2 T3
Line Coverage for Module :
prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=3,UseOldKeySched=0,HalfwayDataReg=0,HalfwayKeyReg=0 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 55 | 55 | 100.00 |
ALWAYS | 56 | 7 | 7 | 100.00 |
ALWAYS | 75 | 3 | 3 | 100.00 |
CONT_ASSIGN | 99 | 1 | 1 | 100.00 |
CONT_ASSIGN | 100 | 1 | 1 | 100.00 |
CONT_ASSIGN | 101 | 1 | 1 | 100.00 |
ALWAYS | 114 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 146 | 1 | 1 | 100.00 |
ALWAYS | 154 | 3 | 3 | 100.00 |
CONT_ASSIGN | 186 | 1 | 1 | 100.00 |
CONT_ASSIGN | 187 | 1 | 1 | 100.00 |
CONT_ASSIGN | 190 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 227 | 3 | 3 | 100.00 |
55 always_comb begin : p_key_expansion
56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]};
Tests: T1 T2 T3
58 1/1 k1_d = key_i[DataWidth-1:0];
Tests: T1 T2 T3
59
60 // modify key for decryption
61 1/1 if (dec_i) begin
Tests: T1 T2 T3
62 1/1 k0 = k0_prime_d;
Tests: T1 T2 T3
63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
65 end
MISSING_ELSE
66 end
67
68 if (UseOldKeySched) begin : gen_legacy_keyschedule
69 // In this case we constantly use k1.
70 assign k0_new_d = k1_d;
71 end else begin : gen_new_keyschedule
72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
73 // In this case we alternate between k1 and k0.
74 always_comb begin : p_new_keyschedule_k0_alpha
75 1/1 k0_new_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode.
77 1/1 if (dec_i) begin
Tests: T1 T2 T3
78 1/1 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
79 end
MISSING_ELSE
80 end
81 end
82
83 if (HalfwayKeyReg) begin : gen_key_reg
84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg
85 if (!rst_ni) begin
86 k1_q <= '0;
87 k0_prime_q <= '0;
88 k0_new_q <= '0;
89 end else begin
90 if (valid_i) begin
91 k1_q <= k1_d;
92 k0_prime_q <= k0_prime_d;
93 k0_new_q <= k0_new_d;
94 end
95 end
96 end
97 end else begin : gen_no_key_reg
98 // just pass the key through in this case
99 1/1 assign k1_q = k1_d;
Tests: T1 T2 T3
100 1/1 assign k0_prime_q = k0_prime_d;
Tests: T1 T2 T3
101 1/1 assign k0_new_q = k0_new_d;
Tests: T1 T2 T3
102 end
103
104 //////////////
105 // datapath //
106 //////////////
107
108 // State variable for holding the rounds
109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo;
110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi;
111
112 // pre-round XOR
113 always_comb begin : p_pre_round_xor
114 1/1 data_state_lo[0] = data_i ^ k0;
Tests: T1 T2 T3
115 1/1 data_state_lo[0] ^= k1_d;
Tests: T1 T2 T3
116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0];
Tests: T1 T2 T3
117 end
118
119 // forward pass
120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass
121 logic [DataWidth-1:0] data_state_round;
122 if (DataWidth == 64) begin : gen_fwd_d64
123 always_comb begin : p_fwd_d64
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 1
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 2
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
129 end
130 end else begin : gen_fwd_d32
131 always_comb begin : p_fwd_d32
132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1],
133 prim_cipher_pkg::PRINCE_SBOX4);
134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round);
135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round,
136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
137 end
138 end
139 logic [DataWidth-1:0] data_state_xor;
140 3/3 assign data_state_xor = data_state_round ^
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0];
142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
143 if (k % 2 == 1) begin : gen_fwd_key_odd
144 2/2 assign data_state_lo[k] = data_state_xor ^ k0_new_d;
Tests: T1 T2 T3 | T1 T2 T3
145 end else begin : gen_fwd_key_even
146 1/1 assign data_state_lo[k] = data_state_xor ^ k1_d;
Tests: T1 T2 T3
147 end
148 end
149
150 // middle part
151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle;
152 if (DataWidth == 64) begin : gen_middle_d64
153 always_comb begin : p_middle_d64
154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf],
Tests: T1 T2 T3
155 prim_cipher_pkg::PRINCE_SBOX4);
156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q);
Tests: T1 T2 T3
157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle,
Tests: T1 T2 T3
158 prim_cipher_pkg::PRINCE_SBOX4_INV);
159 end
160 end else begin : gen_middle_d32
161 always_comb begin : p_middle_d32
162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf],
163 prim_cipher_pkg::PRINCE_SBOX4);
164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q);
165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle,
166 prim_cipher_pkg::PRINCE_SBOX4_INV);
167 end
168 end
169
170 if (HalfwayDataReg) begin : gen_data_reg
171 logic valid_q;
172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg
173 if (!rst_ni) begin
174 valid_q <= 1'b0;
175 data_state_middle_q <= '0;
176 end else begin
177 valid_q <= valid_i;
178 if (valid_i) begin
179 data_state_middle_q <= data_state_middle_d;
180 end
181 end
182 end
183 assign valid_o = valid_q;
184 end else begin : gen_no_data_reg
185 // just pass data through in this case
186 1/1 assign data_state_middle_q = data_state_middle_d;
Tests: T1 T2 T3
187 1/1 assign valid_o = valid_i;
Tests: T1 T2 T3
188 end
189
190 1/1 assign data_state_hi[0] = data_state_middle;
Tests: T1 T2 T3
191
192 // backward pass
193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass
194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1;
195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd
197 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q;
Tests: T1 T2 T3 | T1 T2 T3
198 end else begin : gen_bkwd_key_even
199 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q;
Tests: T1 T2 T3
200 end
201 // the construction is reflective, hence the subtraction with NumRoundsHalf
202 3/3 assign data_state_xor1 = data_state_xor0 ^
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0];
204
205 logic [DataWidth-1:0] data_state_bwd;
206 if (DataWidth == 64) begin : gen_bwd_d64
207 always_comb begin : p_bwd_d64
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 3
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 4
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
212 prim_cipher_pkg::PRINCE_SBOX4_INV);
213 end
214 end else begin : gen_bwd_d32
215 always_comb begin : p_bwd_d32
216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1,
217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd);
219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd,
220 prim_cipher_pkg::PRINCE_SBOX4_INV);
221 end
222 end
223 end
224
225 // post-rounds
226 always_comb begin : p_post_round_xor
227 1/1 data_o = data_state_hi[NumRoundsHalf] ^
Tests: T1 T2 T3
228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0];
229 1/1 data_o ^= k1_q;
Tests: T1 T2 T3
230 1/1 data_o ^= k0_prime_q;
Tests: T1 T2 T3
Line Coverage for Module :
prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=4,UseOldKeySched=0,HalfwayDataReg=0,HalfwayKeyReg=0 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 65 | 65 | 100.00 |
ALWAYS | 56 | 7 | 7 | 100.00 |
ALWAYS | 75 | 3 | 3 | 100.00 |
CONT_ASSIGN | 99 | 1 | 1 | 100.00 |
CONT_ASSIGN | 100 | 1 | 1 | 100.00 |
CONT_ASSIGN | 101 | 1 | 1 | 100.00 |
ALWAYS | 114 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 146 | 1 | 1 | 100.00 |
CONT_ASSIGN | 146 | 1 | 1 | 100.00 |
ALWAYS | 154 | 3 | 3 | 100.00 |
CONT_ASSIGN | 186 | 1 | 1 | 100.00 |
CONT_ASSIGN | 187 | 1 | 1 | 100.00 |
CONT_ASSIGN | 190 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 227 | 3 | 3 | 100.00 |
55 always_comb begin : p_key_expansion
56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]};
Tests: T1 T2 T3
58 1/1 k1_d = key_i[DataWidth-1:0];
Tests: T1 T2 T3
59
60 // modify key for decryption
61 1/1 if (dec_i) begin
Tests: T1 T2 T3
62 1/1 k0 = k0_prime_d;
Tests: T1 T2 T3
63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
65 end
MISSING_ELSE
66 end
67
68 if (UseOldKeySched) begin : gen_legacy_keyschedule
69 // In this case we constantly use k1.
70 assign k0_new_d = k1_d;
71 end else begin : gen_new_keyschedule
72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
73 // In this case we alternate between k1 and k0.
74 always_comb begin : p_new_keyschedule_k0_alpha
75 1/1 k0_new_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode.
77 1/1 if (dec_i) begin
Tests: T1 T2 T3
78 1/1 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
79 end
MISSING_ELSE
80 end
81 end
82
83 if (HalfwayKeyReg) begin : gen_key_reg
84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg
85 if (!rst_ni) begin
86 k1_q <= '0;
87 k0_prime_q <= '0;
88 k0_new_q <= '0;
89 end else begin
90 if (valid_i) begin
91 k1_q <= k1_d;
92 k0_prime_q <= k0_prime_d;
93 k0_new_q <= k0_new_d;
94 end
95 end
96 end
97 end else begin : gen_no_key_reg
98 // just pass the key through in this case
99 1/1 assign k1_q = k1_d;
Tests: T1 T2 T3
100 1/1 assign k0_prime_q = k0_prime_d;
Tests: T1 T2 T3
101 1/1 assign k0_new_q = k0_new_d;
Tests: T1 T2 T3
102 end
103
104 //////////////
105 // datapath //
106 //////////////
107
108 // State variable for holding the rounds
109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo;
110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi;
111
112 // pre-round XOR
113 always_comb begin : p_pre_round_xor
114 1/1 data_state_lo[0] = data_i ^ k0;
Tests: T1 T2 T3
115 1/1 data_state_lo[0] ^= k1_d;
Tests: T1 T2 T3
116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0];
Tests: T1 T2 T3
117 end
118
119 // forward pass
120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass
121 logic [DataWidth-1:0] data_state_round;
122 if (DataWidth == 64) begin : gen_fwd_d64
123 always_comb begin : p_fwd_d64
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 1
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 2
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 3
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
129 end
130 end else begin : gen_fwd_d32
131 always_comb begin : p_fwd_d32
132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1],
133 prim_cipher_pkg::PRINCE_SBOX4);
134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round);
135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round,
136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
137 end
138 end
139 logic [DataWidth-1:0] data_state_xor;
140 4/4 assign data_state_xor = data_state_round ^
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0];
142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
143 if (k % 2 == 1) begin : gen_fwd_key_odd
144 2/2 assign data_state_lo[k] = data_state_xor ^ k0_new_d;
Tests: T1 T2 T3 | T1 T2 T3
145 end else begin : gen_fwd_key_even
146 2/2 assign data_state_lo[k] = data_state_xor ^ k1_d;
Tests: T1 T2 T3 | T1 T2 T3
147 end
148 end
149
150 // middle part
151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle;
152 if (DataWidth == 64) begin : gen_middle_d64
153 always_comb begin : p_middle_d64
154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf],
Tests: T1 T2 T3
155 prim_cipher_pkg::PRINCE_SBOX4);
156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q);
Tests: T1 T2 T3
157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle,
Tests: T1 T2 T3
158 prim_cipher_pkg::PRINCE_SBOX4_INV);
159 end
160 end else begin : gen_middle_d32
161 always_comb begin : p_middle_d32
162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf],
163 prim_cipher_pkg::PRINCE_SBOX4);
164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q);
165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle,
166 prim_cipher_pkg::PRINCE_SBOX4_INV);
167 end
168 end
169
170 if (HalfwayDataReg) begin : gen_data_reg
171 logic valid_q;
172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg
173 if (!rst_ni) begin
174 valid_q <= 1'b0;
175 data_state_middle_q <= '0;
176 end else begin
177 valid_q <= valid_i;
178 if (valid_i) begin
179 data_state_middle_q <= data_state_middle_d;
180 end
181 end
182 end
183 assign valid_o = valid_q;
184 end else begin : gen_no_data_reg
185 // just pass data through in this case
186 1/1 assign data_state_middle_q = data_state_middle_d;
Tests: T1 T2 T3
187 1/1 assign valid_o = valid_i;
Tests: T1 T2 T3
188 end
189
190 1/1 assign data_state_hi[0] = data_state_middle;
Tests: T1 T2 T3
191
192 // backward pass
193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass
194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1;
195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd
197 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q;
Tests: T1 T2 T3 | T1 T2 T3
198 end else begin : gen_bkwd_key_even
199 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q;
Tests: T1 T2 T3 | T1 T2 T3
200 end
201 // the construction is reflective, hence the subtraction with NumRoundsHalf
202 4/4 assign data_state_xor1 = data_state_xor0 ^
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0];
204
205 logic [DataWidth-1:0] data_state_bwd;
206 if (DataWidth == 64) begin : gen_bwd_d64
207 always_comb begin : p_bwd_d64
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 4
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 5
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 6
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
212 prim_cipher_pkg::PRINCE_SBOX4_INV);
213 end
214 end else begin : gen_bwd_d32
215 always_comb begin : p_bwd_d32
216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1,
217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd);
219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd,
220 prim_cipher_pkg::PRINCE_SBOX4_INV);
221 end
222 end
223 end
224
225 // post-rounds
226 always_comb begin : p_post_round_xor
227 1/1 data_o = data_state_hi[NumRoundsHalf] ^
Tests: T1 T2 T3
228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0];
229 1/1 data_o ^= k1_q;
Tests: T1 T2 T3
230 1/1 data_o ^= k0_prime_q;
Tests: T1 T2 T3
Line Coverage for Module :
prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=5,UseOldKeySched=0,HalfwayDataReg=0,HalfwayKeyReg=0 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 75 | 75 | 100.00 |
ALWAYS | 56 | 7 | 7 | 100.00 |
ALWAYS | 75 | 3 | 3 | 100.00 |
CONT_ASSIGN | 99 | 1 | 1 | 100.00 |
CONT_ASSIGN | 100 | 1 | 1 | 100.00 |
CONT_ASSIGN | 101 | 1 | 1 | 100.00 |
ALWAYS | 114 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 146 | 1 | 1 | 100.00 |
CONT_ASSIGN | 146 | 1 | 1 | 100.00 |
ALWAYS | 154 | 3 | 3 | 100.00 |
CONT_ASSIGN | 186 | 1 | 1 | 100.00 |
CONT_ASSIGN | 187 | 1 | 1 | 100.00 |
CONT_ASSIGN | 190 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 227 | 3 | 3 | 100.00 |
55 always_comb begin : p_key_expansion
56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]};
Tests: T1 T2 T3
58 1/1 k1_d = key_i[DataWidth-1:0];
Tests: T1 T2 T3
59
60 // modify key for decryption
61 1/1 if (dec_i) begin
Tests: T1 T2 T3
62 1/1 k0 = k0_prime_d;
Tests: T1 T2 T3
63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
65 end
MISSING_ELSE
66 end
67
68 if (UseOldKeySched) begin : gen_legacy_keyschedule
69 // In this case we constantly use k1.
70 assign k0_new_d = k1_d;
71 end else begin : gen_new_keyschedule
72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
73 // In this case we alternate between k1 and k0.
74 always_comb begin : p_new_keyschedule_k0_alpha
75 1/1 k0_new_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode.
77 1/1 if (dec_i) begin
Tests: T1 T2 T3
78 1/1 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
79 end
MISSING_ELSE
80 end
81 end
82
83 if (HalfwayKeyReg) begin : gen_key_reg
84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg
85 if (!rst_ni) begin
86 k1_q <= '0;
87 k0_prime_q <= '0;
88 k0_new_q <= '0;
89 end else begin
90 if (valid_i) begin
91 k1_q <= k1_d;
92 k0_prime_q <= k0_prime_d;
93 k0_new_q <= k0_new_d;
94 end
95 end
96 end
97 end else begin : gen_no_key_reg
98 // just pass the key through in this case
99 1/1 assign k1_q = k1_d;
Tests: T1 T2 T3
100 1/1 assign k0_prime_q = k0_prime_d;
Tests: T1 T2 T3
101 1/1 assign k0_new_q = k0_new_d;
Tests: T1 T2 T3
102 end
103
104 //////////////
105 // datapath //
106 //////////////
107
108 // State variable for holding the rounds
109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo;
110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi;
111
112 // pre-round XOR
113 always_comb begin : p_pre_round_xor
114 1/1 data_state_lo[0] = data_i ^ k0;
Tests: T1 T2 T3
115 1/1 data_state_lo[0] ^= k1_d;
Tests: T1 T2 T3
116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0];
Tests: T1 T2 T3
117 end
118
119 // forward pass
120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass
121 logic [DataWidth-1:0] data_state_round;
122 if (DataWidth == 64) begin : gen_fwd_d64
123 always_comb begin : p_fwd_d64
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 1
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 2
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 3
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 4
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
129 end
130 end else begin : gen_fwd_d32
131 always_comb begin : p_fwd_d32
132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1],
133 prim_cipher_pkg::PRINCE_SBOX4);
134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round);
135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round,
136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
137 end
138 end
139 logic [DataWidth-1:0] data_state_xor;
140 5/5 assign data_state_xor = data_state_round ^
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0];
142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
143 if (k % 2 == 1) begin : gen_fwd_key_odd
144 3/3 assign data_state_lo[k] = data_state_xor ^ k0_new_d;
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
145 end else begin : gen_fwd_key_even
146 2/2 assign data_state_lo[k] = data_state_xor ^ k1_d;
Tests: T1 T2 T3 | T1 T2 T3
147 end
148 end
149
150 // middle part
151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle;
152 if (DataWidth == 64) begin : gen_middle_d64
153 always_comb begin : p_middle_d64
154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf],
Tests: T1 T2 T3
155 prim_cipher_pkg::PRINCE_SBOX4);
156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q);
Tests: T1 T2 T3
157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle,
Tests: T1 T2 T3
158 prim_cipher_pkg::PRINCE_SBOX4_INV);
159 end
160 end else begin : gen_middle_d32
161 always_comb begin : p_middle_d32
162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf],
163 prim_cipher_pkg::PRINCE_SBOX4);
164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q);
165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle,
166 prim_cipher_pkg::PRINCE_SBOX4_INV);
167 end
168 end
169
170 if (HalfwayDataReg) begin : gen_data_reg
171 logic valid_q;
172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg
173 if (!rst_ni) begin
174 valid_q <= 1'b0;
175 data_state_middle_q <= '0;
176 end else begin
177 valid_q <= valid_i;
178 if (valid_i) begin
179 data_state_middle_q <= data_state_middle_d;
180 end
181 end
182 end
183 assign valid_o = valid_q;
184 end else begin : gen_no_data_reg
185 // just pass data through in this case
186 1/1 assign data_state_middle_q = data_state_middle_d;
Tests: T1 T2 T3
187 1/1 assign valid_o = valid_i;
Tests: T1 T2 T3
188 end
189
190 1/1 assign data_state_hi[0] = data_state_middle;
Tests: T1 T2 T3
191
192 // backward pass
193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass
194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1;
195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd
197 3/3 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q;
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
198 end else begin : gen_bkwd_key_even
199 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q;
Tests: T1 T2 T3 | T1 T2 T3
200 end
201 // the construction is reflective, hence the subtraction with NumRoundsHalf
202 5/5 assign data_state_xor1 = data_state_xor0 ^
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0];
204
205 logic [DataWidth-1:0] data_state_bwd;
206 if (DataWidth == 64) begin : gen_bwd_d64
207 always_comb begin : p_bwd_d64
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 5
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 6
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 7
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 8
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
212 prim_cipher_pkg::PRINCE_SBOX4_INV);
213 end
214 end else begin : gen_bwd_d32
215 always_comb begin : p_bwd_d32
216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1,
217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd);
219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd,
220 prim_cipher_pkg::PRINCE_SBOX4_INV);
221 end
222 end
223 end
224
225 // post-rounds
226 always_comb begin : p_post_round_xor
227 1/1 data_o = data_state_hi[NumRoundsHalf] ^
Tests: T1 T2 T3
228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0];
229 1/1 data_o ^= k1_q;
Tests: T1 T2 T3
230 1/1 data_o ^= k0_prime_q;
Tests: T1 T2 T3
Line Coverage for Module :
prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=1,UseOldKeySched=0,HalfwayDataReg=1,HalfwayKeyReg=1 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 45 | 45 | 100.00 |
ALWAYS | 56 | 7 | 7 | 100.00 |
ALWAYS | 75 | 3 | 3 | 100.00 |
ALWAYS | 85 | 8 | 8 | 100.00 |
ALWAYS | 114 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
ALWAYS | 154 | 3 | 3 | 100.00 |
ALWAYS | 173 | 6 | 6 | 100.00 |
CONT_ASSIGN | 183 | 1 | 1 | 100.00 |
CONT_ASSIGN | 190 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 227 | 3 | 3 | 100.00 |
55 always_comb begin : p_key_expansion
56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]};
Tests: T1 T2 T3
58 1/1 k1_d = key_i[DataWidth-1:0];
Tests: T1 T2 T3
59
60 // modify key for decryption
61 1/1 if (dec_i) begin
Tests: T1 T2 T3
62 1/1 k0 = k0_prime_d;
Tests: T1 T2 T3
63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
65 end
MISSING_ELSE
66 end
67
68 if (UseOldKeySched) begin : gen_legacy_keyschedule
69 // In this case we constantly use k1.
70 assign k0_new_d = k1_d;
71 end else begin : gen_new_keyschedule
72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
73 // In this case we alternate between k1 and k0.
74 always_comb begin : p_new_keyschedule_k0_alpha
75 1/1 k0_new_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode.
77 1/1 if (dec_i) begin
Tests: T1 T2 T3
78 1/1 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
79 end
MISSING_ELSE
80 end
81 end
82
83 if (HalfwayKeyReg) begin : gen_key_reg
84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg
85 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
86 1/1 k1_q <= '0;
Tests: T1 T2 T3
87 1/1 k0_prime_q <= '0;
Tests: T1 T2 T3
88 1/1 k0_new_q <= '0;
Tests: T1 T2 T3
89 end else begin
90 1/1 if (valid_i) begin
Tests: T1 T2 T3
91 1/1 k1_q <= k1_d;
Tests: T1 T2 T3
92 1/1 k0_prime_q <= k0_prime_d;
Tests: T1 T2 T3
93 1/1 k0_new_q <= k0_new_d;
Tests: T1 T2 T3
94 end
MISSING_ELSE
95 end
96 end
97 end else begin : gen_no_key_reg
98 // just pass the key through in this case
99 assign k1_q = k1_d;
100 assign k0_prime_q = k0_prime_d;
101 assign k0_new_q = k0_new_d;
102 end
103
104 //////////////
105 // datapath //
106 //////////////
107
108 // State variable for holding the rounds
109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo;
110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi;
111
112 // pre-round XOR
113 always_comb begin : p_pre_round_xor
114 1/1 data_state_lo[0] = data_i ^ k0;
Tests: T1 T2 T3
115 1/1 data_state_lo[0] ^= k1_d;
Tests: T1 T2 T3
116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0];
Tests: T1 T2 T3
117 end
118
119 // forward pass
120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass
121 logic [DataWidth-1:0] data_state_round;
122 if (DataWidth == 64) begin : gen_fwd_d64
123 always_comb begin : p_fwd_d64
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
129 end
130 end else begin : gen_fwd_d32
131 always_comb begin : p_fwd_d32
132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1],
133 prim_cipher_pkg::PRINCE_SBOX4);
134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round);
135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round,
136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
137 end
138 end
139 logic [DataWidth-1:0] data_state_xor;
140 1/1 assign data_state_xor = data_state_round ^
Tests: T1 T2 T3
141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0];
142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
143 if (k % 2 == 1) begin : gen_fwd_key_odd
144 1/1 assign data_state_lo[k] = data_state_xor ^ k0_new_d;
Tests: T1 T2 T3
145 end else begin : gen_fwd_key_even
146 assign data_state_lo[k] = data_state_xor ^ k1_d;
147 end
148 end
149
150 // middle part
151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle;
152 if (DataWidth == 64) begin : gen_middle_d64
153 always_comb begin : p_middle_d64
154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf],
Tests: T1 T2 T3
155 prim_cipher_pkg::PRINCE_SBOX4);
156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q);
Tests: T1 T2 T3
157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle,
Tests: T1 T2 T3
158 prim_cipher_pkg::PRINCE_SBOX4_INV);
159 end
160 end else begin : gen_middle_d32
161 always_comb begin : p_middle_d32
162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf],
163 prim_cipher_pkg::PRINCE_SBOX4);
164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q);
165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle,
166 prim_cipher_pkg::PRINCE_SBOX4_INV);
167 end
168 end
169
170 if (HalfwayDataReg) begin : gen_data_reg
171 logic valid_q;
172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg
173 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
174 1/1 valid_q <= 1'b0;
Tests: T1 T2 T3
175 1/1 data_state_middle_q <= '0;
Tests: T1 T2 T3
176 end else begin
177 1/1 valid_q <= valid_i;
Tests: T1 T2 T3
178 1/1 if (valid_i) begin
Tests: T1 T2 T3
179 1/1 data_state_middle_q <= data_state_middle_d;
Tests: T1 T2 T3
180 end
MISSING_ELSE
181 end
182 end
183 1/1 assign valid_o = valid_q;
Tests: T1 T2 T3
184 end else begin : gen_no_data_reg
185 // just pass data through in this case
186 assign data_state_middle_q = data_state_middle_d;
187 assign valid_o = valid_i;
188 end
189
190 1/1 assign data_state_hi[0] = data_state_middle;
Tests: T1 T2 T3
191
192 // backward pass
193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass
194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1;
195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd
197 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q;
Tests: T1 T2 T3
198 end else begin : gen_bkwd_key_even
199 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q;
200 end
201 // the construction is reflective, hence the subtraction with NumRoundsHalf
202 1/1 assign data_state_xor1 = data_state_xor0 ^
Tests: T1 T2 T3
203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0];
204
205 logic [DataWidth-1:0] data_state_bwd;
206 if (DataWidth == 64) begin : gen_bwd_d64
207 always_comb begin : p_bwd_d64
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
212 prim_cipher_pkg::PRINCE_SBOX4_INV);
213 end
214 end else begin : gen_bwd_d32
215 always_comb begin : p_bwd_d32
216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1,
217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd);
219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd,
220 prim_cipher_pkg::PRINCE_SBOX4_INV);
221 end
222 end
223 end
224
225 // post-rounds
226 always_comb begin : p_post_round_xor
227 1/1 data_o = data_state_hi[NumRoundsHalf] ^
Tests: T1 T2 T3
228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0];
229 1/1 data_o ^= k1_q;
Tests: T1 T2 T3
230 1/1 data_o ^= k0_prime_q;
Tests: T1 T2 T3
Line Coverage for Module :
prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=2,UseOldKeySched=0,HalfwayDataReg=1,HalfwayKeyReg=1 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 55 | 55 | 100.00 |
ALWAYS | 56 | 7 | 7 | 100.00 |
ALWAYS | 75 | 3 | 3 | 100.00 |
ALWAYS | 85 | 8 | 8 | 100.00 |
ALWAYS | 114 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 146 | 1 | 1 | 100.00 |
ALWAYS | 154 | 3 | 3 | 100.00 |
ALWAYS | 173 | 6 | 6 | 100.00 |
CONT_ASSIGN | 183 | 1 | 1 | 100.00 |
CONT_ASSIGN | 190 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 227 | 3 | 3 | 100.00 |
55 always_comb begin : p_key_expansion
56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]};
Tests: T1 T2 T3
58 1/1 k1_d = key_i[DataWidth-1:0];
Tests: T1 T2 T3
59
60 // modify key for decryption
61 1/1 if (dec_i) begin
Tests: T1 T2 T3
62 1/1 k0 = k0_prime_d;
Tests: T1 T2 T3
63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
65 end
MISSING_ELSE
66 end
67
68 if (UseOldKeySched) begin : gen_legacy_keyschedule
69 // In this case we constantly use k1.
70 assign k0_new_d = k1_d;
71 end else begin : gen_new_keyschedule
72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
73 // In this case we alternate between k1 and k0.
74 always_comb begin : p_new_keyschedule_k0_alpha
75 1/1 k0_new_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode.
77 1/1 if (dec_i) begin
Tests: T1 T2 T3
78 1/1 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
79 end
MISSING_ELSE
80 end
81 end
82
83 if (HalfwayKeyReg) begin : gen_key_reg
84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg
85 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
86 1/1 k1_q <= '0;
Tests: T1 T2 T3
87 1/1 k0_prime_q <= '0;
Tests: T1 T2 T3
88 1/1 k0_new_q <= '0;
Tests: T1 T2 T3
89 end else begin
90 1/1 if (valid_i) begin
Tests: T1 T2 T3
91 1/1 k1_q <= k1_d;
Tests: T1 T2 T3
92 1/1 k0_prime_q <= k0_prime_d;
Tests: T1 T2 T3
93 1/1 k0_new_q <= k0_new_d;
Tests: T1 T2 T3
94 end
MISSING_ELSE
95 end
96 end
97 end else begin : gen_no_key_reg
98 // just pass the key through in this case
99 assign k1_q = k1_d;
100 assign k0_prime_q = k0_prime_d;
101 assign k0_new_q = k0_new_d;
102 end
103
104 //////////////
105 // datapath //
106 //////////////
107
108 // State variable for holding the rounds
109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo;
110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi;
111
112 // pre-round XOR
113 always_comb begin : p_pre_round_xor
114 1/1 data_state_lo[0] = data_i ^ k0;
Tests: T1 T2 T3
115 1/1 data_state_lo[0] ^= k1_d;
Tests: T1 T2 T3
116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0];
Tests: T1 T2 T3
117 end
118
119 // forward pass
120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass
121 logic [DataWidth-1:0] data_state_round;
122 if (DataWidth == 64) begin : gen_fwd_d64
123 always_comb begin : p_fwd_d64
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 1
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
129 end
130 end else begin : gen_fwd_d32
131 always_comb begin : p_fwd_d32
132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1],
133 prim_cipher_pkg::PRINCE_SBOX4);
134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round);
135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round,
136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
137 end
138 end
139 logic [DataWidth-1:0] data_state_xor;
140 2/2 assign data_state_xor = data_state_round ^
Tests: T1 T2 T3 | T1 T2 T3
141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0];
142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
143 if (k % 2 == 1) begin : gen_fwd_key_odd
144 1/1 assign data_state_lo[k] = data_state_xor ^ k0_new_d;
Tests: T1 T2 T3
145 end else begin : gen_fwd_key_even
146 1/1 assign data_state_lo[k] = data_state_xor ^ k1_d;
Tests: T1 T2 T3
147 end
148 end
149
150 // middle part
151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle;
152 if (DataWidth == 64) begin : gen_middle_d64
153 always_comb begin : p_middle_d64
154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf],
Tests: T1 T2 T3
155 prim_cipher_pkg::PRINCE_SBOX4);
156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q);
Tests: T1 T2 T3
157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle,
Tests: T1 T2 T3
158 prim_cipher_pkg::PRINCE_SBOX4_INV);
159 end
160 end else begin : gen_middle_d32
161 always_comb begin : p_middle_d32
162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf],
163 prim_cipher_pkg::PRINCE_SBOX4);
164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q);
165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle,
166 prim_cipher_pkg::PRINCE_SBOX4_INV);
167 end
168 end
169
170 if (HalfwayDataReg) begin : gen_data_reg
171 logic valid_q;
172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg
173 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
174 1/1 valid_q <= 1'b0;
Tests: T1 T2 T3
175 1/1 data_state_middle_q <= '0;
Tests: T1 T2 T3
176 end else begin
177 1/1 valid_q <= valid_i;
Tests: T1 T2 T3
178 1/1 if (valid_i) begin
Tests: T1 T2 T3
179 1/1 data_state_middle_q <= data_state_middle_d;
Tests: T1 T2 T3
180 end
MISSING_ELSE
181 end
182 end
183 1/1 assign valid_o = valid_q;
Tests: T1 T2 T3
184 end else begin : gen_no_data_reg
185 // just pass data through in this case
186 assign data_state_middle_q = data_state_middle_d;
187 assign valid_o = valid_i;
188 end
189
190 1/1 assign data_state_hi[0] = data_state_middle;
Tests: T1 T2 T3
191
192 // backward pass
193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass
194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1;
195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd
197 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q;
Tests: T1 T2 T3
198 end else begin : gen_bkwd_key_even
199 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q;
Tests: T1 T2 T3
200 end
201 // the construction is reflective, hence the subtraction with NumRoundsHalf
202 2/2 assign data_state_xor1 = data_state_xor0 ^
Tests: T1 T2 T3 | T1 T2 T3
203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0];
204
205 logic [DataWidth-1:0] data_state_bwd;
206 if (DataWidth == 64) begin : gen_bwd_d64
207 always_comb begin : p_bwd_d64
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 2
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
212 prim_cipher_pkg::PRINCE_SBOX4_INV);
213 end
214 end else begin : gen_bwd_d32
215 always_comb begin : p_bwd_d32
216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1,
217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd);
219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd,
220 prim_cipher_pkg::PRINCE_SBOX4_INV);
221 end
222 end
223 end
224
225 // post-rounds
226 always_comb begin : p_post_round_xor
227 1/1 data_o = data_state_hi[NumRoundsHalf] ^
Tests: T1 T2 T3
228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0];
229 1/1 data_o ^= k1_q;
Tests: T1 T2 T3
230 1/1 data_o ^= k0_prime_q;
Tests: T1 T2 T3
Line Coverage for Module :
prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=3,UseOldKeySched=0,HalfwayDataReg=1,HalfwayKeyReg=1 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 65 | 65 | 100.00 |
ALWAYS | 56 | 7 | 7 | 100.00 |
ALWAYS | 75 | 3 | 3 | 100.00 |
ALWAYS | 85 | 8 | 8 | 100.00 |
ALWAYS | 114 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 146 | 1 | 1 | 100.00 |
ALWAYS | 154 | 3 | 3 | 100.00 |
ALWAYS | 173 | 6 | 6 | 100.00 |
CONT_ASSIGN | 183 | 1 | 1 | 100.00 |
CONT_ASSIGN | 190 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 227 | 3 | 3 | 100.00 |
55 always_comb begin : p_key_expansion
56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]};
Tests: T1 T2 T3
58 1/1 k1_d = key_i[DataWidth-1:0];
Tests: T1 T2 T3
59
60 // modify key for decryption
61 1/1 if (dec_i) begin
Tests: T1 T2 T3
62 1/1 k0 = k0_prime_d;
Tests: T1 T2 T3
63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
65 end
MISSING_ELSE
66 end
67
68 if (UseOldKeySched) begin : gen_legacy_keyschedule
69 // In this case we constantly use k1.
70 assign k0_new_d = k1_d;
71 end else begin : gen_new_keyschedule
72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
73 // In this case we alternate between k1 and k0.
74 always_comb begin : p_new_keyschedule_k0_alpha
75 1/1 k0_new_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode.
77 1/1 if (dec_i) begin
Tests: T1 T2 T3
78 1/1 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
79 end
MISSING_ELSE
80 end
81 end
82
83 if (HalfwayKeyReg) begin : gen_key_reg
84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg
85 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
86 1/1 k1_q <= '0;
Tests: T1 T2 T3
87 1/1 k0_prime_q <= '0;
Tests: T1 T2 T3
88 1/1 k0_new_q <= '0;
Tests: T1 T2 T3
89 end else begin
90 1/1 if (valid_i) begin
Tests: T1 T2 T3
91 1/1 k1_q <= k1_d;
Tests: T1 T2 T3
92 1/1 k0_prime_q <= k0_prime_d;
Tests: T1 T2 T3
93 1/1 k0_new_q <= k0_new_d;
Tests: T1 T2 T3
94 end
MISSING_ELSE
95 end
96 end
97 end else begin : gen_no_key_reg
98 // just pass the key through in this case
99 assign k1_q = k1_d;
100 assign k0_prime_q = k0_prime_d;
101 assign k0_new_q = k0_new_d;
102 end
103
104 //////////////
105 // datapath //
106 //////////////
107
108 // State variable for holding the rounds
109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo;
110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi;
111
112 // pre-round XOR
113 always_comb begin : p_pre_round_xor
114 1/1 data_state_lo[0] = data_i ^ k0;
Tests: T1 T2 T3
115 1/1 data_state_lo[0] ^= k1_d;
Tests: T1 T2 T3
116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0];
Tests: T1 T2 T3
117 end
118
119 // forward pass
120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass
121 logic [DataWidth-1:0] data_state_round;
122 if (DataWidth == 64) begin : gen_fwd_d64
123 always_comb begin : p_fwd_d64
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 1
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 2
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
129 end
130 end else begin : gen_fwd_d32
131 always_comb begin : p_fwd_d32
132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1],
133 prim_cipher_pkg::PRINCE_SBOX4);
134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round);
135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round,
136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
137 end
138 end
139 logic [DataWidth-1:0] data_state_xor;
140 3/3 assign data_state_xor = data_state_round ^
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0];
142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
143 if (k % 2 == 1) begin : gen_fwd_key_odd
144 2/2 assign data_state_lo[k] = data_state_xor ^ k0_new_d;
Tests: T1 T2 T3 | T1 T2 T3
145 end else begin : gen_fwd_key_even
146 1/1 assign data_state_lo[k] = data_state_xor ^ k1_d;
Tests: T1 T2 T3
147 end
148 end
149
150 // middle part
151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle;
152 if (DataWidth == 64) begin : gen_middle_d64
153 always_comb begin : p_middle_d64
154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf],
Tests: T1 T2 T3
155 prim_cipher_pkg::PRINCE_SBOX4);
156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q);
Tests: T1 T2 T3
157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle,
Tests: T1 T2 T3
158 prim_cipher_pkg::PRINCE_SBOX4_INV);
159 end
160 end else begin : gen_middle_d32
161 always_comb begin : p_middle_d32
162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf],
163 prim_cipher_pkg::PRINCE_SBOX4);
164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q);
165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle,
166 prim_cipher_pkg::PRINCE_SBOX4_INV);
167 end
168 end
169
170 if (HalfwayDataReg) begin : gen_data_reg
171 logic valid_q;
172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg
173 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
174 1/1 valid_q <= 1'b0;
Tests: T1 T2 T3
175 1/1 data_state_middle_q <= '0;
Tests: T1 T2 T3
176 end else begin
177 1/1 valid_q <= valid_i;
Tests: T1 T2 T3
178 1/1 if (valid_i) begin
Tests: T1 T2 T3
179 1/1 data_state_middle_q <= data_state_middle_d;
Tests: T1 T2 T3
180 end
MISSING_ELSE
181 end
182 end
183 1/1 assign valid_o = valid_q;
Tests: T1 T2 T3
184 end else begin : gen_no_data_reg
185 // just pass data through in this case
186 assign data_state_middle_q = data_state_middle_d;
187 assign valid_o = valid_i;
188 end
189
190 1/1 assign data_state_hi[0] = data_state_middle;
Tests: T1 T2 T3
191
192 // backward pass
193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass
194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1;
195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd
197 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q;
Tests: T1 T2 T3 | T1 T2 T3
198 end else begin : gen_bkwd_key_even
199 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q;
Tests: T1 T2 T3
200 end
201 // the construction is reflective, hence the subtraction with NumRoundsHalf
202 3/3 assign data_state_xor1 = data_state_xor0 ^
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0];
204
205 logic [DataWidth-1:0] data_state_bwd;
206 if (DataWidth == 64) begin : gen_bwd_d64
207 always_comb begin : p_bwd_d64
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 3
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 4
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
212 prim_cipher_pkg::PRINCE_SBOX4_INV);
213 end
214 end else begin : gen_bwd_d32
215 always_comb begin : p_bwd_d32
216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1,
217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd);
219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd,
220 prim_cipher_pkg::PRINCE_SBOX4_INV);
221 end
222 end
223 end
224
225 // post-rounds
226 always_comb begin : p_post_round_xor
227 1/1 data_o = data_state_hi[NumRoundsHalf] ^
Tests: T1 T2 T3
228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0];
229 1/1 data_o ^= k1_q;
Tests: T1 T2 T3
230 1/1 data_o ^= k0_prime_q;
Tests: T1 T2 T3
Line Coverage for Module :
prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=4,UseOldKeySched=0,HalfwayDataReg=1,HalfwayKeyReg=1 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 75 | 75 | 100.00 |
ALWAYS | 56 | 7 | 7 | 100.00 |
ALWAYS | 75 | 3 | 3 | 100.00 |
ALWAYS | 85 | 8 | 8 | 100.00 |
ALWAYS | 114 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 146 | 1 | 1 | 100.00 |
CONT_ASSIGN | 146 | 1 | 1 | 100.00 |
ALWAYS | 154 | 3 | 3 | 100.00 |
ALWAYS | 173 | 6 | 6 | 100.00 |
CONT_ASSIGN | 183 | 1 | 1 | 100.00 |
CONT_ASSIGN | 190 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 227 | 3 | 3 | 100.00 |
55 always_comb begin : p_key_expansion
56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]};
Tests: T1 T2 T3
58 1/1 k1_d = key_i[DataWidth-1:0];
Tests: T1 T2 T3
59
60 // modify key for decryption
61 1/1 if (dec_i) begin
Tests: T1 T2 T3
62 1/1 k0 = k0_prime_d;
Tests: T1 T2 T3
63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
65 end
MISSING_ELSE
66 end
67
68 if (UseOldKeySched) begin : gen_legacy_keyschedule
69 // In this case we constantly use k1.
70 assign k0_new_d = k1_d;
71 end else begin : gen_new_keyschedule
72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
73 // In this case we alternate between k1 and k0.
74 always_comb begin : p_new_keyschedule_k0_alpha
75 1/1 k0_new_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode.
77 1/1 if (dec_i) begin
Tests: T1 T2 T3
78 1/1 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
79 end
MISSING_ELSE
80 end
81 end
82
83 if (HalfwayKeyReg) begin : gen_key_reg
84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg
85 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
86 1/1 k1_q <= '0;
Tests: T1 T2 T3
87 1/1 k0_prime_q <= '0;
Tests: T1 T2 T3
88 1/1 k0_new_q <= '0;
Tests: T1 T2 T3
89 end else begin
90 1/1 if (valid_i) begin
Tests: T1 T2 T3
91 1/1 k1_q <= k1_d;
Tests: T1 T2 T3
92 1/1 k0_prime_q <= k0_prime_d;
Tests: T1 T2 T3
93 1/1 k0_new_q <= k0_new_d;
Tests: T1 T2 T3
94 end
MISSING_ELSE
95 end
96 end
97 end else begin : gen_no_key_reg
98 // just pass the key through in this case
99 assign k1_q = k1_d;
100 assign k0_prime_q = k0_prime_d;
101 assign k0_new_q = k0_new_d;
102 end
103
104 //////////////
105 // datapath //
106 //////////////
107
108 // State variable for holding the rounds
109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo;
110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi;
111
112 // pre-round XOR
113 always_comb begin : p_pre_round_xor
114 1/1 data_state_lo[0] = data_i ^ k0;
Tests: T1 T2 T3
115 1/1 data_state_lo[0] ^= k1_d;
Tests: T1 T2 T3
116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0];
Tests: T1 T2 T3
117 end
118
119 // forward pass
120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass
121 logic [DataWidth-1:0] data_state_round;
122 if (DataWidth == 64) begin : gen_fwd_d64
123 always_comb begin : p_fwd_d64
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 1
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 2
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 3
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
129 end
130 end else begin : gen_fwd_d32
131 always_comb begin : p_fwd_d32
132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1],
133 prim_cipher_pkg::PRINCE_SBOX4);
134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round);
135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round,
136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
137 end
138 end
139 logic [DataWidth-1:0] data_state_xor;
140 4/4 assign data_state_xor = data_state_round ^
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0];
142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
143 if (k % 2 == 1) begin : gen_fwd_key_odd
144 2/2 assign data_state_lo[k] = data_state_xor ^ k0_new_d;
Tests: T1 T2 T3 | T1 T2 T3
145 end else begin : gen_fwd_key_even
146 2/2 assign data_state_lo[k] = data_state_xor ^ k1_d;
Tests: T1 T2 T3 | T1 T2 T3
147 end
148 end
149
150 // middle part
151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle;
152 if (DataWidth == 64) begin : gen_middle_d64
153 always_comb begin : p_middle_d64
154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf],
Tests: T1 T2 T3
155 prim_cipher_pkg::PRINCE_SBOX4);
156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q);
Tests: T1 T2 T3
157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle,
Tests: T1 T2 T3
158 prim_cipher_pkg::PRINCE_SBOX4_INV);
159 end
160 end else begin : gen_middle_d32
161 always_comb begin : p_middle_d32
162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf],
163 prim_cipher_pkg::PRINCE_SBOX4);
164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q);
165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle,
166 prim_cipher_pkg::PRINCE_SBOX4_INV);
167 end
168 end
169
170 if (HalfwayDataReg) begin : gen_data_reg
171 logic valid_q;
172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg
173 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
174 1/1 valid_q <= 1'b0;
Tests: T1 T2 T3
175 1/1 data_state_middle_q <= '0;
Tests: T1 T2 T3
176 end else begin
177 1/1 valid_q <= valid_i;
Tests: T1 T2 T3
178 1/1 if (valid_i) begin
Tests: T1 T2 T3
179 1/1 data_state_middle_q <= data_state_middle_d;
Tests: T1 T2 T3
180 end
MISSING_ELSE
181 end
182 end
183 1/1 assign valid_o = valid_q;
Tests: T1 T2 T3
184 end else begin : gen_no_data_reg
185 // just pass data through in this case
186 assign data_state_middle_q = data_state_middle_d;
187 assign valid_o = valid_i;
188 end
189
190 1/1 assign data_state_hi[0] = data_state_middle;
Tests: T1 T2 T3
191
192 // backward pass
193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass
194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1;
195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd
197 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q;
Tests: T1 T2 T3 | T1 T2 T3
198 end else begin : gen_bkwd_key_even
199 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q;
Tests: T1 T2 T3 | T1 T2 T3
200 end
201 // the construction is reflective, hence the subtraction with NumRoundsHalf
202 4/4 assign data_state_xor1 = data_state_xor0 ^
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0];
204
205 logic [DataWidth-1:0] data_state_bwd;
206 if (DataWidth == 64) begin : gen_bwd_d64
207 always_comb begin : p_bwd_d64
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 4
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 5
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 6
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
212 prim_cipher_pkg::PRINCE_SBOX4_INV);
213 end
214 end else begin : gen_bwd_d32
215 always_comb begin : p_bwd_d32
216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1,
217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd);
219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd,
220 prim_cipher_pkg::PRINCE_SBOX4_INV);
221 end
222 end
223 end
224
225 // post-rounds
226 always_comb begin : p_post_round_xor
227 1/1 data_o = data_state_hi[NumRoundsHalf] ^
Tests: T1 T2 T3
228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0];
229 1/1 data_o ^= k1_q;
Tests: T1 T2 T3
230 1/1 data_o ^= k0_prime_q;
Tests: T1 T2 T3
Line Coverage for Module :
prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=5,UseOldKeySched=0,HalfwayDataReg=1,HalfwayKeyReg=1 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 85 | 85 | 100.00 |
ALWAYS | 56 | 7 | 7 | 100.00 |
ALWAYS | 75 | 3 | 3 | 100.00 |
ALWAYS | 85 | 8 | 8 | 100.00 |
ALWAYS | 114 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 146 | 1 | 1 | 100.00 |
CONT_ASSIGN | 146 | 1 | 1 | 100.00 |
ALWAYS | 154 | 3 | 3 | 100.00 |
ALWAYS | 173 | 6 | 6 | 100.00 |
CONT_ASSIGN | 183 | 1 | 1 | 100.00 |
CONT_ASSIGN | 190 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 227 | 3 | 3 | 100.00 |
55 always_comb begin : p_key_expansion
56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]};
Tests: T1 T2 T3
58 1/1 k1_d = key_i[DataWidth-1:0];
Tests: T1 T2 T3
59
60 // modify key for decryption
61 1/1 if (dec_i) begin
Tests: T1 T2 T3
62 1/1 k0 = k0_prime_d;
Tests: T1 T2 T3
63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
65 end
MISSING_ELSE
66 end
67
68 if (UseOldKeySched) begin : gen_legacy_keyschedule
69 // In this case we constantly use k1.
70 assign k0_new_d = k1_d;
71 end else begin : gen_new_keyschedule
72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
73 // In this case we alternate between k1 and k0.
74 always_comb begin : p_new_keyschedule_k0_alpha
75 1/1 k0_new_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode.
77 1/1 if (dec_i) begin
Tests: T1 T2 T3
78 1/1 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
79 end
MISSING_ELSE
80 end
81 end
82
83 if (HalfwayKeyReg) begin : gen_key_reg
84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg
85 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
86 1/1 k1_q <= '0;
Tests: T1 T2 T3
87 1/1 k0_prime_q <= '0;
Tests: T1 T2 T3
88 1/1 k0_new_q <= '0;
Tests: T1 T2 T3
89 end else begin
90 1/1 if (valid_i) begin
Tests: T1 T2 T3
91 1/1 k1_q <= k1_d;
Tests: T1 T2 T3
92 1/1 k0_prime_q <= k0_prime_d;
Tests: T1 T2 T3
93 1/1 k0_new_q <= k0_new_d;
Tests: T1 T2 T3
94 end
MISSING_ELSE
95 end
96 end
97 end else begin : gen_no_key_reg
98 // just pass the key through in this case
99 assign k1_q = k1_d;
100 assign k0_prime_q = k0_prime_d;
101 assign k0_new_q = k0_new_d;
102 end
103
104 //////////////
105 // datapath //
106 //////////////
107
108 // State variable for holding the rounds
109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo;
110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi;
111
112 // pre-round XOR
113 always_comb begin : p_pre_round_xor
114 1/1 data_state_lo[0] = data_i ^ k0;
Tests: T1 T2 T3
115 1/1 data_state_lo[0] ^= k1_d;
Tests: T1 T2 T3
116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0];
Tests: T1 T2 T3
117 end
118
119 // forward pass
120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass
121 logic [DataWidth-1:0] data_state_round;
122 if (DataWidth == 64) begin : gen_fwd_d64
123 always_comb begin : p_fwd_d64
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 1
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 2
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 3
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 4
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
129 end
130 end else begin : gen_fwd_d32
131 always_comb begin : p_fwd_d32
132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1],
133 prim_cipher_pkg::PRINCE_SBOX4);
134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round);
135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round,
136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
137 end
138 end
139 logic [DataWidth-1:0] data_state_xor;
140 5/5 assign data_state_xor = data_state_round ^
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0];
142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
143 if (k % 2 == 1) begin : gen_fwd_key_odd
144 3/3 assign data_state_lo[k] = data_state_xor ^ k0_new_d;
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
145 end else begin : gen_fwd_key_even
146 2/2 assign data_state_lo[k] = data_state_xor ^ k1_d;
Tests: T1 T2 T3 | T1 T2 T3
147 end
148 end
149
150 // middle part
151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle;
152 if (DataWidth == 64) begin : gen_middle_d64
153 always_comb begin : p_middle_d64
154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf],
Tests: T1 T2 T3
155 prim_cipher_pkg::PRINCE_SBOX4);
156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q);
Tests: T1 T2 T3
157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle,
Tests: T1 T2 T3
158 prim_cipher_pkg::PRINCE_SBOX4_INV);
159 end
160 end else begin : gen_middle_d32
161 always_comb begin : p_middle_d32
162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf],
163 prim_cipher_pkg::PRINCE_SBOX4);
164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q);
165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle,
166 prim_cipher_pkg::PRINCE_SBOX4_INV);
167 end
168 end
169
170 if (HalfwayDataReg) begin : gen_data_reg
171 logic valid_q;
172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg
173 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
174 1/1 valid_q <= 1'b0;
Tests: T1 T2 T3
175 1/1 data_state_middle_q <= '0;
Tests: T1 T2 T3
176 end else begin
177 1/1 valid_q <= valid_i;
Tests: T1 T2 T3
178 1/1 if (valid_i) begin
Tests: T1 T2 T3
179 1/1 data_state_middle_q <= data_state_middle_d;
Tests: T1 T2 T3
180 end
MISSING_ELSE
181 end
182 end
183 1/1 assign valid_o = valid_q;
Tests: T1 T2 T3
184 end else begin : gen_no_data_reg
185 // just pass data through in this case
186 assign data_state_middle_q = data_state_middle_d;
187 assign valid_o = valid_i;
188 end
189
190 1/1 assign data_state_hi[0] = data_state_middle;
Tests: T1 T2 T3
191
192 // backward pass
193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass
194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1;
195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd
197 3/3 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q;
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
198 end else begin : gen_bkwd_key_even
199 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q;
Tests: T1 T2 T3 | T1 T2 T3
200 end
201 // the construction is reflective, hence the subtraction with NumRoundsHalf
202 5/5 assign data_state_xor1 = data_state_xor0 ^
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0];
204
205 logic [DataWidth-1:0] data_state_bwd;
206 if (DataWidth == 64) begin : gen_bwd_d64
207 always_comb begin : p_bwd_d64
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 5
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 6
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 7
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 8
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
212 prim_cipher_pkg::PRINCE_SBOX4_INV);
213 end
214 end else begin : gen_bwd_d32
215 always_comb begin : p_bwd_d32
216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1,
217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd);
219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd,
220 prim_cipher_pkg::PRINCE_SBOX4_INV);
221 end
222 end
223 end
224
225 // post-rounds
226 always_comb begin : p_post_round_xor
227 1/1 data_o = data_state_hi[NumRoundsHalf] ^
Tests: T1 T2 T3
228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0];
229 1/1 data_o ^= k1_q;
Tests: T1 T2 T3
230 1/1 data_o ^= k0_prime_q;
Tests: T1 T2 T3
Line Coverage for Module :
prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=1,UseOldKeySched=1,HalfwayDataReg=0,HalfwayKeyReg=0 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 33 | 33 | 100.00 |
ALWAYS | 56 | 7 | 7 | 100.00 |
CONT_ASSIGN | 70 | 1 | 1 | 100.00 |
CONT_ASSIGN | 99 | 1 | 1 | 100.00 |
CONT_ASSIGN | 100 | 1 | 1 | 100.00 |
CONT_ASSIGN | 101 | 1 | 1 | 100.00 |
ALWAYS | 114 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
ALWAYS | 154 | 3 | 3 | 100.00 |
CONT_ASSIGN | 186 | 1 | 1 | 100.00 |
CONT_ASSIGN | 187 | 1 | 1 | 100.00 |
CONT_ASSIGN | 190 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 227 | 3 | 3 | 100.00 |
55 always_comb begin : p_key_expansion
56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]};
Tests: T1 T2 T3
58 1/1 k1_d = key_i[DataWidth-1:0];
Tests: T1 T2 T3
59
60 // modify key for decryption
61 1/1 if (dec_i) begin
Tests: T1 T2 T3
62 1/1 k0 = k0_prime_d;
Tests: T1 T2 T3
63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
65 end
MISSING_ELSE
66 end
67
68 if (UseOldKeySched) begin : gen_legacy_keyschedule
69 // In this case we constantly use k1.
70 1/1 assign k0_new_d = k1_d;
Tests: T1 T2 T3
71 end else begin : gen_new_keyschedule
72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
73 // In this case we alternate between k1 and k0.
74 always_comb begin : p_new_keyschedule_k0_alpha
75 k0_new_d = key_i[2*DataWidth-1 : DataWidth];
76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode.
77 if (dec_i) begin
78 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
79 end
80 end
81 end
82
83 if (HalfwayKeyReg) begin : gen_key_reg
84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg
85 if (!rst_ni) begin
86 k1_q <= '0;
87 k0_prime_q <= '0;
88 k0_new_q <= '0;
89 end else begin
90 if (valid_i) begin
91 k1_q <= k1_d;
92 k0_prime_q <= k0_prime_d;
93 k0_new_q <= k0_new_d;
94 end
95 end
96 end
97 end else begin : gen_no_key_reg
98 // just pass the key through in this case
99 1/1 assign k1_q = k1_d;
Tests: T1 T2 T3
100 1/1 assign k0_prime_q = k0_prime_d;
Tests: T1 T2 T3
101 1/1 assign k0_new_q = k0_new_d;
Tests: T1 T2 T3
102 end
103
104 //////////////
105 // datapath //
106 //////////////
107
108 // State variable for holding the rounds
109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo;
110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi;
111
112 // pre-round XOR
113 always_comb begin : p_pre_round_xor
114 1/1 data_state_lo[0] = data_i ^ k0;
Tests: T1 T2 T3
115 1/1 data_state_lo[0] ^= k1_d;
Tests: T1 T2 T3
116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0];
Tests: T1 T2 T3
117 end
118
119 // forward pass
120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass
121 logic [DataWidth-1:0] data_state_round;
122 if (DataWidth == 64) begin : gen_fwd_d64
123 always_comb begin : p_fwd_d64
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
129 end
130 end else begin : gen_fwd_d32
131 always_comb begin : p_fwd_d32
132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1],
133 prim_cipher_pkg::PRINCE_SBOX4);
134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round);
135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round,
136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
137 end
138 end
139 logic [DataWidth-1:0] data_state_xor;
140 1/1 assign data_state_xor = data_state_round ^
Tests: T1 T2 T3
141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0];
142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
143 if (k % 2 == 1) begin : gen_fwd_key_odd
144 1/1 assign data_state_lo[k] = data_state_xor ^ k0_new_d;
Tests: T1 T2 T3
145 end else begin : gen_fwd_key_even
146 assign data_state_lo[k] = data_state_xor ^ k1_d;
147 end
148 end
149
150 // middle part
151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle;
152 if (DataWidth == 64) begin : gen_middle_d64
153 always_comb begin : p_middle_d64
154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf],
Tests: T1 T2 T3
155 prim_cipher_pkg::PRINCE_SBOX4);
156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q);
Tests: T1 T2 T3
157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle,
Tests: T1 T2 T3
158 prim_cipher_pkg::PRINCE_SBOX4_INV);
159 end
160 end else begin : gen_middle_d32
161 always_comb begin : p_middle_d32
162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf],
163 prim_cipher_pkg::PRINCE_SBOX4);
164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q);
165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle,
166 prim_cipher_pkg::PRINCE_SBOX4_INV);
167 end
168 end
169
170 if (HalfwayDataReg) begin : gen_data_reg
171 logic valid_q;
172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg
173 if (!rst_ni) begin
174 valid_q <= 1'b0;
175 data_state_middle_q <= '0;
176 end else begin
177 valid_q <= valid_i;
178 if (valid_i) begin
179 data_state_middle_q <= data_state_middle_d;
180 end
181 end
182 end
183 assign valid_o = valid_q;
184 end else begin : gen_no_data_reg
185 // just pass data through in this case
186 1/1 assign data_state_middle_q = data_state_middle_d;
Tests: T1 T2 T3
187 1/1 assign valid_o = valid_i;
Tests: T1 T2 T3
188 end
189
190 1/1 assign data_state_hi[0] = data_state_middle;
Tests: T1 T2 T3
191
192 // backward pass
193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass
194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1;
195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd
197 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q;
Tests: T1 T2 T3
198 end else begin : gen_bkwd_key_even
199 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q;
200 end
201 // the construction is reflective, hence the subtraction with NumRoundsHalf
202 1/1 assign data_state_xor1 = data_state_xor0 ^
Tests: T1 T2 T3
203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0];
204
205 logic [DataWidth-1:0] data_state_bwd;
206 if (DataWidth == 64) begin : gen_bwd_d64
207 always_comb begin : p_bwd_d64
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
212 prim_cipher_pkg::PRINCE_SBOX4_INV);
213 end
214 end else begin : gen_bwd_d32
215 always_comb begin : p_bwd_d32
216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1,
217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd);
219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd,
220 prim_cipher_pkg::PRINCE_SBOX4_INV);
221 end
222 end
223 end
224
225 // post-rounds
226 always_comb begin : p_post_round_xor
227 1/1 data_o = data_state_hi[NumRoundsHalf] ^
Tests: T1 T2 T3
228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0];
229 1/1 data_o ^= k1_q;
Tests: T1 T2 T3
230 1/1 data_o ^= k0_prime_q;
Tests: T1 T2 T3
Line Coverage for Module :
prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=2,UseOldKeySched=1,HalfwayDataReg=0,HalfwayKeyReg=0 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 43 | 43 | 100.00 |
ALWAYS | 56 | 7 | 7 | 100.00 |
CONT_ASSIGN | 70 | 1 | 1 | 100.00 |
CONT_ASSIGN | 99 | 1 | 1 | 100.00 |
CONT_ASSIGN | 100 | 1 | 1 | 100.00 |
CONT_ASSIGN | 101 | 1 | 1 | 100.00 |
ALWAYS | 114 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 146 | 1 | 1 | 100.00 |
ALWAYS | 154 | 3 | 3 | 100.00 |
CONT_ASSIGN | 186 | 1 | 1 | 100.00 |
CONT_ASSIGN | 187 | 1 | 1 | 100.00 |
CONT_ASSIGN | 190 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 227 | 3 | 3 | 100.00 |
55 always_comb begin : p_key_expansion
56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]};
Tests: T1 T2 T3
58 1/1 k1_d = key_i[DataWidth-1:0];
Tests: T1 T2 T3
59
60 // modify key for decryption
61 1/1 if (dec_i) begin
Tests: T1 T2 T3
62 1/1 k0 = k0_prime_d;
Tests: T1 T2 T3
63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
65 end
MISSING_ELSE
66 end
67
68 if (UseOldKeySched) begin : gen_legacy_keyschedule
69 // In this case we constantly use k1.
70 1/1 assign k0_new_d = k1_d;
Tests: T1 T2 T3
71 end else begin : gen_new_keyschedule
72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
73 // In this case we alternate between k1 and k0.
74 always_comb begin : p_new_keyschedule_k0_alpha
75 k0_new_d = key_i[2*DataWidth-1 : DataWidth];
76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode.
77 if (dec_i) begin
78 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
79 end
80 end
81 end
82
83 if (HalfwayKeyReg) begin : gen_key_reg
84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg
85 if (!rst_ni) begin
86 k1_q <= '0;
87 k0_prime_q <= '0;
88 k0_new_q <= '0;
89 end else begin
90 if (valid_i) begin
91 k1_q <= k1_d;
92 k0_prime_q <= k0_prime_d;
93 k0_new_q <= k0_new_d;
94 end
95 end
96 end
97 end else begin : gen_no_key_reg
98 // just pass the key through in this case
99 1/1 assign k1_q = k1_d;
Tests: T1 T2 T3
100 1/1 assign k0_prime_q = k0_prime_d;
Tests: T1 T2 T3
101 1/1 assign k0_new_q = k0_new_d;
Tests: T1 T2 T3
102 end
103
104 //////////////
105 // datapath //
106 //////////////
107
108 // State variable for holding the rounds
109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo;
110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi;
111
112 // pre-round XOR
113 always_comb begin : p_pre_round_xor
114 1/1 data_state_lo[0] = data_i ^ k0;
Tests: T1 T2 T3
115 1/1 data_state_lo[0] ^= k1_d;
Tests: T1 T2 T3
116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0];
Tests: T1 T2 T3
117 end
118
119 // forward pass
120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass
121 logic [DataWidth-1:0] data_state_round;
122 if (DataWidth == 64) begin : gen_fwd_d64
123 always_comb begin : p_fwd_d64
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 1
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
129 end
130 end else begin : gen_fwd_d32
131 always_comb begin : p_fwd_d32
132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1],
133 prim_cipher_pkg::PRINCE_SBOX4);
134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round);
135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round,
136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
137 end
138 end
139 logic [DataWidth-1:0] data_state_xor;
140 2/2 assign data_state_xor = data_state_round ^
Tests: T1 T2 T3 | T1 T2 T3
141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0];
142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
143 if (k % 2 == 1) begin : gen_fwd_key_odd
144 1/1 assign data_state_lo[k] = data_state_xor ^ k0_new_d;
Tests: T1 T2 T3
145 end else begin : gen_fwd_key_even
146 1/1 assign data_state_lo[k] = data_state_xor ^ k1_d;
Tests: T1 T2 T3
147 end
148 end
149
150 // middle part
151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle;
152 if (DataWidth == 64) begin : gen_middle_d64
153 always_comb begin : p_middle_d64
154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf],
Tests: T1 T2 T3
155 prim_cipher_pkg::PRINCE_SBOX4);
156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q);
Tests: T1 T2 T3
157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle,
Tests: T1 T2 T3
158 prim_cipher_pkg::PRINCE_SBOX4_INV);
159 end
160 end else begin : gen_middle_d32
161 always_comb begin : p_middle_d32
162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf],
163 prim_cipher_pkg::PRINCE_SBOX4);
164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q);
165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle,
166 prim_cipher_pkg::PRINCE_SBOX4_INV);
167 end
168 end
169
170 if (HalfwayDataReg) begin : gen_data_reg
171 logic valid_q;
172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg
173 if (!rst_ni) begin
174 valid_q <= 1'b0;
175 data_state_middle_q <= '0;
176 end else begin
177 valid_q <= valid_i;
178 if (valid_i) begin
179 data_state_middle_q <= data_state_middle_d;
180 end
181 end
182 end
183 assign valid_o = valid_q;
184 end else begin : gen_no_data_reg
185 // just pass data through in this case
186 1/1 assign data_state_middle_q = data_state_middle_d;
Tests: T1 T2 T3
187 1/1 assign valid_o = valid_i;
Tests: T1 T2 T3
188 end
189
190 1/1 assign data_state_hi[0] = data_state_middle;
Tests: T1 T2 T3
191
192 // backward pass
193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass
194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1;
195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd
197 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q;
Tests: T1 T2 T3
198 end else begin : gen_bkwd_key_even
199 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q;
Tests: T1 T2 T3
200 end
201 // the construction is reflective, hence the subtraction with NumRoundsHalf
202 2/2 assign data_state_xor1 = data_state_xor0 ^
Tests: T1 T2 T3 | T1 T2 T3
203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0];
204
205 logic [DataWidth-1:0] data_state_bwd;
206 if (DataWidth == 64) begin : gen_bwd_d64
207 always_comb begin : p_bwd_d64
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 2
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
212 prim_cipher_pkg::PRINCE_SBOX4_INV);
213 end
214 end else begin : gen_bwd_d32
215 always_comb begin : p_bwd_d32
216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1,
217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd);
219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd,
220 prim_cipher_pkg::PRINCE_SBOX4_INV);
221 end
222 end
223 end
224
225 // post-rounds
226 always_comb begin : p_post_round_xor
227 1/1 data_o = data_state_hi[NumRoundsHalf] ^
Tests: T1 T2 T3
228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0];
229 1/1 data_o ^= k1_q;
Tests: T1 T2 T3
230 1/1 data_o ^= k0_prime_q;
Tests: T1 T2 T3
Line Coverage for Module :
prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=3,UseOldKeySched=1,HalfwayDataReg=0,HalfwayKeyReg=0 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 53 | 53 | 100.00 |
ALWAYS | 56 | 7 | 7 | 100.00 |
CONT_ASSIGN | 70 | 1 | 1 | 100.00 |
CONT_ASSIGN | 99 | 1 | 1 | 100.00 |
CONT_ASSIGN | 100 | 1 | 1 | 100.00 |
CONT_ASSIGN | 101 | 1 | 1 | 100.00 |
ALWAYS | 114 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 146 | 1 | 1 | 100.00 |
ALWAYS | 154 | 3 | 3 | 100.00 |
CONT_ASSIGN | 186 | 1 | 1 | 100.00 |
CONT_ASSIGN | 187 | 1 | 1 | 100.00 |
CONT_ASSIGN | 190 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 227 | 3 | 3 | 100.00 |
55 always_comb begin : p_key_expansion
56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]};
Tests: T1 T2 T3
58 1/1 k1_d = key_i[DataWidth-1:0];
Tests: T1 T2 T3
59
60 // modify key for decryption
61 1/1 if (dec_i) begin
Tests: T1 T2 T3
62 1/1 k0 = k0_prime_d;
Tests: T1 T2 T3
63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
65 end
MISSING_ELSE
66 end
67
68 if (UseOldKeySched) begin : gen_legacy_keyschedule
69 // In this case we constantly use k1.
70 1/1 assign k0_new_d = k1_d;
Tests: T1 T2 T3
71 end else begin : gen_new_keyschedule
72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
73 // In this case we alternate between k1 and k0.
74 always_comb begin : p_new_keyschedule_k0_alpha
75 k0_new_d = key_i[2*DataWidth-1 : DataWidth];
76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode.
77 if (dec_i) begin
78 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
79 end
80 end
81 end
82
83 if (HalfwayKeyReg) begin : gen_key_reg
84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg
85 if (!rst_ni) begin
86 k1_q <= '0;
87 k0_prime_q <= '0;
88 k0_new_q <= '0;
89 end else begin
90 if (valid_i) begin
91 k1_q <= k1_d;
92 k0_prime_q <= k0_prime_d;
93 k0_new_q <= k0_new_d;
94 end
95 end
96 end
97 end else begin : gen_no_key_reg
98 // just pass the key through in this case
99 1/1 assign k1_q = k1_d;
Tests: T1 T2 T3
100 1/1 assign k0_prime_q = k0_prime_d;
Tests: T1 T2 T3
101 1/1 assign k0_new_q = k0_new_d;
Tests: T1 T2 T3
102 end
103
104 //////////////
105 // datapath //
106 //////////////
107
108 // State variable for holding the rounds
109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo;
110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi;
111
112 // pre-round XOR
113 always_comb begin : p_pre_round_xor
114 1/1 data_state_lo[0] = data_i ^ k0;
Tests: T1 T2 T3
115 1/1 data_state_lo[0] ^= k1_d;
Tests: T1 T2 T3
116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0];
Tests: T1 T2 T3
117 end
118
119 // forward pass
120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass
121 logic [DataWidth-1:0] data_state_round;
122 if (DataWidth == 64) begin : gen_fwd_d64
123 always_comb begin : p_fwd_d64
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 1
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 2
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
129 end
130 end else begin : gen_fwd_d32
131 always_comb begin : p_fwd_d32
132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1],
133 prim_cipher_pkg::PRINCE_SBOX4);
134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round);
135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round,
136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
137 end
138 end
139 logic [DataWidth-1:0] data_state_xor;
140 3/3 assign data_state_xor = data_state_round ^
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0];
142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
143 if (k % 2 == 1) begin : gen_fwd_key_odd
144 2/2 assign data_state_lo[k] = data_state_xor ^ k0_new_d;
Tests: T1 T2 T3 | T1 T2 T3
145 end else begin : gen_fwd_key_even
146 1/1 assign data_state_lo[k] = data_state_xor ^ k1_d;
Tests: T1 T2 T3
147 end
148 end
149
150 // middle part
151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle;
152 if (DataWidth == 64) begin : gen_middle_d64
153 always_comb begin : p_middle_d64
154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf],
Tests: T1 T2 T3
155 prim_cipher_pkg::PRINCE_SBOX4);
156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q);
Tests: T1 T2 T3
157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle,
Tests: T1 T2 T3
158 prim_cipher_pkg::PRINCE_SBOX4_INV);
159 end
160 end else begin : gen_middle_d32
161 always_comb begin : p_middle_d32
162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf],
163 prim_cipher_pkg::PRINCE_SBOX4);
164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q);
165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle,
166 prim_cipher_pkg::PRINCE_SBOX4_INV);
167 end
168 end
169
170 if (HalfwayDataReg) begin : gen_data_reg
171 logic valid_q;
172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg
173 if (!rst_ni) begin
174 valid_q <= 1'b0;
175 data_state_middle_q <= '0;
176 end else begin
177 valid_q <= valid_i;
178 if (valid_i) begin
179 data_state_middle_q <= data_state_middle_d;
180 end
181 end
182 end
183 assign valid_o = valid_q;
184 end else begin : gen_no_data_reg
185 // just pass data through in this case
186 1/1 assign data_state_middle_q = data_state_middle_d;
Tests: T1 T2 T3
187 1/1 assign valid_o = valid_i;
Tests: T1 T2 T3
188 end
189
190 1/1 assign data_state_hi[0] = data_state_middle;
Tests: T1 T2 T3
191
192 // backward pass
193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass
194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1;
195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd
197 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q;
Tests: T1 T2 T3 | T1 T2 T3
198 end else begin : gen_bkwd_key_even
199 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q;
Tests: T1 T2 T3
200 end
201 // the construction is reflective, hence the subtraction with NumRoundsHalf
202 3/3 assign data_state_xor1 = data_state_xor0 ^
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0];
204
205 logic [DataWidth-1:0] data_state_bwd;
206 if (DataWidth == 64) begin : gen_bwd_d64
207 always_comb begin : p_bwd_d64
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 3
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 4
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
212 prim_cipher_pkg::PRINCE_SBOX4_INV);
213 end
214 end else begin : gen_bwd_d32
215 always_comb begin : p_bwd_d32
216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1,
217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd);
219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd,
220 prim_cipher_pkg::PRINCE_SBOX4_INV);
221 end
222 end
223 end
224
225 // post-rounds
226 always_comb begin : p_post_round_xor
227 1/1 data_o = data_state_hi[NumRoundsHalf] ^
Tests: T1 T2 T3
228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0];
229 1/1 data_o ^= k1_q;
Tests: T1 T2 T3
230 1/1 data_o ^= k0_prime_q;
Tests: T1 T2 T3
Line Coverage for Module :
prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=4,UseOldKeySched=1,HalfwayDataReg=0,HalfwayKeyReg=0 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 63 | 63 | 100.00 |
ALWAYS | 56 | 7 | 7 | 100.00 |
CONT_ASSIGN | 70 | 1 | 1 | 100.00 |
CONT_ASSIGN | 99 | 1 | 1 | 100.00 |
CONT_ASSIGN | 100 | 1 | 1 | 100.00 |
CONT_ASSIGN | 101 | 1 | 1 | 100.00 |
ALWAYS | 114 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 146 | 1 | 1 | 100.00 |
CONT_ASSIGN | 146 | 1 | 1 | 100.00 |
ALWAYS | 154 | 3 | 3 | 100.00 |
CONT_ASSIGN | 186 | 1 | 1 | 100.00 |
CONT_ASSIGN | 187 | 1 | 1 | 100.00 |
CONT_ASSIGN | 190 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 227 | 3 | 3 | 100.00 |
55 always_comb begin : p_key_expansion
56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]};
Tests: T1 T2 T3
58 1/1 k1_d = key_i[DataWidth-1:0];
Tests: T1 T2 T3
59
60 // modify key for decryption
61 1/1 if (dec_i) begin
Tests: T1 T2 T3
62 1/1 k0 = k0_prime_d;
Tests: T1 T2 T3
63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
65 end
MISSING_ELSE
66 end
67
68 if (UseOldKeySched) begin : gen_legacy_keyschedule
69 // In this case we constantly use k1.
70 1/1 assign k0_new_d = k1_d;
Tests: T1 T2 T3
71 end else begin : gen_new_keyschedule
72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
73 // In this case we alternate between k1 and k0.
74 always_comb begin : p_new_keyschedule_k0_alpha
75 k0_new_d = key_i[2*DataWidth-1 : DataWidth];
76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode.
77 if (dec_i) begin
78 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
79 end
80 end
81 end
82
83 if (HalfwayKeyReg) begin : gen_key_reg
84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg
85 if (!rst_ni) begin
86 k1_q <= '0;
87 k0_prime_q <= '0;
88 k0_new_q <= '0;
89 end else begin
90 if (valid_i) begin
91 k1_q <= k1_d;
92 k0_prime_q <= k0_prime_d;
93 k0_new_q <= k0_new_d;
94 end
95 end
96 end
97 end else begin : gen_no_key_reg
98 // just pass the key through in this case
99 1/1 assign k1_q = k1_d;
Tests: T1 T2 T3
100 1/1 assign k0_prime_q = k0_prime_d;
Tests: T1 T2 T3
101 1/1 assign k0_new_q = k0_new_d;
Tests: T1 T2 T3
102 end
103
104 //////////////
105 // datapath //
106 //////////////
107
108 // State variable for holding the rounds
109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo;
110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi;
111
112 // pre-round XOR
113 always_comb begin : p_pre_round_xor
114 1/1 data_state_lo[0] = data_i ^ k0;
Tests: T1 T2 T3
115 1/1 data_state_lo[0] ^= k1_d;
Tests: T1 T2 T3
116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0];
Tests: T1 T2 T3
117 end
118
119 // forward pass
120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass
121 logic [DataWidth-1:0] data_state_round;
122 if (DataWidth == 64) begin : gen_fwd_d64
123 always_comb begin : p_fwd_d64
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 1
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 2
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 3
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
129 end
130 end else begin : gen_fwd_d32
131 always_comb begin : p_fwd_d32
132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1],
133 prim_cipher_pkg::PRINCE_SBOX4);
134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round);
135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round,
136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
137 end
138 end
139 logic [DataWidth-1:0] data_state_xor;
140 4/4 assign data_state_xor = data_state_round ^
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0];
142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
143 if (k % 2 == 1) begin : gen_fwd_key_odd
144 2/2 assign data_state_lo[k] = data_state_xor ^ k0_new_d;
Tests: T1 T2 T3 | T1 T2 T3
145 end else begin : gen_fwd_key_even
146 2/2 assign data_state_lo[k] = data_state_xor ^ k1_d;
Tests: T1 T2 T3 | T1 T2 T3
147 end
148 end
149
150 // middle part
151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle;
152 if (DataWidth == 64) begin : gen_middle_d64
153 always_comb begin : p_middle_d64
154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf],
Tests: T1 T2 T3
155 prim_cipher_pkg::PRINCE_SBOX4);
156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q);
Tests: T1 T2 T3
157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle,
Tests: T1 T2 T3
158 prim_cipher_pkg::PRINCE_SBOX4_INV);
159 end
160 end else begin : gen_middle_d32
161 always_comb begin : p_middle_d32
162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf],
163 prim_cipher_pkg::PRINCE_SBOX4);
164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q);
165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle,
166 prim_cipher_pkg::PRINCE_SBOX4_INV);
167 end
168 end
169
170 if (HalfwayDataReg) begin : gen_data_reg
171 logic valid_q;
172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg
173 if (!rst_ni) begin
174 valid_q <= 1'b0;
175 data_state_middle_q <= '0;
176 end else begin
177 valid_q <= valid_i;
178 if (valid_i) begin
179 data_state_middle_q <= data_state_middle_d;
180 end
181 end
182 end
183 assign valid_o = valid_q;
184 end else begin : gen_no_data_reg
185 // just pass data through in this case
186 1/1 assign data_state_middle_q = data_state_middle_d;
Tests: T1 T2 T3
187 1/1 assign valid_o = valid_i;
Tests: T1 T2 T3
188 end
189
190 1/1 assign data_state_hi[0] = data_state_middle;
Tests: T1 T2 T3
191
192 // backward pass
193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass
194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1;
195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd
197 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q;
Tests: T1 T2 T3 | T1 T2 T3
198 end else begin : gen_bkwd_key_even
199 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q;
Tests: T1 T2 T3 | T1 T2 T3
200 end
201 // the construction is reflective, hence the subtraction with NumRoundsHalf
202 4/4 assign data_state_xor1 = data_state_xor0 ^
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0];
204
205 logic [DataWidth-1:0] data_state_bwd;
206 if (DataWidth == 64) begin : gen_bwd_d64
207 always_comb begin : p_bwd_d64
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 4
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 5
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 6
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
212 prim_cipher_pkg::PRINCE_SBOX4_INV);
213 end
214 end else begin : gen_bwd_d32
215 always_comb begin : p_bwd_d32
216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1,
217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd);
219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd,
220 prim_cipher_pkg::PRINCE_SBOX4_INV);
221 end
222 end
223 end
224
225 // post-rounds
226 always_comb begin : p_post_round_xor
227 1/1 data_o = data_state_hi[NumRoundsHalf] ^
Tests: T1 T2 T3
228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0];
229 1/1 data_o ^= k1_q;
Tests: T1 T2 T3
230 1/1 data_o ^= k0_prime_q;
Tests: T1 T2 T3
Line Coverage for Module :
prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=5,UseOldKeySched=1,HalfwayDataReg=0,HalfwayKeyReg=0 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 73 | 73 | 100.00 |
ALWAYS | 56 | 7 | 7 | 100.00 |
CONT_ASSIGN | 70 | 1 | 1 | 100.00 |
CONT_ASSIGN | 99 | 1 | 1 | 100.00 |
CONT_ASSIGN | 100 | 1 | 1 | 100.00 |
CONT_ASSIGN | 101 | 1 | 1 | 100.00 |
ALWAYS | 114 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 146 | 1 | 1 | 100.00 |
CONT_ASSIGN | 146 | 1 | 1 | 100.00 |
ALWAYS | 154 | 3 | 3 | 100.00 |
CONT_ASSIGN | 186 | 1 | 1 | 100.00 |
CONT_ASSIGN | 187 | 1 | 1 | 100.00 |
CONT_ASSIGN | 190 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 227 | 3 | 3 | 100.00 |
55 always_comb begin : p_key_expansion
56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]};
Tests: T1 T2 T3
58 1/1 k1_d = key_i[DataWidth-1:0];
Tests: T1 T2 T3
59
60 // modify key for decryption
61 1/1 if (dec_i) begin
Tests: T1 T2 T3
62 1/1 k0 = k0_prime_d;
Tests: T1 T2 T3
63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
65 end
MISSING_ELSE
66 end
67
68 if (UseOldKeySched) begin : gen_legacy_keyschedule
69 // In this case we constantly use k1.
70 1/1 assign k0_new_d = k1_d;
Tests: T1 T2 T3
71 end else begin : gen_new_keyschedule
72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
73 // In this case we alternate between k1 and k0.
74 always_comb begin : p_new_keyschedule_k0_alpha
75 k0_new_d = key_i[2*DataWidth-1 : DataWidth];
76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode.
77 if (dec_i) begin
78 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
79 end
80 end
81 end
82
83 if (HalfwayKeyReg) begin : gen_key_reg
84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg
85 if (!rst_ni) begin
86 k1_q <= '0;
87 k0_prime_q <= '0;
88 k0_new_q <= '0;
89 end else begin
90 if (valid_i) begin
91 k1_q <= k1_d;
92 k0_prime_q <= k0_prime_d;
93 k0_new_q <= k0_new_d;
94 end
95 end
96 end
97 end else begin : gen_no_key_reg
98 // just pass the key through in this case
99 1/1 assign k1_q = k1_d;
Tests: T1 T2 T3
100 1/1 assign k0_prime_q = k0_prime_d;
Tests: T1 T2 T3
101 1/1 assign k0_new_q = k0_new_d;
Tests: T1 T2 T3
102 end
103
104 //////////////
105 // datapath //
106 //////////////
107
108 // State variable for holding the rounds
109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo;
110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi;
111
112 // pre-round XOR
113 always_comb begin : p_pre_round_xor
114 1/1 data_state_lo[0] = data_i ^ k0;
Tests: T1 T2 T3
115 1/1 data_state_lo[0] ^= k1_d;
Tests: T1 T2 T3
116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0];
Tests: T1 T2 T3
117 end
118
119 // forward pass
120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass
121 logic [DataWidth-1:0] data_state_round;
122 if (DataWidth == 64) begin : gen_fwd_d64
123 always_comb begin : p_fwd_d64
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 1
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 2
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 3
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 4
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
129 end
130 end else begin : gen_fwd_d32
131 always_comb begin : p_fwd_d32
132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1],
133 prim_cipher_pkg::PRINCE_SBOX4);
134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round);
135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round,
136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
137 end
138 end
139 logic [DataWidth-1:0] data_state_xor;
140 5/5 assign data_state_xor = data_state_round ^
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0];
142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
143 if (k % 2 == 1) begin : gen_fwd_key_odd
144 3/3 assign data_state_lo[k] = data_state_xor ^ k0_new_d;
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
145 end else begin : gen_fwd_key_even
146 2/2 assign data_state_lo[k] = data_state_xor ^ k1_d;
Tests: T1 T2 T3 | T1 T2 T3
147 end
148 end
149
150 // middle part
151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle;
152 if (DataWidth == 64) begin : gen_middle_d64
153 always_comb begin : p_middle_d64
154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf],
Tests: T1 T2 T3
155 prim_cipher_pkg::PRINCE_SBOX4);
156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q);
Tests: T1 T2 T3
157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle,
Tests: T1 T2 T3
158 prim_cipher_pkg::PRINCE_SBOX4_INV);
159 end
160 end else begin : gen_middle_d32
161 always_comb begin : p_middle_d32
162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf],
163 prim_cipher_pkg::PRINCE_SBOX4);
164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q);
165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle,
166 prim_cipher_pkg::PRINCE_SBOX4_INV);
167 end
168 end
169
170 if (HalfwayDataReg) begin : gen_data_reg
171 logic valid_q;
172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg
173 if (!rst_ni) begin
174 valid_q <= 1'b0;
175 data_state_middle_q <= '0;
176 end else begin
177 valid_q <= valid_i;
178 if (valid_i) begin
179 data_state_middle_q <= data_state_middle_d;
180 end
181 end
182 end
183 assign valid_o = valid_q;
184 end else begin : gen_no_data_reg
185 // just pass data through in this case
186 1/1 assign data_state_middle_q = data_state_middle_d;
Tests: T1 T2 T3
187 1/1 assign valid_o = valid_i;
Tests: T1 T2 T3
188 end
189
190 1/1 assign data_state_hi[0] = data_state_middle;
Tests: T1 T2 T3
191
192 // backward pass
193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass
194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1;
195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd
197 3/3 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q;
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
198 end else begin : gen_bkwd_key_even
199 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q;
Tests: T1 T2 T3 | T1 T2 T3
200 end
201 // the construction is reflective, hence the subtraction with NumRoundsHalf
202 5/5 assign data_state_xor1 = data_state_xor0 ^
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0];
204
205 logic [DataWidth-1:0] data_state_bwd;
206 if (DataWidth == 64) begin : gen_bwd_d64
207 always_comb begin : p_bwd_d64
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 5
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 6
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 7
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 8
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
212 prim_cipher_pkg::PRINCE_SBOX4_INV);
213 end
214 end else begin : gen_bwd_d32
215 always_comb begin : p_bwd_d32
216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1,
217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd);
219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd,
220 prim_cipher_pkg::PRINCE_SBOX4_INV);
221 end
222 end
223 end
224
225 // post-rounds
226 always_comb begin : p_post_round_xor
227 1/1 data_o = data_state_hi[NumRoundsHalf] ^
Tests: T1 T2 T3
228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0];
229 1/1 data_o ^= k1_q;
Tests: T1 T2 T3
230 1/1 data_o ^= k0_prime_q;
Tests: T1 T2 T3
Line Coverage for Module :
prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=1,UseOldKeySched=1,HalfwayDataReg=1,HalfwayKeyReg=1 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 43 | 43 | 100.00 |
ALWAYS | 56 | 7 | 7 | 100.00 |
CONT_ASSIGN | 70 | 1 | 1 | 100.00 |
ALWAYS | 85 | 8 | 8 | 100.00 |
ALWAYS | 114 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
ALWAYS | 154 | 3 | 3 | 100.00 |
ALWAYS | 173 | 6 | 6 | 100.00 |
CONT_ASSIGN | 183 | 1 | 1 | 100.00 |
CONT_ASSIGN | 190 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 227 | 3 | 3 | 100.00 |
55 always_comb begin : p_key_expansion
56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]};
Tests: T1 T2 T3
58 1/1 k1_d = key_i[DataWidth-1:0];
Tests: T1 T2 T3
59
60 // modify key for decryption
61 1/1 if (dec_i) begin
Tests: T1 T2 T3
62 1/1 k0 = k0_prime_d;
Tests: T1 T2 T3
63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
65 end
MISSING_ELSE
66 end
67
68 if (UseOldKeySched) begin : gen_legacy_keyschedule
69 // In this case we constantly use k1.
70 1/1 assign k0_new_d = k1_d;
Tests: T1 T2 T3
71 end else begin : gen_new_keyschedule
72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
73 // In this case we alternate between k1 and k0.
74 always_comb begin : p_new_keyschedule_k0_alpha
75 k0_new_d = key_i[2*DataWidth-1 : DataWidth];
76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode.
77 if (dec_i) begin
78 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
79 end
80 end
81 end
82
83 if (HalfwayKeyReg) begin : gen_key_reg
84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg
85 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
86 1/1 k1_q <= '0;
Tests: T1 T2 T3
87 1/1 k0_prime_q <= '0;
Tests: T1 T2 T3
88 1/1 k0_new_q <= '0;
Tests: T1 T2 T3
89 end else begin
90 1/1 if (valid_i) begin
Tests: T1 T2 T3
91 1/1 k1_q <= k1_d;
Tests: T1 T2 T3
92 1/1 k0_prime_q <= k0_prime_d;
Tests: T1 T2 T3
93 1/1 k0_new_q <= k0_new_d;
Tests: T1 T2 T3
94 end
MISSING_ELSE
95 end
96 end
97 end else begin : gen_no_key_reg
98 // just pass the key through in this case
99 assign k1_q = k1_d;
100 assign k0_prime_q = k0_prime_d;
101 assign k0_new_q = k0_new_d;
102 end
103
104 //////////////
105 // datapath //
106 //////////////
107
108 // State variable for holding the rounds
109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo;
110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi;
111
112 // pre-round XOR
113 always_comb begin : p_pre_round_xor
114 1/1 data_state_lo[0] = data_i ^ k0;
Tests: T1 T2 T3
115 1/1 data_state_lo[0] ^= k1_d;
Tests: T1 T2 T3
116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0];
Tests: T1 T2 T3
117 end
118
119 // forward pass
120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass
121 logic [DataWidth-1:0] data_state_round;
122 if (DataWidth == 64) begin : gen_fwd_d64
123 always_comb begin : p_fwd_d64
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
129 end
130 end else begin : gen_fwd_d32
131 always_comb begin : p_fwd_d32
132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1],
133 prim_cipher_pkg::PRINCE_SBOX4);
134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round);
135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round,
136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
137 end
138 end
139 logic [DataWidth-1:0] data_state_xor;
140 1/1 assign data_state_xor = data_state_round ^
Tests: T1 T2 T3
141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0];
142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
143 if (k % 2 == 1) begin : gen_fwd_key_odd
144 1/1 assign data_state_lo[k] = data_state_xor ^ k0_new_d;
Tests: T1 T2 T3
145 end else begin : gen_fwd_key_even
146 assign data_state_lo[k] = data_state_xor ^ k1_d;
147 end
148 end
149
150 // middle part
151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle;
152 if (DataWidth == 64) begin : gen_middle_d64
153 always_comb begin : p_middle_d64
154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf],
Tests: T1 T2 T3
155 prim_cipher_pkg::PRINCE_SBOX4);
156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q);
Tests: T1 T2 T3
157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle,
Tests: T1 T2 T3
158 prim_cipher_pkg::PRINCE_SBOX4_INV);
159 end
160 end else begin : gen_middle_d32
161 always_comb begin : p_middle_d32
162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf],
163 prim_cipher_pkg::PRINCE_SBOX4);
164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q);
165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle,
166 prim_cipher_pkg::PRINCE_SBOX4_INV);
167 end
168 end
169
170 if (HalfwayDataReg) begin : gen_data_reg
171 logic valid_q;
172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg
173 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
174 1/1 valid_q <= 1'b0;
Tests: T1 T2 T3
175 1/1 data_state_middle_q <= '0;
Tests: T1 T2 T3
176 end else begin
177 1/1 valid_q <= valid_i;
Tests: T1 T2 T3
178 1/1 if (valid_i) begin
Tests: T1 T2 T3
179 1/1 data_state_middle_q <= data_state_middle_d;
Tests: T1 T2 T3
180 end
MISSING_ELSE
181 end
182 end
183 1/1 assign valid_o = valid_q;
Tests: T1 T2 T3
184 end else begin : gen_no_data_reg
185 // just pass data through in this case
186 assign data_state_middle_q = data_state_middle_d;
187 assign valid_o = valid_i;
188 end
189
190 1/1 assign data_state_hi[0] = data_state_middle;
Tests: T1 T2 T3
191
192 // backward pass
193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass
194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1;
195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd
197 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q;
Tests: T1 T2 T3
198 end else begin : gen_bkwd_key_even
199 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q;
200 end
201 // the construction is reflective, hence the subtraction with NumRoundsHalf
202 1/1 assign data_state_xor1 = data_state_xor0 ^
Tests: T1 T2 T3
203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0];
204
205 logic [DataWidth-1:0] data_state_bwd;
206 if (DataWidth == 64) begin : gen_bwd_d64
207 always_comb begin : p_bwd_d64
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
212 prim_cipher_pkg::PRINCE_SBOX4_INV);
213 end
214 end else begin : gen_bwd_d32
215 always_comb begin : p_bwd_d32
216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1,
217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd);
219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd,
220 prim_cipher_pkg::PRINCE_SBOX4_INV);
221 end
222 end
223 end
224
225 // post-rounds
226 always_comb begin : p_post_round_xor
227 1/1 data_o = data_state_hi[NumRoundsHalf] ^
Tests: T1 T2 T3
228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0];
229 1/1 data_o ^= k1_q;
Tests: T1 T2 T3
230 1/1 data_o ^= k0_prime_q;
Tests: T1 T2 T3
Line Coverage for Module :
prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=2,UseOldKeySched=1,HalfwayDataReg=1,HalfwayKeyReg=1 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 53 | 53 | 100.00 |
ALWAYS | 56 | 7 | 7 | 100.00 |
CONT_ASSIGN | 70 | 1 | 1 | 100.00 |
ALWAYS | 85 | 8 | 8 | 100.00 |
ALWAYS | 114 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 146 | 1 | 1 | 100.00 |
ALWAYS | 154 | 3 | 3 | 100.00 |
ALWAYS | 173 | 6 | 6 | 100.00 |
CONT_ASSIGN | 183 | 1 | 1 | 100.00 |
CONT_ASSIGN | 190 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 227 | 3 | 3 | 100.00 |
55 always_comb begin : p_key_expansion
56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]};
Tests: T1 T2 T3
58 1/1 k1_d = key_i[DataWidth-1:0];
Tests: T1 T2 T3
59
60 // modify key for decryption
61 1/1 if (dec_i) begin
Tests: T1 T2 T3
62 1/1 k0 = k0_prime_d;
Tests: T1 T2 T3
63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
65 end
MISSING_ELSE
66 end
67
68 if (UseOldKeySched) begin : gen_legacy_keyschedule
69 // In this case we constantly use k1.
70 1/1 assign k0_new_d = k1_d;
Tests: T1 T2 T3
71 end else begin : gen_new_keyschedule
72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
73 // In this case we alternate between k1 and k0.
74 always_comb begin : p_new_keyschedule_k0_alpha
75 k0_new_d = key_i[2*DataWidth-1 : DataWidth];
76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode.
77 if (dec_i) begin
78 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
79 end
80 end
81 end
82
83 if (HalfwayKeyReg) begin : gen_key_reg
84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg
85 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
86 1/1 k1_q <= '0;
Tests: T1 T2 T3
87 1/1 k0_prime_q <= '0;
Tests: T1 T2 T3
88 1/1 k0_new_q <= '0;
Tests: T1 T2 T3
89 end else begin
90 1/1 if (valid_i) begin
Tests: T1 T2 T3
91 1/1 k1_q <= k1_d;
Tests: T1 T2 T3
92 1/1 k0_prime_q <= k0_prime_d;
Tests: T1 T2 T3
93 1/1 k0_new_q <= k0_new_d;
Tests: T1 T2 T3
94 end
MISSING_ELSE
95 end
96 end
97 end else begin : gen_no_key_reg
98 // just pass the key through in this case
99 assign k1_q = k1_d;
100 assign k0_prime_q = k0_prime_d;
101 assign k0_new_q = k0_new_d;
102 end
103
104 //////////////
105 // datapath //
106 //////////////
107
108 // State variable for holding the rounds
109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo;
110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi;
111
112 // pre-round XOR
113 always_comb begin : p_pre_round_xor
114 1/1 data_state_lo[0] = data_i ^ k0;
Tests: T1 T2 T3
115 1/1 data_state_lo[0] ^= k1_d;
Tests: T1 T2 T3
116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0];
Tests: T1 T2 T3
117 end
118
119 // forward pass
120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass
121 logic [DataWidth-1:0] data_state_round;
122 if (DataWidth == 64) begin : gen_fwd_d64
123 always_comb begin : p_fwd_d64
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 1
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
129 end
130 end else begin : gen_fwd_d32
131 always_comb begin : p_fwd_d32
132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1],
133 prim_cipher_pkg::PRINCE_SBOX4);
134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round);
135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round,
136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
137 end
138 end
139 logic [DataWidth-1:0] data_state_xor;
140 2/2 assign data_state_xor = data_state_round ^
Tests: T1 T2 T3 | T1 T2 T3
141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0];
142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
143 if (k % 2 == 1) begin : gen_fwd_key_odd
144 1/1 assign data_state_lo[k] = data_state_xor ^ k0_new_d;
Tests: T1 T2 T3
145 end else begin : gen_fwd_key_even
146 1/1 assign data_state_lo[k] = data_state_xor ^ k1_d;
Tests: T1 T2 T3
147 end
148 end
149
150 // middle part
151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle;
152 if (DataWidth == 64) begin : gen_middle_d64
153 always_comb begin : p_middle_d64
154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf],
Tests: T1 T2 T3
155 prim_cipher_pkg::PRINCE_SBOX4);
156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q);
Tests: T1 T2 T3
157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle,
Tests: T1 T2 T3
158 prim_cipher_pkg::PRINCE_SBOX4_INV);
159 end
160 end else begin : gen_middle_d32
161 always_comb begin : p_middle_d32
162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf],
163 prim_cipher_pkg::PRINCE_SBOX4);
164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q);
165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle,
166 prim_cipher_pkg::PRINCE_SBOX4_INV);
167 end
168 end
169
170 if (HalfwayDataReg) begin : gen_data_reg
171 logic valid_q;
172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg
173 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
174 1/1 valid_q <= 1'b0;
Tests: T1 T2 T3
175 1/1 data_state_middle_q <= '0;
Tests: T1 T2 T3
176 end else begin
177 1/1 valid_q <= valid_i;
Tests: T1 T2 T3
178 1/1 if (valid_i) begin
Tests: T1 T2 T3
179 1/1 data_state_middle_q <= data_state_middle_d;
Tests: T1 T2 T3
180 end
MISSING_ELSE
181 end
182 end
183 1/1 assign valid_o = valid_q;
Tests: T1 T2 T3
184 end else begin : gen_no_data_reg
185 // just pass data through in this case
186 assign data_state_middle_q = data_state_middle_d;
187 assign valid_o = valid_i;
188 end
189
190 1/1 assign data_state_hi[0] = data_state_middle;
Tests: T1 T2 T3
191
192 // backward pass
193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass
194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1;
195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd
197 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q;
Tests: T1 T2 T3
198 end else begin : gen_bkwd_key_even
199 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q;
Tests: T1 T2 T3
200 end
201 // the construction is reflective, hence the subtraction with NumRoundsHalf
202 2/2 assign data_state_xor1 = data_state_xor0 ^
Tests: T1 T2 T3 | T1 T2 T3
203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0];
204
205 logic [DataWidth-1:0] data_state_bwd;
206 if (DataWidth == 64) begin : gen_bwd_d64
207 always_comb begin : p_bwd_d64
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 2
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
212 prim_cipher_pkg::PRINCE_SBOX4_INV);
213 end
214 end else begin : gen_bwd_d32
215 always_comb begin : p_bwd_d32
216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1,
217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd);
219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd,
220 prim_cipher_pkg::PRINCE_SBOX4_INV);
221 end
222 end
223 end
224
225 // post-rounds
226 always_comb begin : p_post_round_xor
227 1/1 data_o = data_state_hi[NumRoundsHalf] ^
Tests: T1 T2 T3
228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0];
229 1/1 data_o ^= k1_q;
Tests: T1 T2 T3
230 1/1 data_o ^= k0_prime_q;
Tests: T1 T2 T3
Line Coverage for Module :
prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=3,UseOldKeySched=1,HalfwayDataReg=1,HalfwayKeyReg=1 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 63 | 63 | 100.00 |
ALWAYS | 56 | 7 | 7 | 100.00 |
CONT_ASSIGN | 70 | 1 | 1 | 100.00 |
ALWAYS | 85 | 8 | 8 | 100.00 |
ALWAYS | 114 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 146 | 1 | 1 | 100.00 |
ALWAYS | 154 | 3 | 3 | 100.00 |
ALWAYS | 173 | 6 | 6 | 100.00 |
CONT_ASSIGN | 183 | 1 | 1 | 100.00 |
CONT_ASSIGN | 190 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 227 | 3 | 3 | 100.00 |
55 always_comb begin : p_key_expansion
56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]};
Tests: T1 T2 T3
58 1/1 k1_d = key_i[DataWidth-1:0];
Tests: T1 T2 T3
59
60 // modify key for decryption
61 1/1 if (dec_i) begin
Tests: T1 T2 T3
62 1/1 k0 = k0_prime_d;
Tests: T1 T2 T3
63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
65 end
MISSING_ELSE
66 end
67
68 if (UseOldKeySched) begin : gen_legacy_keyschedule
69 // In this case we constantly use k1.
70 1/1 assign k0_new_d = k1_d;
Tests: T1 T2 T3
71 end else begin : gen_new_keyschedule
72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
73 // In this case we alternate between k1 and k0.
74 always_comb begin : p_new_keyschedule_k0_alpha
75 k0_new_d = key_i[2*DataWidth-1 : DataWidth];
76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode.
77 if (dec_i) begin
78 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
79 end
80 end
81 end
82
83 if (HalfwayKeyReg) begin : gen_key_reg
84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg
85 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
86 1/1 k1_q <= '0;
Tests: T1 T2 T3
87 1/1 k0_prime_q <= '0;
Tests: T1 T2 T3
88 1/1 k0_new_q <= '0;
Tests: T1 T2 T3
89 end else begin
90 1/1 if (valid_i) begin
Tests: T1 T2 T3
91 1/1 k1_q <= k1_d;
Tests: T1 T2 T3
92 1/1 k0_prime_q <= k0_prime_d;
Tests: T1 T2 T3
93 1/1 k0_new_q <= k0_new_d;
Tests: T1 T2 T3
94 end
MISSING_ELSE
95 end
96 end
97 end else begin : gen_no_key_reg
98 // just pass the key through in this case
99 assign k1_q = k1_d;
100 assign k0_prime_q = k0_prime_d;
101 assign k0_new_q = k0_new_d;
102 end
103
104 //////////////
105 // datapath //
106 //////////////
107
108 // State variable for holding the rounds
109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo;
110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi;
111
112 // pre-round XOR
113 always_comb begin : p_pre_round_xor
114 1/1 data_state_lo[0] = data_i ^ k0;
Tests: T1 T2 T3
115 1/1 data_state_lo[0] ^= k1_d;
Tests: T1 T2 T3
116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0];
Tests: T1 T2 T3
117 end
118
119 // forward pass
120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass
121 logic [DataWidth-1:0] data_state_round;
122 if (DataWidth == 64) begin : gen_fwd_d64
123 always_comb begin : p_fwd_d64
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 1
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 2
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
129 end
130 end else begin : gen_fwd_d32
131 always_comb begin : p_fwd_d32
132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1],
133 prim_cipher_pkg::PRINCE_SBOX4);
134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round);
135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round,
136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
137 end
138 end
139 logic [DataWidth-1:0] data_state_xor;
140 3/3 assign data_state_xor = data_state_round ^
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0];
142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
143 if (k % 2 == 1) begin : gen_fwd_key_odd
144 2/2 assign data_state_lo[k] = data_state_xor ^ k0_new_d;
Tests: T1 T2 T3 | T1 T2 T3
145 end else begin : gen_fwd_key_even
146 1/1 assign data_state_lo[k] = data_state_xor ^ k1_d;
Tests: T1 T2 T3
147 end
148 end
149
150 // middle part
151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle;
152 if (DataWidth == 64) begin : gen_middle_d64
153 always_comb begin : p_middle_d64
154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf],
Tests: T1 T2 T3
155 prim_cipher_pkg::PRINCE_SBOX4);
156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q);
Tests: T1 T2 T3
157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle,
Tests: T1 T2 T3
158 prim_cipher_pkg::PRINCE_SBOX4_INV);
159 end
160 end else begin : gen_middle_d32
161 always_comb begin : p_middle_d32
162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf],
163 prim_cipher_pkg::PRINCE_SBOX4);
164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q);
165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle,
166 prim_cipher_pkg::PRINCE_SBOX4_INV);
167 end
168 end
169
170 if (HalfwayDataReg) begin : gen_data_reg
171 logic valid_q;
172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg
173 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
174 1/1 valid_q <= 1'b0;
Tests: T1 T2 T3
175 1/1 data_state_middle_q <= '0;
Tests: T1 T2 T3
176 end else begin
177 1/1 valid_q <= valid_i;
Tests: T1 T2 T3
178 1/1 if (valid_i) begin
Tests: T1 T2 T3
179 1/1 data_state_middle_q <= data_state_middle_d;
Tests: T1 T2 T3
180 end
MISSING_ELSE
181 end
182 end
183 1/1 assign valid_o = valid_q;
Tests: T1 T2 T3
184 end else begin : gen_no_data_reg
185 // just pass data through in this case
186 assign data_state_middle_q = data_state_middle_d;
187 assign valid_o = valid_i;
188 end
189
190 1/1 assign data_state_hi[0] = data_state_middle;
Tests: T1 T2 T3
191
192 // backward pass
193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass
194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1;
195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd
197 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q;
Tests: T1 T2 T3 | T1 T2 T3
198 end else begin : gen_bkwd_key_even
199 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q;
Tests: T1 T2 T3
200 end
201 // the construction is reflective, hence the subtraction with NumRoundsHalf
202 3/3 assign data_state_xor1 = data_state_xor0 ^
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0];
204
205 logic [DataWidth-1:0] data_state_bwd;
206 if (DataWidth == 64) begin : gen_bwd_d64
207 always_comb begin : p_bwd_d64
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 3
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 4
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
212 prim_cipher_pkg::PRINCE_SBOX4_INV);
213 end
214 end else begin : gen_bwd_d32
215 always_comb begin : p_bwd_d32
216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1,
217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd);
219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd,
220 prim_cipher_pkg::PRINCE_SBOX4_INV);
221 end
222 end
223 end
224
225 // post-rounds
226 always_comb begin : p_post_round_xor
227 1/1 data_o = data_state_hi[NumRoundsHalf] ^
Tests: T1 T2 T3
228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0];
229 1/1 data_o ^= k1_q;
Tests: T1 T2 T3
230 1/1 data_o ^= k0_prime_q;
Tests: T1 T2 T3
Line Coverage for Module :
prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=4,UseOldKeySched=1,HalfwayDataReg=1,HalfwayKeyReg=1 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 73 | 73 | 100.00 |
ALWAYS | 56 | 7 | 7 | 100.00 |
CONT_ASSIGN | 70 | 1 | 1 | 100.00 |
ALWAYS | 85 | 8 | 8 | 100.00 |
ALWAYS | 114 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 146 | 1 | 1 | 100.00 |
CONT_ASSIGN | 146 | 1 | 1 | 100.00 |
ALWAYS | 154 | 3 | 3 | 100.00 |
ALWAYS | 173 | 6 | 6 | 100.00 |
CONT_ASSIGN | 183 | 1 | 1 | 100.00 |
CONT_ASSIGN | 190 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 227 | 3 | 3 | 100.00 |
55 always_comb begin : p_key_expansion
56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]};
Tests: T1 T2 T3
58 1/1 k1_d = key_i[DataWidth-1:0];
Tests: T1 T2 T3
59
60 // modify key for decryption
61 1/1 if (dec_i) begin
Tests: T1 T2 T3
62 1/1 k0 = k0_prime_d;
Tests: T1 T2 T3
63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
65 end
MISSING_ELSE
66 end
67
68 if (UseOldKeySched) begin : gen_legacy_keyschedule
69 // In this case we constantly use k1.
70 1/1 assign k0_new_d = k1_d;
Tests: T1 T2 T3
71 end else begin : gen_new_keyschedule
72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
73 // In this case we alternate between k1 and k0.
74 always_comb begin : p_new_keyschedule_k0_alpha
75 k0_new_d = key_i[2*DataWidth-1 : DataWidth];
76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode.
77 if (dec_i) begin
78 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
79 end
80 end
81 end
82
83 if (HalfwayKeyReg) begin : gen_key_reg
84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg
85 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
86 1/1 k1_q <= '0;
Tests: T1 T2 T3
87 1/1 k0_prime_q <= '0;
Tests: T1 T2 T3
88 1/1 k0_new_q <= '0;
Tests: T1 T2 T3
89 end else begin
90 1/1 if (valid_i) begin
Tests: T1 T2 T3
91 1/1 k1_q <= k1_d;
Tests: T1 T2 T3
92 1/1 k0_prime_q <= k0_prime_d;
Tests: T1 T2 T3
93 1/1 k0_new_q <= k0_new_d;
Tests: T1 T2 T3
94 end
MISSING_ELSE
95 end
96 end
97 end else begin : gen_no_key_reg
98 // just pass the key through in this case
99 assign k1_q = k1_d;
100 assign k0_prime_q = k0_prime_d;
101 assign k0_new_q = k0_new_d;
102 end
103
104 //////////////
105 // datapath //
106 //////////////
107
108 // State variable for holding the rounds
109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo;
110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi;
111
112 // pre-round XOR
113 always_comb begin : p_pre_round_xor
114 1/1 data_state_lo[0] = data_i ^ k0;
Tests: T1 T2 T3
115 1/1 data_state_lo[0] ^= k1_d;
Tests: T1 T2 T3
116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0];
Tests: T1 T2 T3
117 end
118
119 // forward pass
120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass
121 logic [DataWidth-1:0] data_state_round;
122 if (DataWidth == 64) begin : gen_fwd_d64
123 always_comb begin : p_fwd_d64
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 1
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 2
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 3
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
129 end
130 end else begin : gen_fwd_d32
131 always_comb begin : p_fwd_d32
132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1],
133 prim_cipher_pkg::PRINCE_SBOX4);
134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round);
135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round,
136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
137 end
138 end
139 logic [DataWidth-1:0] data_state_xor;
140 4/4 assign data_state_xor = data_state_round ^
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0];
142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
143 if (k % 2 == 1) begin : gen_fwd_key_odd
144 2/2 assign data_state_lo[k] = data_state_xor ^ k0_new_d;
Tests: T1 T2 T3 | T1 T2 T3
145 end else begin : gen_fwd_key_even
146 2/2 assign data_state_lo[k] = data_state_xor ^ k1_d;
Tests: T1 T2 T3 | T1 T2 T3
147 end
148 end
149
150 // middle part
151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle;
152 if (DataWidth == 64) begin : gen_middle_d64
153 always_comb begin : p_middle_d64
154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf],
Tests: T1 T2 T3
155 prim_cipher_pkg::PRINCE_SBOX4);
156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q);
Tests: T1 T2 T3
157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle,
Tests: T1 T2 T3
158 prim_cipher_pkg::PRINCE_SBOX4_INV);
159 end
160 end else begin : gen_middle_d32
161 always_comb begin : p_middle_d32
162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf],
163 prim_cipher_pkg::PRINCE_SBOX4);
164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q);
165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle,
166 prim_cipher_pkg::PRINCE_SBOX4_INV);
167 end
168 end
169
170 if (HalfwayDataReg) begin : gen_data_reg
171 logic valid_q;
172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg
173 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
174 1/1 valid_q <= 1'b0;
Tests: T1 T2 T3
175 1/1 data_state_middle_q <= '0;
Tests: T1 T2 T3
176 end else begin
177 1/1 valid_q <= valid_i;
Tests: T1 T2 T3
178 1/1 if (valid_i) begin
Tests: T1 T2 T3
179 1/1 data_state_middle_q <= data_state_middle_d;
Tests: T1 T2 T3
180 end
MISSING_ELSE
181 end
182 end
183 1/1 assign valid_o = valid_q;
Tests: T1 T2 T3
184 end else begin : gen_no_data_reg
185 // just pass data through in this case
186 assign data_state_middle_q = data_state_middle_d;
187 assign valid_o = valid_i;
188 end
189
190 1/1 assign data_state_hi[0] = data_state_middle;
Tests: T1 T2 T3
191
192 // backward pass
193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass
194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1;
195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd
197 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q;
Tests: T1 T2 T3 | T1 T2 T3
198 end else begin : gen_bkwd_key_even
199 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q;
Tests: T1 T2 T3 | T1 T2 T3
200 end
201 // the construction is reflective, hence the subtraction with NumRoundsHalf
202 4/4 assign data_state_xor1 = data_state_xor0 ^
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0];
204
205 logic [DataWidth-1:0] data_state_bwd;
206 if (DataWidth == 64) begin : gen_bwd_d64
207 always_comb begin : p_bwd_d64
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 4
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 5
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 6
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
212 prim_cipher_pkg::PRINCE_SBOX4_INV);
213 end
214 end else begin : gen_bwd_d32
215 always_comb begin : p_bwd_d32
216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1,
217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd);
219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd,
220 prim_cipher_pkg::PRINCE_SBOX4_INV);
221 end
222 end
223 end
224
225 // post-rounds
226 always_comb begin : p_post_round_xor
227 1/1 data_o = data_state_hi[NumRoundsHalf] ^
Tests: T1 T2 T3
228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0];
229 1/1 data_o ^= k1_q;
Tests: T1 T2 T3
230 1/1 data_o ^= k0_prime_q;
Tests: T1 T2 T3
Line Coverage for Module :
prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=5,UseOldKeySched=1,HalfwayDataReg=1,HalfwayKeyReg=1 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 83 | 83 | 100.00 |
ALWAYS | 56 | 7 | 7 | 100.00 |
CONT_ASSIGN | 70 | 1 | 1 | 100.00 |
ALWAYS | 85 | 8 | 8 | 100.00 |
ALWAYS | 114 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
ALWAYS | 124 | 3 | 3 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 140 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 146 | 1 | 1 | 100.00 |
CONT_ASSIGN | 146 | 1 | 1 | 100.00 |
ALWAYS | 154 | 3 | 3 | 100.00 |
ALWAYS | 173 | 6 | 6 | 100.00 |
CONT_ASSIGN | 183 | 1 | 1 | 100.00 |
CONT_ASSIGN | 190 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
CONT_ASSIGN | 202 | 1 | 1 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 208 | 3 | 3 | 100.00 |
ALWAYS | 227 | 3 | 3 | 100.00 |
55 always_comb begin : p_key_expansion
56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]};
Tests: T1 T2 T3
58 1/1 k1_d = key_i[DataWidth-1:0];
Tests: T1 T2 T3
59
60 // modify key for decryption
61 1/1 if (dec_i) begin
Tests: T1 T2 T3
62 1/1 k0 = k0_prime_d;
Tests: T1 T2 T3
63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth];
Tests: T1 T2 T3
64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
Tests: T1 T2 T3
65 end
MISSING_ELSE
66 end
67
68 if (UseOldKeySched) begin : gen_legacy_keyschedule
69 // In this case we constantly use k1.
70 1/1 assign k0_new_d = k1_d;
Tests: T1 T2 T3
71 end else begin : gen_new_keyschedule
72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
73 // In this case we alternate between k1 and k0.
74 always_comb begin : p_new_keyschedule_k0_alpha
75 k0_new_d = key_i[2*DataWidth-1 : DataWidth];
76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode.
77 if (dec_i) begin
78 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
79 end
80 end
81 end
82
83 if (HalfwayKeyReg) begin : gen_key_reg
84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg
85 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
86 1/1 k1_q <= '0;
Tests: T1 T2 T3
87 1/1 k0_prime_q <= '0;
Tests: T1 T2 T3
88 1/1 k0_new_q <= '0;
Tests: T1 T2 T3
89 end else begin
90 1/1 if (valid_i) begin
Tests: T1 T2 T3
91 1/1 k1_q <= k1_d;
Tests: T1 T2 T3
92 1/1 k0_prime_q <= k0_prime_d;
Tests: T1 T2 T3
93 1/1 k0_new_q <= k0_new_d;
Tests: T1 T2 T3
94 end
MISSING_ELSE
95 end
96 end
97 end else begin : gen_no_key_reg
98 // just pass the key through in this case
99 assign k1_q = k1_d;
100 assign k0_prime_q = k0_prime_d;
101 assign k0_new_q = k0_new_d;
102 end
103
104 //////////////
105 // datapath //
106 //////////////
107
108 // State variable for holding the rounds
109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo;
110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi;
111
112 // pre-round XOR
113 always_comb begin : p_pre_round_xor
114 1/1 data_state_lo[0] = data_i ^ k0;
Tests: T1 T2 T3
115 1/1 data_state_lo[0] ^= k1_d;
Tests: T1 T2 T3
116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0];
Tests: T1 T2 T3
117 end
118
119 // forward pass
120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass
121 logic [DataWidth-1:0] data_state_round;
122 if (DataWidth == 64) begin : gen_fwd_d64
123 always_comb begin : p_fwd_d64
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 1
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 2
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 3
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
***repeat 4
124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1],
Tests: T1 T2 T3
125 prim_cipher_pkg::PRINCE_SBOX4);
126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round);
Tests: T1 T2 T3
127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round,
Tests: T1 T2 T3
128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
129 end
130 end else begin : gen_fwd_d32
131 always_comb begin : p_fwd_d32
132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1],
133 prim_cipher_pkg::PRINCE_SBOX4);
134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round);
135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round,
136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
137 end
138 end
139 logic [DataWidth-1:0] data_state_xor;
140 5/5 assign data_state_xor = data_state_round ^
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0];
142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
143 if (k % 2 == 1) begin : gen_fwd_key_odd
144 3/3 assign data_state_lo[k] = data_state_xor ^ k0_new_d;
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
145 end else begin : gen_fwd_key_even
146 2/2 assign data_state_lo[k] = data_state_xor ^ k1_d;
Tests: T1 T2 T3 | T1 T2 T3
147 end
148 end
149
150 // middle part
151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle;
152 if (DataWidth == 64) begin : gen_middle_d64
153 always_comb begin : p_middle_d64
154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf],
Tests: T1 T2 T3
155 prim_cipher_pkg::PRINCE_SBOX4);
156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q);
Tests: T1 T2 T3
157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle,
Tests: T1 T2 T3
158 prim_cipher_pkg::PRINCE_SBOX4_INV);
159 end
160 end else begin : gen_middle_d32
161 always_comb begin : p_middle_d32
162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf],
163 prim_cipher_pkg::PRINCE_SBOX4);
164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q);
165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle,
166 prim_cipher_pkg::PRINCE_SBOX4_INV);
167 end
168 end
169
170 if (HalfwayDataReg) begin : gen_data_reg
171 logic valid_q;
172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg
173 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
174 1/1 valid_q <= 1'b0;
Tests: T1 T2 T3
175 1/1 data_state_middle_q <= '0;
Tests: T1 T2 T3
176 end else begin
177 1/1 valid_q <= valid_i;
Tests: T1 T2 T3
178 1/1 if (valid_i) begin
Tests: T1 T2 T3
179 1/1 data_state_middle_q <= data_state_middle_d;
Tests: T1 T2 T3
180 end
MISSING_ELSE
181 end
182 end
183 1/1 assign valid_o = valid_q;
Tests: T1 T2 T3
184 end else begin : gen_no_data_reg
185 // just pass data through in this case
186 assign data_state_middle_q = data_state_middle_d;
187 assign valid_o = valid_i;
188 end
189
190 1/1 assign data_state_hi[0] = data_state_middle;
Tests: T1 T2 T3
191
192 // backward pass
193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass
194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1;
195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf
196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd
197 3/3 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q;
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
198 end else begin : gen_bkwd_key_even
199 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q;
Tests: T1 T2 T3 | T1 T2 T3
200 end
201 // the construction is reflective, hence the subtraction with NumRoundsHalf
202 5/5 assign data_state_xor1 = data_state_xor0 ^
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0];
204
205 logic [DataWidth-1:0] data_state_bwd;
206 if (DataWidth == 64) begin : gen_bwd_d64
207 always_comb begin : p_bwd_d64
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 5
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 6
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 7
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
***repeat 8
208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1,
Tests: T1 T2 T3
209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd);
Tests: T1 T2 T3
211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd,
Tests: T1 T2 T3
212 prim_cipher_pkg::PRINCE_SBOX4_INV);
213 end
214 end else begin : gen_bwd_d32
215 always_comb begin : p_bwd_d32
216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1,
217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd);
219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd,
220 prim_cipher_pkg::PRINCE_SBOX4_INV);
221 end
222 end
223 end
224
225 // post-rounds
226 always_comb begin : p_post_round_xor
227 1/1 data_o = data_state_hi[NumRoundsHalf] ^
Tests: T1 T2 T3
228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0];
229 1/1 data_o ^= k1_q;
Tests: T1 T2 T3
230 1/1 data_o ^= k0_prime_q;
Tests: T1 T2 T3
Cond Coverage for Module :
prim_prince
| Total | Covered | Percent |
Conditions | 4 | 4 | 100.00 |
Logical | 4 | 4 | 100.00 |
Non-Logical | 0 | 0 | |
Event | 0 | 0 | |
LINE 57
SUB-EXPRESSION (k0[(DataWidth - 1)] ^ k0[1])
---------1--------- --2--
-1- | -2- | Status | Tests |
0 | 0 | Covered | T1,T2,T3 |
0 | 1 | Covered | T1,T2,T3 |
1 | 0 | Covered | T1,T2,T3 |
1 | 1 | Covered | T1,T2,T3 |
Toggle Coverage for Module :
prim_prince
| Total | Covered | Percent |
Totals |
8 |
8 |
100.00 |
Total Bits |
522 |
522 |
100.00 |
Total Bits 0->1 |
261 |
261 |
100.00 |
Total Bits 1->0 |
261 |
261 |
100.00 |
| | | |
Ports |
8 |
8 |
100.00 |
Port Bits |
522 |
522 |
100.00 |
Port Bits 0->1 |
261 |
261 |
100.00 |
Port Bits 1->0 |
261 |
261 |
100.00 |
Port Details
Name | Toggle | Toggle 1->0 | Tests | Toggle 0->1 | Tests | Direction |
clk_i |
Yes |
Yes |
T1,T2,T3 |
Yes |
T1,T2,T3 |
INPUT |
rst_ni |
Yes |
Yes |
T1,T2,T3 |
Yes |
T1,T2,T3 |
INPUT |
valid_i |
Yes |
Yes |
T1,T2,T3 |
Yes |
T1,T2,T3 |
INPUT |
data_i[63:0] |
Yes |
Yes |
T1,T2,T3 |
Yes |
T1,T2,T3 |
INPUT |
key_i[127:0] |
Yes |
Yes |
T1,T2,T3 |
Yes |
T1,T2,T3 |
INPUT |
dec_i |
Yes |
Yes |
T1,T2,T3 |
Yes |
T1,T2,T3 |
INPUT |
valid_o |
Yes |
Yes |
T1,T2,T3 |
Yes |
T1,T2,T3 |
OUTPUT |
data_o[63:0] |
Yes |
Yes |
T1,T2,T3 |
Yes |
T1,T2,T3 |
OUTPUT |
Branch Coverage for Module :
prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=1,UseOldKeySched=1,HalfwayDataReg=0,HalfwayKeyReg=0 + DataWidth=64,KeyWidth=128,NumRoundsHalf=2,UseOldKeySched=1,HalfwayDataReg=0,HalfwayKeyReg=0 + DataWidth=64,KeyWidth=128,NumRoundsHalf=3,UseOldKeySched=1,HalfwayDataReg=0,HalfwayKeyReg=0 + DataWidth=64,KeyWidth=128,NumRoundsHalf=4,UseOldKeySched=1,HalfwayDataReg=0,HalfwayKeyReg=0 + DataWidth=64,KeyWidth=128,NumRoundsHalf=5,UseOldKeySched=1,HalfwayDataReg=0,HalfwayKeyReg=0 )
Branch Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
Branches |
|
2 |
2 |
100.00 |
IF |
61 |
2 |
2 |
100.00 |
61 if (dec_i) begin
-1-
62 k0 = k0_prime_d;
==>
63 k0_prime_d = key_i[2*DataWidth-1 : DataWidth];
64 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
65 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |
Branch Coverage for Module :
prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=1,UseOldKeySched=1,HalfwayDataReg=1,HalfwayKeyReg=1 + DataWidth=64,KeyWidth=128,NumRoundsHalf=2,UseOldKeySched=1,HalfwayDataReg=1,HalfwayKeyReg=1 + DataWidth=64,KeyWidth=128,NumRoundsHalf=3,UseOldKeySched=1,HalfwayDataReg=1,HalfwayKeyReg=1 + DataWidth=64,KeyWidth=128,NumRoundsHalf=4,UseOldKeySched=1,HalfwayDataReg=1,HalfwayKeyReg=1 + DataWidth=64,KeyWidth=128,NumRoundsHalf=5,UseOldKeySched=1,HalfwayDataReg=1,HalfwayKeyReg=1 )
Branch Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
Branches |
|
8 |
8 |
100.00 |
IF |
61 |
2 |
2 |
100.00 |
IF |
85 |
3 |
3 |
100.00 |
IF |
173 |
3 |
3 |
100.00 |
61 if (dec_i) begin
-1-
62 k0 = k0_prime_d;
==>
63 k0_prime_d = key_i[2*DataWidth-1 : DataWidth];
64 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
65 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |
85 if (!rst_ni) begin
-1-
86 k1_q <= '0;
==>
87 k0_prime_q <= '0;
88 k0_new_q <= '0;
89 end else begin
90 if (valid_i) begin
-2-
91 k1_q <= k1_d;
==>
92 k0_prime_q <= k0_prime_d;
93 k0_new_q <= k0_new_d;
94 end
MISSING_ELSE
==>
Branches:
-1- | -2- | Status | Tests |
1 |
- |
Covered |
T1,T2,T3 |
0 |
1 |
Covered |
T1,T2,T3 |
0 |
0 |
Covered |
T1,T2,T3 |
173 if (!rst_ni) begin
-1-
174 valid_q <= 1'b0;
==>
175 data_state_middle_q <= '0;
176 end else begin
177 valid_q <= valid_i;
178 if (valid_i) begin
-2-
179 data_state_middle_q <= data_state_middle_d;
==>
180 end
MISSING_ELSE
==>
Branches:
-1- | -2- | Status | Tests |
1 |
- |
Covered |
T1,T2,T3 |
0 |
1 |
Covered |
T1,T2,T3 |
0 |
0 |
Covered |
T1,T2,T3 |
Branch Coverage for Module :
prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=1,UseOldKeySched=0,HalfwayDataReg=0,HalfwayKeyReg=0 + DataWidth=64,KeyWidth=128,NumRoundsHalf=2,UseOldKeySched=0,HalfwayDataReg=0,HalfwayKeyReg=0 + DataWidth=64,KeyWidth=128,NumRoundsHalf=3,UseOldKeySched=0,HalfwayDataReg=0,HalfwayKeyReg=0 + DataWidth=64,KeyWidth=128,NumRoundsHalf=4,UseOldKeySched=0,HalfwayDataReg=0,HalfwayKeyReg=0 + DataWidth=64,KeyWidth=128,NumRoundsHalf=5,UseOldKeySched=0,HalfwayDataReg=0,HalfwayKeyReg=0 )
Branch Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
Branches |
|
4 |
4 |
100.00 |
IF |
61 |
2 |
2 |
100.00 |
IF |
77 |
2 |
2 |
100.00 |
61 if (dec_i) begin
-1-
62 k0 = k0_prime_d;
==>
63 k0_prime_d = key_i[2*DataWidth-1 : DataWidth];
64 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
65 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |
77 if (dec_i) begin
-1-
78 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
==>
79 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |
Branch Coverage for Module :
prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=1,UseOldKeySched=0,HalfwayDataReg=1,HalfwayKeyReg=1 + DataWidth=64,KeyWidth=128,NumRoundsHalf=2,UseOldKeySched=0,HalfwayDataReg=1,HalfwayKeyReg=1 + DataWidth=64,KeyWidth=128,NumRoundsHalf=3,UseOldKeySched=0,HalfwayDataReg=1,HalfwayKeyReg=1 + DataWidth=64,KeyWidth=128,NumRoundsHalf=4,UseOldKeySched=0,HalfwayDataReg=1,HalfwayKeyReg=1 + DataWidth=64,KeyWidth=128,NumRoundsHalf=5,UseOldKeySched=0,HalfwayDataReg=1,HalfwayKeyReg=1 )
Branch Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
Branches |
|
10 |
10 |
100.00 |
IF |
61 |
2 |
2 |
100.00 |
IF |
77 |
2 |
2 |
100.00 |
IF |
85 |
3 |
3 |
100.00 |
IF |
173 |
3 |
3 |
100.00 |
61 if (dec_i) begin
-1-
62 k0 = k0_prime_d;
==>
63 k0_prime_d = key_i[2*DataWidth-1 : DataWidth];
64 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
65 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |
77 if (dec_i) begin
-1-
78 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0];
==>
79 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |
85 if (!rst_ni) begin
-1-
86 k1_q <= '0;
==>
87 k0_prime_q <= '0;
88 k0_new_q <= '0;
89 end else begin
90 if (valid_i) begin
-2-
91 k1_q <= k1_d;
==>
92 k0_prime_q <= k0_prime_d;
93 k0_new_q <= k0_new_d;
94 end
MISSING_ELSE
==>
Branches:
-1- | -2- | Status | Tests |
1 |
- |
Covered |
T1,T2,T3 |
0 |
1 |
Covered |
T1,T2,T3 |
0 |
0 |
Covered |
T1,T2,T3 |
173 if (!rst_ni) begin
-1-
174 valid_q <= 1'b0;
==>
175 data_state_middle_q <= '0;
176 end else begin
177 valid_q <= valid_i;
178 if (valid_i) begin
-2-
179 data_state_middle_q <= data_state_middle_d;
==>
180 end
MISSING_ELSE
==>
Branches:
-1- | -2- | Status | Tests |
1 |
- |
Covered |
T1,T2,T3 |
0 |
1 |
Covered |
T1,T2,T3 |
0 |
0 |
Covered |
T1,T2,T3 |
Assert Coverage for Module :
prim_prince
Assertion Details
SupportedNumRounds_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
10000 |
10000 |
0 |
0 |
T1 |
20 |
20 |
0 |
0 |
T2 |
20 |
20 |
0 |
0 |
T3 |
20 |
20 |
0 |
0 |
T4 |
20 |
20 |
0 |
0 |
T5 |
20 |
20 |
0 |
0 |
T6 |
20 |
20 |
0 |
0 |
T7 |
20 |
20 |
0 |
0 |
T8 |
20 |
20 |
0 |
0 |
T9 |
20 |
20 |
0 |
0 |
T10 |
20 |
20 |
0 |
0 |
SupportedWidths_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
10000 |
10000 |
0 |
0 |
T1 |
20 |
20 |
0 |
0 |
T2 |
20 |
20 |
0 |
0 |
T3 |
20 |
20 |
0 |
0 |
T4 |
20 |
20 |
0 |
0 |
T5 |
20 |
20 |
0 |
0 |
T6 |
20 |
20 |
0 |
0 |
T7 |
20 |
20 |
0 |
0 |
T8 |
20 |
20 |
0 |
0 |
T9 |
20 |
20 |
0 |
0 |
T10 |
20 |
20 |
0 |
0 |