Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
45 changes: 0 additions & 45 deletions META.sh

This file was deleted.

12 changes: 3 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,12 @@ build: func kat acvp wycheproof
test: run_kat run_func run_acvp run_wycheproof run_unit run_alloc run_rng_fail
$(Q)echo " Everything checks fine!"

# Detect available SHA256 command
SHA256SUM := $(shell command -v shasum >/dev/null 2>&1 && echo "shasum -a 256" || (command -v sha256sum >/dev/null 2>&1 && echo "sha256sum" || echo ""))
ifeq ($(SHA256SUM),)
$(error Neither 'shasum' nor 'sha256sum' found. Please install one of these tools.)
endif

run_kat_512: kat_512
set -o pipefail; $(W) $(MLKEM512_DIR)/bin/gen_KAT512 | $(SHA256SUM) | cut -d " " -f 1 | xargs ./META.sh ML-KEM-512 kat-sha256
EXEC_WRAPPER="$(EXEC_WRAPPER)" python3 test/src/kat_client.py --scheme 512
run_kat_768: kat_768
set -o pipefail; $(W) $(MLKEM768_DIR)/bin/gen_KAT768 | $(SHA256SUM) | cut -d " " -f 1 | xargs ./META.sh ML-KEM-768 kat-sha256
EXEC_WRAPPER="$(EXEC_WRAPPER)" python3 test/src/kat_client.py --scheme 768
run_kat_1024: kat_1024
set -o pipefail; $(W) $(MLKEM1024_DIR)/bin/gen_KAT1024 | $(SHA256SUM) | cut -d " " -f 1 | xargs ./META.sh ML-KEM-1024 kat-sha256
EXEC_WRAPPER="$(EXEC_WRAPPER)" python3 test/src/kat_client.py --scheme 1024
run_kat: run_kat_512 run_kat_768 run_kat_1024

run_func_512: func_512
Expand Down
31 changes: 28 additions & 3 deletions Makefile.Microsoft_nmake
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,40 @@ acvp_mlkem1024: $(OBJ_FILES_1024) $(MLKEM1024_BUILD_DIR)\test\acvp\acvp_mlkem.ob
@if NOT EXIST $(MLKEM1024_BUILD_DIR)\bin mkdir $(MLKEM1024_BUILD_DIR)\bin
$(CC) $(CFLAGS) /D MLK_CONFIG_PARAMETER_SET=1024 /Fe$(MLKEM1024_BUILD_DIR)\bin\acvp_mlkem1024 $** /link

# compile KAT generator for mlkem512
gen_KAT512: $(OBJ_FILES_512) $(MLKEM512_BUILD_DIR)\test\gen_KAT.obj $(BUILD_DIR)\randombytes\notrandombytes.obj
@if NOT EXIST $(MLKEM512_BUILD_DIR)\bin mkdir $(MLKEM512_BUILD_DIR)\bin
$(CC) $(CFLAGS) /D MLK_CONFIG_PARAMETER_SET=512 /Fe$(MLKEM512_BUILD_DIR)\bin\gen_KAT512 $** /link

# compile KAT generator for mlkem768
gen_KAT768: $(OBJ_FILES_768) $(MLKEM768_BUILD_DIR)\test\gen_KAT.obj $(BUILD_DIR)\randombytes\notrandombytes.obj
@if NOT EXIST $(MLKEM768_BUILD_DIR)\bin mkdir $(MLKEM768_BUILD_DIR)\bin
$(CC) $(CFLAGS) /D MLK_CONFIG_PARAMETER_SET=768 /Fe$(MLKEM768_BUILD_DIR)\bin\gen_KAT768 $** /link

# compile KAT generator for mlkem1024
gen_KAT1024: $(OBJ_FILES_1024) $(MLKEM1024_BUILD_DIR)\test\gen_KAT.obj $(BUILD_DIR)\randombytes\notrandombytes.obj
@if NOT EXIST $(MLKEM1024_BUILD_DIR)\bin mkdir $(MLKEM1024_BUILD_DIR)\bin
$(CC) $(CFLAGS) /D MLK_CONFIG_PARAMETER_SET=1024 /Fe$(MLKEM1024_BUILD_DIR)\bin\gen_KAT1024 $** /link

