Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
e3cee36
[mldsa] Verify matrix-vector mul performance tweak.
jadephilipoom Nov 19, 2025
edbd470
[mldsa] Make hint usage loop in verify use loopi.
jadephilipoom Nov 19, 2025
72026b4
[mldsa] Add STACK_SIZE references to verify.
jadephilipoom Nov 20, 2025
2f713fb
[mldsa] Restore the MOD register before finishing verify.
jadephilipoom Nov 20, 2025
9217ca9
[mldsa] Stream the matrix A in ML-DSA key generation.
jadephilipoom Nov 18, 2025
df8f0c1
[mldsa] Use less stack space in poly_uniform and poly_uniform_eta.
jadephilipoom Nov 19, 2025
551a4b1
[mldsa] Stream s1 in key generation.
jadephilipoom Nov 18, 2025
9a6b5ba
[mldsa] Remove some unneeded register saves in key generation.
jadephilipoom Nov 19, 2025
2426d41
[mldsa] Stream s2 in key generation.
jadephilipoom Nov 19, 2025
1220397
[mldsa] Stream t0 in key generation.
jadephilipoom Nov 19, 2025
4e15c53
[mldsa] Rename STACK_T1 to STACK_T and revise comments.
jadephilipoom Nov 19, 2025
6f4c9bc
[mldsa] Add STACK_SIZE references to keygen.
jadephilipoom Nov 20, 2025
cc4ef2b
[mldsa] Add a standalone test for poly_uniform.
jadephilipoom Nov 20, 2025
e04b626
[mldsa] Vectorize the poly_uniform routine.
jadephilipoom Nov 24, 2025
feb6395
[mldsa] Add adversarial tests for poly_uniform postprocessing.
jadephilipoom Nov 24, 2025
e093fda
[otbn] Fixed DV errors related to small message sizes in otbnsim and …
apinise Nov 18, 2025
ceee6de
[otbnsim] Moved the kmac interface simulation to its own file.
apinise Dec 2, 2025
48a61f9
[otbmsim] Lift the KMAC block into the OTBN state.
jadephilipoom Nov 26, 2025
e010d63
[otbnsim] Move KMAC step into top-level simulation step.
jadephilipoom Nov 26, 2025
f2022e9
[otbnsim] Move KMAC interface logic out of digest_ready().
apinise Dec 2, 2025
3217ba8
[otbn] Updated AppIntf to speculatively request the next digest after…
apinise Dec 2, 2025
acac52d
[otbn] Reduced OTBN DMEM size from 128KB to 32KB
apinise Nov 20, 2025
230e9d6
[otbn] Replaced PQC ifdef versioning with proper systemverilog parame…
apinise Nov 14, 2025
f31ad12
[otbn] Created new sim configs for OTBN for simulating PQC version
apinise Nov 14, 2025
6a947a8
[otbn] Updated snippet generators to produce pqc versioned random tes…
apinise Nov 14, 2025
5e51e87
[otbn] New darjeeling and earlgrey tops for OTBN parameter changes an…
apinise Dec 3, 2025
c507e91
[otbn] Replaced +define usage with new package and fusesoc virtual co…
apinise Dec 9, 2025
6bc8d49
[otbn] Added unique secure wipe enable for acch register.
apinise Dec 11, 2025
333fb24
[otbn, rig] Added PQC instructions to bad_insn gen conditionally for …
apinise Dec 12, 2025
a62c76f
[otbnsim] Added illegal instruction flag for vector ISA and operating…
apinise Dec 12, 2025
2e6aeb7
[otbn] Fixed predecode setting control flags for ADDV/SUBV illegally
apinise Dec 12, 2025
d51cc21
[otbnsim] Remove not implemented CSR registers from otbnsim.
apinise Dec 15, 2025
d6d728d
[otbnsim, rig] Allow for illegal WSR/CSR addresses to be tested.
apinise Dec 15, 2025
efd8990
[otbn] Updated illegal WSR address flag in the controller
apinise Dec 15, 2025
ee9f350
[otbnsim] Updated bazel targets for PQC tests to set otbnsim parameter.
apinise Dec 17, 2025
8e05fbe
[mldsa] Reduce stalls in poly_uniform.
jadephilipoom Nov 25, 2025
8e848a1
[mldsa] Make full use of KMAC stalls in poly_uniform.
jadephilipoom Nov 26, 2025
461fd2e
[mldsa] Inline a couple of loops in poly_uniform.
jadephilipoom Nov 27, 2025
deda641
[mldsa] Initialize SHAKE computation before calling poly_uniform.
jadephilipoom Nov 27, 2025
4241e6e
[mldsa] Inline small loops in poly_uniform sampling.
jadephilipoom Nov 27, 2025
0fd84ed
[crypto] Optimize poly_gen_matrix to minimize stalls
pqcfox Jan 15, 2026
a3a86ae
[mlkem] Separate SHAKE inits from poly_getnoise_eta_* for performance
pqcfox Jan 22, 2026
1afdff0
[mlkem] Use wide register for poly_gen_matrix nonce instead of stack
pqcfox Jan 22, 2026
43bac91
[otbnsim, rig] Added a CSRRW insn to app_req RIG to read status of Ap…
apinise Dec 17, 2025
4693b60
[otbn] Removed unused CSR mapping for KMAC digest
apinise Dec 17, 2025
21e2793
[otbn rig] Added chance for long message between 2 KB and 8 KB
apinise Dec 22, 2025
8e1ec7f
[otbn] Fixed bug in ctrl_redun vseq causing improper signal sampling
apinise Dec 30, 2025
7269586
[otbn, dv] Fixed otbn_sw_no_acc_vseq with updated DMEM sizes.
apinise Jan 8, 2026
501fc44
[otbn] Added new covergroups for vector ISA and parameterized using O…
apinise Dec 17, 2025
4940da6
[otbn] Updated AppIntf UVM driver and sequence to handle random resets
apinise Nov 25, 2025
bf0ace9
[otbn] Added toggle exclusions for AppIntf based on mode
apinise Dec 19, 2025
2c41140
[otbn, rtl] Reset the partial write register value after a write to m…
apinise Jan 28, 2026
ecd946d
[mlkem] Use external lib file for constants in ML-KEM.
jadephilipoom Dec 12, 2025
5d0def8
[mldsa] Move sign variables within the DMEM buffer.
jadephilipoom Dec 1, 2025
8cf81bc
[mldsa] Modify all tests to use external constants.
jadephilipoom Dec 2, 2025
839978d
[deps] Add kyber-py and dilithium-py to python dependencies for testi…
jadephilipoom Jan 27, 2026
93422de
[otbn] Add a script to profile OTBN programs.
jadephilipoom Dec 16, 2025
b54ecc5
[kmac, rtl] Fixed assertion error with OTBN AppIntf
apinise Jan 28, 2026
9d73544
[kmac, rtl] Fixes FSM error state handling for invalid keys
apinise Jan 29, 2026
7b55552
[otbn, smoke] Reset original smoke test assembly to upstream
apinise Jan 29, 2026
7daecd1
[otbn] Add expected-memory support to testgen infrastructure.
jadephilipoom Dec 2, 2025
d06a924
[mldsa] Move sign data to separate files.
jadephilipoom Dec 2, 2025
2634a73
[mldsa] Make keypair and verify use external data.
jadephilipoom Dec 2, 2025
6f4c7dc
[mldsa] Autogenerate keypair tests.
jadephilipoom Dec 4, 2025
d67304f
[mldsa] Autogenerate verify tests.
jadephilipoom Dec 5, 2025
13537a4
[mldsa] Autogenerate sign tests.
jadephilipoom Dec 5, 2025
1fadf3c
[mldsa] Add a benchmarking setup for ML-DSA.
jadephilipoom Dec 12, 2025
8721a5e
[mldsa] Change max message lengths to 3kB.
jadephilipoom Dec 12, 2025
3f8d9bc
[mlkem] Randomly generate ML-KEM key generation tests.
jadephilipoom Dec 16, 2025
e329f9c
[mlkem] Generate ML-KEM encapsulation tests randomly.
jadephilipoom Dec 16, 2025
dba06ce
[mlkem] Generate ML-KEM decaps tests randomly.
jadephilipoom Dec 16, 2025
ac88321
[crypto] Fix PQC flag for ML-KEM and ML-DSA autogen tests
pqcfox Jan 15, 2026
3439faa
[mldsa,mlkem] Remove now-unused test data files.
jadephilipoom Jan 27, 2026
e939fe3
[mldsa,mlkem] Set the default number of tests to 3.
jadephilipoom Jan 27, 2026
b047e20
[lint] Fix linter errors.
jadephilipoom Jan 29, 2026
8ab5aa9
[mldsa] Fix a bug in poly_make_hint.
jadephilipoom Jan 26, 2026
9dfb840
[mldsa] Clean up comments and save a couple instructions in poly_make…
jadephilipoom Jan 29, 2026
a72c8b3
[mldsa] Add a regression test for poly_make_hint.
jadephilipoom Jan 29, 2026
2209734
[mldsa] Fix instruction alignment in poly_make_hint.
jadephilipoom Feb 5, 2026
8804a85
[License Headers] Standardized contribution headers for ML-KEM and ML…
apinise Jan 23, 2026
d9f3376
[otbnsim] Fixed otbn stall cycle count after stat collect changes
apinise Feb 4, 2026
222f321
[otbn, smoke] Added fusesoc core for pqc parameter to smoke test import
apinise Feb 5, 2026
cdf1787
[mypy, otbn] Fixed mypy linting errors for otbnsim python files
apinise Jan 23, 2026
b0879e4
[verible, rtl] Fixed verible lint warnings for rtl and dv
apinise Feb 6, 2026
23b1d6c
[verible, rtl] Tied off unused input ports in OTBN from PQC param
apinise Feb 10, 2026
0b55d28
[integration] Resolve issues with hjson dmem endianess in crypto tests
apinise Jan 23, 2026
36c3ff5
[tops] Regenerate top_darjeeling and top_earlgrey
apinise Jan 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion MODULE.bazel.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

