Skip to content

Commit aec746a

Browse files
committed
ACVP: Remove submodule and remove ACVP testvectors transparently
This commit removes the ACVP server submodule and extend the acvp_client.py to automatically download the required files to test/.acvp-data. While at it, we add a argument specifing the ACVP version and extend the CI to run both the latest version (v1.0.0.40) and the previous version (v1.0.0.39). Signed-off-by: Matthias J. Kannwischer <[email protected]>
1 parent bb72042 commit aec746a

File tree

6 files changed

+66
-19
lines changed

6 files changed

+66
-19
lines changed

.github/workflows/base.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,18 @@ jobs:
2525
name: 'macos (aarch64)'
2626
- runner: macos-13
2727
name: 'macos (x86_64)'
28+
acvp-version: [v1.1.0.40, v1.1.0.39]
2829
exclude:
2930
- {external: true,
3031
target: {
3132
runner: pqcp-arm64,
3233
name: 'aarch64'
3334
}}
34-
name: Quickcheck (${{ matrix.target.name }})
35+
name: Quickcheck (${{ matrix.target.name }}, ACVP ${{ matrix.acvp-version }})
3536
runs-on: ${{ matrix.target.runner }}
3637
steps:
3738
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
38-
with:
39-
submodules: true
40-
- name: make test
39+
- name: Run ACVP test
4140
run: |
42-
make test
41+
make
42+
python3 test/acvp_client.py --version ${{ matrix.acvp-version }}

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,5 @@ modules.order
6363
Module.symvers
6464
Mkfile.old
6565
dkms.conf
66+
# Downloaded ACVP test data
67+
test/.acvp-data/

.gitmodules

Lines changed: 0 additions & 3 deletions
This file was deleted.

test/ACVP-Server

Lines changed: 0 additions & 1 deletion
This file was deleted.

test/Makefile

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,6 @@ new_param.csv: $(XCOUNT) test_param.py new_param.txt
2626
./$(XCOUNT) | tee /dev/tty | sort >> $@
2727
python3 test_param.py | parallel | tee /dev/tty | sort >> $@
2828

29-
ACVP-Server/gen-val/json-files:
30-
git submodule update --init ACVP-Server
31-
3229
clean:
3330
$(RM) -rf $(XCOUNT) $(OBJS) *.log
3431
$(RM) -f *.pyc *.cprof */*.pyc *.rsp *.log

test/acvp_client.py

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,55 @@
99
import os
1010
import subprocess
1111
import sys
12+
import urllib.request
1213
from concurrent.futures import ThreadPoolExecutor, as_completed
13-
14-
# === JSON parsing functions ===
14+
from pathlib import Path
15+
16+
# === ACVP file downloading ===
17+
18+
def download_acvp_files(version="v1.1.0.40"):
19+
"""Download ACVP test files for the specified version if not present."""
20+
base_url = f"https://raw.githubusercontent.com/usnistgov/ACVP-Server/{version}/gen-val/json-files"
21+
22+
# Files we need to download
23+
files_to_download = [
24+
"SLH-DSA-keyGen-FIPS205/prompt.json",
25+
"SLH-DSA-keyGen-FIPS205/expectedResults.json",
26+
"SLH-DSA-sigGen-FIPS205/prompt.json",
27+
"SLH-DSA-sigGen-FIPS205/expectedResults.json",
28+
"SLH-DSA-sigVer-FIPS205/prompt.json",
29+
"SLH-DSA-sigVer-FIPS205/expectedResults.json",
30+
"SLH-DSA-sigVer-FIPS205/internalProjection.json"
31+
]
32+
33+
# Create directory structure
34+
data_dir = Path(f"test/.acvp-data/{version}/files")
35+
data_dir.mkdir(parents=True, exist_ok=True)
36+
37+
for file_path in files_to_download:
38+
local_file = data_dir / file_path
39+
local_file.parent.mkdir(parents=True, exist_ok=True)
40+
41+
if not local_file.exists():
42+
url = f"{base_url}/{file_path}"
43+
print(f"Downloading {file_path}...", file=sys.stderr)
44+
try:
45+
urllib.request.urlretrieve(url, local_file)
46+
# Verify the file is valid JSON
47+
with open(local_file, 'r') as f:
48+
json.load(f)
49+
except json.JSONDecodeError as e:
50+
print(f"Error: Downloaded file {file_path} is not valid JSON: {e}", file=sys.stderr)
51+
local_file.unlink(missing_ok=True) # Remove corrupted file
52+
return False
53+
except Exception as e:
54+
print(f"Error downloading {file_path}: {e}", file=sys.stderr)
55+
local_file.unlink(missing_ok=True) # Remove partial file
56+
return False
57+
58+
return True
59+
60+
# === JSON parsing functions ===
1561

1662
def slhdsa_load_keygen(req_fn, res_fn):
1763
with open(req_fn) as f:
@@ -170,15 +216,22 @@ def build_command(x):
170216

171217
def main():
172218
parser = argparse.ArgumentParser(description="SLH-DSA ACVP test runner")
173-
parser.add_argument("--jobs", "-j", type=int, default=os.cpu_count() or 4,
219+
parser.add_argument("--jobs", "-j", type=int, default=os.cpu_count() or 4,
174220
help="Number of parallel jobs (default: auto-detect CPU cores)")
221+
parser.add_argument("--version", "-v", default="v1.1.0.40",
222+
help="ACVP test vector version (default: v1.1.0.40)")
175223

176224
args = parser.parse_args()
177225

178-
print("Generating test commands from ACVP JSON files...", file=sys.stderr)
226+
print(f"Using ACVP test vectors version {args.version}", file=sys.stderr)
227+
228+
# Download files if needed
229+
if not download_acvp_files(args.version):
230+
print("Failed to download ACVP test files", file=sys.stderr)
231+
return 1
179232

180233
try:
181-
json_path = 'test/ACVP-Server/gen-val/json-files/'
234+
json_path = f"test/.acvp-data/{args.version}/files/"
182235

183236
keygen_kat = slhdsa_load_keygen(
184237
json_path + 'SLH-DSA-keyGen-FIPS205/prompt.json',
@@ -194,8 +247,7 @@ def main():
194247
json_path + 'SLH-DSA-sigVer-FIPS205/internalProjection.json')
195248

196249
except FileNotFoundError as e:
197-
print(f"Error: Could not find ACVP JSON files. Make sure submodule is initialized.", file=sys.stderr)
198-
print(f"Run: git submodule update --init --recursive", file=sys.stderr)
250+
print(f"Error: Could not find ACVP JSON files: {e}", file=sys.stderr)
199251
return 1
200252

201253
total_tests = len(keygen_kat) + len(siggen_kat) + len(sigver_kat)

0 commit comments

Comments
 (0)