acvp: acvp_mlkem512 acvp_mlkem768 acvp_mlkem1024

gen_KAT: gen_KAT512 gen_KAT768 gen_KAT1024

run_kat: gen_KAT
python test/src/kat_client.py

run_acvp: acvp
python test/acvp/acvp_client.py

quickcheck: test_mlkem512 test_mlkem768 test_mlkem1024 run_acvp
run_func: test_mlkem512 test_mlkem768 test_mlkem1024
$(MLKEM512_BUILD_DIR)\bin\test_mlkem512.exe
$(MLKEM768_BUILD_DIR)\bin\test_mlkem768.exe
$(MLKEM1024_BUILD_DIR)\bin\test_mlkem1024.exe
$(MLKEM768_BUILD_DIR)\bin\test_mlkem768.exe
$(MLKEM1024_BUILD_DIR)\bin\test_mlkem1024.exe

test: run_func run_acvp run_kat
@echo Everything checks fine!

quickcheck: test

clean:
-DEL $(BUILD_DIR)
103 changes: 103 additions & 0 deletions test/src/kat_client.py
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a fan of introducing a second way of running KAT tests.

@hanno-becker, would it be an option to also migrate the other KAT tests to use a Python wrapper?

Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#!/usr/bin/env python3
# Copyright (c) The mlkem-native project authors
# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT

import hashlib
import os
import subprocess
import sys
import argparse
from pathlib import Path


# Check if we need to use a wrapper for execution (e.g. QEMU)
exec_prefix = os.environ.get("EXEC_WRAPPER", "")
exec_prefix = exec_prefix.split(" ") if exec_prefix != "" else []


def err(msg, **kwargs):
print(msg, file=sys.stderr, **kwargs)


def info(msg, **kwargs):
print(msg, **kwargs)


def read_meta_hashes():
hashes = {}
current_name = None
with open("META.yml") as f:
for line in f:
line = line.strip()
if line.startswith("- name:"):
current_name = line.split(":", 1)[1].strip()
elif line.startswith("kat-sha256:") and current_name:
hashes[current_name] = line.split(":", 1)[1].strip()
return hashes


def get_kat_binary(level):
suffix = ".exe" if sys.platform == "win32" else ""
return Path("test/build") / f"mlkem{level}" / "bin" / f"gen_KAT{level}{suffix}"


def run_kat_single(scheme_name, level, ref_hash):
binary = get_kat_binary(level)

if not binary.exists():
err(f"Binary not found: {binary}")
return False

cmd = exec_prefix + [str(binary)]
result = subprocess.run(cmd, capture_output=True)

if result.returncode != 0:
err("FAIL!")
err(f"{cmd} failed with error code {result.returncode}")
err(result.stderr.decode("utf-8", errors="replace"))
return False

computed = hashlib.sha256(result.stdout).hexdigest()

if computed == ref_hash:
info(f"META.yml {scheme_name} kat-sha256: OK")
return True
else:
err(f"META.yml {scheme_name} kat-sha256: FAIL ({ref_hash} != {computed})")
return False


def main():
parser = argparse.ArgumentParser()
parser.add_argument(
"--scheme",
choices=["512", "768", "1024"],
help="Run KAT for only one parameter set (default: all)",
)
args = parser.parse_args()

all_schemes = [("ML-KEM-512", 512), ("ML-KEM-768", 768), ("ML-KEM-1024", 1024)]
if args.scheme is not None:
schemes = [s for s in all_schemes if str(s[1]) == args.scheme]
else:
schemes = all_schemes

ref_hashes = read_meta_hashes()

failed = False
for scheme_name, level in schemes:
if scheme_name not in ref_hashes:
err(f"META.yml: no kat-sha256 entry for {scheme_name}")
failed = True
continue
if not run_kat_single(scheme_name, level, ref_hashes[scheme_name]):
failed = True

if failed:
sys.exit(1)

info("ALL GOOD!")


if __name__ == "__main__":
main()
Loading