feat(enc): Encaps E0 - op_i/msg_i/ek-load scaffold + H(ek)+G(m||H(ek))
Extend mlkem_top with a runtime op_i select (0=KeyGen, 1=Encaps) and the
first Encaps stages, reusing the shared keccak_core and the ST_H multi-block
SHA3-256 machinery:
ST_ENC_H: H(ek) over preloaded ek_bram (same FSM as KeyGen ST_H)
ST_ENC_G: (K,r) = G(m||H(ek)) via new 64-byte single-block SHA3-512
- sha3_top_shared: add mode=2'b11 = SHA3-512 over a full 512-bit message
(g512_pad). Standalone tb_sha3_g512 confirms it byte-exact.
- mlkem_top: new ports op_i, msg_i, ek_in_{we,addr,byte} (ek preload), ss_o,
dbg_ct_*, dbg_r_o/dbg_hek_o. st widened 4->5 bits; ST_ENC_* states added.
Renamed message port to msg_i to avoid collision with ST_M counter m_i.
- TB tb_mlkem_enc_katK + gen_encaps_vectors.py (per-byte ek/m/ct/ss vectors).
Verified ss==KAT.ss for K=2/3/4, cases 0-2 (all PASS). KeyGen unaffected
(K=2 c0 still ek==pk, dk==sk byte-exact).
This commit is contained in:
50
sync_rtl/sha3/TB/tb_sha3_g512.v
Normal file
50
sync_rtl/sha3/TB/tb_sha3_g512.v
Normal file
@@ -0,0 +1,50 @@
|
||||
// tb_sha3_g512.v - isolate sha3_top_shared mode=11 (64-byte SHA3-512).
|
||||
`timescale 1ns/1ps
|
||||
module tb_sha3_g512;
|
||||
reg clk=0, rst_n=0;
|
||||
reg [1:0] mode;
|
||||
reg [511:0] data_i;
|
||||
reg valid_i, ready_i;
|
||||
wire ready_o, valid_o;
|
||||
wire [511:0] hash_o;
|
||||
// shared keccak
|
||||
wire [1599:0] kc_state_i, kc_state_o;
|
||||
wire kc_valid_i, kc_valid_o, kc_ready_o, kc_ready_i;
|
||||
|
||||
sha3_top_shared u_sha3 (
|
||||
.clk(clk), .rst_n(rst_n), .mode(mode), .data_i(data_i),
|
||||
.valid_i(valid_i), .ready_o(ready_o), .hash_o(hash_o), .valid_o(valid_o),
|
||||
.ready_i(ready_i),
|
||||
.mb_en(1'b0), .mb_block_i(1088'd0), .mb_valid_i(1'b0), .mb_last_i(1'b0), .mb_ready_o(),
|
||||
.kc_state_o(kc_state_o), .kc_valid_o(kc_valid_o), .kc_ready_o(kc_ready_o),
|
||||
.kc_state_i(kc_state_i), .kc_valid_i(kc_valid_i), .kc_ready_i(kc_ready_i)
|
||||
);
|
||||
keccak_core #(.ROUNDS(24)) u_kc (
|
||||
.clk(clk), .rst_n(rst_n), .state_i(kc_state_i), .valid_i(kc_valid_i),
|
||||
.ready_o(kc_ready_o), .state_o(kc_state_o), .valid_o(kc_valid_o), .ready_i(1'b1)
|
||||
);
|
||||
always #5 clk=~clk;
|
||||
|
||||
integer j;
|
||||
initial begin
|
||||
// m || hek (byte0 in [7:0]); m=20a7..ffff, hek=ca87..aac6
|
||||
// build little-endian-in-register: byte0 at [7:0]
|
||||
data_i = 512'd0;
|
||||
// m bytes 0..31
|
||||
data_i[ 0 +: 256] = 256'hffff80fc331b2ca1904ccf554ed114bf99f6de44b92082c36c49700fe1b7a720;
|
||||
// hek bytes 32..63
|
||||
data_i[256 +: 256] = 256'hc6aa5100ed06d0c2db8cc3d1a36a62055b182f8d51ea71602501857e7c5d87ca;
|
||||
mode=2'b11; valid_i=0; ready_i=1;
|
||||
rst_n=0; repeat(4) @(posedge clk); rst_n=1; @(posedge clk);
|
||||
valid_i=1; @(posedge clk);
|
||||
while(!(valid_i && ready_o)) @(posedge clk);
|
||||
valid_i=0;
|
||||
while(!valid_o) @(posedge clk);
|
||||
$write("K_ss = "); for(j=0;j<32;j=j+1) $write("%02x", hash_o[8*j +: 8]); $write("\n");
|
||||
$write("r = "); for(j=0;j<32;j=j+1) $write("%02x", hash_o[256+8*j +: 8]); $write("\n");
|
||||
$display("want K_ss = 2b5c52ee72946331983ba050be0f435055c0547901e03559b356517889ea27c5");
|
||||
$display("want r = 08cd245f59e6cb6e3687c6632749b6c0737d183701f0b0492b843358893c6a24");
|
||||
$finish;
|
||||
end
|
||||
initial begin #100000; $display("timeout"); $finish; end
|
||||
endmodule
|
||||
@@ -63,6 +63,7 @@ module sha3_top_shared (
|
||||
// Absorb state: message || suffix || pad10*1 into rate bits
|
||||
// ================================================================
|
||||
wire [575:0] g_pad;
|
||||
wire [575:0] g512_pad;
|
||||
wire [1087:0] h_pad;
|
||||
wire [1087:0] j_pad;
|
||||
|
||||
@@ -70,12 +71,15 @@ module sha3_top_shared (
|
||||
assign h_pad = {1'b1, {828{1'b0}}, 1'b1, 2'b10, data_i[255:0]};
|
||||
// J: SHAKE suffix is "1111" — all ones, order irrelevant
|
||||
assign j_pad = {1'b1, {570{1'b0}}, 1'b1, 4'b1111, data_i[511:0]};
|
||||
// mode 11 = G over a full 64-byte (512-bit) message (Encaps: G(m||H(ek))).
|
||||
// SHA3-512 rate=576; suffix 01 + pad10*1: 1 + 60 zeros + 1 + 2'b10 + 512 = 576.
|
||||
assign g512_pad = {1'b1, {60{1'b0}}, 1'b1, 2'b10, data_i[511:0]};
|
||||
|
||||
wire [1599:0] absorb_state;
|
||||
assign absorb_state = (mode == 2'b00) ? {{(1600-576){1'b0}}, g_pad} :
|
||||
(mode == 2'b01) ? {{(1600-1088){1'b0}}, h_pad} :
|
||||
(mode == 2'b10) ? {{(1600-1088){1'b0}}, j_pad} :
|
||||
1600'd0;
|
||||
{{(1600-576){1'b0}}, g512_pad};
|
||||
|
||||
// ================================================================
|
||||
// Multi-block SHA3-256 absorb FSM (active only when mb_en=1)
|
||||
|
||||
Reference in New Issue
Block a user