146 changes: 146 additions & 0 deletions bench/analyze_stats.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#! /usr/bin/env python3
#
# Copyright zeroRISC Inc.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

import argparse
import pathlib
import re

CYCLES_PAT = re.compile(r'.*instructions in ([0-9]+) cycles.')
FILENAME_PAT = re.compile(r'(.*)_test[0-9]+.stats')


def parse_file_stats(file):
stats = {}
for line in file.readlines():
m = re.match(CYCLES_PAT, line)
if m:
stats['total_cycles'] = int(m.group(1))
if 'total_cycles' not in stats:
raise ValueError(f'Unable to find cycle count in file: {file.name}')
return stats


def parse_dir_stats(dirpath):
out = {}
for path in dirpath.iterdir():
with path.open() as f:
out[path.name] = parse_file_stats(f)
return out


def analyze_stats(file_stats):
ops = {}
for filename, stats in file_stats.items():
m = re.match(FILENAME_PAT, filename)
if not m:
raise ValueError(f'Unexpected file name format: {filename}')
op = m.group(1)
if op in ops:
assert all(k in ops[op] for k in stats)
assert all(k in stats for k in ops[op])
else:
ops[op] = {k: [] for k in stats}
for k, v in stats.items():
ops[op][k].append(v)

out = {}
for op, stats in ops.items():
total_cycles = stats['total_cycles']
count = len(total_cycles)
assert count != 0
out[op] = {}
out[op]['count'] = count
out[op]['avg_cycles'] = sum(total_cycles) // count
out[op]['min_cycles'] = min(total_cycles)
out[op]['max_cycles'] = max(total_cycles)
total_cycles.sort()
if count % 2:
median_cycles = total_cycles[count // 2]
else:
below = total_cycles[(count // 2) - 1]
above = total_cycles[(count // 2)]
median_cycles = (below + above) // 2
out[op]['median_cycles'] = median_cycles

return out


def pretty_print_table(rows, aligns):
if len(rows) == 0:
return None
ncols = len(rows[0])
assert len(aligns) == ncols
assert all([len(r) == ncols for r in rows])
assert all([x in ['l', 'r'] for x in aligns])
rows = [[str(x) for x in r] for r in rows]
col_widths = [max([len(r[i]) for r in rows]) for i in range(ncols)]
for r in rows:
line = ''
for i in range(ncols):
if aligns[i] == 'l':
line += r[i]
line += ' ' * (col_widths[i] - len(r[i]))
if aligns[i] == 'r':
line += r[i]
print(line)


def format_change(new, base, statname):
'''Represents change in benchmark values as a table row.'''
newval = new[statname]
baseval = base[statname]
diff = newval - baseval
sign = '' if diff < 0 else '+'
pct = (diff / baseval) * 100
return [baseval, ' -> ', newval, f' ({sign}{diff},', f'{sign}{pct:.02f}%)']


def compare_stats(stats1, stats2):
ops1 = set(stats1.keys())
ops2 = set(stats2.keys())
ops = ops1 & ops2
diff = (ops1 - ops) | (ops2 - ops)
if diff:
print(f'Warning: skipping operations that only appear in one dataset: {diff}')

for op in sorted(list(ops)):
print(f'--- {op} ---')
rows = []
rows.append(['Average cycles: '] + format_change(stats1[op], stats2[op], 'avg_cycles'))
rows.append(['Median cycles: '] + format_change(stats1[op], stats2[op], 'median_cycles'))
aligns = ['l', 'r', 'r', 'r', 'r', 'r']
pretty_print_table(rows, aligns)


def print_stats(stats):
for op in sorted(stats.keys()):
op_stats = stats[op]
print(f'--- {op} ({op_stats["count"]} tests) ---')
print('Average cycles:', op_stats['avg_cycles'])
print('Median cycles: ', op_stats['median_cycles'])
print('Minimum cycles:', op_stats['min_cycles'])
print('Maximum cycles:', op_stats['max_cycles'])


if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument(
'benchdir', type=pathlib.Path, help=('Directory with collected execution stats.'))
parser.add_argument(
'--compare', type=pathlib.Path, required=False,
help=('Second directory with collected execution stats, for comparison.'))
args = parser.parse_args()

files = parse_dir_stats(args.benchdir)
stats = analyze_stats(files)

if args.compare:
cfiles = parse_dir_stats(args.compare)
cstats = analyze_stats(cfiles)
print(f'Comparing {args.benchdir.name} against baseline {args.compare.name}.')
compare_stats(stats, cstats)
else:
print_stats(stats)
35 changes: 35 additions & 0 deletions bench/collect_stats.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/bash
#
# Copyright zeroRISC Inc.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

set -e

# Create the destination directory.
hash=$(git log --pretty=format:'%h' -n 1)
benchdir=$(dirname "$0")
mkdir -p $benchdir/$hash

# Freshly test all targets. If they are set to collect statistics, these will
# be gathered in the test logs.
bzlpath="$1"
echo "./bazelisk.sh test $bzlpath"
./bazelisk.sh test $bzlpath

# Collect the test logs for each target.
echo "Collecting logs for all otbn_autogen_sim_test targets..."
targets=$(./bazelisk.sh query "kind(otbn_autogen_sim_test, $bzlpath)")
for target in $targets
do
shortname=$(echo $target | cut -d ":" -f 2)
testdir=$(echo $target | cut -d ":" -f 1 | cut -c 2-)
logfile="bazel-testlogs/$testdir/$shortname/test.log"
statsfile="$benchdir/$hash/$shortname.stats"
if grep -q "cycles" $logfile; then
cp -f $logfile $statsfile
else
echo "Target $shortname does not appear to include execution statistics. Is the 'stats' parameter set in the otbn_autogen_sim_test rule?"
exit 1
fi
done
7 changes: 5 additions & 2 deletions hw/dv/sv/kmac_app_agent/kmac_app_intf.sv
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ interface kmac_app_intf (input clk, input rst_n);

assign kmac_data_req = (if_mode == dv_utils_pkg::Host) ?
{req_data_if.valid, hold, next, req_data_if.h_data} : 'z;
assign {req_data_if.valid, hold_tmp, next_tmp, req_data_if.h_data} = (if_mode == dv_utils_pkg::Device) ?
kmac_data_req : 'z;
assign {req_data_if.valid, hold_tmp, next_tmp, req_data_if.h_data} =
(if_mode == dv_utils_pkg::Device) ? kmac_data_req : 'z;

assign {req_data_if.ready, rsp_done, rsp_digest_share0, rsp_digest_share1, rsp_error} =
(if_mode == dv_utils_pkg::Host) ? kmac_data_rsp : 'z;
Expand Down Expand Up @@ -146,6 +146,9 @@ interface kmac_app_intf (input clk, input rst_n);
end
end
end
default: begin
// This case shouldn't be reachable
end
endcase
end

Expand Down
12 changes: 8 additions & 4 deletions hw/ip/kmac/dv/env/kmac_if.sv
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,20 @@ interface kmac_if(input clk_i, input rst_ni);
`ASSERT(KmacMaskingO_A, `EN_MASKING == en_masking_o)

`ASSERT(AppKeymgrErrOutputZeros_A, app_rsp[kmac_app_agent_pkg::AppKeymgr].error |->
app_rsp[kmac_app_agent_pkg::AppKeymgr].digest_share0 == 0 && app_rsp[kmac_app_agent_pkg::AppKeymgr].digest_share1 == 0)
app_rsp[kmac_app_agent_pkg::AppKeymgr].digest_share0 == 0 &&
app_rsp[kmac_app_agent_pkg::AppKeymgr].digest_share1 == 0)

`ASSERT(AppLcErrOutputZeros_A, app_rsp[kmac_app_agent_pkg::AppLc].error |->
app_rsp[kmac_app_agent_pkg::AppLc].digest_share0 == 0 && app_rsp[kmac_app_agent_pkg::AppLc].digest_share1 == 0)
app_rsp[kmac_app_agent_pkg::AppLc].digest_share0 == 0 &&
app_rsp[kmac_app_agent_pkg::AppLc].digest_share1 == 0)

`ASSERT(AppRomErrOutputZeros_A, app_rsp[kmac_app_agent_pkg::AppRom].error |->
app_rsp[kmac_app_agent_pkg::AppRom].digest_share0 == 0 && app_rsp[kmac_app_agent_pkg::AppRom].digest_share1 == 0)
app_rsp[kmac_app_agent_pkg::AppRom].digest_share0 == 0 &&
app_rsp[kmac_app_agent_pkg::AppRom].digest_share1 == 0)

`ASSERT(AppOtbnErrOutputZeros_A, app_rsp[kmac_app_agent_pkg::AppOtbn].error |->
app_rsp[kmac_app_agent_pkg::AppOtbn].digest_share0 == 0 && app_rsp[kmac_app_agent_pkg::AppOtbn].digest_share1 == 0)
app_rsp[kmac_app_agent_pkg::AppOtbn].digest_share0 == 0 &&
app_rsp[kmac_app_agent_pkg::AppOtbn].digest_share1 == 0)

// Assertions to check if hold is high outside of OTBN mode
`ASSERT(AppKeymgrHoldNever_A, !app_req[kmac_app_agent_pkg::AppKeymgr].hold)
Expand Down
7 changes: 4 additions & 3 deletions hw/ip/kmac/rtl/kmac.sv
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright lowRISC contributors (OpenTitan project).
// Modified by Authors of "Towards ML-KEM & ML-DSA on OpenTitan" (https://eprint.iacr.org/2024/1192)
// Copyright "Towards ML-KEM & ML-DSA on OpenTitan" Authors
// Copyright zeroRISC Inc.
// Modified by Authors of "Towards ML-KEM & ML-DSA on OpenTitan" (https://eprint.iacr.org/2024/1192).
// Copyright "Towards ML-KEM & ML-DSA on OpenTitan" Authors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
Expand Down Expand Up @@ -33,7 +33,8 @@ module kmac
// Accept SW message when idle and before receiving a START command. Useful for SCA only.
parameter bit SecIdleAcceptSwMsg = 1'b0,
parameter int unsigned NumAppIntf = 4,
parameter app_config_t AppCfg[NumAppIntf] = '{AppCfgKeyMgr, AppCfgLcCtrl, AppCfgRomCtrl, AppCfgOTBN},
parameter app_config_t AppCfg[NumAppIntf] = '{AppCfgKeyMgr, AppCfgLcCtrl,
AppCfgRomCtrl, AppCfgOTBN},

parameter lfsr_perm_t RndCnstLfsrPerm = RndCnstLfsrPermDefault,
parameter lfsr_seed_t RndCnstLfsrSeed = RndCnstLfsrSeedDefault,
Expand Down
Loading