feat(dec): Decaps D0 - op_i widen + dk/c load + parse

Scaffolding for ML-KEM Decaps (FIPS 203 Alg 18):
- op_i widened to 2-bit: 00=KeyGen, 01=Encaps, 10=Decaps (op_r too).
- New ST_DEC_LOAD state (D0: settles to DONE so load/parse is dbg-checkable).
- dk (=sk) streamed via dk_in_*; load logic routes each byte by region:
  [0,384K)->dk_pke (dkp_bram), [384K,768K+32)->ek_pke (ek_bram),
  [768K+32,+32)->H(ek) (hek_r), [768K+64,+32)->z (z_r). Routing uses the
  LIVE k_i input, not start-captured k_r (dk is streamed before start_i).
- c (=ct) streamed via c_in_* into a SEPARATE c_in_bram, so the computed c'
  (ct_bram) can later be compared against original c and J(z||c) can read c.
- New dbg taps: dbg_mprime_o/dbg_kbar_o/dbg_decz_o/dbg_dech_o.

TB: tb_mlkem_dec_katK_xsim verifies dk parse (H(ek), z, ek_pke/dk_pke BRAM
round-trip). gen_decaps_vectors.py emits dec_k{K}_c{N}_{dk,ct,ss,ctn,ssn}.hex
from the NIST KAT. run_tb.sh gains a 'dec' module (mirrors 'enc').

Regression fix: old KeyGen/Encaps TBs didn't connect the new input ports,
floating them to X and corrupting the ek/dkp write muxes -> tied off
dk_in_*/c_in_*/new dbg taps in both.

Verified: dec D0 K=2/3/4 PASS; KeyGen K=2 + Encaps K=2 unregressed.
This commit is contained in:
2026-06-29 15:22:34 +08:00
parent 4091fd0676
commit 030931d4e5
52 changed files with 43220 additions and 27 deletions

View File

