diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..e89b249 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,21 @@ +name: "Tests" +on: + pull_request: + push: + +jobs: + tests: + name: tests + runs-on: ubuntu-latest + strategy: + fail-fast: false + steps: + - uses: actions/checkout@v4 + - uses: cachix/install-nix-action@v25 + with: + nix_path: nixpkgs=channel:nixos-unstable + #- uses: DeterminateSystems/magic-nix-cache-action@v3 + - run: nix-shell --run "echo Dependencies OK…" + #- run: nix-shell --run "make test" + #- run: nix-shell --run "make large-kat-test" + - run: nix-shell --run '${JASMINC} -slice ml_dsa_65_keygen -checksafety ml_dsa_65/ref/ml_dsa.jazz' diff --git a/Makefile b/Makefile index 6f4b285..c81a0b5 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,10 @@ -TOP = /home/efgh/repos/formosa-mldsa - PARAMETER_SET = 65 IMPLEMENTATION_TYPE = ref # -------------------------------------------------------------------- JASMINC ?= jasminc -JASMIN_COMMAND ?= $(JASMINC) $(JASMINC_FLAGS) $(INCLUDE) # -------------------------------------------------------------------- -IMPLEMENTATION = $(TOP)/ml_dsa_$(PARAMETER_SET)/$(IMPLEMENTATION_TYPE) +IMPLEMENTATION = ml_dsa_$(PARAMETER_SET)/$(IMPLEMENTATION_TYPE) IMPLEMENTATION_SOURCES = $(IMPLEMENTATION)/ml_dsa.jazz \ $(wildcard $(IMPLEMENTATION)/*.jinc) \ @@ -18,23 +15,29 @@ IMPLEMENTATION_SOURCES = $(IMPLEMENTATION)/ml_dsa.jazz \ OUTPUT_FILE_NAME = ml_dsa_$(PARAMETER_SET)_$(IMPLEMENTATION_TYPE) $(OUTPUT_FILE_NAME).s: $(IMPLEMENTATION_SOURCES) - $(JASMIN_COMMAND) -o $@ $< + $(JASMINC) -o $@ $< # -------------------------------------------------------------------- -.PHONY: test +.PHONY: test large-kat-test test: $(OUTPUT_FILE_NAME).so - cd test && \ - python3 nist_drbg_kat_tests.py && \ - python3 nist_acvp_tests.py && \ - python3 wycheproof_verify_tests.py && \ - python3 wycheproof_sign_tests.py + cd test && python3 nist_drbg_kat_tests.py && \ + python3 nist_acvp_tests.py && \ + python3 wycheproof_verify_tests.py && \ + python3 wycheproof_sign_tests.py + +.PHONY: large-kat-test +large-kat-test: $(OUTPUT_FILE_NAME).so + cd test && python3 large_kat_test.py $(OUTPUT_FILE_NAME).so: $(OUTPUT_FILE_NAME).s $(CC) $^ -fPIC -shared -o $@ # -------------------------------------------------------------------- ml_dsa_$(PARAMETER_SET)_$(IMPLEMENTATION_TYPE)_bench.o: $(OUTPUT_FILE_NAME).s bench/bench.c - $(CC) -DVERIFICATION_KEY_SIZE=1952 \ + $(CC) -DKEYGEN=ml_dsa_$(PARAMETER_SET)_keygen \ + -DSIGN=ml_dsa_$(PARAMETER_SET)_sign \ + -DVERIFY=ml_dsa_$(PARAMETER_SET)_verify \ + -DVERIFICATION_KEY_SIZE=1952 \ -DSIGNING_KEY_SIZE=4032 \ -DSIGNATURE_SIZE=3309 \ $^ -o $@ @@ -42,6 +45,5 @@ ml_dsa_$(PARAMETER_SET)_$(IMPLEMENTATION_TYPE)_bench.o: $(OUTPUT_FILE_NAME).s be # -------------------------------------------------------------------- .PHONY: clean clean: - rm -fr \ - $(TOP)/*.s \ - $(TOP)/*.so + rm -fr *.s \ + *.so diff --git a/bench/bench.c b/bench/bench.c index c536586..27c5576 100644 --- a/bench/bench.c +++ b/bench/bench.c @@ -8,12 +8,12 @@ #define DATA_POINTS 10000 -extern void ml_dsa_65_keygen(uint8_t *verification_key, uint8_t *signing_key, +extern void KEYGEN(uint8_t *verification_key, uint8_t *signing_key, const uint8_t key_generation_randomness[32]); -extern void ml_dsa_65_sign(uint8_t *signature, const uint8_t *signing_key, +extern void SIGN(uint8_t *signature, const uint8_t *signing_key, const uint8_t *message, const size_t message_size, const uint8_t randomness[32]); -extern void ml_dsa_65_verify(const uint8_t *verification_key, +extern void VERIFY(const uint8_t *verification_key, const uint8_t *message, const size_t message_size, const uint8_t signature[SIGNATURE_SIZE]); @@ -43,14 +43,14 @@ int main(void) { // Test key-generation. for (i = 0; i < DATA_POINTS; i++) { observations[i] = cpucycles(); - ml_dsa_65_keygen(verification_key, signing_key, key_generation_randomness); + KEYGEN(verification_key, signing_key, key_generation_randomness); } print_results("--- Key Generation ---", observations, DATA_POINTS); // Test signing. for (i = 0; i < DATA_POINTS; i++) { observations[i] = cpucycles(); - ml_dsa_65_sign(signature, signing_key, message, sizeof(message), + SIGN(signature, signing_key, message, sizeof(message), signing_randomness); } print_results("--- Signing ---", observations, DATA_POINTS); @@ -58,7 +58,7 @@ int main(void) { // Test verification. for (i = 0; i < DATA_POINTS; i++) { observations[i] = cpucycles(); - ml_dsa_65_verify(verification_key, message, sizeof(message), signature); + VERIFY(verification_key, message, sizeof(message), signature); } print_results("--- Verification ---", observations, DATA_POINTS); diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..d659dc7 --- /dev/null +++ b/shell.nix @@ -0,0 +1,11 @@ +let + pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/6dbbd5a2622d9abf9263a5cb0a85ca218974b085.tar.gz") {}; +in pkgs.mkShell { + packages = [ + (pkgs.python3.withPackages (python-pkgs: with python-pkgs; [ + pycryptodome + ])) + ]; + JASMINC = "${pkgs.jasmin-compiler.bin}/bin/jasminc"; + JASMIN_CT = "${pkgs.jasmin-compiler.bin}/bin/jazzct"; +} diff --git a/test/large_kat_test.py b/test/large_kat_test.py index b2a255c..f0dc721 100644 --- a/test/large_kat_test.py +++ b/test/large_kat_test.py @@ -1,7 +1,6 @@ from ml_dsa import ML_DSA import json from Crypto.Hash import SHAKE128 -from tqdm import tqdm ml_dsa_65 = ML_DSA("ml_dsa_65_ref") @@ -20,7 +19,7 @@ def read(self, length): rng = RNG() kat_hasher = SHAKE128.new() -for i in tqdm(range(KAT_ITERATIONS)): +for i in range(KAT_ITERATIONS): key_generation_seed = bytearray(rng.read(32)) (verification_key, signing_key) = ml_dsa_65.generate_keypair(key_generation_seed) diff --git a/test/nist_drbg_kat_tests.py b/test/nist_drbg_kat_tests.py index a7a128e..d58a6eb 100644 --- a/test/nist_drbg_kat_tests.py +++ b/test/nist_drbg_kat_tests.py @@ -1,14 +1,13 @@ from ml_dsa import ML_DSA import json import hashlib -from tqdm import tqdm ml_dsa_65 = ML_DSA("ml_dsa_65_ref") with open("nist_drbg_kats/nist_drbg_kats_65.json", "r") as nistkats_65_raw: nistkats_65 = json.load(nistkats_65_raw) - for kat in tqdm(nistkats_65): + for kat in nistkats_65: # Test key generation. key_generation_seed = bytearray.fromhex(kat["key_generation_seed"]) (verification_key, signing_key) = ml_dsa_65.generate_keypair(