@@ -0,0 +1,80 @@
#!/usr/bin/env python3
"""gen_decaps_vectors.py - Emit per-byte Decaps KAT vectors for the XSIM TB.
For ML-KEM-512/768/1024, parse the NIST .rsp and write, per case:
dec_k{K}_c{N}_dk.hex : dk (=sk) bytes, one hex byte per line, byte 0 first
dec_k{K}_c{N}_ct.hex : ct bytes (valid ciphertext), one per line, byte 0 first
dec_k{K}_c{N}_ss.hex : ss bytes (shared secret for valid ct), byte 0 first
dec_k{K}_c{N}_ctn.hex : ct_n bytes (corrupted ct -> implicit reject)
dec_k{K}_c{N}_ssn.hex : ss_n bytes (shared secret K-bar for the reject path)
The TB streams dk into the design via dk_in_* (routed to dk_pke/ek_pke/h/z by
region) and ct into c_in_*, runs Decaps, and checks ss:
valid ct -> ss == ss (c'==c, K' kept)
ct_n -> ss == ss_n (c'!=c, K-bar via J(z||c_n))
Run: python3 gen_decaps_vectors.py [num_cases]
"""
import os
import re
import sys
ML_KEM_R = os.environ.get("ML_KEM_R", os.path.expanduser("~/Dev/ml-kem-r"))
OUT_DIR = os.path.join(os.path.dirname(__file__), "vectors")
KATS = {2: "kat_MLKEM_512.rsp", 3: "kat_MLKEM_768.rsp", 4: "kat_MLKEM_1024.rsp"}
def parse_kat(path, n):
"""Return list of dicts {count, sk, ct, ss, ct_n, ss_n} (hex) for first n."""
vecs, cur = [], {}
with open(path) as f:
for line in f:
line = line.strip()
m = re.match(r"^count\s*=\s*(\d+)$", line)
if m:
if cur:
vecs.append(cur)
if len(vecs) >= n:
break
cur = {"count": int(m.group(1))}
continue
# exact-key match: 'ct =' vs 'ct_n =', 'ss =' vs 'ss_n ='
m = re.match(r"^(sk|ct|ss|ct_n|ss_n)\s*=\s*([0-9a-fA-F]+)$", line)
if m and cur:
cur[m.group(1)] = m.group(2).lower()
if cur and len(vecs) < n:
vecs.append(cur)
return vecs
def write_bytes(path, hexstr):
"""Write hex string as one byte per line (byte 0 = first 2 hex chars)."""
with open(path, "w") as f:
for i in range(0, len(hexstr), 2):
f.write(hexstr[i:i + 2] + "\n")
def main():
ncases = int(sys.argv[1]) if len(sys.argv) > 1 else 3
os.makedirs(OUT_DIR, exist_ok=True)
for k, fname in KATS.items():
path = os.path.join(ML_KEM_R, "test_data", fname)
if not os.path.exists(path):
print(f"skip K={k}: {path} not found", file=sys.stderr)
continue
vecs = parse_kat(path, ncases)
for v in vecs:
n = v["count"]
base = os.path.join(OUT_DIR, f"dec_k{k}_c{n}")
write_bytes(f"{base}_dk.hex", v["sk"])
write_bytes(f"{base}_ct.hex", v["ct"])
write_bytes(f"{base}_ss.hex", v["ss"])
write_bytes(f"{base}_ctn.hex", v["ct_n"])
write_bytes(f"{base}_ssn.hex", v["ss_n"])
print(f"K={k}: wrote {len(vecs)} cases "
f"(dk={len(vecs[0]['sk'])//2}B ct={len(vecs[0]['ct'])//2}B)")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,153 @@
// tb_mlkem_dec_katK_xsim.v - ML-KEM Decaps vs NIST KAT, parametric K (KP) + CASE.
// D0 stage: stream dk (=sk) into the design via dk_in_* (routed to
// dk_pke/ek_pke/h/z by region) and ct via c_in_*, pulse start with op=2, and
// verify the dk PARSE: H(ek) (dbg_dech_o), z (dbg_decz_o), and round-trip a few
// ek_pke bytes (dbg_byte sel=0) and dk_pke bytes (sel=1) back out of BRAM.
//
// xelab -generic_top KP=2|3|4 ; xsim -testplusarg CASE=n
// dk/ct/ss vectors: sync_rtl/top/TB/vectors/dec_k{K}_c{N}_{dk,ct,ss,ctn,ssn}.hex
`timescale 1ns/1ps
module tb_mlkem_dec_katK_xsim;
parameter KP = 2;
localparam DKB = 768*KP + 96; // dk (=sk) bytes: 1632/2400/3168
localparam EKB = 384*KP + 32; // ek_pke bytes within dk
localparam DKPB = 384*KP; // dk_pke bytes
localparam CTB = (KP==4) ? 1568 : (32*(10*KP+4)); // ct bytes: 768/1088/1568
reg clk=0, rst_n=0, start_i=0;
reg [2:0] k_i;
reg [255:0] d_i=0, z_i=0, m_i=0;
wire busy_o, done_o;
// ek preload port (unused in Decaps; ek_pke comes from dk)
reg ek_in_we=0; reg [10:0] ek_in_addr=0; reg [7:0] ek_in_byte=0;
// dk / c input ports
reg dk_in_we=0; reg [11:0] dk_in_addr=0; reg [7:0] dk_in_byte=0;
reg c_in_we=0; reg [10:0] c_in_addr=0; reg [7:0] c_in_byte=0;
wire [255:0] ss_o;
reg [10:0] dbg_ct_idx_i=0; wire [7:0] dbg_ct_o;
reg [3:0] dbg_slot_i=0; reg [7:0] dbg_idx_i=0; wire [11:0] dbg_coeff_o;
reg dbg_byte_sel_i=0; reg [10:0] dbg_byte_idx_i=0; wire [7:0] dbg_byte_o;
reg [11:0] dbg_dk_idx_i=0; wire [7:0] dbg_dk_o;
wire [255:0] dbg_rho_o, dbg_sigma_o, dbg_r_o, dbg_hek_o;
wire [255:0] dbg_mprime_o, dbg_kbar_o, dbg_decz_o, dbg_dech_o;
mlkem_top dut (
.clk(clk), .rst_n(rst_n), .k_i(k_i), .op_i(2'd2),
.d_i(d_i), .z_i(z_i), .msg_i(m_i), .start_i(start_i),
.busy_o(busy_o), .done_o(done_o),
.ek_in_we(ek_in_we), .ek_in_addr(ek_in_addr), .ek_in_byte(ek_in_byte),
.dk_in_we(dk_in_we), .dk_in_addr(dk_in_addr), .dk_in_byte(dk_in_byte),
.c_in_we(c_in_we), .c_in_addr(c_in_addr), .c_in_byte(c_in_byte),
.ss_o(ss_o), .dbg_ct_idx_i(dbg_ct_idx_i), .dbg_ct_o(dbg_ct_o),
.dbg_slot_i(dbg_slot_i), .dbg_idx_i(dbg_idx_i), .dbg_coeff_o(dbg_coeff_o),
.dbg_byte_sel_i(dbg_byte_sel_i), .dbg_byte_idx_i(dbg_byte_idx_i), .dbg_byte_o(dbg_byte_o),
.dbg_dk_idx_i(dbg_dk_idx_i), .dbg_dk_o(dbg_dk_o),
.dbg_rho_o(dbg_rho_o), .dbg_sigma_o(dbg_sigma_o),
.dbg_r_o(dbg_r_o), .dbg_hek_o(dbg_hek_o),
.dbg_mprime_o(dbg_mprime_o), .dbg_kbar_o(dbg_kbar_o),
.dbg_decz_o(dbg_decz_o), .dbg_dech_o(dbg_dech_o)
);
always #5 clk = ~clk;
reg [7:0] dk_b [0:DKB-1];
reg [7:0] ct_b [0:CTB-1];
reg [7:0] ss_b [0:31];
integer c, i, j, errors, casenum;
reg [8*80-1:0] tag, dkfile, ctfile, ssfile;
initial begin
if (!$value$plusargs("CASE=%d", casenum)) casenum = 0;
$sformat(tag, "k%0d", KP);
$sformat(dkfile, "sync_rtl/top/TB/vectors/dec_%0s_c%0d_dk.hex", tag, casenum);
$sformat(ctfile, "sync_rtl/top/TB/vectors/dec_%0s_c%0d_ct.hex", tag, casenum);
$sformat(ssfile, "sync_rtl/top/TB/vectors/dec_%0s_c%0d_ss.hex", tag, casenum);
$readmemh(dkfile, dk_b);
$readmemh(ctfile, ct_b);
$readmemh(ssfile, ss_b);
k_i = KP[2:0];
$display("=== ML-KEM K=%0d Decaps KAT case %0d (D0: load+parse) ===", KP, casenum);
rst_n=0; repeat(4) @(posedge clk); rst_n=1; @(posedge clk);
// ---- stream dk into the design (1 byte/cycle) ----
for (i = 0; i < DKB; i = i + 1) begin
dk_in_we = 1'b1; dk_in_addr = i[11:0]; dk_in_byte = dk_b[i];
@(posedge clk);
end
dk_in_we = 1'b0;
// ---- stream ct into c_in_bram (1 byte/cycle) ----
for (i = 0; i < CTB; i = i + 1) begin
c_in_we = 1'b1; c_in_addr = i[10:0]; c_in_byte = ct_b[i];
@(posedge clk);
end
c_in_we = 1'b0; @(posedge clk);
// ---- run Decaps ----
start_i=1; @(posedge clk); start_i=0;
c=0; while(!done_o && c<2000000) begin @(posedge clk); c=c+1; end
if(!done_o) begin $display("FAIL K=%0d case %0d: timeout", KP, casenum); $finish; end
$display("=== Decaps D0 done in %0d cyc ===", c);
verify_d0;
$finish;
end
initial begin #120000000; $display("FAIL: global timeout"); $finish; end
// D0: verify dk parse. H(ek)=dk[768K+32:+32], z=dk[768K+64:+32] captured into
// hek_r/z_r (dbg_dech_o/dbg_decz_o). ek_pke=dk[384K:768K+32] in ek_bram
// (dbg_byte sel=0), dk_pke=dk[0:384K] in dkp_bram (sel=1).
task verify_d0;
integer be;
reg [7:0] got;
begin
errors = 0;
// H(ek)
for (j = 0; j < 32; j = j + 1)
if (dbg_dech_o[8*j +: 8] !== dk_b[DKPB + EKB + j]) errors = errors + 1;
if (errors == 0) $display(" PASS: H(ek) parsed == dk[768K+32 ..]");
else $display(" FAIL: H(ek) %0d byte mismatches", errors);
// z
be = 0;
for (j = 0; j < 32; j = j + 1)
if (dbg_decz_o[8*j +: 8] !== dk_b[DKPB + EKB + 32 + j]) be = be + 1;
if (be == 0) $display(" PASS: z parsed == dk[768K+64 ..]");
else $display(" FAIL: z %0d byte mismatches", be);
errors = errors + be;
// ek_pke round-trip (every 97th byte to keep it quick)
be = 0;
for (i = 0; i < EKB; i = i + 97) begin
dbg_byte_sel_i = 1'b0; dbg_byte_idx_i = i[10:0];
@(posedge clk); @(posedge clk);
if (dbg_byte_o !== dk_b[DKPB + i]) begin
if (be < 6) $display(" ekpke[%0d] got=%02x exp=%02x", i, dbg_byte_o, dk_b[DKPB+i]);
be = be + 1;
end
end
if (be == 0) $display(" PASS: ek_pke round-trip (BRAM) == dk[384K ..]");
else $display(" FAIL: ek_pke %0d byte mismatches", be);
errors = errors + be;
// dk_pke round-trip
be = 0;
for (i = 0; i < DKPB; i = i + 97) begin
dbg_byte_sel_i = 1'b1; dbg_byte_idx_i = i[10:0];
@(posedge clk); @(posedge clk);
if (dbg_byte_o !== dk_b[i]) begin
if (be < 6) $display(" dkpke[%0d] got=%02x exp=%02x", i, dbg_byte_o, dk_b[i]);
be = be + 1;
end
end
if (be == 0) $display(" PASS: dk_pke round-trip (BRAM) == dk[0 ..]");
else $display(" FAIL: dk_pke %0d byte mismatches", be);
errors = errors + be;
if (errors == 0) $display("K=%0d CASE %0d PASS (D0): dk parse OK", KP, casenum);
else $display("K=%0d CASE %0d FAIL (D0): %0d total errors", KP, casenum, errors);
end
endtask
endmodule

View File

@@ -27,16 +27,19 @@ module tb_mlkem_enc_katK_xsim;
wire [255:0] dbg_rho_o, dbg_sigma_o, dbg_r_o, dbg_hek_o;
mlkem_top dut (
.clk(clk), .rst_n(rst_n), .k_i(k_i), .op_i(1'b1),
.clk(clk), .rst_n(rst_n), .k_i(k_i), .op_i(2'd1),
.d_i(d_i), .z_i(z_i), .msg_i(m_i), .start_i(start_i),
.busy_o(busy_o), .done_o(done_o),
.ek_in_we(ek_in_we), .ek_in_addr(ek_in_addr), .ek_in_byte(ek_in_byte),
.dk_in_we(1'b0), .dk_in_addr(12'd0), .dk_in_byte(8'd0),
.c_in_we(1'b0), .c_in_addr(11'd0), .c_in_byte(8'd0),
.ss_o(ss_o), .dbg_ct_idx_i(dbg_ct_idx_i), .dbg_ct_o(dbg_ct_o),
.dbg_slot_i(dbg_slot_i), .dbg_idx_i(dbg_idx_i), .dbg_coeff_o(dbg_coeff_o),
.dbg_byte_sel_i(dbg_byte_sel_i), .dbg_byte_idx_i(dbg_byte_idx_i), .dbg_byte_o(dbg_byte_o),
.dbg_dk_idx_i(dbg_dk_idx_i), .dbg_dk_o(dbg_dk_o),
.dbg_rho_o(dbg_rho_o), .dbg_sigma_o(dbg_sigma_o),
.dbg_r_o(dbg_r_o), .dbg_hek_o(dbg_hek_o)
.dbg_r_o(dbg_r_o), .dbg_hek_o(dbg_hek_o),
.dbg_mprime_o(), .dbg_kbar_o(), .dbg_decz_o(), .dbg_dech_o()
);
always #5 clk = ~clk;

View File

@@ -19,16 +19,19 @@ module tb_mlkem_kg_katK_xsim;
// KMAX defaults to 4 (worst-case sizing); KP selects the runtime k value.
mlkem_top dut (
.clk(clk), .rst_n(rst_n), .k_i(k_i), .op_i(1'b0),
.clk(clk), .rst_n(rst_n), .k_i(k_i), .op_i(2'd0),
.d_i(d_i), .z_i(z_i), .msg_i(256'd0), .start_i(start_i),
.busy_o(busy_o), .done_o(done_o),
.ek_in_we(1'b0), .ek_in_addr(11'd0), .ek_in_byte(8'd0),
.dk_in_we(1'b0), .dk_in_addr(12'd0), .dk_in_byte(8'd0),
.c_in_we(1'b0), .c_in_addr(11'd0), .c_in_byte(8'd0),
.ss_o(), .dbg_ct_idx_i(11'd0), .dbg_ct_o(),
.dbg_slot_i(dbg_slot_i), .dbg_idx_i(dbg_idx_i), .dbg_coeff_o(dbg_coeff_o),
.dbg_byte_sel_i(dbg_byte_sel_i), .dbg_byte_idx_i(dbg_byte_idx_i), .dbg_byte_o(dbg_byte_o),
.dbg_dk_idx_i(dbg_dk_idx_i), .dbg_dk_o(dbg_dk_o),
.dbg_rho_o(dbg_rho_o), .dbg_sigma_o(dbg_sigma_o),
.dbg_r_o(), .dbg_hek_o()
.dbg_r_o(), .dbg_hek_o(),
.dbg_mprime_o(), .dbg_kbar_o(), .dbg_decz_o(), .dbg_dech_o()
);
always #5 clk = ~clk;

View File

@@ -0,0 +1,768 @@
91
7e
59
d1
e1
82
a2
96
48
a6
19
55
a1
54
b3
04
a8
42
f4
58
eb
a5
93
f3
06
5f
b7
d7
44
fb
a2
4f
a3
a0
d5
38
85
4e
32
84
4d
b2
48
d4
81
00
c3
89
c4
c4
b3
ca
6c
23
4f
2f
61
a6
79
32
ae
ee
80
8d
bf
e9
8d
89
6d
1e
96
68
82
09
65
c6
34
3b
bb
4a
4d
e6
4b
7a
99
fb
53
b5
26
4e
31
99
d5
87
ff
a5
e0
47
9f
6b
73
86
b2
3c
b9
c2
43
fa
6f
54
57
fc
97
db
c9
6d
cc
03
9b
d6
c4
e7
e8
5a
90
b5
c5
23
24
16
43
4e
a9
42
cc
71
13
4b
b9
a2
f4
99
1e
05
95
e3
48
7f
ea
ba
c4
79
ca
b9
51
0d
57
b8
62
50
ee
7c
96
a6
7a
9f
2c
61
21
f7
da
a0
2c
5c
fa
3b
23
b0
c7
32
c2
b1
56
94
e1
cc
ba
c8
2b
78
7c
f2
11
8d
08
42
5c
bb
a1
21
88
22
17
94
0c
89
4c
be
47
aa
e2
54
1f
5c
6e
0b
d1
ba
ab
31
fd
2b
2e
cb
34
b9
e6
93
f6
fc
0f
de
ea
90
67
16
d0
88
18
f5
1d
f0
c4
69
40
29
e8
c3
23
4b
e0
b6
24
71
b2
76
9d
9a
c4
ce
b9
47
60
23
80
f3
a4
97
b2
a0
1f
f7
b8
74
6c
1c
7a
e8
19
83
e0
16
bd
65
c7
cd
17
62
c1
91
85
7e
41
c2
32
19
81
f6
c7
aa
8d
7a
fa
aa
9f
a0
b5
57
ec
1e
c1
28
5f
8b
4d
6c
78
8a
ff
15
9e
a5
86
2e
81
4d
08
25
c8
83
4b
7c
a4
5d
b7
c8
ed
a3
fa
6a
6a
7b
8a
40
51
95
29
bf
74
b6
a0
f8
0c
48
49
17
f4
0c
10
7d
18
2b
ce
3e
34
4f
d3
6d
1b
37
7a
98
2f
6b
f2
36
1b
8d
66
28
75
c1
66
dc
ca
73
24
0b
86
df
5e
e0
fa
42
31
b3
56
f0
cd
d6
b3
17
0f
f8
91
13
db
0b
1b
9d
d2
64
33
57
83
22
2c
be
7b
e8
44
64
2b
0b
19
88
d1
8b
26
8d
a6
f7
8c
c9
44
f4
3b
82
71
43
c4
dc
5e
e1
f0
d6
58
b8
7b
9c
00
86
2f
26
3d
6f
57
98
fc
82
e8
be
07
9a
11
08
de
fd
d4
c7
86
3c
31
47
e9
bd
f0
fb
c8
4d
eb
a2
15
fd
fb
9c
a4
23
7a
84
19
b2
6f
de
ff
63
a7
f9
5c
44
2b
ce
67
96
6e
be
6b
5f
9a
f1
fd
2a
7c
be
d6
48
ea
72
76
db
74
2d
ac
3e
47
0f
6c
c7
41
d8
2e
77
e9
c0
dd
01
9b
54
58
17
75
51
97
5b
59
63
3b
e6
7b
35
c0
d4
30
b7
25
52
4d
ea
fd
eb
a6
d3
64
3c
5c
82
eb
b5
24
79
66
9c
41
1b
b5
6b
39
7f
8d
37
b8
f7
fa
4c
ed
03
16
54
6c
aa
ee
41
9c
0e
7f
1d
96
a0
ec
61
4c
6c
9c
8e
03
e0
10
03
17
65
12
1f
1e
b8
fd
54
9f
de
04
6a
50
44
3e
ba
b9
fe
a2
e7
8a
29
f4
96
44
55
92
8d
b1
f9
e7
82
0e
53
3c
57
12
98
9b
3a
36
37
ea
00
a1
de
3e
46
9a
80
0c
43
1d
4d
f2
43
c1
dc
7d
6a
89
ba
79
00
d5
2b
78
bc
c1
03
47
4f
9d
2c
21
28
02
5c
31
93
c4
d1
a0
9f
50
90
5a
d2
de
7f
e8
e0
9f
04
7e
0e
72
e6
da
b0
ed
f7
e3
b0
8e
d1
31
6a
cf
85
72
54
b6
c1
fb
f6
4c
e5
82
f2
99
0c
ce
cf
95
05
fd
7e
85
17
99
8a
af
58
3b
e1
aa
64
1e
9b
54
db
b9
1c
a9
d0
70
09
13
96
7f
b0
34
92
01
b5
d6
79
b3
2d

View File

@@ -0,0 +1,768 @@
96
ac
62
43
c9
b1
27
2b
e7
7b
97
5a
40
48
bf
00
ff
2c
48
f9
4a
34
83
36
24
49
27
38
80
d4
5e
54
bd
a1
57
29
68
2b
f5
91
a7
43
82
a7
08
be
b7
81
18
ca
b2
9a
d7
4a
c2
f4
05
ba
72
00
76
df
b5
71
88
dc
16
84
87
cd
20
08
1f
6b
f4
12
f2
57
de
a0
34
06
b2
3a
6a
75
2e
47
8b
a4
ef
9c
7c
0f
48
10
92
1f
a3
25
45
be
64
dc
5d
9f
18
d4
e1
32
0e
fc
65
08
15
4c
da
35
ab
91
2d
05
9e
02
91
a1
15
0a
e0
a1
0d
a5
e3
d7
bd
22
1a
85
1c
59
8d
f4
d0
b1
8d
aa
92
09
76
55
60
99
d1
c0
de
4e
22
2d
53
04
d4
4f
a9
cb
9b
d4
ff
e1
57
69
dd
6c
47
93
fa
80
9f
52
64
cf
0f
eb
ca
4b
59
75
ba
28
76
39
78
3a
a1
f4
b6
45
ff
7a
00
d4
6e
e7
b1
9f
ec
17
b3
e8
3b
ca
f4
36
1d
53
49
e3
0c
ea
b6
0c
38
6b
6b
0d
1b
90
d8
b3
36
ee
6a
62
7a
d2
a3
86
70
cb
51
13
b0
fb
4a
c2
dd
c4
25
00
97
48
3f
ef
d1
82
67
0e
a4
0f
0f
45
cc
e9
0b
9e
d5
8d
af
ae
f6
57
d6
4e
25
fd
66
92
a6
97
21
99
4e
7d
00
b4
94
92
05
eb
e4
c4
f9
c4
6e
e5
a1
01
8b
22
0a
26
d8
0a
e2
d2
b4
86
37
2e
97
4d
75
b2
0a
00
5b
16
16
ad
1e
13
d1
62
91
5c
c2
4f
27
46
70
d1
e5
e8
bd
34
58
74
a7
e7
c9
75
9c
8e
43
ff
33
68
92
00
73
9a
61
33
95
f7
ae
78
d7
3c
6a
7b
90
f6
5a
b5
11
f0
df
3c
5d
ca
85
d0
b9
43
0b
4e
97
09
87
15
ff
82
3b
61
73
21
79
9a
ea
0a
b9
c7
22
34
78
03
39
ec
7b
54
1d
5e
6f
8c
15
51
14
6c
24
a6
54
11
81
1b
23
67
4c
26
12
33
56
cf
23
33
51
38
2c
39
94
cb
a5
dc
6c
25
a0
7e
1b
a9
af
33
ec
a1
8b
ba
3e
97
93
5e
3a
bd
f0
7e
9f
a3
2c
ec
f2
41
e7
ca
fc
65
92
db
4e
e4
87
ff
2b
98
a4
a4
78
05
de
e1
7f
d9
34
48
dc
98
45
7b
75
3e
d4
99
5e
e6
b1
bf
a9
ff
1d
38
6c
91
f3
96
ca
8f
48
ca
b5
b0
9a
78
2e
c3
b6
16
a8
7a
64
48
a9
62
36
c4
65
54
13
af
75
53
23
d3
6a
8d
b2
e1
65
09
45
44
89
e6
ec
83
62
91
30
cd
2a
54
81
79
18
af
36
2c
83
18
34
94
b4
b5
90
db
af
69
cf
39
9d
3e
2d
c3
e9
c0
c1
22
4f
14
8e
65
ef
68
28
73
41
ab
72
ad
58
ad
fc
69
b2
8e
27
e9
1e
bb
f8
30
fa
c5
3b
94
f7
62
f0
1c
c9
b1
56
1a
e3
5f
16
ed
ab
f5
1f
f1
64
c1
30
9d
1f
db
52
cd
2b
fe
db
5a
49
2e
b6
5c
b9
fc
86
b8
f0
5e
d2
6d
13
23
3f
b0
a3
eb
33
a9
dc
e2
cf
98
e6
51
6c
ee
42
fb
e1
e9
7e
20
ab
6c
99
65
f5
8a
37
7d
c7
3e
53
06
67
ab
8f
45
e6
a7
0b
23
db
50
f0
df
41
17
32
d8
ac
da
be
50
c5
1a
db
88
6c
0e
5a
52
96
d4
aa
1b
13
a3
36
f0
c1
78
12
f7
9f
c6
94
18
a7
d8
90
1c
56
8f
41
0e
ff
2a
f7
4b
aa
eb
83
36
f4
6c
a1
7e
14
e0
60
ce
2d
45
cd
b3
76
28
6e
ec
8b
8b
ef
a5
ab
80
25
80
27
20
a1
e7
39
3a
f5
79
db
13

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
2b
5c
52
ee
72
94
63
31
98
3b
a0
50
be
0f
43
50
55
c0
54
79
01
e0
35
59
b3
56
51
78
89
ea
27
c5

View File

@@ -0,0 +1,32 @@
6e
5c
52
2a
6d
19
b8
6c
61
bd
98
3b
56
a0
be
f3
51
c5
ce
71
6f
02
1b
49
bd
ec
d7
bd
fd
5e
d5
5a

View File

@@ -0,0 +1,768 @@
1c
43
de
77
0e
9c
d5
98
46
b6
f8
1f
9c
61
cc
d8
37
97
8e
26
d3
2c
33
0d
50
9d
8e
29
d9
e7
fb
1a
4f
ba
52
10
1e
48
88
0d
80
61
6e
53
3a
ac
59
1f
eb
d3
93
cb
b1
28
2d
e1
53
56
0d
43
73
cb
88
2c
66
d3
07
32
95
97
91
0e
d3
ff
10
58
40
96
4a
64
0b
c7
62
e6
32
9b
9f
3b
a4
1a
9e
c3
1e
04
c8
c9
ef
ec
96
35
e0
a9
b4
56
f6
19
f1
06
58
be
d3
6a
13
3c
ed
0c
23
0b
3c
fd
d8
07
37
75
d7
59
49
2a
7e
3b
e0
ce
27
72
5e
b7
c2
47
4c
56
8d
03
92
43
fe
81
0b
31
db
2f
ce
8e
e4
03
73
06
a5
a9
bb
ee
1b
a7
45
c2
b4
fc
11
11
65
9f
5d
e9
19
94
1c
89
c8
cc
66
1e
ca
aa
e3
e9
61
0e
ac
66
cd
41
28
e3
d4
bb
5a
bb
38
83
7d
99
6d
b7
e5
c3
1f
d0
92
22
f2
2f
85
4c
25
fa
d8
ae
12
de
d3
e3
37
c3
24
14
68
ee
eb
ec
da
5d
d6
82
e6
e5
7f
51
ad
35
28
58
d0
40
48
a4
70
3a
dc
13
52
63
c4
7b
3a
5d
6e
6c
59
5b
a1
ea
06
02
bd
34
35
3e
19
1b
fd
f3
6d
56
b2
05
39
74
8a
d6
1c
66
c2
50
e0
7f
2e
3c
6d
60
89
44
72
fe
7e
67
7c
35
3f
70
a1
75
f0
4c
60
f6
9d
d9
21
e9
b9
24
9b
d6
29
14
40
58
29
ae
fa
05
2c
92
9c
f2
3a
ba
06
7a
7e
b7
fe
d0
c1
5f
40
1e
f5
08
4a
97
a6
1c
ed
6f
bf
87
91
48
72
31
c0
5f
c2
3a
38
7c
77
c0
31
65
38
ad
09
be
82
b1
0e
e8
f8
d6
a9
d9
79
f6
3a
2e
c2
36
4f
08
67
30
6e
9b
f6
e3
c0
38
84
96
be
c8
ad
16
15
15
b0
16
e9
1b
5a
b4
e4
ee
9c
48
f0
de
49
50
aa
49
6b
3b
ac
3a
bf
a8
6b
9c
be
27
a9
2a
c8
a8
17
65
0b
2c
4c
53
6e
da
1d
2a
b5
81
95
cd
42
3e
0f
4a
fb
5b
ae
71
01
43
88
21
b8
9a
99
20
6b
a5
fd
d9
d0
6c
39
df
d6
f0
6f
ba
8c
71
94
21
3d
0e
86
f8
0e
4e
5a
24
97
7e
fa
ac
f7
eb
c0
2b
02
8c
fc
96
73
de
6c
8a
0c
c6
ae
1e
57
73
50
93
5c
91
2c
e1
d5
6c
67
08
75
c4
d6
be
d8
75
0a
9e
fb
b4
50
79
1c
3d
56
0c
e5
10
21
32
74
f7
d4
b3
b8
8a
d9
96
70
34
75
10
68
58
0a
9d
ed
f0
ab
3c
ad
bb
2f
3b
bf
37
19
ce
73
e9
38
66
6f
2a
7f
e8
2f
10
f0
8d
32
5d
20
3e
c0
b0
58
5b
58
22
16
b7
fc
05
a7
29
14
81
d1
22
27
91
38
5b
64
16
e8
07
e6
97
02
6b
e2
18
c5
19
c1
b2
15
84
2a
fa
0e
58
f9
88
f8
8f
3d
90
cf
6c
f4
21
87
87
6b
db
d7
be
0b
2c
26
1b
0d
d3
6d
16
dd
e6
ed
83
54
bd
74
32
b6
6d
10
bc
ac
cb
69
c8
94
47
78
90
2f
c3
6d
c7
0f
4e
63
85
b9
d5
9a
ec
c6
44
5c
e4
ad
65
bc
c9
58
e8
86
a9
2a
1d
4d
17
5c
f3
54
b4
fe
e8
89
0e
a4
ce
21
f5
e8
31
f6
90
5a
e5
28
db
39
91
83
4a
24
52
f5
91
c3
ea
88
d7
61
2a
59
9a
30
14
fc
8e
10
b3
0d
48
39
8b
b8
99
1c
0f
f1
2a
73
56
64
50
32
53
0d
81
8d
8a
a2
50
0b
25
21
a7
3e
18
59
1e
c6
ef
42
2d
ae
ed
66
d2

View File

@@ -0,0 +1,768 @@
d0
bf
2e
1d
68
51
37
8c
b5
de
83
ae
9b
44
32
34
ca
a0
1b
a5
85
35
24
2d
00
89
a7
44
c4
b1
27
53
ff
84
42
96
6b
f5
63
f8
97
2c
d0
42
6e
81
5a
34
88
3f
74
0c
60
16
92
8e
e0
70
29
1d
8e
fb
bd
32
60
88
f3
0d
50
55
0b
06
1c
cf
fd
99
22
e5
a3
04
68
b6
2a
0e
bc
bf
0a
eb
74
f8
df
e3
e1
30
c2
b1
ba
83
e4
70
75
ad
51
9b
94
c2
1f
3c
06
07
8f
46
45
d5
44
4b
41
12
7d
bf
8d
dc
67
a8
cf
44
0a
be
95
ad
1d
58
6a
29
ff
3d
8a
4d
67
1b
05
19
8d
2e
2e
af
06
d7
f0
be
6c
55
0f
1c
54
46
81
82
96
32
e9
8c
de
07
1b
1e
86
81
c7
8a
98
08
19
30
d1
c9
80
9a
49
7c
f4
09
bb
c6
7d
1d
8d
e8
b9
a3
e8
f5
eb
ea
8f
a7
95
38
d6
5c
01
76
ed
20
34
d7
4f
cd
a3
82
88
c3
6c
6b
5a
f1
34
eb
9e
60
ff
bf
13
8f
e5
d6
c0
37
8e
e8
91
e6
9b
f5
bf
ed
3b
16
14
d2
5b
58
d3
79
8a
7e
b3
dc
7f
e4
2f
1f
a3
e3
09
53
d9
2e
79
d4
18
c7
41
e6
59
45
5a
61
8e
7a
5a
ba
4f
59
d1
2e
17
d0
57
eb
69
8f
3c
2f
9a
6b
1d
4e
58
1d
09
a9
d6
c1
da
5f
5f
0e
c6
9f
84
63
d9
22
b1
85
25
6b
fa
5c
75
1e
03
21
d0
2c
58
e4
28
4a
02
1b
1c
af
a5
0f
73
39
d5
a5
b6
02
ee
59
ba
d9
9f
09
dc
0e
28
2d
ab
53
9c
bb
f9
70
41
8d
cf
30
2f
2b
47
cf
c1
e9
7a
e2
a8
38
85
b7
ef
6b
5b
65
e6
62
32
56
44
50
43
38
ee
13
9e
cc
4b
43
08
cd
8a
ec
eb
0e
9b
40
af
fd
ea
c0
e0
27
95
b5
40
74
eb
44
6b
85
cb
4a
57
12
20
79
bd
7c
34
f3
10
d1
26
0e
fb
ab
0f
4a
7e
04
ce
43
8d
62
4e
25
be
c7
e0
06
1e
25
3c
89
d5
7e
84
bd
d4
48
39
34
3f
6c
4d
85
8e
de
fd
ca
4f
a7
94
db
91
d1
74
45
c5
f5
8e
c0
8b
5b
c5
8c
fe
aa
cb
95
3f
b0
04
fb
b8
f7
b1
dc
1e
1b
56
22
be
61
2f
df
b1
88
94
42
cd
8a
ff
5e
18
a7
5b
02
ce
6f
4e
e1
ef
bd
96
dd
f8
d0
2f
cd
2a
42
bf
c8
99
7c
b4
59
e2
67
2a
f4
23
1a
75
d5
9d
c6
78
a2
18
53
74
be
c3
d9
85
04
e6
e1
25
a1
6e
58
f4
28
05
b1
26
51
47
8a
1c
e8
df
3c
ae
5b
0e
0d
ec
53
ca
78
b2
c3
8b
64
d7
dd
7c
99
85
f5
18
e0
2e
fe
08
ce
6f
f9
b4
cc
3c
52
1b
3c
1c
0a
c4
05
04
68
7a
f6
87
08
bc
27
94
67
04
eb
49
00
ec
aa
f4
17
77
a2
23
f1
66
8a
69
c7
04
7e
9b
86
3a
fb
4c
ca
c0
39
33
4f
58
dd
13
2b
fd
55
34
da
9d
45
e6
40
ed
d9
e8
81
04
ad
04
55
bd
2f
aa
38
3d
35
c0
c9
ec
5f
c6
a6
32
4b
c1
42
9c
53
9b
0b
ac
dc
cc
b5
51
21
f2
47
f7
5c
a6
06
8c
a9
15
e1
6d
13
13
7f
b9
5e
ae
12
8b
04
dd
ed
f9
a0
f4
a1
7f
fd
5f
23
25
00
8a
e1
21
e2
1f
9f
4a
64
b4
d8
06
ce
2d
93
13
59
68
b3
12
9b
4d
ea
fb
e0
7b
d6
be
34
de
1a
5a
de
bb
3e
00
02
55
6a
13
92
c7
7a
23
e4
61
20
61
ec
71
48
65
2d
70
2a
64
93

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
63
df
b8
42
bf
76
7f
89
71
78
39
64
2a
9b
92
fc
cf
82
bf
46
a9
f3
9b
a1
a3
29
29
95
f3
f9
34
dc

View File

@@ -0,0 +1,32 @@
76
08
dd
95
ec
12
b1
3d
bf
17
85
d1
06
22
61
4a
90
7b
3c
8b
93
16
97
21
2d
9b
d0
84
5e
ff
66
0d

View File

@@ -0,0 +1,768 @@
55
33
60
42
56
12
0d
54
80
65
76
94
13
b8
2f
b5
ab
d0
01
4e
7e
9f
10
49
2f
f1
5f
d4
5d
c7
82
b2
dc
4c
55
32
5f
cc
57
68
5f
13
4f
f7
e1
23
cf
02
8f
a7
b4
5d
cc
71
7c
f2
d7
b2
74
d8
f2
a8
b7
d1
ac
d6
63
53
a5
63
35
f4
82
ec
3d
04
50
4d
2e
05
2d
ed
28
11
2a
c7
41
0f
a8
e4
7f
0d
7c
5e
b1
d6
a2
9e
94
87
81
db
38
63
76
7b
7e
a8
7a
59
1e
0d
7e
a4
13
0c
1c
9f
a5
e8
14
2d
ab
f7
ee
8c
02
19
1c
df
1b
8c
80
4d
38
e2
b6
e4
44
5c
d8
fd
34
1a
63
ec
00
01
b9
d8
82
9d
4c
8f
5e
53
dc
6e
87
86
df
67
f4
ac
0b
b9
d1
88
f0
64
da
50
c1
fa
b3
96
55
10
a0
48
eb
6b
4a
a7
8a
85
1c
47
b1
06
42
9b
30
f8
a9
a3
b5
46
48
c8
b4
3d
cf
76
19
0b
bc
8c
66
a6
a3
6d
f7
b9
5a
e3
d9
78
4a
dd
87
58
23
5b
29
1c
0a
1d
b1
ba
80
54
12
e8
b9
2c
14
16
fb
e6
4c
42
db
12
38
30
ed
1b
d9
7e
69
e5
22
e4
82
e8
33
25
e9
e8
8a
d9
40
3f
7e
86
d8
8d
53
5e
39
1a
e4
cd
33
0e
e0
58
92
a1
14
e4
43
9b
59
b3
06
02
d9
d9
87
04
aa
55
30
5f
a1
f8
5b
23
d7
c3
b0
f3
06
54
c8
b7
cb
4c
e0
29
85
e6
cb
e9
a8
7c
f0
e9
99
a5
65
41
30
99
fd
fa
f5
77
84
5a
40
7c
d6
c2
ea
5e
de
db
04
ba
43
4d
80
e1
13
24
67
08
88
61
d6
51
99
81
8e
d4
ba
3a
09
5e
06
63
39
f3
53
39
48
77
e3
bf
79
26
28
8c
dd
37
ac
31
cd
b4
99
b5
eb
8c
a0
68
59
be
b5
c6
60
73
0f
a7
93
cf
11
34
7f
bf
ed
73
a8
2e
1d
2b
22
9a
09
59
32
79
ad
04
45
bc
11
b4
f1
64
d0
15
ec
51
41
da
dc
10
d3
22
c9
28
3e
5a
64
11
57
df
e5
3b
da
4c
3c
a7
36
46
99
df
0b
f7
94
d4
68
3f
b1
fd
ec
e8
e3
18
da
3f
f0
28
b6
3a
a7
d9
f5
0b
58
78
53
78
be
79
fc
7e
8a
2b
12
73
a8
d7
87
74
85
33
57
ae
c5
23
ef
7d
92
76
44
b0
7d
3d
0f
28
76
bf
0b
55
d4
59
2e
33
a6
58
c4
61
c9
6c
8b
81
cc
c2
b1
d4
8c
39
29
ad
99
4d
01
5a
e6
dc
4c
98
a7
54
16
76
7c
7b
a1
60
bf
74
91
b4
a0
aa
db
5e
43
a3
97
f6
3c
e1
cf
7f
91
64
79
f7
63
35
0c
54
dc
29
6a
22
31
4b
4f
48
4c
8c
22
e3
64
fc
e5
a6
ca
6e
15
0b
81
02
1b
44
b5
f4
9f
91
49
27
89
64
37
21
3d
0a
bc
ae
a2
80
62
db
28
54
13
8d
0e
0b
ec
84
1e
6b
e8
e0
39
b8
a0
d7
62
e6
0e
c8
b6
41
6d
fe
7c
7c
8e
d9
b7
41
59
08
b8
dd
9a
69
89
50
69
7f
a5
fa
a5
b1
92
6a
54
de
98
6a
00
93
da
97
6c
89
ed
bf
83
71
1a
4b
aa
bc
2c
21
c7
4f
2b
7f
e9
6a
aa
9e
b0
82
dd
66
e3
40
8c
d3
00
02
cd
bd
57
3d
27
f6
6a
80
6e
b0
b3
14
4c
42
7e
07
ef
7a
39
67
f0
4f
0a
43
36
f5
5e
8e
12
c6
3a
67
80
25
18
44
80
22
73
ac
90
1d
4f
6a
55
65
02
db
49
6d
4b
b4
61
09
be
1f
90
b7
ef
a7
6d
34
03
a3
bb
ec
6a
32
e8
e5
cf
4e
db
a3

View File

@@ -0,0 +1,768 @@
cf
31
25
a6
f3
0c
f0
d7
8f
4b
76
f6
c6
87
7d
cc
d1
80
b2
b8
f7
af
a1
ed
73
26
a1
81
23
c0
b2
01
56
90
2b
b1
fc
6b
a1
f4
f4
1a
00
6b
15
e4
1d
18
a7
64
40
e5
e2
0b
23
75
66
58
06
c3
ef
56
63
70
4d
c0
98
d1
e6
f4
34
a5
6f
5f
75
79
b8
60
28
4f
d8
df
e8
49
70
cc
47
ef
1a
fd
9e
4e
3b
80
a3
ec
8f
d7
39
ce
fc
ef
f6
56
7d
ca
09
44
ef
62
af
06
82
98
af
c6
72
3f
19
6b
4b
71
16
1c
61
77
e2
e8
ea
4a
0f
9d
d3
78
15
b7
0d
2d
71
a2
cd
de
ae
73
b2
8c
9e
c9
c8
fb
57
27
ee
d2
52
fa
16
75
43
a7
70
04
f9
45
98
a3
21
52
a2
2b
f6
11
d2
75
d1
b2
49
ef
ed
12
b2
22
69
ed
b1
07
18
a4
9c
31
61
b4
a3
87
a8
65
4a
50
9f
9d
e7
c8
e1
da
b5
a5
d1
3c
6b
5b
48
0c
87
a7
28
3a
a8
df
02
3f
0b
fd
ca
6c
32
b1
8b
7a
e3
f1
f8
9b
c2
22
61
e1
af
19
20
2c
ce
59
98
12
84
d8
09
4b
c1
46
aa
0a
0b
cd
5f
c3
1f
5c
3d
22
f8
e3
9a
ba
1c
4f
53
84
e9
01
8c
0a
fd
af
39
5b
76
1b
64
af
be
fd
50
a8
9e
d9
9b
82
0b
09
ba
28
62
16
46
32
13
cd
d3
e5
23
9f
26
33
28
41
9d
6c
8f
37
78
96
cc
c6
d4
9c
ac
9c
b3
b1
9a
64
39
91
d1
c1
e9
a3
b3
f8
48
2a
03
1f
99
e1
ca
83
9c
03
39
e8
14
1e
b4
8c
4a
93
11
55
14
cf
ad
b9
c4
7a
6e
ab
84
97
35
9f
d9
2d
db
44
2a
8a
e5
b2
77
6b
c0
ff
ad
5d
39
9f
05
cf
72
b8
72
b4
92
ab
b5
5f
8a
6c
0c
64
3d
8f
ff
62
78
75
10
06
62
39
6a
84
9b
da
87
8b
90
89
5b
93
61
46
23
56
3a
fd
24
d7
6c
9e
02
a8
50
65
e9
db
a0
56
a3
42
f0
c7
f5
16
a3
72
35
02
3e
bc
18
e8
fb
8f
b6
a6
75
fc
bd
d5
63
1f
fc
69
30
d7
73
5d
74
bf
7d
7c
ee
b7
9c
1d
6d
82
7f
f1
af
5f
b2
5b
9c
c2
0b
93
87
fb
11
bc
e9
c8
84
4d
18
36
e6
5c
ad
1b
c3
f5
08
7b
de
b4
ca
c0
3d
e2
8f
c6
e3
10
70
63
1f
36
ab
55
26
d3
d2
f8
86
dc
a8
43
61
22
c6
05
38
59
85
cb
5d
ee
7b
09
ba
88
d6
94
8a
7e
da
d4
a8
82
a0
bf
6a
38
f9
ba
0e
9f
0d
ce
a1
fa
1d
19
fb
68
dd
f4
3e
ec
73
34
c2
0e
a8
c7
b1
d6
33
b5
5b
b3
fd
43
07
4b
5d
72
5a
0b
92
cb
cb
c3
52
21
db
a0
14
2c
5a
94
2f
e8
41
51
5d
19
1d
e0
4c
a0
a8
54
0f
15
da
a5
c5
b4
37
26
c1
e0
ba
c8
5f
ef
00
68
ec
de
dc
16
b2
e7
13
5e
1c
24
67
74
39
d9
67
5c
ac
9c
f6
4f
cb
b7
6a
18
c1
d0
98
33
6c
76
cb
5a
04
fd
2a
c3
95
ee
7a
96
35
37
5c
6f
fb
a5
1f
9c
44
04
2e
e1
df
0c
f3
68
f3
5b
c7
1a
ea
bd
ec
02
cd
35
c3
bd
0b
59
43
eb
1d
99
a8
17
3f
43
a7
89
cf
ac
ea
1c
e6
f1
96
6e
86
94
98
d0
97
df
7d
c2
62
c8
b5
ef
a2
2e
5a
b4
72
46
13
33
a1
3b
ae
03
bf
c8
fe
c7
69
90
97
ee
85
74
ec
c0
e9
12
24
c8
a2
c1
0e
b8
57
32
5c
62
7c
19
7a
bb
8a
c3
fc
3f

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
13
5b
97
48
c6
aa
6d
1a
e9
b5
42
0c
72
67
9f
f6
5c
ae
62
2b
8a
7d
f5
4c
d7
65
01
31
b5
fd
77
f8

View File

@@ -0,0 +1,32 @@
f1
33
05
54
e2
67
00
b8
96
75
8d
b1
cc
8e
ec
b7
3b
8c
80
9a
40
83
46
6e
4e
0c
65
4f
34
6a
fa
e1

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
b4
08
d5
d1
15
71
3f
0a
93
04
7d
bb
ea
83
2e
43
40
78
76
86
d5
9a
9a
2d
10
6b
d6
62
ba
0a
a0
35

View File

@@ -0,0 +1,32 @@
e7
bc
f8
99
fe
b5
db
69
d1
17
41
a8
83
8e
cf
ee
25
3e
80
b7
6d
6a
35
af
46
e2
20
e8
1d
c4
1d
af

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
8c
97
02
42
40
61
11
e2
63
68
ad
87
60
c4
d0
2a
8b
28
d1
7d
13
82
10
ad
c1
27
19
7b
50
96
81
40

View File

@@ -0,0 +1,32 @@
40
69
db
99
97
53
67
57
c9
b1
2f
02
6f
fb
3d
02
f4
35
55
9d
f6
32
14
71
17
50
cd
04
b1
f0
5d
5f

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
c0
d4
57
64
e3
db
f0
94
8b
91
4d
6f
65
c9
2b
d0
eb
d2
15
56
e5
07
67
53
af
48
df
8f
ff
d6
ba
dc

View File

@@ -0,0 +1,32 @@
48
85
52
10
1a
21
c9
cd
87
31
46
b8
3f
ed
69
d2
63
76
f7
00
31
25
66
ca
6b
6d
f0
7b
d5
58
5d
59

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
23
f2
11
b8
4a
6e
e2
0c
8c
29
f6
e5
31
4c
91
b4
14
e9
40
51
3d
38
0a
dd
17
bd
72
4a
b3
a1
3a
52

View File

@@ -0,0 +1,32 @@
24
7d
3f
ed
8c
ac
db
06
bd
e6
37
c7
49
fe
e6
89
a2
cc
0a
14
25
e9
c5
b8
ec
90
19
2e
f4
bd
a1
80

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
26
22
50
3a
2a
54
4f
35
83
92
90
3e
6f
2a
dc
5a
2d
94
fe
01
05
83
b5
74
a5
4d
9a
7e
6d
22
3a
24

View File

@@ -0,0 +1,32 @@
c9
65
7c
41
49
98
e2
f9
64
d2
a6
b8
74
73
9e
2c
65
cc
91
f4
cd
fa
33
51
aa
54
d0
34
22
33
98
32

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
72
3a
b6
2b
92
58
0b
3d
ef
8c
e8
87
00
1e
ef
e4
d9
05
65
aa
ca
f5
43
0e
e2
aa
b7
de
cf
99
db
76

View File

@@ -0,0 +1,32 @@
f5
95
77
44
20
dd
2c
b8
d0
39
f9
ce
8e
b7
4b
b9
c2
95
2d
94
af
91
e8
e8
6e
29
2f
ff
27
2a
71
73

View File

@@ -28,7 +28,7 @@ module mlkem_top #(
input clk,
input rst_n,
input [2:0] k_i, // RUNTIME ML-KEM param: 2=512, 3=768, 4=1024
input op_i, // 0 = KeyGen, 1 = Encaps (captured at start_i)
input [1:0] op_i, // 0=KeyGen, 1=Encaps, 2=Decaps (captured at start_i)
input [255:0] d_i, // KeyGen seed d (byte 0 in d_i[7:0])
input [255:0] z_i, // implicit-rejection seed z
input [255:0] msg_i, // Encaps message m (byte 0 in msg_i[7:0])
@@ -41,6 +41,21 @@ module mlkem_top #(
input ek_in_we, // write one ek byte (only honored in ST_IDLE for Encaps preload)
input [10:0] ek_in_addr, // ek byte address 0..ek_bytes-1
input [7:0] ek_in_byte, // ek byte value
// Decaps dk input: stream dk bytes (=sk, 768K+96) into the design before
// start_i with op_i=2. The load logic routes each byte by region:
// [0,384K) -> dk_pke (dkp_bram) = s_hat encoding
// [384K, 768K+32) -> ek_pke (ek_bram) = t_hat encoding || rho
// [768K+32, 768K+64) -> H(ek) (hek_r)
// [768K+64, 768K+96) -> z (z_r)
input dk_in_we, // write one dk byte (ST_IDLE Decaps preload)
input [11:0] dk_in_addr, // dk byte address 0..(768K+96)-1
input [7:0] dk_in_byte, // dk byte value
// Decaps ciphertext input: stream c bytes (=ct) into c_in_bram before
// start_i. Kept separate from ct_bram so the computed c' can be compared
// against the original c (and J(z||c) can read c) without aliasing.
input c_in_we, // write one c byte (ST_IDLE Decaps preload)
input [10:0] c_in_addr, // c byte address 0..ct_bytes-1
input [7:0] c_in_byte, // c byte value
// Encaps shared secret output (= K), valid at done_o
output [255:0] ss_o,
// Encaps ciphertext readback tap: ct byte by index 0..ct_bytes-1
@@ -65,7 +80,12 @@ module mlkem_top #(
output [255:0] dbg_sigma_o,
// Encaps debug taps: r (G high half) and H(ek)
output [255:0] dbg_r_o,
output [255:0] dbg_hek_o
output [255:0] dbg_hek_o,
// Decaps debug taps: m' (Decrypt output), K-bar (J output), parsed z/h.
output [255:0] dbg_mprime_o,
output [255:0] dbg_kbar_o,
output [255:0] dbg_decz_o, // parsed z (dk[768K+64:+32])
output [255:0] dbg_dech_o // parsed H(ek) (dk[768K+32:+32])
);
localparam Q = `Q; // 3329
@@ -82,15 +102,28 @@ module mlkem_top #(
wire [5:0] slot_t_rt = kk_rt + {1'b0, k_r} + {1'b0, k_r}; // t_hat base = kk+2k
wire [11:0] ek_bytes_rt = 12'd384 * {9'b0, k_r} + 12'd32; // 800/1184/1568
wire [11:0] dk_bytes_rt = 12'd384 * {9'b0, k_r}; // 768/1152/1536
// full dk = dk_pke(dk_bytes) || ek(ek_bytes) || H(ek)(32) || z(32). Region
// boundaries (used by Decaps dk load routing and dk readback).
wire [11:0] dk_ek_end = dk_bytes_rt + ek_bytes_rt; // ek_pke region end
wire [11:0] dk_hek_end = dk_ek_end + 12'd32; // H(ek) region end
// LOAD-TIME boundaries: dk is streamed in BEFORE start_i, so k_r is not yet
// captured. Route the dk load by the LIVE k_i input instead of k_r.
wire [11:0] dkp_bytes_ld = 12'd384 * {9'b0, k_i}; // 768/1152/1536
wire [11:0] ek_bytes_ld = 12'd384 * {9'b0, k_i} + 12'd32; // 800/1184/1568
wire [11:0] dk_ek_end_ld = dkp_bytes_ld + ek_bytes_ld; // ek_pke region end
wire [11:0] dk_hek_end_ld= dk_ek_end_ld + 12'd32; // H(ek) region end
// H(ek) block count = ceil((ek_bytes+1)/136): 6/9/12 for k=2/3/4 (table)
wire [3:0] h_nblk_rt = (k_r == 3'd2) ? 4'd6 : (k_r == 3'd3) ? 4'd9 : 4'd12;
wire [11:0] h_last_rt = {6'b0, h_nblk_rt} * 12'd136 - 12'd1; // final padded byte index
// ---- Encaps runtime params ----
reg op_r; // 0=KeyGen 1=Encaps (captured at start)
reg [255:0] m_r; // Encaps message m (captured at start)
reg [1:0] op_r; // 0=KeyGen 1=Encaps 2=Decaps (captured at start)
reg [255:0] m_r; // Encaps message m (captured at start); Decaps reuses for m'
reg [255:0] ss_r; // Encaps shared secret K (= G output low half)
reg [255:0] r_r; // Encaps PRF seed r (= G output high half)
// ---- Decaps runtime params (parsed from dk during load) ----
reg [255:0] z_r; // implicit-rejection seed z (dk tail), captured at load
reg [255:0] kbar_r; // K-bar = J(z||c) (D5)
// FIPS 203: eta2 = 2 for all parameter sets.
wire [1:0] eta2_rt = 2'd2;
// Compression params: (du,dv) = (10,4) for k=2/3, (11,5) for k=4.
@@ -100,6 +133,7 @@ module mlkem_top #(
wire [11:0] c1_bytes_rt = 12'd32 * {7'b0, du_rt} * {9'b0, k_r}; // 640/960/1408
wire [11:0] c2_bytes_rt = 12'd32 * {7'b0, dv_rt}; // 128/128/160
wire [11:0] ct_bytes_rt = c1_bytes_rt + c2_bytes_rt; // 768/1088/1568
wire [11:0] ct_bytes_rt = c1_bytes_rt + c2_bytes_rt; // 768/1088/1568
assign ss_o = ss_r;
// ---- E1: rho-load + byteDecode12 bookkeeping ----
@@ -145,6 +179,23 @@ module mlkem_top #(
assign ct_rd_addr = dbg_ct_idx_i;
assign dbg_ct_o = ct_rd_data;
// ---- c_in_bram: Decaps input ciphertext c (<=1568 B). Preloaded via
// c_in_* in ST_IDLE. Kept separate from ct_bram (which holds the computed
// c') so D7 can compare c' vs c and D5 J(z||c) can read c. Read port is
// muxed (D5 J-feed / D7 compare); for D0 only the load write path exists.
wire [10:0] cin_rd_addr;
wire [7:0] cin_rd_data;
reg [10:0] cin_rd_addr_r; // D5/D7 read address (tied 0 until then)
sd_bram #(.W(8), .D(2048), .A(11)) u_c_in_bram (
.clk(clk),
.rd_addr(cin_rd_addr), .rd_data(cin_rd_data),
.wr_en(c_in_we), .wr_addr(c_in_addr), .wr_data(c_in_byte)
);
assign cin_rd_addr = cin_rd_addr_r;
/* verilator lint_off UNUSEDSIGNAL */
wire [7:0] cin_rd_data_unused = cin_rd_data; // consumed in D5/D7
/* verilator lint_on UNUSEDSIGNAL */
// ================================================================
// Polynomial storage, sized for KMAX (worst case). Runtime k uses a
// sub-range. Slot layout (each slot = 256 coeffs):
@@ -330,26 +381,39 @@ module mlkem_top #(
reg [7:0] ek_wd, dkp_wd;
// ek BRAM write port: KeyGen ST_E drives ek_we/ek_wa/ek_wd; Encaps preloads
// ek from the external ek_in_* port (TB streams ek=pk before start_i). The
// two never overlap (preload happens in ST_IDLE before an Encaps run).
wire ek_we_mux = ek_in_we ? 1'b1 : ek_we;
wire [10:0] ek_wa_mux = ek_in_we ? ek_in_addr : ek_wa;
wire [7:0] ek_wd_mux = ek_in_we ? ek_in_byte : ek_wd;
// ek from the external ek_in_* port (TB streams ek=pk before start_i). Decaps
// routes the dk's ek_pke region (dk[384K:768K+32]) here at load time. The
// three never overlap (preloads happen in ST_IDLE before a run).
wire dk_ld_ekpke = dk_in_we && (dk_in_addr >= dkp_bytes_ld)
&& (dk_in_addr < dk_ek_end_ld); // ek_pke region
wire dk_ld_dkpke = dk_in_we && (dk_in_addr < dkp_bytes_ld); // dk_pke region
wire [10:0] dk_ek_off = (dk_in_addr - dkp_bytes_ld); // offset within ek
wire ek_we_mux = ek_in_we ? 1'b1 :
dk_ld_ekpke ? 1'b1 : ek_we;
wire [10:0] ek_wa_mux = ek_in_we ? ek_in_addr :
dk_ld_ekpke ? dk_ek_off : ek_wa;
wire [7:0] ek_wd_mux = ek_in_we ? ek_in_byte :
dk_ld_ekpke ? dk_in_byte : ek_wd;
sd_bram #(.W(8), .D(2048), .A(11)) u_ek_bram (
.clk(clk),
.rd_addr(ek_rd_addr), .rd_data(ek_rd_data),
.wr_en(ek_we_mux), .wr_addr(ek_wa_mux), .wr_data(ek_wd_mux)
);
// dk_pke BRAM write port: KeyGen ST_E (s_hat byteEncode) drives dkp_we/wa/wd;
// Decaps routes the dk's dk_pke region (dk[0:384K]) here at load time. The
// two never overlap (preload in ST_IDLE before a Decaps run).
wire dkp_we_mux = dk_ld_dkpke ? 1'b1 : dkp_we;
wire [10:0] dkp_wa_mux = dk_ld_dkpke ? dk_in_addr[10:0] : dkp_wa;
wire [7:0] dkp_wd_mux = dk_ld_dkpke ? dk_in_byte : dkp_wd;
sd_bram #(.W(8), .D(2048), .A(11)) u_dkp_bram (
.clk(clk),
.rd_addr(dkp_rd_addr), .rd_data(dkp_rd_data),
.wr_en(dkp_we), .wr_addr(dkp_wa), .wr_data(dkp_wd)
.wr_en(dkp_we_mux), .wr_addr(dkp_wa_mux), .wr_data(dkp_wd_mux)
);
// full dk = dk_pke(dk_bytes) || ek(ek_bytes) || H(ek)(32) || z(32)
wire [11:0] dk_ek_end = dk_bytes_rt + ek_bytes_rt; // ek region end
wire [11:0] dk_hek_end = dk_ek_end + 12'd32; // H(ek) region end
// full dk = dk_pke(dk_bytes) || ek(ek_bytes) || H(ek)(32) || z(32).
// (dk_ek_end / dk_hek_end declared near the top with the other size wires.)
// Debug-region selects for dk readback (combinational region decode).
wire dbgdk_in_dkp = (dbg_dk_idx_i < dk_bytes_rt);
@@ -390,6 +454,8 @@ module mlkem_top #(
localparam ST_ENC_V = 5'd17; // v = INTT(sum t_hat o y_hat) + e2 + mu
localparam ST_ENC_C2 = 5'd18; // Compress_dv + byteEncode_dv -> ct c2
localparam ST_ENC_E2MV = 5'd19; // relocate e2 bank_t[0] -> bank_a[E2_ASLOT]
// ---- Decaps states ----
localparam ST_DEC_LOAD = 5'd20; // dk/c already streamed in; parse/settle (D0)
localparam ST_DONE = 5'd31;
reg [4:0] st, st_next;
@@ -418,6 +484,11 @@ module mlkem_top #(
assign dbg_sigma_o = sigma_r;
assign dbg_r_o = r_r;
assign dbg_hek_o = hek_r;
// Decaps taps: m' reuses m_r (Decrypt writes it), z/h parsed from dk at load.
assign dbg_mprime_o = m_r;
assign dbg_kbar_o = kbar_r;
assign dbg_decz_o = z_r;
assign dbg_dech_o = hek_r; // Decaps parses dk's H(ek) into hek_r at load
// ---- sha3_top in G mode: data_i = {K_byte, d} (d byte0 in [7:0]) ----
reg sha3_valid;
@@ -897,7 +968,11 @@ module mlkem_top #(
always @(*) begin
st_next = st;
case (st)
ST_IDLE: if (start_i) st_next = op_i ? ST_ENC_H : ST_G;
ST_IDLE: if (start_i) st_next = (op_i == 2'd2) ? ST_DEC_LOAD :
(op_i == 2'd1) ? ST_ENC_H : ST_G;
// D0: settle after dk/c parse, then (D1+) proceed to Decrypt. For now
// ST_DEC_LOAD just lands in DONE so the load/parse can be dbg-checked.
ST_DEC_LOAD: st_next = ST_DONE;
ST_G: if (sha3_vo) st_next = ST_A;
ST_A: if (a_pair >= kk_rt) st_next = ST_C;
ST_C: if (c_poly >= {1'b0, k_r, 1'b0}) st_next = ST_N;
@@ -927,7 +1002,7 @@ module mlkem_top #(
if (!rst_n) begin
st <= ST_IDLE;
k_r <= 3'd0;
op_r <= 1'b0;
op_r <= 2'd0;
m_r <= 256'd0;
ss_r <= 256'd0;
r_r <= 256'd0;
@@ -1024,6 +1099,9 @@ module mlkem_top #(
h_mblast <= 1'b0;
h_ack <= 1'b0;
hek_r <= 256'd0;
z_r <= 256'd0;
kbar_r <= 256'd0;
cin_rd_addr_r <= 11'd0;
h_blk <= 3'd0;
h_byte <= 8'd0;
h_phase <= 2'd0;
@@ -1043,11 +1121,12 @@ module mlkem_top #(
em_we <= 1'b0; // e2-relocate bank_a write default low (E6)
// Kick off when entering from IDLE: KeyGen starts G; Encaps captures
// op/m and arms the H(ek) machinery (ST_ENC_H reuses the ST_H FSM).
// op/m and arms the H(ek) machinery (ST_ENC_H reuses the ST_H FSM);
// Decaps captures op (dk/c already streamed; z/h captured at load).
if (st == ST_IDLE && start_i) begin
k_r <= k_i; // capture runtime ML-KEM param
op_r <= op_i;
if (op_i) begin
if (op_i == 2'd1) begin
m_r <= msg_i; // capture Encaps message
// arm H(ek) (same fields the ST_E->ST_H arming sets)
h_blk <= 3'd0;
@@ -1057,11 +1136,25 @@ module mlkem_top #(
h_mblast <= 1'b0;
h_ack <= 1'b1; // ready to consume final digest
h_wb_vld <= 1'b0;
end else if (op_i == 2'd2) begin
// Decaps: dk_pke/ek_pke already in BRAM; z/H(ek) captured into
// z_r/hek_r during load (below). Nothing else to arm in D0.
end else begin
sha3_valid <= 1'b1;
sha3_ack <= 1'b1;
end
end
// Decaps dk load: capture the H(ek) and z byte regions into registers
// as they stream in (the dk_pke/ek_pke regions go to BRAM via the
// write muxes). Byte i within a region lands in [8i +: 8]. Uses the
// LIVE k_i boundaries (k_r not yet captured during preload).
if (dk_in_we) begin
if (dk_in_addr >= dk_ek_end_ld && dk_in_addr < dk_hek_end_ld)
hek_r[(dk_in_addr - dk_ek_end_ld)*8 +: 8] <= dk_in_byte; // H(ek)
else if (dk_in_addr >= dk_hek_end_ld)
z_r[(dk_in_addr - dk_hek_end_ld)*8 +: 8] <= dk_in_byte; // z
end
// Drop valid once accepted
if (sha3_valid && sha3_ready) sha3_valid <= 1'b0;