diff --git a/.github/workflows/ct.yml b/.github/workflows/ct.yml index f71d25fa..2b03ed9b 100644 --- a/.github/workflows/ct.yml +++ b/.github/workflows/ct.yml @@ -18,4 +18,4 @@ jobs: nix_path: nixpkgs=channel:nixos-unstable - uses: DeterminateSystems/magic-nix-cache-action@v3 - run: nix-shell --arg full false --run "echo Dependencies OK…" - - run: nix-shell --arg full false --run "make -C code/jasmin/mlkem_${{matrix.dir}}/ ct" + - run: nix-shell --arg full false --run "make -C code/jasmin/mlkem_${{matrix.dir}}/ check-constant-time" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..b23450f5 --- /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 + matrix: + dir: [ 'ref', 'avx2' ] + 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 --arg full false --run "echo Dependencies OK…" + - run: nix-shell --arg full false --run "make -C code/jasmin/mlkem_${{matrix.dir}}/ run-tests" diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..5761abcf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.o diff --git a/Makefile b/Makefile index 71fd1aad..b36e18c1 100644 --- a/Makefile +++ b/Makefile @@ -5,18 +5,40 @@ ECCONF := config/tests.config CHECKS ?= mlkem # -------------------------------------------------------------------- -.PHONY: default check checkec jasmin clean_eco +.PHONY: default check checkec jasmin clean_eco test bench default: check check: jasmin checkec jasmin: - make -C code/jasmin/mlkem_ref/extraction - make -C code/jasmin/mlkem_avx2/extraction + $(MAKE) -C code/jasmin/mlkem_ref/extraction + $(MAKE) -C code/jasmin/mlkem_avx2/extraction checkec: easycrypt runtest $(ECCONF) $(CHECKS) clean_eco: find proof -name '*.eco' -exec rm '{}' ';' + +test: + $(MAKE) -C code/jasmin/mlkem_ref/ -j$(nproc) compile-tests + $(MAKE) -C code/jasmin/mlkem_avx2/ -j$(nproc) compile-tests + @echo "\n\n### Testing the reference implementation" + $(MAKE) -C code/jasmin/mlkem_ref/ run-tests + @echo "\n\n### Testing the avx2 implementation" + $(MAKE) -C code/jasmin/mlkem_avx2/ run-tests + +bench: + $(MAKE) -C code/jasmin/mlkem_ref/ -j$(nproc) compile-speed + $(MAKE) -C code/jasmin/mlkem_avx2/ -j$(nproc) compile-speed + @echo "\n\n### Benchmarking the reference implementation" + $(MAKE) -C code/jasmin/mlkem_ref/ run-speed + @echo "\n\n### Benchmarking the avx2 implementation" + $(MAKE) -C code/jasmin/mlkem_avx2/ run-speed + +example: + $(MAKE) -C code/jasmin/mlkem_ref/example + $(MAKE) -C code/jasmin/mlkem_avx2/example + + diff --git a/code/Makefile.conf b/code/Makefile.conf index c9c59546..c9fa6822 100644 --- a/code/Makefile.conf +++ b/code/Makefile.conf @@ -1,8 +1,9 @@ # -*- Makefile -*- # -------------------------------------------------------------------- -current_dir := $(dir $(realpath $(lastword $(MAKEFILE_LIST)))) +CURRENT_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST)))) +PROJECT_DIR := $(abspath $(CURRENT_DIR)/../) # -------------------------------------------------------------------- -JASMINC ?= $(current_dir)/../jasmin/compiler/jasminc -JAZZCT ?= $(current_dir)/../jasmin/compiler/jazzct +JASMINC ?= $(abspath $(PROJECT_DIR)/jasmin/compiler/jasminc) +JASMIN_CT ?= $(abspath $(PROJECT_DIR)/jasmin/compiler/jasmin-ct) diff --git a/code/jasmin/mlkem_avx2/.gitignore b/code/jasmin/mlkem_avx2/.gitignore new file mode 100644 index 00000000..cfa7440f --- /dev/null +++ b/code/jasmin/mlkem_avx2/.gitignore @@ -0,0 +1,36 @@ +jfips202.s +jindcpa.s +jkem.s +jpoly.s +jpolyvec.s +jspeed.s +test/test_fips202 +test/test_indcpa +test/test_kem +test/test_poly_add2 +test/test_poly_basemul +test/test_poly_compress +test/test_poly_csubq +test/test_poly_decompress +test/test_poly_frombytes +test/test_poly_frommont +test/test_poly_frommsg +test/test_poly_getnoise +test/test_poly_invntt +test/test_poly_ntt +test/test_poly_reduce +test/test_poly_sub +test/test_poly_tobytes +test/test_poly_tomsg +test/test_polyvec_add2 +test/test_polyvec_compress +test/test_polyvec_csubq +test/test_polyvec_decompress +test/test_polyvec_frombytes +test/test_polyvec_invntt +test/test_polyvec_ntt +test/test_polyvec_pointwise_acc +test/test_polyvec_reduce +test/test_polyvec_tobytes +test/speed_indcpa +test/speed_mlkem diff --git a/code/jasmin/mlkem_avx2/Makefile b/code/jasmin/mlkem_avx2/Makefile index 4a3a7f3e..533bda5f 100644 --- a/code/jasmin/mlkem_avx2/Makefile +++ b/code/jasmin/mlkem_avx2/Makefile @@ -1,143 +1,192 @@ # -*- Makefile -*- - -include ../../Makefile.conf CC ?= /usr/bin/gcc GFLAGS ?= -CFLAGS := -Wall -Wextra -g -Ofast -fomit-frame-pointer +CFLAGS := -Wall -Wextra -g -O3 -fomit-frame-pointer JFLAGS := ${JADDFLAGS} OS := $(shell uname -s) -.SECONDARY: jpoly.s jpolyvec.s jfips202.s jindcpa.s jindcpa.o jkem.s - -default: test speed - -test: test/test_poly_compress \ - test/test_poly_decompress \ - test/test_poly_tobytes \ - test/test_poly_frombytes \ - test/test_poly_tomsg \ - test/test_poly_frommsg \ - test/test_poly_add2 \ - test/test_poly_sub \ - test/test_poly_ntt \ - test/test_poly_invntt \ - test/test_poly_basemul \ - test/test_poly_frommont \ - test/test_poly_reduce \ - test/test_poly_csubq \ - test/test_poly_getnoise \ - test/test_polyvec_compress\ - test/test_polyvec_decompress\ - test/test_polyvec_tobytes \ - test/test_polyvec_frombytes \ - test/test_polyvec_add2 \ - test/test_polyvec_ntt \ - test/test_polyvec_invntt \ - test/test_polyvec_pointwise_acc \ - test/test_polyvec_reduce\ - test/test_polyvec_csubq \ - test/test_fips202 \ - test/test_indcpa \ - test/test_kem - -speed: test/speed_indcpa \ - test/speed_mlkem - -HEADERS = params.h poly.h fips202.h ntt.h indcpa.h kem.h \ - -JHEADERS = params.jinc \ - reduce.jinc \ - fips202_common.jinc \ - fips202.jinc \ - fips202_4x.jinc \ - keccakf1600.jinc \ - consts.jinc \ - shuffle.jinc \ - indcpa.jinc \ - verify.jinc - -POLYHEADERS = poly.jinc \ - consts.jinc \ - -POLYVECHEADERS = polyvec.jinc \ - gen_matrix.jinc \ - -INCS = fq.inc shuffle.inc -SOURCES = poly.c polyvec.c cbd.c fips202.c ntt.c reduce.c symmetric-fips202.c indcpa.c kem.c consts.c shuffle.S fq.S\ - -test/test_indcpa: test/test_indcpa.c $(HEADERS) $(SOURCES) $(INCS) jindcpa.o - $(CC) $(CFLAGS) -o $@ $(SOURCES) jindcpa.o $< - -test/test_kem: test/test_kem.c $(HEADERS) $(SOURCES) $(INCS) jkem.o - $(CC) $(CFLAGS) -o $@ $(SOURCES) jkem.o ~/Desktop/Repos/jasmin/compiler/syscall/jasmin_syscall.o $< - -test/speed_indcpa: test/speed_indcpa.c $(HEADERS) $(SOURCES) $(INCS) jindcpa.o - $(CC) $(CFLAGS) -o $@ $(SOURCES) jindcpa.o $< - -test/speed_mlkem: test/speed_mlkem.c $(HEADERS) $(SOURCES) $(INCS) jspeed.s - $(CC) $(CFLAGS) -o $@ $(SOURCES) jspeed.s $< - -test/test_fips202: test/test_fips202.c $(HEADERS) fips202.c jfips202.s - $(CC) $(CFLAGS) -o $@ fips202.c jfips202.s $< - -test/test_gen_matrix: test/test_gen_matrix.c $(HEADERS) gen_matrix.s - $(CC) $(CFLAGS) -o $@ gen_matrix.s $< - -test/test_poly_%: test/test_poly_%.c $(HEADERS) $(SOURCES) $(INCS) jpoly.s - $(CC) $(CFLAGS) -o $@ $(SOURCES) jpoly.s $< - -test/test_polyvec_%: test/test_polyvec_%.c $(HEADERS) $(SOURCES) $(INCS) jpolyvec.s - $(CC) $(CFLAGS) -o $@ $(SOURCES) jpolyvec.s $< - +default: run-tests run-speed + +# -- +TESTS_POLY := \ + test/test_poly_compress \ + test/test_poly_decompress \ + test/test_poly_tobytes \ + test/test_poly_frombytes \ + test/test_poly_tomsg \ + test/test_poly_frommsg \ + test/test_poly_add2 \ + test/test_poly_sub \ + test/test_poly_ntt \ + test/test_poly_invntt \ + test/test_poly_basemul \ + test/test_poly_frommont \ + test/test_poly_reduce \ + test/test_poly_csubq \ + test/test_poly_getnoise + +TESTS_POLYVEC := \ + test/test_polyvec_compress\ + test/test_polyvec_decompress\ + test/test_polyvec_tobytes \ + test/test_polyvec_frombytes \ + test/test_polyvec_add2 \ + test/test_polyvec_ntt \ + test/test_polyvec_invntt \ + test/test_polyvec_pointwise_acc \ + test/test_polyvec_reduce\ + test/test_polyvec_csubq + +TESTS := \ + $(TESTS_POLY) \ + $(TESTS_POLYVEC) \ + test/test_fips202 \ + test/test_indcpa \ + test/test_kem + +test: $(TESTS) + +speed: test/speed_mlkem + +# -- + +HEADERS := \ + params.h \ + poly.h \ + fips202.h \ + ntt.h \ + indcpa.h \ + kem.h + +C_SOURCES := \ + poly.c \ + polyvec.c \ + cbd.c \ + fips202.c \ + ntt.c \ + reduce.c \ + symmetric-fips202.c \ + indcpa.c \ + kem.c \ + consts.c \ + shuffle.S \ + fq.S + +JHEADERS := \ + params.jinc \ + reduce.jinc \ + fips202_common.jinc \ + fips202.jinc \ + fips202_4x.jinc \ + keccakf1600.jinc \ + consts.jinc \ + shuffle.jinc \ + indcpa.jinc \ + verify.jinc + +POLYHEADERS := \ + poly.jinc \ + consts.jinc + +POLYVECHEADERS := \ + polyvec.jinc \ + gen_matrix.jinc + +S_INC := \ + fq.inc \ + shuffle.inc + +# -- + +# -- + +JASMIN_SOURCES := \ + jpoly.jazz \ + jpolyvec.jazz \ + jfips202.jazz \ + jindcpa.jazz \ + jkem.jazz \ + jspeed.jazz + +JASMIN_ASSEMBLY := $(JASMIN_SOURCES:%.jazz=%.s) + +# - + +RANDOMBYTES := $(PROJECT_DIR)/ext/randombytes/jasmin_syscall.o + +$(RANDOMBYTES): $(PROJECT_DIR)/ext/randombytes/jasmin_syscall.c $(PROJECT_DIR)/ext/randombytes/jasmin_syscall.h + $(MAKE) -C $(@D) + +$(JASMIN_ASSEMBLY): %.s: %.jazz - $(JASMINC) -o $@ $(JFLAGS) $^ + $(JASMINC) -nowarning -o $@ $(JFLAGS) $^ + +#-- + +compile-tests-poly: $(TESTS_POLY) +$(TESTS_POLY): +test/test_poly_%: test/test_poly_%.c $(HEADERS) $(C_SOURCES) $(S_INC) jpoly.s + $(CC) $(CFLAGS) -o $@ $(C_SOURCES) jpoly.s $< + +compile-tests-polyvec: $(TESTS_POLYVEC) +$(TESTS_POLYVEC): +test/test_polyvec_%: test/test_polyvec_%.c $(HEADERS) $(C_SOURCES) $(S_INC) jpolyvec.s + $(CC) $(CFLAGS) -o $@ $(C_SOURCES) jpolyvec.s $< + +test/test_fips202: test/test_fips202.c $(HEADERS) $(C_SOURCES) jfips202.s + $(CC) $(CFLAGS) -o $@ $(C_SOURCES) jfips202.s $< + +test/test_indcpa: test/test_indcpa.c $(HEADERS) $(C_SOURCES) $(S_INC) jindcpa.s + $(CC) $(CFLAGS) -o $@ $(C_SOURCES) jindcpa.s $< + +test/test_kem: test/test_kem.c $(HEADERS) $(C_SOURCES) $(S_INC) $(RANDOMBYTES) jkem.s + $(CC) $(CFLAGS) -o $@ $(C_SOURCES) $(RANDOMBYTES) jkem.s $< + +compile-tests: test + +# -- +# note: to improve speed, remove for loop and define *.out targets + +run-tests-poly: compile-tests-poly + for i in $(TESTS_POLY); do ./$$i; done + +run-tests-polyvec: compile-tests-polyvec + for i in $(TESTS_POLYVEC); do ./$$i; done + +run-tests: compile-tests + @for i in $(TESTS); do ./$$i; done + +# -- + +test/speed_mlkem: test/speed_mlkem.c $(HEADERS) $(C_SOURCES) $(S_INC) $(RANDOMBYTES) jspeed.s + $(CC) $(CFLAGS) -o $@ $(C_SOURCES) $(RANDOMBYTES) jspeed.s $< + +compile-speed: test/speed_mlkem + +run-speed: compile-speed + ./test/speed_mlkem + +# -- + +.PHONY: check-constant-time + +check-constant-time: + $(JASMIN_CT) --infer jkem.jazz -.PHONY: ct clean +# -- -ct: - $(JAZZCT) --infer jkem.jazz +.PHONY: clean clean: - -rm -f *.o - -rm -f gen_matrix.s - -rm -f jindcpa.s - -rm -f jkem.s - -rm -f jfips202.s - -rm -f jpoly.s - -rm -f jpolyvec.s - -rm -f jspeed.s - -rm -f test/test_poly_compress - -rm -f test/test_poly_decompress - -rm -f test/test_poly_tobytes - -rm -f test/test_poly_frombytes - -rm -f test/test_poly_tomsg - -rm -f test/test_poly_frommsg - -rm -f test/test_poly_add2 - -rm -f test/test_poly_sub - -rm -f test/test_poly_ntt - -rm -f test/test_poly_invntt - -rm -f test/test_poly_basemul - -rm -f test/test_poly_frommont - -rm -f test/test_poly_reduce - -rm -f test/test_poly_csubq - -rm -f test/test_poly_getnoise - -rm -f test/test_polyvec_compress - -rm -f test/test_polyvec_decompress - -rm -f test/test_polyvec_tobytes - -rm -f test/test_polyvec_frombytes - -rm -f test/test_polyvec_add2 - -rm -f test/test_polyvec_ntt - -rm -f test/test_polyvec_invntt - -rm -f test/test_polyvec_pointwise_acc - -rm -f test/test_polyvec_reduce - -rm -f test/test_polyvec_csubq + -rm -f $(JASMIN_ASSEMBLY) + -rm -f $(TESTS_POLY) + -rm -f $(TESTS_POLYVEC) -rm -f test/test_fips202 - -rm -f test/test_gen_matrix -rm -f test/test_indcpa -rm -f test/test_kem - -rm -f test/speed_indcpa -rm -f test/speed_mlkem ifeq ($(OS),Darwin) -rm -r -f test/*.dSYM diff --git a/code/jasmin/mlkem_avx2/cycles.jinc b/code/jasmin/mlkem_avx2/cycles.jinc new file mode 100644 index 00000000..bcdf5f10 --- /dev/null +++ b/code/jasmin/mlkem_avx2/cycles.jinc @@ -0,0 +1,23 @@ +inline fn tsc() -> stack u32[2] +{ + reg u64 l h; + stack u32[2] t; + + h, l = #RDTSC(); + + t[0] = (32u) l; + t[1] = (32u) h; + + return t; +} + +inline fn cycles(stack u32[2] start end) -> reg u64 +{ + reg u64 t; + + t = end[u64 0]; + t -= start[u64 0]; + + return t; +} + diff --git a/code/jasmin/mlkem_avx2/example/.gitignore b/code/jasmin/mlkem_avx2/example/.gitignore new file mode 100644 index 00000000..7ff73178 --- /dev/null +++ b/code/jasmin/mlkem_avx2/example/.gitignore @@ -0,0 +1,2 @@ +example +jkem.s diff --git a/code/jasmin/mlkem_avx2/example/Makefile b/code/jasmin/mlkem_avx2/example/Makefile new file mode 100644 index 00000000..011e0ef7 --- /dev/null +++ b/code/jasmin/mlkem_avx2/example/Makefile @@ -0,0 +1,35 @@ +include ../../../Makefile.conf + +CC ?= /usr/bin/gcc +CFLAGS := -Wall -Wextra -g -O3 -fomit-frame-pointer + +default: run-example + +RANDOMBYTES := $(PROJECT_DIR)/ext/randombytes/jasmin_syscall.o +$(RANDOMBYTES): $(PROJECT_DIR)/ext/randombytes/jasmin_syscall.c $(PROJECT_DIR)/ext/randombytes/jasmin_syscall.h + $(MAKE) -C $(@D) + +.PHONY: ../jkem.s +../jkem.s: + $(MAKE) -C $(@D) $(@F) + +jkem.s: ../jkem.s + cp $< $@ + + +example: example.c jkem.s api.h $(RANDOMBYTES) + $(CC) $(CFLAGS) -o $@ example.c jkem.s $(RANDOMBYTES) + +run-example: example + ./example + + + +.PHONY: clean distclean +clean: + rm -f example jkem.s + +distclean: clean + rm -f ../jkem.s + $(MAKE) -C $(dir $(RANDOMBYTES)) clean + diff --git a/code/jasmin/mlkem_avx2/example/api.h b/code/jasmin/mlkem_avx2/example/api.h new file mode 100644 index 00000000..7e9a8b82 --- /dev/null +++ b/code/jasmin/mlkem_avx2/example/api.h @@ -0,0 +1,47 @@ +#ifndef JADE_KEM_mlkem_mlkem768_amd64_avx2_API_H +#define JADE_KEM_mlkem_mlkem768_amd64_avx2_API_H + +#include + +#define JADE_KEM_mlkem_mlkem768_amd64_avx2_SECRETKEYBYTES 2400 +#define JADE_KEM_mlkem_mlkem768_amd64_avx2_PUBLICKEYBYTES 1184 +#define JADE_KEM_mlkem_mlkem768_amd64_avx2_CIPHERTEXTBYTES 1088 +#define JADE_KEM_mlkem_mlkem768_amd64_avx2_KEYPAIRCOINBYTES 64 +#define JADE_KEM_mlkem_mlkem768_amd64_avx2_ENCCOINBYTES 32 +#define JADE_KEM_mlkem_mlkem768_amd64_avx2_BYTES 32 + +#define JADE_KEM_mlkem_mlkem768_amd64_avx2_ALGNAME "mlkem768" +#define JADE_KEM_mlkem_mlkem768_amd64_avx2_ARCH "amd64" +#define JADE_KEM_mlkem_mlkem768_amd64_avx2_IMPL "avx2" + +int jade_kem_mlkem_mlkem768_amd64_avx2_keypair_derand( + uint8_t *public_key, + uint8_t *secret_key, + const uint8_t *coins +); + +int jade_kem_mlkem_mlkem768_amd64_avx2_keypair( + uint8_t *public_key, + uint8_t *secret_key +); + +int jade_kem_mlkem_mlkem768_amd64_avx2_enc_derand( + uint8_t *ciphertext, + uint8_t *shared_secret, + const uint8_t *public_key, + const uint8_t *coins +); + +int jade_kem_mlkem_mlkem768_amd64_avx2_enc( + uint8_t *ciphertext, + uint8_t *shared_secret, + const uint8_t *public_key +); + +int jade_kem_mlkem_mlkem768_amd64_avx2_dec( + uint8_t *shared_secret, + const uint8_t *ciphertext, + const uint8_t *secret_key +); + +#endif diff --git a/code/jasmin/mlkem_avx2/example/example.c b/code/jasmin/mlkem_avx2/example/example.c new file mode 100644 index 00000000..d88c8fd3 --- /dev/null +++ b/code/jasmin/mlkem_avx2/example/example.c @@ -0,0 +1,139 @@ +#include +#include +#include +#include +#include + +#include "api.h" + +// print functions +static void print_info(const char *algname, const char *arch, const char *impl) +{ + printf("// {\"%s\" : { architecture : \"%s\", implementation : \"%s\"} }", + algname, arch, impl); + printf("\n"); +} + +static void print_u8(const uint8_t *a, size_t l) +{ + size_t i; + + if(l == 0) + { return; } + + printf("{\n "); + for(i=0; i<(l-1); i++) + { printf("0x%02" PRIx8 ", ", a[i]); + if((i+1)%16 == 0) + { printf("\n "); } + } + + printf("0x%02" PRIx8 "\n};\n", a[i]); + return; +} + +static void print_str_u8(const char *str, const uint8_t *a, size_t l) +{ + if( l == 0 ) + { printf("uint8_t *%s = NULL;\n", str); + return; + } + + printf("uint8_t %s[%zu] = ",str, l); + print_u8(a, l); +} + +// randombytes implementation, in this case we use the __jasmin_syscall_randombytes__ +extern uint8_t* __jasmin_syscall_randombytes__(uint8_t* x, uint64_t xlen); + +uint8_t* randombytes(uint8_t* x, uint64_t xlen) +{ + return __jasmin_syscall_randombytes__(x, xlen); +} + +// mapping the fully namespaced macros from api.h into shorter names +#define JADE_KEM_SECRETKEYBYTES JADE_KEM_mlkem_mlkem768_amd64_avx2_SECRETKEYBYTES +#define JADE_KEM_PUBLICKEYBYTES JADE_KEM_mlkem_mlkem768_amd64_avx2_PUBLICKEYBYTES +#define JADE_KEM_CIPHERTEXTBYTES JADE_KEM_mlkem_mlkem768_amd64_avx2_CIPHERTEXTBYTES +#define JADE_KEM_KEYPAIRCOINBYTES JADE_KEM_mlkem_mlkem768_amd64_avx2_KEYPAIRCOINBYTES +#define JADE_KEM_ENCCOINBYTES JADE_KEM_mlkem_mlkem768_amd64_avx2_ENCCOINBYTES +#define JADE_KEM_BYTES JADE_KEM_mlkem_mlkem768_amd64_avx2_BYTES + +#define jade_kem_keypair jade_kem_mlkem_mlkem768_amd64_avx2_keypair +#define jade_kem_enc jade_kem_mlkem_mlkem768_amd64_avx2_enc +#define jade_kem_dec jade_kem_mlkem_mlkem768_amd64_avx2_dec + +#define jade_kem_keypair_derand jade_kem_mlkem_mlkem768_amd64_avx2_keypair_derand +#define jade_kem_enc_derand jade_kem_mlkem_mlkem768_amd64_avx2_enc_derand + +#define JADE_KEM_ALGNAME JADE_KEM_mlkem_mlkem768_amd64_avx2_ALGNAME +#define JADE_KEM_ARCH JADE_KEM_mlkem_mlkem768_amd64_avx2_ARCH +#define JADE_KEM_IMPL JADE_KEM_mlkem_mlkem768_amd64_avx2_IMPL + +// this example program does the following: +// - creates a keypair (with the randomized api +// - encapsulates/decapsulates and checks that the shared secret is the same +// +// - it repeats the process using the derandomized ('derand') functions +// +int main(void) +{ + int r; + uint8_t public_key[JADE_KEM_PUBLICKEYBYTES]; + uint8_t secret_key[JADE_KEM_SECRETKEYBYTES]; + + uint8_t shared_secret_a[JADE_KEM_BYTES]; + uint8_t ciphertext[JADE_KEM_CIPHERTEXTBYTES]; + uint8_t shared_secret_b[JADE_KEM_BYTES]; + + uint8_t keypair_coins[JADE_KEM_KEYPAIRCOINBYTES]; + uint8_t enc_coins[JADE_KEM_ENCCOINBYTES]; + + // create key pair + r = jade_kem_keypair(public_key, secret_key); + assert(r == 0); + + // encapsulate + r = jade_kem_enc(ciphertext, shared_secret_a, public_key); + assert(r == 0); + + // decapsulate + r = jade_kem_dec(shared_secret_b, ciphertext, secret_key); + assert(r == 0); + assert(memcmp(shared_secret_a, shared_secret_b, JADE_KEM_BYTES) == 0); + + print_info(JADE_KEM_ALGNAME, JADE_KEM_ARCH, JADE_KEM_IMPL); + print_str_u8("secret_key", secret_key, JADE_KEM_SECRETKEYBYTES); + print_str_u8("public_key", public_key, JADE_KEM_PUBLICKEYBYTES); + print_str_u8("ciphertext", ciphertext, JADE_KEM_CIPHERTEXTBYTES); + print_str_u8("shared_secret", shared_secret_a, JADE_KEM_BYTES); + + // create key pair using derand function (random coins are given as input) + randombytes(keypair_coins, JADE_KEM_KEYPAIRCOINBYTES); + r = jade_kem_keypair_derand(public_key, secret_key, keypair_coins); + assert(r == 0); + + // encapsulate using derand function (random coins are given as input) + randombytes(enc_coins, JADE_KEM_ENCCOINBYTES); + r = jade_kem_enc_derand(ciphertext, shared_secret_a, public_key, enc_coins); + assert(r == 0); + + // decapsulate + r = jade_kem_dec(shared_secret_b, ciphertext, secret_key); + assert(r == 0); + assert(memcmp(shared_secret_a, shared_secret_b, JADE_KEM_BYTES) == 0); + + print_info(JADE_KEM_ALGNAME, JADE_KEM_ARCH, JADE_KEM_IMPL); + print_str_u8("keypair_derand_coins", keypair_coins, JADE_KEM_KEYPAIRCOINBYTES); + print_str_u8("secret_key_derand", secret_key, JADE_KEM_SECRETKEYBYTES); + print_str_u8("public_key_derand", public_key, JADE_KEM_PUBLICKEYBYTES); + + print_str_u8("enc_derand_coins", enc_coins, JADE_KEM_ENCCOINBYTES); + print_str_u8("ciphertext_derand", ciphertext, JADE_KEM_CIPHERTEXTBYTES); + print_str_u8("shared_secret_derand", shared_secret_a, JADE_KEM_BYTES); + + + + return 0; +} + diff --git a/code/jasmin/mlkem_avx2/extraction/Makefile b/code/jasmin/mlkem_avx2/extraction/Makefile index 51ce760c..51033d90 100644 --- a/code/jasmin/mlkem_avx2/extraction/Makefile +++ b/code/jasmin/mlkem_avx2/extraction/Makefile @@ -11,9 +11,9 @@ all: ec ec: $(JASMINC) ../jkem.jazz -oec jkem_avx2.ec \ - -ec jade_kem_mlkem_mlkem768_amd64_avx2v_keypair \ - -ec jade_kem_mlkem_mlkem768_amd64_avx2v_enc \ - -ec jade_kem_mlkem_mlkem768_amd64_avx2v_dec + -ec jade_kem_mlkem_mlkem768_amd64_avx2_keypair \ + -ec jade_kem_mlkem_mlkem768_amd64_avx2_enc \ + -ec jade_kem_mlkem_mlkem768_amd64_avx2_dec clean: rm -f *.ec diff --git a/code/jasmin/mlkem_avx2/extraction/jkem_avx2.ec b/code/jasmin/mlkem_avx2/extraction/jkem_avx2.ec index 104ed9a4..6ede73cd 100644 --- a/code/jasmin/mlkem_avx2/extraction/jkem_avx2.ec +++ b/code/jasmin/mlkem_avx2/extraction/jkem_avx2.ec @@ -5121,7 +5121,7 @@ module M(SC:Syscall_t) = { return (); } - proc jade_kem_mlkem_mlkem768_amd64_avx2v_keypair (public_key:W64.t, + proc jade_kem_mlkem_mlkem768_amd64_avx2_keypair (public_key:W64.t, secret_key:W64.t) : W64.t = { @@ -5144,7 +5144,7 @@ module M(SC:Syscall_t) = { return (r); } - proc jade_kem_mlkem_mlkem768_amd64_avx2v_enc (ciphertext:W64.t, + proc jade_kem_mlkem_mlkem768_amd64_avx2_enc (ciphertext:W64.t, shared_secret:W64.t, public_key:W64.t) : W64.t = { @@ -5169,7 +5169,7 @@ module M(SC:Syscall_t) = { return (r); } - proc jade_kem_mlkem_mlkem768_amd64_avx2v_dec (shared_secret:W64.t, + proc jade_kem_mlkem_mlkem768_amd64_avx2_dec (shared_secret:W64.t, ciphertext:W64.t, secret_key:W64.t) : W64.t = { diff --git a/code/jasmin/mlkem_avx2/gen_matrix.jazz b/code/jasmin/mlkem_avx2/jgen_matrix.jazz similarity index 50% rename from code/jasmin/mlkem_avx2/gen_matrix.jazz rename to code/jasmin/mlkem_avx2/jgen_matrix.jazz index 22b1ea24..8f444570 100644 --- a/code/jasmin/mlkem_avx2/gen_matrix.jazz +++ b/code/jasmin/mlkem_avx2/jgen_matrix.jazz @@ -1,35 +1,5 @@ require "gen_matrix.jinc" -/* -require "gen_matrix_old.jinc" -export fn gen_matrix_old_jazz(reg u64 ap, reg u64 seedp) -{ - stack u16[MLKEM_K*MLKEM_VECN] aa; - stack u8[MLKEM_SYMBYTES] seed; - reg u8 c; - reg u16 t; - inline int i; - stack u64 sap; - - sap = ap; - - for i = 0 to MLKEM_SYMBYTES - { - c = (u8)[seedp + i]; - seed[i] = c; - } - - aa = __gen_matrix_old(seed, 1); - - ap = sap; - - for i = 0 to MLKEM_K*MLKEM_VECN - { - t = aa[i]; - (u16)[ap + 2*i] = t; - } -} -*/ export fn gen_matrix_jazz(reg u64 ap, reg u64 seedp) { stack u16[MLKEM_K*MLKEM_VECN] aa; diff --git a/code/jasmin/mlkem_avx2/jkem.jazz b/code/jasmin/mlkem_avx2/jkem.jazz index ce77dcf4..13ba3cc9 100644 --- a/code/jasmin/mlkem_avx2/jkem.jazz +++ b/code/jasmin/mlkem_avx2/jkem.jazz @@ -1,6 +1,6 @@ require "kem.jinc" -export fn jade_kem_mlkem_mlkem768_amd64_avx2v_keypair_derand(reg u64 public_key secret_key coins) -> reg u64 +export fn jade_kem_mlkem_mlkem768_amd64_avx2_keypair_derand(reg u64 public_key secret_key coins) -> reg u64 { reg u64 r; stack u8[MLKEM_SYMBYTES*2] randomness; @@ -22,7 +22,7 @@ export fn jade_kem_mlkem_mlkem768_amd64_avx2v_keypair_derand(reg u64 public_key return r; } -export fn jade_kem_mlkem_mlkem768_amd64_avx2v_enc_derand(reg u64 ciphertext shared_secret public_key coins) -> reg u64 +export fn jade_kem_mlkem_mlkem768_amd64_avx2_enc_derand(reg u64 ciphertext shared_secret public_key coins) -> reg u64 { reg u64 r; stack u8[MLKEM_SYMBYTES] randomness; @@ -45,7 +45,7 @@ export fn jade_kem_mlkem_mlkem768_amd64_avx2v_enc_derand(reg u64 ciphertext shar return r; } -export fn jade_kem_mlkem_mlkem768_amd64_avx2v_keypair(reg u64 public_key secret_key) -> reg u64 +export fn jade_kem_mlkem_mlkem768_amd64_avx2_keypair(reg u64 public_key secret_key) -> reg u64 { reg u64 r; stack u8[MLKEM_SYMBYTES*2] randomness; @@ -61,7 +61,7 @@ export fn jade_kem_mlkem_mlkem768_amd64_avx2v_keypair(reg u64 public_key secret_ return r; } -export fn jade_kem_mlkem_mlkem768_amd64_avx2v_enc(reg u64 ciphertext shared_secret public_key) -> reg u64 +export fn jade_kem_mlkem_mlkem768_amd64_avx2_enc(reg u64 ciphertext shared_secret public_key) -> reg u64 { reg u64 r; stack u8[MLKEM_SYMBYTES] randomness; @@ -78,7 +78,7 @@ export fn jade_kem_mlkem_mlkem768_amd64_avx2v_enc(reg u64 ciphertext shared_secr return r; } -export fn jade_kem_mlkem_mlkem768_amd64_avx2v_dec(reg u64 shared_secret ciphertext secret_key) -> reg u64 +export fn jade_kem_mlkem_mlkem768_amd64_avx2_dec(reg u64 shared_secret ciphertext secret_key) -> reg u64 { reg u64 r; __crypto_kem_dec_jazz(shared_secret, ciphertext, secret_key); diff --git a/code/jasmin/mlkem_avx2/jspeed.jazz b/code/jasmin/mlkem_avx2/jspeed.jazz index 911a3d43..8f787640 100644 --- a/code/jasmin/mlkem_avx2/jspeed.jazz +++ b/code/jasmin/mlkem_avx2/jspeed.jazz @@ -5,193 +5,296 @@ require "indcpa.jinc" require "kem.jinc" require "verify.jinc" -/* Exported functions only for benchmarking */ -export fn gen_matrix_jazz(reg u64 ap, reg u64 seedp) +require "cycles.jinc" + +// note: this code needs to be reviewed and properly tested + +// exported functions only for benchmarking + +export fn gen_matrix_jazz(reg u64 ap seedp) -> reg u64 { - stack u16[MLKEM_K*MLKEM_VECN] aa; + stack u32[2] start end; + reg u64 t; + stack u64 aps; + stack u16[MLKEM_K*MLKEM_VECN] a; stack u8[MLKEM_SYMBYTES] seed; + reg u64 i; - aa = __gen_matrix(seed, 1); -} + aps = ap; + i=0; while(i < MLKEM_SYMBYTES){ seed[i] = (u8)[seedp + i]; i += 1; } -export fn poly_compress_jazz(reg u64 rp, reg u64 ap) -{ - stack u16[MLKEM_N] a; + start = tsc(); - a = _poly_compress(rp, a); -} + a = __gen_matrix(seed, 1); -export fn poly_decompress_jazz(reg u64 rp, reg u64 ap) -{ - stack u16[MLKEM_N] r; + end = tsc(); - r = _poly_decompress(r, ap); + ap = aps; + i=0; while(i < MLKEM_K*MLKEM_VECN){ (u16)[ap + 2*i] = a[i]; i += 1; } + + t = cycles(start, end); + return t; } -export fn poly_tomsg_jazz(reg u64 rp, reg u64 ap) +// ////////////////////////////////////////////////////////////////// + +export fn poly_getnoise_4x_jazz(reg u64 r0p r1p r2p r3p, reg u64 seedp, reg u8 nonce) -> reg u64 { - stack u16[MLKEM_N] a; + stack u32[2] start end; + reg u64 t; + stack u16[MLKEM_N] r0 r1 r2 r3; + stack u8[MLKEM_SYMBYTES] seed; + reg u64 i; - a = _poly_tomsg(rp, a); -} + () = #spill(r0p, r1p, r2p, r3p); + i=0; while(i < MLKEM_SYMBYTES){ seed[i] = (u8)[seedp + i]; i += 1; } -export fn poly_frommsg_jazz(reg u64 rp, reg u64 ap) -{ - stack u16[MLKEM_N] r; + start = tsc(); + + r0, r1, r2, r3 = _poly_getnoise_eta1_4x(r0, r1, r2, r3, seed, nonce); - r = _poly_frommsg(r, ap); + end = tsc(); + + () = #unspill(r0p, r1p, r2p, r3p); + + i=0; while(i < MLKEM_N) + { (u16)[r0p + 2*i] = r0[i]; + (u16)[r1p + 2*i] = r1[i]; + (u16)[r2p + 2*i] = r2[i]; + (u16)[r3p + 2*i] = r3[i]; + i+= 1; + } + + t = cycles(start, end); + return t; } -export fn poly_ntt_jazz(reg u64 rp) + +export fn poly_ntt_jazz(reg u64 rp) -> reg u64 { + stack u32[2] start end; + reg u64 t; stack u16[MLKEM_N] r; + reg u64 i; + + () = #spill(rp); + i=0; while(i < MLKEM_N){ r[i] = (u16)[rp + 2*i]; i += 1; } + + start = tsc(); r = _poly_ntt(r); + + end = tsc(); + + () = #unspill(rp); + i=0; while(i < MLKEM_N){ (u16)[rp + 2*i] = r[i]; i += 1; } + + t = cycles(start, end); + return t; } -export fn poly_invntt_jazz(reg u64 rp) + +export fn poly_invntt_jazz(reg u64 rp) -> reg u64 { + stack u32[2] start end; + reg u64 t; stack u16[MLKEM_N] r; + reg u64 i; + + () = #spill(rp); + i=0; while(i < MLKEM_N){ r[i] = (u16)[rp + 2*i]; i += 1; } + + start = tsc(); r = _poly_invntt(r); + + end = tsc(); + + () = #unspill(rp); + i=0; while(i < MLKEM_N){ (u16)[rp + 2*i] = r[i]; i += 1; } + + t = cycles(start, end); + return t; } -export fn poly_getnoise_jazz(reg u64 rp, reg u64 seedp, reg u8 nonce) +export fn poly_tomsg_jazz(reg u64 rp ap) -> reg u64 { - stack u16[MLKEM_N] r; - stack u8[MLKEM_SYMBYTES] seed; + stack u32[2] start end; + reg u64 t; + stack u16[MLKEM_N] a; + reg u64 i; + + () = #spill(ap); + i=0; while(i < MLKEM_N){ a[i] = (u16)[ap + 2*i]; i += 1; } + + start = tsc(); - //r = _poly_getnoise_eta1_4x(r, seed, nonce); + a = _poly_tomsg(rp, a); + + end = tsc(); + + () = #unspill(ap); + i=0; while(i < MLKEM_N){ (u16)[ap + 2*i] = a[i]; i += 1; } + + t = cycles(start, end); + return t; } -export fn poly_getnoise_4x_jazz(reg u64 r0 r1 r2 r3, reg u64 seedp, reg u8 nonce) +export fn poly_frommsg_jazz(reg u64 rp ap) -> reg u64 { - stack u16[MLKEM_N] r0 r1 r2 r3; - stack u8[MLKEM_SYMBYTES] seed; + stack u32[2] start end; + reg u64 t; + stack u16[MLKEM_N] r; + reg u64 i; - r0, r1, r2, r3 = _poly_getnoise_eta1_4x(r0, r1, r2, r3, seed, nonce); -} + () = #spill(rp); + i=0; while(i < MLKEM_N){ r[i] = (u16)[rp + 2*i]; i += 1; } + start = tsc(); + r = _poly_frommsg(r, ap); -export fn polyvec_decompress_jazz(reg u64 rp, reg u64 ap) -{ - stack u16[MLKEM_VECN] r; + end = tsc(); - r = __polyvec_decompress(ap); + () = #unspill(rp); + i=0; while(i < MLKEM_N){ (u16)[rp + 2*i] = r[i]; i += 1; } + + t = cycles(start, end); + return t; } -export fn polyvec_compress_jazz(reg u64 rp, reg u64 ap) +export fn poly_compress_jazz(reg u64 rp ap) -> reg u64 { - stack u16[MLKEM_VECN] a; + stack u32[2] start end; + reg u64 t; + stack u16[MLKEM_N] a; + reg u64 i; - __polyvec_compress(rp, a); -} + () = #spill(ap); + i=0; while(i < MLKEM_N){ a[i] = (u16)[ap + 2*i]; i += 1; } + start = tsc(); -export fn polyvec_pointwise_acc_jazz(reg u64 rp, reg u64 ap, reg u64 bp) + a = _poly_compress(rp, a); + + end = tsc(); + + () = #unspill(ap); + i=0; while(i < MLKEM_N){ (u16)[ap + 2*i] = a[i]; i += 1; } + + t = cycles(start, end); + return t; +} + +export fn poly_decompress_jazz(reg u64 rp ap) -> reg u64 { - stack u16[MLKEM_VECN] a; - stack u16[MLKEM_VECN] b; + stack u32[2] start end; + reg u64 t; stack u16[MLKEM_N] r; + reg u64 i; - r = __polyvec_pointwise_acc(r, a, b); -} + () = #spill(rp); + i=0; while(i < MLKEM_N){ r[i] = (u16)[rp + 2*i]; i += 1; } + start = tsc(); + + r = _poly_decompress(r, ap); + + end = tsc(); + + () = #unspill(rp); + i=0; while(i < MLKEM_N){ (u16)[rp + 2*i] = r[i]; i += 1; } + + t = cycles(start, end); + return t; -export fn indcpa_keypair_jazz(reg u64 pkp, reg u64 skp, reg u64 randomnessp) -{ - //__indcpa_keypair(pkp, skp, randomnessp); } +// ////////////////////////////////////////////////////////////////// -export fn indcpa_enc_jazz(reg u64 ctp, reg u64 msgp, reg u64 pkp, reg u64 coinsp) +export fn polyvec_pointwise_acc_jazz(reg u64 rp ap bp) -> reg u64 { - stack u16[MLKEM_VECN] pkpv sp ep bp; - stack u16[MLKEM_K*MLKEM_VECN] aat; - stack u16[MLKEM_N] k epp v; - stack u8[MLKEM_SYMBYTES] publicseed; - stack u8[MLKEM_SYMBYTES] noiseseed; + stack u32[2] start end; + reg u64 t; + stack u16[MLKEM_VECN] a; + stack u16[MLKEM_VECN] b; + stack u16[MLKEM_N] r; reg u64 i; - reg u8 c nonce; - stack u64 sctp; - sctp = ctp; + () = #spill(rp); + i=0; while(i < MLKEM_VECN){ a[i] = (u16)[ap + 2*i]; i += 1; } + i=0; while(i < MLKEM_VECN){ b[i] = (u16)[bp + 2*i]; i += 1; } - i = 0; - while (i < MLKEM_SYMBYTES) - { - c = (u8)[coinsp+i]; - noiseseed[(int)i] = c; - i += 1; - } + start = tsc(); - pkpv = __polyvec_frombytes(pkp); + r = __polyvec_pointwise_acc(r, a, b); - i = 0; - pkp += MLKEM_POLYVECBYTES; - while (i < MLKEM_SYMBYTES) - { - c = (u8)[pkp]; - publicseed[(int)i] = c; - pkp += 1; - i += 1; - } + end = tsc(); - k = _poly_frommsg(k, msgp); + () = #unspill(rp); + i=0; while(i < MLKEM_N){ (u16)[rp + 2*i] = r[i]; i += 1; } - aat = __gen_matrix(publicseed, 1); + t = cycles(start, end); + return t; +} - nonce = 0; - sp[0:MLKEM_N], sp[MLKEM_N:MLKEM_N], sp[2*MLKEM_N:MLKEM_N], ep[0:MLKEM_N] = _poly_getnoise_eta1_4x(sp[0:MLKEM_N], sp[MLKEM_N:MLKEM_N], sp[2*MLKEM_N:MLKEM_N], ep[0:MLKEM_N], noiseseed, nonce); +export fn polyvec_compress_jazz(reg u64 rp ap) -> reg u64 +{ + stack u32[2] start end; + reg u64 t; + stack u16[MLKEM_VECN] a; + reg u64 i; - nonce = 4; - ep[MLKEM_N:MLKEM_N], ep[2*MLKEM_N:MLKEM_N], epp, bp[0:MLKEM_N] = _poly_getnoise_eta1_4x(ep[MLKEM_N:MLKEM_N], ep[2*MLKEM_N:MLKEM_N], epp, bp[0:MLKEM_N], noiseseed, nonce); + i=0; while(i < MLKEM_VECN){ a[i] = (u16)[ap + 2*i]; i += 1; } - sp = __polyvec_ntt(sp); - - bp[0:MLKEM_N] = __polyvec_pointwise_acc(bp[0:MLKEM_N], aat[0:MLKEM_VECN], sp); - bp[MLKEM_N:MLKEM_N]= __polyvec_pointwise_acc(bp[MLKEM_N:MLKEM_N], aat[MLKEM_VECN:MLKEM_VECN], sp); - bp[2*MLKEM_N:MLKEM_N] = __polyvec_pointwise_acc(bp[2*MLKEM_N:MLKEM_N], aat[2*MLKEM_VECN:MLKEM_VECN], sp); - - v = __polyvec_pointwise_acc(v, pkpv, sp); + start = tsc(); - bp = __polyvec_invntt(bp); - v = _poly_invntt(v); + __polyvec_compress(rp, a); - bp = __polyvec_add2(bp, ep); - v = _poly_add2(v, epp); - v = _poly_add2(v, k); - bp = __polyvec_reduce(bp); - v = __poly_reduce(v); + end = tsc(); - ctp = sctp; - __polyvec_compress(ctp, bp); - ctp += MLKEM_POLYVECCOMPRESSEDBYTES; - v = _poly_compress(ctp, v); + t = cycles(start, end); + return t; } - -export fn indcpa_dec_jazz(reg u64 msgp, reg u64 ctp, reg u64 skp) +export fn polyvec_decompress_jazz(reg u64 rp ap) -> reg u64 { - __indcpa_dec_0(msgp, ctp, skp); + stack u32[2] start end; + reg u64 t; + stack u16[MLKEM_VECN] r; + reg u64 i; + + () = #spill(rp); + start = tsc(); + + r = __polyvec_decompress(ap); + + end = tsc(); + + () = #unspill(rp); + i=0; while(i < MLKEM_N){ (u16)[rp + 2*i] = r[i]; i += 1; } + + t = cycles(start, end); + return t; } -export fn crypto_kem_keypair_jazz(reg u64 pkp, reg u64 skp, reg u64 randomnessp) +// ////////////////////////////////////////////////////////////////// + +export fn crypto_kem_keypair_jazz(reg u64 pkp skp, reg ptr u8[MLKEM_SYMBYTES*2] randomnessp) { - //__crypto_kem_keypair_jazz(pkp, skp, randomnessp); + __crypto_kem_keypair_jazz(pkp, skp, randomnessp); } - -export fn crypto_kem_enc_jazz(reg u64 ctp, reg u64 shkp, reg u64 pkp, reg u64 randomnessp) +export fn crypto_kem_enc_jazz(reg u64 ctp shkp pkp, reg ptr u8[MLKEM_SYMBYTES] randomnessp) { - //__crypto_kem_enc_jazz(ctp, shkp, pkp, randomnessp); + __crypto_kem_enc_jazz(ctp, shkp, pkp, randomnessp); } -export fn crypto_kem_dec_jazz(reg u64 shkp, reg u64 ctp, reg u64 skp) +export fn crypto_kem_dec_jazz(reg u64 shkp ctp skp) { __crypto_kem_dec_jazz(shkp, ctp, skp); } + diff --git a/code/jasmin/mlkem_avx2/kem.h b/code/jasmin/mlkem_avx2/kem.h index c86b2540..130c142d 100644 --- a/code/jasmin/mlkem_avx2/kem.h +++ b/code/jasmin/mlkem_avx2/kem.h @@ -16,24 +16,24 @@ void crypto_kem_dec(unsigned char *m, const unsigned char *c, const unsigned char *sk); -void jade_kem_mlkem_mlkem768_amd64_avx2v_keypair_derand(unsigned char *pk, +void jade_kem_mlkem_mlkem768_amd64_avx2_keypair_derand(unsigned char *pk, unsigned char *sk, const unsigned char *randomness); -void jade_kem_mlkem_mlkem768_amd64_avx2v_enc_derand(unsigned char *c, +void jade_kem_mlkem_mlkem768_amd64_avx2_enc_derand(unsigned char *c, const unsigned char *m, const unsigned char *pk, const unsigned char *coins); -void jade_kem_mlkem_mlkem768_amd64_avx2v_keypair(unsigned char *pk, +void jade_kem_mlkem_mlkem768_amd64_avx2_keypair(unsigned char *pk, unsigned char *sk); -void jade_kem_mlkem_mlkem768_amd64_avx2v_enc(unsigned char *c, +void jade_kem_mlkem_mlkem768_amd64_avx2_enc(unsigned char *c, const unsigned char *m, const unsigned char *pk); -void jade_kem_mlkem_mlkem768_amd64_avx2v_dec(unsigned char *m, +void jade_kem_mlkem_mlkem768_amd64_avx2_dec(unsigned char *m, const unsigned char *c, const unsigned char *sk); diff --git a/code/jasmin/mlkem_avx2/ntt.h b/code/jasmin/mlkem_avx2/ntt.h index dd5498a2..eb24d751 100644 --- a/code/jasmin/mlkem_avx2/ntt.h +++ b/code/jasmin/mlkem_avx2/ntt.h @@ -8,7 +8,9 @@ extern int16_t zetas[128]; extern int16_t zetas_inv[128]; -void invntt(int16_t *poly); +void ntt(int16_t r[256]); +void invntt(int16_t r[256]); + void basemul(int16_t r[2], const int16_t a[2], const int16_t b[2], int16_t zeta); #define ntt_avx MLKEM_NAMESPACE(ntt_avx) @@ -39,7 +41,4 @@ void ntttobytes_avx(uint8_t *r, const int16_t *a, const uint16_t *qdata); #define nttfrombytes_avx MLKEM_NAMESPACE(nttfrombytes_avx) void nttfrombytes_avx(int16_t *r, const uint8_t *a, const uint16_t *qdata); - -void ntt(int16_t *poly); - #endif diff --git a/code/jasmin/mlkem_avx2/poly.h b/code/jasmin/mlkem_avx2/poly.h index a583f034..17960c94 100644 --- a/code/jasmin/mlkem_avx2/poly.h +++ b/code/jasmin/mlkem_avx2/poly.h @@ -22,7 +22,7 @@ void poly_frommsg(poly *r, const unsigned char msg[MLKEM_SYMBYTES]); void poly_tomsg(unsigned char msg[MLKEM_SYMBYTES], poly *r); void poly_getnoise_eta1(poly *r,const unsigned char *seed, unsigned char nonce); -void poly_getnoise_eta2(poly *r,const unsigned char *seed, unsigned char nonce); +void poly_getnoise_eta2(poly *r,const uint8_t seed[MLKEM_SYMBYTES], unsigned char nonce); void poly_ntt(poly *r); void poly_invntt(poly *r); diff --git a/code/jasmin/mlkem_avx2/speed.h b/code/jasmin/mlkem_avx2/speed.h index 070b30ac..e521f72d 100644 --- a/code/jasmin/mlkem_avx2/speed.h +++ b/code/jasmin/mlkem_avx2/speed.h @@ -12,28 +12,26 @@ typedef struct{ poly vec[MLKEM_K]; } polyvec; -void gen_matrix_jazz(polyvec *a, unsigned char *seed); +uint64_t gen_matrix_jazz(polyvec *a, unsigned char *seed); -/*Poly functions*/ -void poly_compress_jazz(unsigned char *r, poly *a); -void poly_decompress_jazz(poly *r, const unsigned char *a); +// Poly functions +uint64_t poly_getnoise_4x_jazz(poly *r0, poly *r1, poly *r2, poly *r3,const unsigned char *seed, unsigned char nonce); -void poly_frommsg_jazz(poly *r, const unsigned char msg[MLKEM_SYMBYTES]); -void poly_tomsg_jazz(unsigned char msg[MLKEM_SYMBYTES], poly *r); +uint64_t poly_ntt_jazz(poly *r); +uint64_t poly_invntt_jazz(poly *r); -void poly_getnoise_jazz(poly *r,const unsigned char *seed, unsigned char nonce); -void poly_getnoise_4x_jazz(poly *r0, poly *r1, poly *r2, poly *r3,const unsigned char *seed, unsigned char nonce); +uint64_t poly_frommsg_jazz(poly *r, const unsigned char msg[MLKEM_SYMBYTES]); +uint64_t poly_tomsg_jazz(unsigned char msg[MLKEM_SYMBYTES], poly *r); -void poly_ntt_jazz(poly *r); -void poly_invntt_jazz(poly *r); +uint64_t poly_compress_jazz(unsigned char *r, poly *a); +uint64_t poly_decompress_jazz(poly *r, const unsigned char *a); -/*Polyvec functions*/ -void polyvec_compress_jazz(unsigned char *r, polyvec *a); -void polyvec_decompress_jazz(polyvec *r, const unsigned char *a); +// Polyvec functions +uint64_t polyvec_pointwise_acc_jazz(poly *r, const polyvec *a, const polyvec *b); +uint64_t polyvec_compress_jazz(unsigned char *r, polyvec *a); +uint64_t polyvec_decompress_jazz(polyvec *r, const unsigned char *a); -void polyvec_pointwise_acc_jazz(poly *r, const polyvec *a, const polyvec *b); - -/* Indcpa functions*/ +// Indcpa functions void indcpa_keypair_jazz(unsigned char *pk, unsigned char *sk, const unsigned char *randomness); @@ -47,7 +45,7 @@ void indcpa_dec_jazz(unsigned char *m, const unsigned char *c, const unsigned char *sk); -/* KEM functions */ +// KEM functions void crypto_kem_keypair_jazz(unsigned char *pk, unsigned char *sk, const unsigned char *randomness); @@ -56,6 +54,7 @@ void crypto_kem_enc_jazz(unsigned char *c, const unsigned char *m, const unsigned char *pk, const unsigned char *coins); + void crypto_kem_dec_jazz(unsigned char *m, const unsigned char *c, const unsigned char *sk); diff --git a/code/jasmin/mlkem_avx2/test/speed_indcpa.c b/code/jasmin/mlkem_avx2/test/speed_indcpa.c deleted file mode 100644 index b1dc32f5..00000000 --- a/code/jasmin/mlkem_avx2/test/speed_indcpa.c +++ /dev/null @@ -1,100 +0,0 @@ -#include -#include -#include -#include - -#include "../params.h" -#include "../ntt.h" -#include "../indcpa.h" - -#define NRUNS 100 - -static inline uint64_t cpucycles(void) { - uint64_t result; - - asm volatile("rdtsc; shlq $32,%%rdx; orq %%rdx,%%rax" - : "=a" (result) : : "%rdx"); - - return result; -} - -static int cmp_uint64(const void *a, const void *b) { - if(*(uint64_t *)a < *(uint64_t *)b) return -1; - if(*(uint64_t *)a > *(uint64_t *)b) return 1; - return 0; -} - -static uint64_t median(uint64_t *l, size_t llen) { - qsort(l,llen,sizeof(uint64_t),cmp_uint64); - - if(llen%2) return l[llen/2]; - else return (l[llen/2-1]+l[llen/2])/2; -} - -static uint64_t average(uint64_t *t, size_t tlen) { - size_t i; - uint64_t acc=0; - - for(i=0;i #include #include +#include #include "../params.h" #include "../speed.h" -#define NRUNS 1000 +#define NRUNS 10000 static inline uint64_t cpucycles(void) { uint64_t result; @@ -72,6 +73,14 @@ void print_results(const char *s, uint64_t *t, size_t tlen) { printf("\n"); } +void print_results_jasmin(const char *s, uint64_t *t, size_t tlen) { + printf("%s\n", s); + printf("median: %llu cycles/ticks\n", (unsigned long long)median(t, tlen)); + printf("average: %llu cycles/ticks\n", (unsigned long long)average(t, tlen)); + printf("\n"); +} + + int main(void) { unsigned char sk[MLKEM_INDCPA_SECRETKEYBYTES]; @@ -86,134 +95,110 @@ int main(void) uint8_t seed[MLKEM_SYMBYTES] = {0}; poly ap; - FILE *urandom = fopen("/dev/urandom", "r"); - fread(randomness0, MLKEM_SYMBYTES, 1, urandom); - fread(randomness1, MLKEM_SYMBYTES, 1, urandom); - fread(message, MLKEM_SYMBYTES, 1, urandom); - uint64_t t[NRUNS], i; + size_t ri; - /* Test gen_matrix */ - for(i=0;i +#include #include "../fips202.h" +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + #define MAXINLEN 33 #define MAXOUTLEN 168 int main(void) { + int test_ok = 1, test_ok_shake256_128_33 = 1, test_ok_sha3512_32 = 1, + test_ok_shake128_absorb34 = 1, test_ok_shake128_squeezeblock = 1; + size_t test_iteration = 0; unsigned char in[MAXINLEN]; unsigned char out0[MAXOUTLEN]; unsigned char out1[MAXOUTLEN]; @@ -14,35 +22,83 @@ int main(void) int k; FILE *urandom = fopen("/dev/urandom", "r"); - fread(in, 1, sizeof(in), urandom); - shake256(out0, 128, in, 33); - shake256_128_33_jazz(out1, in); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + size_t ri = fread(in, 1, sizeof(in), urandom); + assert(ri == sizeof(in)); + + // + shake256(out0, 128, in, 33); + shake256_128_33_jazz(out1, in); - for(k=0;k<128;k++) - if(out0[k] != out1[k]) printf("error shake256 at %d: %d %d\n", k, out0[k], out1[k]); + for(k=0;k<128;k++) + { if(out0[k] != out1[k]) + { fprintf(stderr, "ERROR: shake256_128_33 at %d: %d %d\n", k, out0[k], out1[k]); + test_ok_shake256_128_33 = 0; + test_ok = 0; + } + } - sha3_512(out0, in, 32); - sha3_512_32_jazz(out1, in); + // + sha3_512(out0, in, 32); + sha3_512_32_jazz(out1, in); - for(k=0;k<64;k++) - if(out0[k] != out1[k]) printf("error sha3512 at %d: %d %d\n", k, out0[k], out1[k]); + for(k=0;k<64;k++) + { if(out0[k] != out1[k]) + { fprintf(stderr, "ERROR: sha3512 at %d: %d %d\n", k, out0[k], out1[k]); + test_ok_sha3512_32 = 0; + test_ok = 0; + } + } - shake128_absorb(state0, in, 34); - shake128_absorb34_jazz(state1, in); + // + shake128_absorb(state0, in, 34); + shake128_absorb34_jazz(state1, in); - for(k=0;k<25;k++) - if(state0[k] != state1[k]) printf("error shake128_absorb at %d: %lu %lu\n", k, state0[k], state1[k]); + for(k=0;k<25;k++) + { if(state0[k] != state1[k]) + { fprintf(stderr, "ERROR: shake128_absorb at %d: %lu %lu\n", k, state0[k], state1[k]); + test_ok_shake128_absorb34 = 0; + test_ok = 0; + } + } - shake128_squeezeblocks(out0, 1, state0); - shake128_squeezeblock_jazz(out1, state1); + // + shake128_squeezeblocks(out0, 1, state0); + shake128_squeezeblock_jazz(out1, state1); - for(k=0;k<25;k++) - if(state0[k] != state1[k]) printf("error shake128_squeezeblock (state) at %d: %lu %lu\n", k, state0[k], state1[k]); + for(k=0;k<25;k++) + { if(state0[k] != state1[k]) + { fprintf(stderr, "ERROR: shake128_squeezeblock (state) at %d: %lu %lu\n", k, state0[k], state1[k]); + test_ok_shake128_squeezeblock = 0; + test_ok = 0; + } + } - for(k=0;k - +#include #include "../params.h" #include "../ntt.h" #include "../indcpa.h" +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + int main(void) { + int test_ok = 1, test_ok_indcpa_keypair_sk = 1, test_ok_indcpa_keypair_pk = 1, + test_ok_indcpa_enc = 1, test_ok_indcpa_dec = 1, test_ok_decryption = 1; + size_t test_iteration = 0; + size_t ri; + unsigned char sk0[MLKEM_INDCPA_SECRETKEYBYTES]; unsigned char sk1[MLKEM_INDCPA_SECRETKEYBYTES]; unsigned char pk0[MLKEM_INDCPA_PUBLICKEYBYTES]; @@ -25,38 +34,88 @@ int main(void) unsigned char outmsg1[MLKEM_POLYVECBYTES]; FILE *urandom = fopen("/dev/urandom", "r"); - fread(randomness0, MLKEM_SYMBYTES, 1, urandom); - fread(randomness1, MLKEM_SYMBYTES, 1, urandom); - fread(message, MLKEM_SYMBYTES, 1, urandom); - fclose(urandom); - /* TEST KEYPAIR */ - indcpa_keypair_jazz(pk1, sk1, randomness0); - indcpa_keypair(pk0, sk0, randomness0); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + ri = fread(randomness0, MLKEM_SYMBYTES, 1, urandom); + assert(ri == 1); - for(int i=0;i -#include +#include +#include #include "../params.h" #include "../ntt.h" #include "../kem.h" +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + int main(void) { + int test_ok = 1, test_ok_kem_keypair_sk = 1, test_ok_kem_keypair_pk = 1, + test_ok_kem_enc_ct = 1, test_ok_kem_enc_ss = 1, + test_ok_kem_dec_success = 1, test_ok_kem_dec_failure = 1; + size_t test_iteration = 0; + size_t ri; + unsigned char sk0[MLKEM_SECRETKEYBYTES]; unsigned char sk1[MLKEM_SECRETKEYBYTES]; unsigned char pk0[MLKEM_PUBLICKEYBYTES]; @@ -20,52 +31,108 @@ int main(void) unsigned char randomness1[2*MLKEM_SYMBYTES]; FILE *urandom = fopen("/dev/urandom", "r"); - fread(randomness0, 2*MLKEM_SYMBYTES, 1, urandom); - fread(randomness1, 2*MLKEM_SYMBYTES, 1, urandom); - fclose(urandom); - - /* TEST KEYPAIR */ - jade_kem_mlkem_mlkem768_amd64_avx2v_keypair_derand(pk1, sk1, randomness0); - crypto_kem_keypair(pk0, sk0, randomness0); - - for(int i=0;i #include "../poly.h" -void poly_setrandom(poly *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); - for(int i=0;icoeffs[i] %= MLKEM_Q; - fclose(urandom); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_poly_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; poly a, b, r0; - poly_setrandom(&a); - poly_setrandom(&b); - - poly_add(&r0, &a, &b); - - poly_add2_jazz(&a, &b); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + poly_setrandom(&a); + poly_setrandom(&b); + + poly_add(&r0, &a, &b); + + poly_add2_jazz(&a, &b); + + for(int i=0;icoeffs, sizeof(int16_t), MLKEM_N, urandom); - for(int i=0;icoeffs[i] %= MLKEM_Q; - fclose(urandom); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_poly_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; poly a, b, r0, r1; - poly_setrandom(&a); - poly_setrandom(&b); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + poly_setrandom(&a); + poly_setrandom(&b); + + poly_basemul(&r0, &a, &b); + + poly_basemul_jazz(&r1, &a, &b); + + for(int i=0;i +#include #include "../poly.h" #include "../ntt.h" -void poly_setrandom(poly *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); - fclose(urandom); - poly_reduce(r); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_poly_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; unsigned char out0[128]; unsigned char out1[128]; poly a; - poly_setrandom(&a); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + poly_setrandom_nomodq(&a); - poly_compress(out0, &a); - poly_compress_jazz(out1, &a); + poly_compress(out0, &a); + poly_compress_jazz(out1, &a); - for(int i=0;i<128;i++) - { - if(out0[i] != out1[i]) - printf("error compress %d, %d, %d\n", i, out0[i], out1[i]); + for(int i=0;i<128;i++) + { if(out0[i] != out1[i]) + { fprintf(stderr, "ERROR: poly_compress: %d, %d, %d\n", i, out0[i], out1[i]); + test_ok = 0; + } + } + + test_iteration += 1; } + if(test_ok == 1) + { printf("OK: poly_compress\n"); } + return 0; } diff --git a/code/jasmin/mlkem_avx2/test/test_poly_csubq.c b/code/jasmin/mlkem_avx2/test/test_poly_csubq.c index fbaf8478..aa56ba63 100644 --- a/code/jasmin/mlkem_avx2/test/test_poly_csubq.c +++ b/code/jasmin/mlkem_avx2/test/test_poly_csubq.c @@ -1,32 +1,42 @@ #include +#include #include "../poly.h" #include "../ntt.h" -void poly_setrandom(poly *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); - fclose(urandom); - poly_reduce(r); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_poly_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; poly r0, r1; - poly_setrandom(&r0); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + poly_setrandom_nomodq(&r0); - for(int i=0;i +#include #include "../poly.h" #include "../ntt.h" +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + int main(void) { + int test_ok = 1; + size_t test_iteration = 0; + size_t ri; unsigned char in[MLKEM_POLYCOMPRESSEDBYTES]; poly r0, r1; - - FILE *urandom = fopen("/dev/urandom", "r"); - fread(in, 1, MLKEM_POLYCOMPRESSEDBYTES, urandom); - fclose(urandom); - poly_decompress(&r0, in); - poly_decompress_jazz(&r1, in); + FILE *urandom = fopen("/dev/urandom", "r"); - for(int i=0;i +#include #include "../poly.h" #include "../ntt.h" +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + int main(void) { + int test_ok = 1; + size_t test_iteration = 0; + size_t ri; unsigned char in[MLKEM_POLYBYTES]; poly r0, r1; - - FILE *urandom = fopen("/dev/urandom", "r"); - fread(in, 1, MLKEM_POLYBYTES, urandom); - fclose(urandom); - poly_frombytes(&r0, in); - poly_frombytes_jazz(&r1, in); + FILE *urandom = fopen("/dev/urandom", "r"); - for(int i=0;i +#include #include "../poly.h" #include "../ntt.h" -void poly_setrandom(poly *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); - for(int i=0;icoeffs[i] %= MLKEM_Q; - } - fclose(urandom); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_poly_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; poly r0, r1; - poly_setrandom(&r0); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + poly_setrandom(&r0); + for(int i=0;i +#include #include "../poly.h" #include "../ntt.h" +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + int main(void) { + int test_ok = 1; + size_t test_iteration = 0; + size_t ri; unsigned char in[32]; poly r0, r1; - - FILE *urandom = fopen("/dev/urandom", "r"); - fread(in, 1, 32, urandom); - fclose(urandom); - poly_frommsg(&r0, in); - poly_frommsg_jazz(&r1, in); + FILE *urandom = fopen("/dev/urandom", "r"); - for(int i=0;i +#include #include "../poly.h" #include "../ntt.h" #include "../params.h" +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif int main(void) { + int test_ok = 1, test_ok_poly_getnoise_eta1_4x = 1, + test_ok_poly_getnoise_eta1122_4x = 1; + size_t test_iteration = 0; + size_t ri; poly r0[4], r1[4]; unsigned char seed[MLKEM_SYMBYTES]; FILE *urandom = fopen("/dev/urandom", "r"); - fread(seed, 1, MLKEM_SYMBYTES, urandom); - fclose(urandom); - - poly_getnoise_eta1(r0, seed, 0); - poly_getnoise_eta1(&r0[1], seed, 1); - poly_getnoise_eta1(&r0[2], seed, 2); - poly_getnoise_eta1(&r0[3], seed, 3); - poly_getnoise_eta1_4x_jazz(r1, seed, 0); - for(int i=0;i<4;i++) + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) { - for(int j=0;j +#include #include "../poly.h" #include "../ntt.h" -void poly_setrandom(poly *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); - for(int i=0;icoeffs[i] %= MLKEM_Q; - } - fclose(urandom); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_poly_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; poly r0, r1; - poly_setrandom(&r0); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + poly_setrandom_mod2q(&r0); + for(int i=0;i +#include #include "../poly.h" #include "../ntt.h" -void poly_setrandom(poly *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); - for(int i=0;icoeffs[i] %= MLKEM_Q; - } - fclose(urandom); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_poly_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; poly r0, r1; - poly_setrandom(&r0); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + poly_setrandom_mod2q(&r0); - for(int i=0;i +#include #include "../poly.h" #include "../ntt.h" -void poly_setrandom(poly *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); - fclose(urandom); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_poly_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; poly r0, r1; - poly_setrandom(&r0); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + poly_setrandom_nomodq(&r0); - for(int i=0;i +#include +#include "../poly.h" + +// note: extend to *_setrandom_open; *_setrandom; *_setrandom_close; +// to not open the file so many times + +void poly_setrandom(poly *r) +{ + FILE *urandom = fopen("/dev/urandom", "r"); + size_t ri = fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); + assert(ri == MLKEM_N); + for(int i=0;icoeffs[i] %= MLKEM_Q; } + fclose(urandom); +} + +void poly_setrandom_mod2q(poly *r) +{ + FILE *urandom = fopen("/dev/urandom", "r"); + size_t ri = fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); + assert(ri == MLKEM_N); + for(int i=0;icoeffs[i] %= 2*MLKEM_Q; } + fclose(urandom); +} + +void poly_setrandom_nomodq(poly *r) +{ + FILE *urandom = fopen("/dev/urandom", "r"); + size_t ri = fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); + assert(ri == MLKEM_N); + fclose(urandom); + poly_reduce(r); +} + +#endif diff --git a/code/jasmin/mlkem_avx2/test/test_poly_sub.c b/code/jasmin/mlkem_avx2/test/test_poly_sub.c index f46326f2..08510804 100644 --- a/code/jasmin/mlkem_avx2/test/test_poly_sub.c +++ b/code/jasmin/mlkem_avx2/test/test_poly_sub.c @@ -1,29 +1,40 @@ #include +#include #include "../poly.h" -void poly_setrandom(poly *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); - for(int i=0;icoeffs[i] %= MLKEM_Q; - fclose(urandom); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_poly_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; poly a, b, r0, r1; - poly_setrandom(&a); - poly_setrandom(&b); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + poly_setrandom(&a); + poly_setrandom(&b); + + poly_sub(&r0, &a, &b); + + poly_sub_jazz(&r1, &a, &b); + + for(int i=0;i +#include #include "../poly.h" #include "../ntt.h" -void poly_setrandom(poly *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); - fclose(urandom); - poly_reduce(r); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_poly_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; unsigned char out0[MLKEM_POLYBYTES]; unsigned char out1[MLKEM_POLYBYTES]; poly a; - - poly_setrandom(&a); - - poly_tobytes(out0, &a); - poly_tobytes_jazz(out1, &a); - for(int i=0;i +#include #include "../poly.h" #include "../ntt.h" -void poly_setrandom(poly *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); - fclose(urandom); - poly_reduce(r); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_poly_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; unsigned char out0[MLKEM_INDCPA_MSGBYTES]; unsigned char out1[MLKEM_INDCPA_MSGBYTES]; poly a; - - poly_setrandom(&a); - - poly_tomsg(out0, &a); - poly_tomsg_jazz(out1, &a); - for(int i=0;i +#include #include "../polyvec.h" -void polyvec_setrandom(polyvec *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - for(int i=0;ivec[i].coeffs, sizeof(int16_t), MLKEM_N, urandom); - for(int i=0;ivec[i].coeffs[j] %= MLKEM_Q; - fclose(urandom); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_polyvec_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; polyvec a, b, r0; - polyvec_setrandom(&a); - polyvec_setrandom(&b); - - polyvec_add(&r0, &a, &b); - polyvec_add2_jazz(&a, &b); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + polyvec_setrandom(&a); + polyvec_setrandom(&b); + + polyvec_add(&r0, &a, &b); + polyvec_add2_jazz(&a, &b); + + for(int i=0;i +#include #include "../polyvec.h" #include "../ntt.h" -void polyvec_setrandom(polyvec *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - for(int i=0;ivec[i].coeffs, sizeof(int16_t), MLKEM_N, urandom); +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif - polyvec_reduce(r); - fclose(urandom); -} +#include "test_polyvec_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; unsigned char out0[MLKEM_POLYVECCOMPRESSEDBYTES]; unsigned char out1[MLKEM_POLYVECCOMPRESSEDBYTES]; polyvec a; - polyvec_setrandom(&a); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + polyvec_setrandom_reduce(&a); - polyvec_compress(out0, &a); - polyvec_compress_jazz(out1, &a); + polyvec_compress(out0, &a); + polyvec_compress_jazz(out1, &a); - for(int i=0;i +#include #include "../poly.h" #include "../polyvec.h" -void polyvec_setrandom(polyvec *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - for(int i=0;ivec[i].coeffs, sizeof(int16_t), MLKEM_N, urandom); - fclose(urandom); - polyvec_reduce(r); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_polyvec_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; polyvec r0, r1; - polyvec_setrandom(&r0); - - for(int i = 0;i +#include #include "../polyvec.h" +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + int main(void) { + int test_ok = 1; + size_t test_iteration = 0; + size_t ri; + unsigned char in[MLKEM_POLYVECCOMPRESSEDBYTES]; polyvec r0, r1; - + FILE *urandom = fopen("/dev/urandom", "r"); - fread(in, 1, MLKEM_POLYVECCOMPRESSEDBYTES, urandom); - fclose(urandom); - polyvec_decompress(&r0, in); - polyvec_decompress_jazz(&r1, in); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + ri = fread(in, 1, MLKEM_POLYVECCOMPRESSEDBYTES, urandom); + assert(ri == MLKEM_POLYVECCOMPRESSEDBYTES); + + polyvec_decompress(&r0, in); + polyvec_decompress_jazz(&r1, in); + + for(int i=0;i +#include #include "../polyvec.h" +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + int main(void) { + int test_ok = 1; + size_t test_iteration = 0; + size_t ri; unsigned char in[MLKEM_POLYVECBYTES]; polyvec r0, r1; - + FILE *urandom = fopen("/dev/urandom", "r"); - fread(in, 1, MLKEM_POLYVECBYTES, urandom); - fclose(urandom); - polyvec_frombytes(&r0, in); - polyvec_frombytes_jazz(&r1, in); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + ri = fread(in, 1, MLKEM_POLYVECBYTES, urandom); + assert(ri == MLKEM_POLYVECBYTES); + + polyvec_frombytes(&r0, in); + polyvec_frombytes_jazz(&r1, in); + + for(int i=0;i +#include #include "../ntt.h" #include "../poly.h" #include "../polyvec.h" -void polyvec_setrandom(polyvec *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - for(int i=0;ivec[i].coeffs, sizeof(int16_t), MLKEM_N, urandom); - for(int i=0;ivec[i].coeffs[j] %= MLKEM_Q; - fclose(urandom); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_polyvec_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; polyvec r0, r1; - polyvec_setrandom(&r0); - - for(int i = 0;i +#include #include "../ntt.h" #include "../poly.h" #include "../polyvec.h" -void polyvec_setrandom(polyvec *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - for(int i=0;ivec[i].coeffs, sizeof(int16_t), MLKEM_N, urandom); - for(int i=0;ivec[i].coeffs[j] %= 2*MLKEM_Q; - fclose(urandom); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_polyvec_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; polyvec r0, r1; - polyvec_setrandom(&r0); - - for(int i = 0;i +#include #include "../ntt.h" #include "../polyvec.h" +#include "../poly.h" -void polyvec_setrandom(polyvec *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - for(int i=0;ivec[i].coeffs, sizeof(int16_t), MLKEM_N, urandom); - for(int i=0;ivec[i].coeffs[j] %= MLKEM_Q; - fclose(urandom); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_polyvec_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; polyvec a, b; poly r0, r1; - polyvec_setrandom(&a); - polyvec_setrandom(&b); - - polyvec_pointwise_acc(&r0, &a, &b); - polyvec_pointwise_acc_jazz(&r1, &a, &b); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + polyvec_setrandom(&a); + polyvec_setrandom(&b); + + polyvec_pointwise_acc(&r0, &a, &b); + polyvec_pointwise_acc_jazz(&r1, &a, &b); for(int j=0;j +#include #include "../poly.h" #include "../polyvec.h" -void polyvec_setrandom(polyvec *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - for(int i=0;ivec[i].coeffs, sizeof(int16_t), MLKEM_N, urandom); - fclose(urandom); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_polyvec_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; polyvec r0, r1; - polyvec_setrandom(&r0); - - for(int i = 0;i +#include +#include "../polyvec.h" + +// note: extend to *_setrandom_open; *_setrandom; *_setrandom_close; +// to not open the file so many times + +void polyvec_setrandom(polyvec *r) +{ + FILE *urandom = fopen("/dev/urandom", "r"); + for(int i=0;ivec[i].coeffs, sizeof(int16_t), MLKEM_N, urandom); + assert(ri == MLKEM_N); + } + for(int i=0;ivec[i].coeffs[j] %= MLKEM_Q; + fclose(urandom); +} + +void polyvec_setrandom_reduce(polyvec *r) +{ + FILE *urandom = fopen("/dev/urandom", "r"); + for(int i=0;ivec[i].coeffs, sizeof(int16_t), MLKEM_N, urandom); + assert(ri == MLKEM_N); + } + polyvec_reduce(r); + fclose(urandom); +} + +void polyvec_setrandom_mod2q(polyvec *r) +{ + FILE *urandom = fopen("/dev/urandom", "r"); + for(int i=0;ivec[i].coeffs, sizeof(int16_t), MLKEM_N, urandom); + assert(ri == MLKEM_N); + } + for(int i=0;ivec[i].coeffs[j] %= 2*MLKEM_Q; + fclose(urandom); +} + +void polyvec_setrandom_nomodq(polyvec *r) +{ + FILE *urandom = fopen("/dev/urandom", "r"); + for(int i=0;ivec[i].coeffs, sizeof(int16_t), MLKEM_N, urandom); + assert(ri == MLKEM_N); + } + fclose(urandom); +} + +#endif diff --git a/code/jasmin/mlkem_avx2/test/test_polyvec_tobytes.c b/code/jasmin/mlkem_avx2/test/test_polyvec_tobytes.c index a23b160a..6a51f5c5 100644 --- a/code/jasmin/mlkem_avx2/test/test_polyvec_tobytes.c +++ b/code/jasmin/mlkem_avx2/test/test_polyvec_tobytes.c @@ -1,35 +1,42 @@ #include +#include #include "../polyvec.h" #include "../ntt.h" -#include "../reduce.h" -void polyvec_setrandom(polyvec *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - for(int i=0;ivec[i].coeffs, sizeof(int16_t), MLKEM_N, urandom); - - polyvec_reduce(r); +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif - fclose(urandom); -} +#include "test_polyvec_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; unsigned char out0[MLKEM_POLYVECBYTES]; unsigned char out1[MLKEM_POLYVECBYTES]; polyvec a; - - polyvec_setrandom(&a); - polyvec_tobytes(out0, &a); - polyvec_tobytes_jazz(out1, &a); - - for(int i=0;i stack u32[2] +{ + reg u64 l h; + stack u32[2] t; + + h, l = #RDTSC(); + + t[0] = (32u) l; + t[1] = (32u) h; + + return t; +} + +inline fn cycles(stack u32[2] start end) -> reg u64 +{ + reg u64 t; + + t = end[u64 0]; + t -= start[u64 0]; + + return t; +} + diff --git a/code/jasmin/mlkem_ref/example/.gitignore b/code/jasmin/mlkem_ref/example/.gitignore new file mode 100644 index 00000000..7ff73178 --- /dev/null +++ b/code/jasmin/mlkem_ref/example/.gitignore @@ -0,0 +1,2 @@ +example +jkem.s diff --git a/code/jasmin/mlkem_ref/example/Makefile b/code/jasmin/mlkem_ref/example/Makefile new file mode 100644 index 00000000..011e0ef7 --- /dev/null +++ b/code/jasmin/mlkem_ref/example/Makefile @@ -0,0 +1,35 @@ +include ../../../Makefile.conf + +CC ?= /usr/bin/gcc +CFLAGS := -Wall -Wextra -g -O3 -fomit-frame-pointer + +default: run-example + +RANDOMBYTES := $(PROJECT_DIR)/ext/randombytes/jasmin_syscall.o +$(RANDOMBYTES): $(PROJECT_DIR)/ext/randombytes/jasmin_syscall.c $(PROJECT_DIR)/ext/randombytes/jasmin_syscall.h + $(MAKE) -C $(@D) + +.PHONY: ../jkem.s +../jkem.s: + $(MAKE) -C $(@D) $(@F) + +jkem.s: ../jkem.s + cp $< $@ + + +example: example.c jkem.s api.h $(RANDOMBYTES) + $(CC) $(CFLAGS) -o $@ example.c jkem.s $(RANDOMBYTES) + +run-example: example + ./example + + + +.PHONY: clean distclean +clean: + rm -f example jkem.s + +distclean: clean + rm -f ../jkem.s + $(MAKE) -C $(dir $(RANDOMBYTES)) clean + diff --git a/code/jasmin/mlkem_ref/example/api.h b/code/jasmin/mlkem_ref/example/api.h new file mode 100644 index 00000000..5768789c --- /dev/null +++ b/code/jasmin/mlkem_ref/example/api.h @@ -0,0 +1,47 @@ +#ifndef JADE_KEM_mlkem_mlkem768_amd64_ref_API_H +#define JADE_KEM_mlkem_mlkem768_amd64_ref_API_H + +#include + +#define JADE_KEM_mlkem_mlkem768_amd64_ref_SECRETKEYBYTES 2400 +#define JADE_KEM_mlkem_mlkem768_amd64_ref_PUBLICKEYBYTES 1184 +#define JADE_KEM_mlkem_mlkem768_amd64_ref_CIPHERTEXTBYTES 1088 +#define JADE_KEM_mlkem_mlkem768_amd64_ref_KEYPAIRCOINBYTES 64 +#define JADE_KEM_mlkem_mlkem768_amd64_ref_ENCCOINBYTES 32 +#define JADE_KEM_mlkem_mlkem768_amd64_ref_BYTES 32 + +#define JADE_KEM_mlkem_mlkem768_amd64_ref_ALGNAME "mlkem768" +#define JADE_KEM_mlkem_mlkem768_amd64_ref_ARCH "amd64" +#define JADE_KEM_mlkem_mlkem768_amd64_ref_IMPL "ref" + +int jade_kem_mlkem_mlkem768_amd64_ref_keypair_derand( + uint8_t *public_key, + uint8_t *secret_key, + const uint8_t *coins +); + +int jade_kem_mlkem_mlkem768_amd64_ref_keypair( + uint8_t *public_key, + uint8_t *secret_key +); + +int jade_kem_mlkem_mlkem768_amd64_ref_enc_derand( + uint8_t *ciphertext, + uint8_t *shared_secret, + const uint8_t *public_key, + const uint8_t *coins +); + +int jade_kem_mlkem_mlkem768_amd64_ref_enc( + uint8_t *ciphertext, + uint8_t *shared_secret, + const uint8_t *public_key +); + +int jade_kem_mlkem_mlkem768_amd64_ref_dec( + uint8_t *shared_secret, + const uint8_t *ciphertext, + const uint8_t *secret_key +); + +#endif diff --git a/code/jasmin/mlkem_ref/example/example.c b/code/jasmin/mlkem_ref/example/example.c new file mode 100644 index 00000000..a92e2d1b --- /dev/null +++ b/code/jasmin/mlkem_ref/example/example.c @@ -0,0 +1,139 @@ +#include +#include +#include +#include +#include + +#include "api.h" + +// print functions +static void print_info(const char *algname, const char *arch, const char *impl) +{ + printf("// {\"%s\" : { architecture : \"%s\", implementation : \"%s\"} }", + algname, arch, impl); + printf("\n"); +} + +static void print_u8(const uint8_t *a, size_t l) +{ + size_t i; + + if(l == 0) + { return; } + + printf("{\n "); + for(i=0; i<(l-1); i++) + { printf("0x%02" PRIx8 ", ", a[i]); + if((i+1)%16 == 0) + { printf("\n "); } + } + + printf("0x%02" PRIx8 "\n};\n", a[i]); + return; +} + +static void print_str_u8(const char *str, const uint8_t *a, size_t l) +{ + if( l == 0 ) + { printf("uint8_t *%s = NULL;\n", str); + return; + } + + printf("uint8_t %s[%zu] = ",str, l); + print_u8(a, l); +} + +// randombytes implementation, in this case we use the __jasmin_syscall_randombytes__ +extern uint8_t* __jasmin_syscall_randombytes__(uint8_t* x, uint64_t xlen); + +uint8_t* randombytes(uint8_t* x, uint64_t xlen) +{ + return __jasmin_syscall_randombytes__(x, xlen); +} + +// mapping the fully namespaced macros from api.h into shorter names +#define JADE_KEM_SECRETKEYBYTES JADE_KEM_mlkem_mlkem768_amd64_ref_SECRETKEYBYTES +#define JADE_KEM_PUBLICKEYBYTES JADE_KEM_mlkem_mlkem768_amd64_ref_PUBLICKEYBYTES +#define JADE_KEM_CIPHERTEXTBYTES JADE_KEM_mlkem_mlkem768_amd64_ref_CIPHERTEXTBYTES +#define JADE_KEM_KEYPAIRCOINBYTES JADE_KEM_mlkem_mlkem768_amd64_ref_KEYPAIRCOINBYTES +#define JADE_KEM_ENCCOINBYTES JADE_KEM_mlkem_mlkem768_amd64_ref_ENCCOINBYTES +#define JADE_KEM_BYTES JADE_KEM_mlkem_mlkem768_amd64_ref_BYTES + +#define jade_kem_keypair jade_kem_mlkem_mlkem768_amd64_ref_keypair +#define jade_kem_enc jade_kem_mlkem_mlkem768_amd64_ref_enc +#define jade_kem_dec jade_kem_mlkem_mlkem768_amd64_ref_dec + +#define jade_kem_keypair_derand jade_kem_mlkem_mlkem768_amd64_ref_keypair_derand +#define jade_kem_enc_derand jade_kem_mlkem_mlkem768_amd64_ref_enc_derand + +#define JADE_KEM_ALGNAME JADE_KEM_mlkem_mlkem768_amd64_ref_ALGNAME +#define JADE_KEM_ARCH JADE_KEM_mlkem_mlkem768_amd64_ref_ARCH +#define JADE_KEM_IMPL JADE_KEM_mlkem_mlkem768_amd64_ref_IMPL + +// this example program does the following: +// - creates a keypair (with the randomized api +// - encapsulates/decapsulates and checks that the shared secret is the same +// +// - it repeats the process using the derandomized ('derand') functions +// +int main(void) +{ + int r; + uint8_t public_key[JADE_KEM_PUBLICKEYBYTES]; + uint8_t secret_key[JADE_KEM_SECRETKEYBYTES]; + + uint8_t shared_secret_a[JADE_KEM_BYTES]; + uint8_t ciphertext[JADE_KEM_CIPHERTEXTBYTES]; + uint8_t shared_secret_b[JADE_KEM_BYTES]; + + uint8_t keypair_coins[JADE_KEM_KEYPAIRCOINBYTES]; + uint8_t enc_coins[JADE_KEM_ENCCOINBYTES]; + + // create key pair + r = jade_kem_keypair(public_key, secret_key); + assert(r == 0); + + // encapsulate + r = jade_kem_enc(ciphertext, shared_secret_a, public_key); + assert(r == 0); + + // decapsulate + r = jade_kem_dec(shared_secret_b, ciphertext, secret_key); + assert(r == 0); + assert(memcmp(shared_secret_a, shared_secret_b, JADE_KEM_BYTES) == 0); + + print_info(JADE_KEM_ALGNAME, JADE_KEM_ARCH, JADE_KEM_IMPL); + print_str_u8("secret_key", secret_key, JADE_KEM_SECRETKEYBYTES); + print_str_u8("public_key", public_key, JADE_KEM_PUBLICKEYBYTES); + print_str_u8("ciphertext", ciphertext, JADE_KEM_CIPHERTEXTBYTES); + print_str_u8("shared_secret", shared_secret_a, JADE_KEM_BYTES); + + // create key pair using derand function (random coins are given as input) + randombytes(keypair_coins, JADE_KEM_KEYPAIRCOINBYTES); + r = jade_kem_keypair_derand(public_key, secret_key, keypair_coins); + assert(r == 0); + + // encapsulate using derand function (random coins are given as input) + randombytes(enc_coins, JADE_KEM_ENCCOINBYTES); + r = jade_kem_enc_derand(ciphertext, shared_secret_a, public_key, enc_coins); + assert(r == 0); + + // decapsulate + r = jade_kem_dec(shared_secret_b, ciphertext, secret_key); + assert(r == 0); + assert(memcmp(shared_secret_a, shared_secret_b, JADE_KEM_BYTES) == 0); + + print_info(JADE_KEM_ALGNAME, JADE_KEM_ARCH, JADE_KEM_IMPL); + print_str_u8("keypair_derand_coins", keypair_coins, JADE_KEM_KEYPAIRCOINBYTES); + print_str_u8("secret_key_derand", secret_key, JADE_KEM_SECRETKEYBYTES); + print_str_u8("public_key_derand", public_key, JADE_KEM_PUBLICKEYBYTES); + + print_str_u8("enc_derand_coins", enc_coins, JADE_KEM_ENCCOINBYTES); + print_str_u8("ciphertext_derand", ciphertext, JADE_KEM_CIPHERTEXTBYTES); + print_str_u8("shared_secret_derand", shared_secret_a, JADE_KEM_BYTES); + + + + return 0; +} + diff --git a/code/jasmin/mlkem_ref/jpoly.jazz b/code/jasmin/mlkem_ref/jpoly.jazz index 7d72519d..4ccd1492 100644 --- a/code/jasmin/mlkem_ref/jpoly.jazz +++ b/code/jasmin/mlkem_ref/jpoly.jazz @@ -7,9 +7,7 @@ export fn poly_compress_jazz(reg u64 rp, reg u64 ap) { inline int i; reg u16 t; - reg u8 c; stack u16[MLKEM_N] a; - stack u8[128] r; for i = 0 to MLKEM_N { t = (u16)[ap + 2*i]; @@ -23,9 +21,7 @@ export fn poly_decompress_jazz(reg u64 rp, reg u64 ap) { inline int i; reg u16 t; - reg u8 c; stack u16[MLKEM_N] r; - stack u8[128] a; r = _poly_decompress(r, ap); @@ -39,7 +35,6 @@ export fn poly_tobytes_jazz(reg u64 rp, reg u64 ap) { inline int i; reg u16 t; - reg u8 c; stack u16[MLKEM_N] a; for i = 0 to MLKEM_N { @@ -54,7 +49,6 @@ export fn poly_frombytes_jazz(reg u64 rp, reg u64 ap) { inline int i; reg u16 t; - reg u8 c; stack u16[MLKEM_N] r; r = _poly_frombytes(r, ap); @@ -69,9 +63,7 @@ export fn poly_tomsg_jazz(reg u64 rp, reg u64 ap) { inline int i; reg u16 t; - reg u8 c; stack u16[MLKEM_N] a; - stack u8[32] r; for i = 0 to MLKEM_N { t = (u16)[ap + 2*i]; @@ -85,7 +77,6 @@ export fn poly_frommsg_jazz(reg u64 rp, reg u64 ap) { inline int i; reg u16 t; - reg u8 c; stack u16[MLKEM_N] r; r = _poly_frommsg(r, ap); diff --git a/code/jasmin/mlkem_ref/jpolyvec.jazz b/code/jasmin/mlkem_ref/jpolyvec.jazz index d4080f03..b34cce62 100644 --- a/code/jasmin/mlkem_ref/jpolyvec.jazz +++ b/code/jasmin/mlkem_ref/jpolyvec.jazz @@ -7,7 +7,6 @@ export fn polyvec_tobytes_jazz(reg u64 rp, reg u64 ap) { inline int i; reg u16 t; - reg u8 c; stack u16[MLKEM_VECN] a; for i = 0 to MLKEM_VECN { @@ -23,7 +22,6 @@ export fn polyvec_decompress_jazz(reg u64 rp, reg u64 ap) { inline int i; reg u16 t; - reg u8 c; stack u16[MLKEM_VECN] r; r = __polyvec_decompress(ap); @@ -39,7 +37,6 @@ export fn polyvec_compress_jazz(reg u64 rp, reg u64 ap) { inline int i; reg u16 t; - reg u8 c; stack u16[MLKEM_VECN] a; for i = 0 to MLKEM_VECN { @@ -55,7 +52,6 @@ export fn polyvec_frombytes_jazz(reg u64 rp, reg u64 ap) { inline int i; reg u16 t; - reg u8 c; stack u16[MLKEM_VECN] r; r = __polyvec_frombytes(ap); diff --git a/code/jasmin/mlkem_ref/jspeed.jazz b/code/jasmin/mlkem_ref/jspeed.jazz new file mode 100644 index 00000000..d03fa4b0 --- /dev/null +++ b/code/jasmin/mlkem_ref/jspeed.jazz @@ -0,0 +1,297 @@ +require "poly.jinc" +require "polyvec.jinc" +require "gen_matrix.jinc" +require "indcpa.jinc" +require "kem.jinc" +require "verify.jinc" + +require "cycles.jinc" + +// note: this code needs to be reviewed and properly tested + +// exported functions only for benchmarking + +export fn gen_matrix_jazz(reg u64 ap seedp) -> reg u64 +{ + stack u32[2] start end; + reg u64 t; + stack u64 aps; + stack u16[MLKEM_K*MLKEM_VECN] a; + stack u8[MLKEM_SYMBYTES] seed; + reg u64 i; + + aps = ap; + i=0; while(i < MLKEM_SYMBYTES){ seed[i] = (u8)[seedp + i]; i += 1; } + + start = tsc(); + + a = __gen_matrix(seed, 1); + + end = tsc(); + + ap = aps; + i=0; while(i < MLKEM_K*MLKEM_VECN){ (u16)[ap + 2*i] = a[i]; i += 1; } + + t = cycles(start, end); + return t; +} + +// ////////////////////////////////////////////////////////////////// + +export fn poly_getnoise_jazz(reg u64 rp, reg u64 seedp, reg u8 nonce) -> reg u64 +{ + stack u32[2] start end; + reg u64 t; + stack u16[MLKEM_N] r; + stack u8[MLKEM_SYMBYTES] seed; + reg u64 i; + + nonce = nonce; + () = #spill(rp); + i=0; while(i < MLKEM_SYMBYTES){ seed[i] = (u8)[seedp + i]; i += 1; } + + start = tsc(); + + r = _poly_getnoise(r, seed, nonce); + + end = tsc(); + + () = #unspill(rp); + i=0; while(i < MLKEM_N) + { (u16)[rp + 2*i] = r[i]; + i+= 1; + } + + t = cycles(start, end); + return t; +} + + +export fn poly_ntt_jazz(reg u64 rp) -> reg u64 +{ + stack u32[2] start end; + reg u64 t; + stack u16[MLKEM_N] r; + reg u64 i; + + () = #spill(rp); + i=0; while(i < MLKEM_N){ r[i] = (u16)[rp + 2*i]; i += 1; } + + start = tsc(); + + r = _poly_ntt(r); + + end = tsc(); + + () = #unspill(rp); + i=0; while(i < MLKEM_N){ (u16)[rp + 2*i] = r[i]; i += 1; } + + t = cycles(start, end); + return t; +} + + +export fn poly_invntt_jazz(reg u64 rp) -> reg u64 +{ + stack u32[2] start end; + reg u64 t; + stack u16[MLKEM_N] r; + reg u64 i; + + () = #spill(rp); + i=0; while(i < MLKEM_N){ r[i] = (u16)[rp + 2*i]; i += 1; } + + start = tsc(); + + r = _poly_invntt(r); + + end = tsc(); + + () = #unspill(rp); + i=0; while(i < MLKEM_N){ (u16)[rp + 2*i] = r[i]; i += 1; } + + t = cycles(start, end); + return t; +} + + +export fn poly_tomsg_jazz(reg u64 rp ap) -> reg u64 +{ + stack u32[2] start end; + reg u64 t; + stack u16[MLKEM_N] a; + reg u64 i; + + () = #spill(ap); + i=0; while(i < MLKEM_N){ a[i] = (u16)[ap + 2*i]; i += 1; } + + start = tsc(); + + a = _poly_tomsg(rp, a); + + end = tsc(); + + () = #unspill(ap); + i=0; while(i < MLKEM_N){ (u16)[ap + 2*i] = a[i]; i += 1; } + + t = cycles(start, end); + return t; +} + + +export fn poly_frommsg_jazz(reg u64 rp ap) -> reg u64 +{ + stack u32[2] start end; + reg u64 t; + stack u16[MLKEM_N] r; + reg u64 i; + + () = #spill(rp); + i=0; while(i < MLKEM_N){ r[i] = (u16)[rp + 2*i]; i += 1; } + + start = tsc(); + + r = _poly_frommsg(r, ap); + + end = tsc(); + + () = #unspill(rp); + i=0; while(i < MLKEM_N){ (u16)[rp + 2*i] = r[i]; i += 1; } + + t = cycles(start, end); + return t; +} + + +export fn poly_compress_jazz(reg u64 rp ap) -> reg u64 +{ + stack u32[2] start end; + reg u64 t; + stack u16[MLKEM_N] a; + reg u64 i; + + () = #spill(ap); + i=0; while(i < MLKEM_N){ a[i] = (u16)[ap + 2*i]; i += 1; } + + start = tsc(); + + a = _poly_compress(rp, a); + + end = tsc(); + + () = #unspill(ap); + i=0; while(i < MLKEM_N){ (u16)[ap + 2*i] = a[i]; i += 1; } + + t = cycles(start, end); + return t; +} + +export fn poly_decompress_jazz(reg u64 rp ap) -> reg u64 +{ + stack u32[2] start end; + reg u64 t; + stack u16[MLKEM_N] r; + reg u64 i; + + () = #spill(rp); + i=0; while(i < MLKEM_N){ r[i] = (u16)[rp + 2*i]; i += 1; } + + start = tsc(); + + r = _poly_decompress(r, ap); + + end = tsc(); + + () = #unspill(rp); + i=0; while(i < MLKEM_N){ (u16)[rp + 2*i] = r[i]; i += 1; } + + t = cycles(start, end); + return t; + +} + +// ////////////////////////////////////////////////////////////////// + +export fn polyvec_pointwise_acc_jazz(reg u64 rp ap bp) -> reg u64 +{ + stack u32[2] start end; + reg u64 t; + stack u16[MLKEM_VECN] a; + stack u16[MLKEM_VECN] b; + stack u16[MLKEM_N] r; + reg u64 i; + + () = #spill(rp); + i=0; while(i < MLKEM_VECN){ a[i] = (u16)[ap + 2*i]; i += 1; } + i=0; while(i < MLKEM_VECN){ b[i] = (u16)[bp + 2*i]; i += 1; } + + start = tsc(); + + r = __polyvec_pointwise_acc(a, b); + + end = tsc(); + + () = #unspill(rp); + i=0; while(i < MLKEM_N){ (u16)[rp + 2*i] = r[i]; i += 1; } + + t = cycles(start, end); + return t; +} + +export fn polyvec_compress_jazz(reg u64 rp ap) -> reg u64 +{ + stack u32[2] start end; + reg u64 t; + stack u16[MLKEM_VECN] a; + reg u64 i; + + i=0; while(i < MLKEM_VECN){ a[i] = (u16)[ap + 2*i]; i += 1; } + + start = tsc(); + + __polyvec_compress(rp, a); + + end = tsc(); + + t = cycles(start, end); + return t; +} + +export fn polyvec_decompress_jazz(reg u64 rp ap) -> reg u64 +{ + stack u32[2] start end; + reg u64 t; + stack u16[MLKEM_VECN] r; + reg u64 i; + + () = #spill(rp); + start = tsc(); + + r = __polyvec_decompress(ap); + + end = tsc(); + + () = #unspill(rp); + i=0; while(i < MLKEM_N){ (u16)[rp + 2*i] = r[i]; i += 1; } + + t = cycles(start, end); + return t; +} + +// ////////////////////////////////////////////////////////////////// + +export fn crypto_kem_keypair_jazz(reg u64 pkp skp, reg ptr u8[MLKEM_SYMBYTES*2] randomnessp) +{ + __crypto_kem_keypair_jazz(pkp, skp, randomnessp); +} + +export fn crypto_kem_enc_jazz(reg u64 ctp shkp pkp, reg ptr u8[MLKEM_SYMBYTES] randomnessp) +{ + __crypto_kem_enc_jazz(ctp, shkp, pkp, randomnessp); +} + +export fn crypto_kem_dec_jazz(reg u64 shkp ctp skp) +{ + __crypto_kem_dec_jazz(shkp, ctp, skp); +} + diff --git a/code/jasmin/mlkem_ref/ntt.h b/code/jasmin/mlkem_ref/ntt.h index f7ad4605..aedaed09 100644 --- a/code/jasmin/mlkem_ref/ntt.h +++ b/code/jasmin/mlkem_ref/ntt.h @@ -6,10 +6,10 @@ extern int16_t zetas[128]; extern int16_t zetas_inv[128]; -void ntt(int16_t *poly); +void ntt(int16_t poly[256]); void splitntt(int16_t *poly); -void invntt(int16_t *poly); +void invntt(int16_t poly[256]); void basemul(int16_t r[2], const int16_t a[2], const int16_t b[2], int16_t zeta); #endif diff --git a/code/jasmin/mlkem_ref/speed.h b/code/jasmin/mlkem_ref/speed.h new file mode 100644 index 00000000..f03345d9 --- /dev/null +++ b/code/jasmin/mlkem_ref/speed.h @@ -0,0 +1,61 @@ +#ifndef SPEED_H +#define SPEED_H + +#include +#include "params.h" + +typedef struct{ + int16_t __attribute__((aligned(32))) coeffs[MLKEM_N]; +} poly; + +typedef struct{ + poly vec[MLKEM_K]; +} polyvec; + +uint64_t gen_matrix_jazz(polyvec *a, unsigned char *seed); + +// Poly functions +uint64_t poly_getnoise_jazz(poly *r,const unsigned char *seed, unsigned char nonce); + +uint64_t poly_ntt_jazz(poly *r); +uint64_t poly_invntt_jazz(poly *r); + +uint64_t poly_frommsg_jazz(poly *r, const unsigned char msg[MLKEM_SYMBYTES]); +uint64_t poly_tomsg_jazz(unsigned char msg[MLKEM_SYMBYTES], poly *r); + +uint64_t poly_compress_jazz(unsigned char *r, poly *a); +uint64_t poly_decompress_jazz(poly *r, const unsigned char *a); + +// Polyvec functions +uint64_t polyvec_pointwise_acc_jazz(poly *r, const polyvec *a, const polyvec *b); +uint64_t polyvec_compress_jazz(unsigned char *r, polyvec *a); +uint64_t polyvec_decompress_jazz(polyvec *r, const unsigned char *a); + +// Indcpa functions +void indcpa_keypair_jazz(unsigned char *pk, + unsigned char *sk, + const unsigned char *randomness); + +void indcpa_enc_jazz(unsigned char *c, + const unsigned char *m, + const unsigned char *pk, + const unsigned char *coins); + +void indcpa_dec_jazz(unsigned char *m, + const unsigned char *c, + const unsigned char *sk); + +// KEM functions +void crypto_kem_keypair_jazz(unsigned char *pk, + unsigned char *sk, + const unsigned char *randomness); + +void crypto_kem_enc_jazz(unsigned char *c, + const unsigned char *m, + const unsigned char *pk, + const unsigned char *coins); + +void crypto_kem_dec_jazz(unsigned char *m, + const unsigned char *c, + const unsigned char *sk); +#endif diff --git a/code/jasmin/mlkem_ref/test/speed_indcpa.c b/code/jasmin/mlkem_ref/test/speed_indcpa.c index b1dc32f5..9fb8fca5 100644 --- a/code/jasmin/mlkem_ref/test/speed_indcpa.c +++ b/code/jasmin/mlkem_ref/test/speed_indcpa.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "../params.h" #include "../ntt.h" @@ -65,11 +66,15 @@ int main(void) unsigned char outmsg[MLKEM_POLYVECBYTES]; uint64_t t[NRUNS], i; + size_t ri; FILE *urandom = fopen("/dev/urandom", "r"); - fread(randomness0, MLKEM_SYMBYTES, 1, urandom); - fread(randomness1, MLKEM_SYMBYTES, 1, urandom); - fread(message, MLKEM_SYMBYTES, 1, urandom); + ri = fread(randomness0, MLKEM_SYMBYTES, 1, urandom); + assert( ri == 1 ); + ri = fread(randomness1, MLKEM_SYMBYTES, 1, urandom); + assert( ri == 1 ); + ri = fread(message, MLKEM_SYMBYTES, 1, urandom); + assert( ri == 1 ); fclose(urandom); /* TEST KEYPAIR */ diff --git a/code/jasmin/mlkem_ref/test/speed_mlkem.c b/code/jasmin/mlkem_ref/test/speed_mlkem.c new file mode 100644 index 00000000..d70ff119 --- /dev/null +++ b/code/jasmin/mlkem_ref/test/speed_mlkem.c @@ -0,0 +1,226 @@ +#include +#include +#include +#include +#include + +#include "../params.h" +#include "../speed.h" + +#define NRUNS 10000 + +static inline uint64_t cpucycles(void) { + uint64_t result; + + asm volatile("rdtsc; shlq $32,%%rdx; orq %%rdx,%%rax" + : "=a" (result) : : "%rdx"); + + return result; +} + +static int cmp_uint64(const void *a, const void *b) { + if(*(uint64_t *)a < *(uint64_t *)b) return -1; + if(*(uint64_t *)a > *(uint64_t *)b) return 1; + return 0; +} + +static uint64_t median(uint64_t *l, size_t llen) { + qsort(l,llen,sizeof(uint64_t),cmp_uint64); + + if(llen%2) return l[llen/2]; + else return (l[llen/2-1]+l[llen/2])/2; +} + +static uint64_t average(uint64_t *t, size_t tlen) { + size_t i; + uint64_t acc=0; + + for(i=0;i +#include #include "../fips202.h" +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + #define MAXINLEN 33 #define MAXOUTLEN 168 int main(void) { + int test_ok = 1, test_ok_shake256_128_33 = 1, test_ok_sha3512_32 = 1, + test_ok_shake128_absorb34 = 1, test_ok_shake128_squeezeblock = 1; + size_t test_iteration = 0; unsigned char in[MAXINLEN]; unsigned char out0[MAXOUTLEN]; unsigned char out1[MAXOUTLEN]; @@ -14,35 +22,83 @@ int main(void) int k; FILE *urandom = fopen("/dev/urandom", "r"); - fread(in, 1, sizeof(in), urandom); - shake256(out0, 128, in, 33); - shake256_128_33_jazz(out1, in); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + size_t ri = fread(in, 1, sizeof(in), urandom); + assert(ri == sizeof(in)); + + // + shake256(out0, 128, in, 33); + shake256_128_33_jazz(out1, in); - for(k=0;k<128;k++) - if(out0[k] != out1[k]) printf("error shake256 at %d: %d %d\n", k, out0[k], out1[k]); + for(k=0;k<128;k++) + { if(out0[k] != out1[k]) + { fprintf(stderr, "ERROR: shake256_128_33 at %d: %d %d\n", k, out0[k], out1[k]); + test_ok_shake256_128_33 = 0; + test_ok = 0; + } + } - sha3_512(out0, in, 32); - sha3512_32_jazz(out1, in); + // + sha3_512(out0, in, 32); + sha3512_32_jazz(out1, in); - for(k=0;k<64;k++) - if(out0[k] != out1[k]) printf("error sha3512 at %d: %d %d\n", k, out0[k], out1[k]); + for(k=0;k<64;k++) + { if(out0[k] != out1[k]) + { fprintf(stderr, "ERROR: sha3512 at %d: %d %d\n", k, out0[k], out1[k]); + test_ok_sha3512_32 = 0; + test_ok = 0; + } + } - shake128_absorb(state0, in, 34); - shake128_absorb34_jazz(state1, in); + // + shake128_absorb(state0, in, 34); + shake128_absorb34_jazz(state1, in); - for(k=0;k<25;k++) - if(state0[k] != state1[k]) printf("error shake128_absorb at %d: %lu %lu\n", k, state0[k], state1[k]); + for(k=0;k<25;k++) + { if(state0[k] != state1[k]) + { fprintf(stderr, "ERROR: shake128_absorb at %d: %lu %lu\n", k, state0[k], state1[k]); + test_ok_shake128_absorb34 = 0; + test_ok = 0; + } + } - shake128_squeezeblocks(out0, 1, state0); - shake128_squeezeblock_jazz(out1, state1); + // + shake128_squeezeblocks(out0, 1, state0); + shake128_squeezeblock_jazz(out1, state1); - for(k=0;k<25;k++) - if(state0[k] != state1[k]) printf("error shake128_squeezeblock (state) at %d: %lu %lu\n", k, state0[k], state1[k]); + for(k=0;k<25;k++) + { if(state0[k] != state1[k]) + { fprintf(stderr, "ERROR: shake128_squeezeblock (state) at %d: %lu %lu\n", k, state0[k], state1[k]); + test_ok_shake128_squeezeblock = 0; + test_ok = 0; + } + } - for(k=0;k - +#include #include "../params.h" #include "../ntt.h" #include "../indcpa.h" +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + int main(void) { + int test_ok = 1, test_ok_indcpa_keypair_sk = 1, test_ok_indcpa_keypair_pk = 1, + test_ok_indcpa_enc = 1, test_ok_indcpa_dec = 1, test_ok_decryption = 1; + size_t test_iteration = 0; + size_t ri; + unsigned char sk0[MLKEM_INDCPA_SECRETKEYBYTES]; unsigned char sk1[MLKEM_INDCPA_SECRETKEYBYTES]; unsigned char pk0[MLKEM_INDCPA_PUBLICKEYBYTES]; @@ -25,38 +34,88 @@ int main(void) unsigned char outmsg1[MLKEM_POLYVECBYTES]; FILE *urandom = fopen("/dev/urandom", "r"); - fread(randomness0, MLKEM_SYMBYTES, 1, urandom); - fread(randomness1, MLKEM_SYMBYTES, 1, urandom); - fread(message, MLKEM_SYMBYTES, 1, urandom); - fclose(urandom); - /* TEST KEYPAIR */ - indcpa_keypair_jazz(pk1, sk1, randomness0); - indcpa_keypair(pk0, sk0, randomness0); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + ri = fread(randomness0, MLKEM_SYMBYTES, 1, urandom); + assert(ri == 1); - for(int i=0;i -#include +#include +#include #include "../params.h" #include "../ntt.h" #include "../kem.h" +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + int main(void) { + int test_ok = 1, test_ok_kem_keypair_sk = 1, test_ok_kem_keypair_pk = 1, + test_ok_kem_enc_ct = 1, test_ok_kem_enc_ss = 1, + test_ok_kem_dec_success = 1, test_ok_kem_dec_failure = 1; + size_t test_iteration = 0; + size_t ri; + unsigned char sk0[MLKEM_SECRETKEYBYTES]; unsigned char sk1[MLKEM_SECRETKEYBYTES]; unsigned char pk0[MLKEM_PUBLICKEYBYTES]; @@ -20,52 +31,108 @@ int main(void) unsigned char randomness1[2*MLKEM_SYMBYTES]; FILE *urandom = fopen("/dev/urandom", "r"); - fread(randomness0, 2*MLKEM_SYMBYTES, 1, urandom); - fread(randomness1, 2*MLKEM_SYMBYTES, 1, urandom); - fclose(urandom); - - /* TEST KEYPAIR */ - jade_kem_mlkem_mlkem768_amd64_ref_keypair_derand(pk1, sk1, randomness0); - crypto_kem_keypair(pk0, sk0, randomness0); - - for(int i=0;i #include "../poly.h" -void poly_setrandom(poly *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); - for(int i=0;icoeffs[i] %= MLKEM_Q; - fclose(urandom); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_poly_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; poly a, b, r0; - poly_setrandom(&a); - poly_setrandom(&b); - - poly_add(&r0, &a, &b); - - poly_add2_jazz(&a, &b); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + poly_setrandom(&a); + poly_setrandom(&b); + + poly_add(&r0, &a, &b); + + poly_add2_jazz(&a, &b); + + for(int i=0;icoeffs, sizeof(int16_t), MLKEM_N, urandom); - for(int i=0;icoeffs[i] %= MLKEM_Q; - fclose(urandom); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_poly_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; poly a, b, r0, r1; - poly_setrandom(&a); - poly_setrandom(&b); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + poly_setrandom(&a); + poly_setrandom(&b); + + poly_basemul(&r0, &a, &b); + + poly_basemul_jazz(&r1, &a, &b); + + for(int i=0;i +#include #include "../poly.h" #include "../ntt.h" -void poly_setrandom(poly *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); - fclose(urandom); - poly_reduce(r); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_poly_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; unsigned char out0[128]; unsigned char out1[128]; poly a; - poly_setrandom(&a); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + poly_setrandom_nomodq(&a); - poly_compress(out0, &a); - poly_compress_jazz(out1, &a); + poly_compress(out0, &a); + poly_compress_jazz(out1, &a); - for(int i=0;i<128;i++) - { - if(out0[i] != out1[i]) - printf("error compress %d, %d, %d\n", i, out0[i], out1[i]); + for(int i=0;i<128;i++) + { if(out0[i] != out1[i]) + { fprintf(stderr, "ERROR: poly_compress: %d, %d, %d\n", i, out0[i], out1[i]); + test_ok = 0; + } + } + + test_iteration += 1; } + if(test_ok == 1) + { printf("OK: poly_compress\n"); } + return 0; } diff --git a/code/jasmin/mlkem_ref/test/test_poly_csubq.c b/code/jasmin/mlkem_ref/test/test_poly_csubq.c index fbaf8478..aa56ba63 100644 --- a/code/jasmin/mlkem_ref/test/test_poly_csubq.c +++ b/code/jasmin/mlkem_ref/test/test_poly_csubq.c @@ -1,32 +1,42 @@ #include +#include #include "../poly.h" #include "../ntt.h" -void poly_setrandom(poly *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); - fclose(urandom); - poly_reduce(r); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_poly_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; poly r0, r1; - poly_setrandom(&r0); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + poly_setrandom_nomodq(&r0); - for(int i=0;i +#include #include "../poly.h" #include "../ntt.h" +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + int main(void) { + int test_ok = 1; + size_t test_iteration = 0; + size_t ri; unsigned char in[MLKEM_POLYCOMPRESSEDBYTES]; poly r0, r1; - - FILE *urandom = fopen("/dev/urandom", "r"); - fread(in, 1, MLKEM_POLYCOMPRESSEDBYTES, urandom); - fclose(urandom); - poly_decompress(&r0, in); - poly_decompress_jazz(&r1, in); + FILE *urandom = fopen("/dev/urandom", "r"); - for(int i=0;i +#include #include "../poly.h" #include "../ntt.h" +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + int main(void) { + int test_ok = 1; + size_t test_iteration = 0; + size_t ri; unsigned char in[MLKEM_POLYBYTES]; poly r0, r1; - - FILE *urandom = fopen("/dev/urandom", "r"); - fread(in, 1, MLKEM_POLYBYTES, urandom); - fclose(urandom); - poly_frombytes(&r0, in); - poly_frombytes_jazz(&r1, in); + FILE *urandom = fopen("/dev/urandom", "r"); - for(int i=0;i +#include #include "../poly.h" #include "../ntt.h" -void poly_setrandom(poly *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); - for(int i=0;icoeffs[i] %= MLKEM_Q; - } - fclose(urandom); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_poly_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; poly r0, r1; - poly_setrandom(&r0); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + poly_setrandom(&r0); + for(int i=0;i +#include #include "../poly.h" #include "../ntt.h" +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + int main(void) { + int test_ok = 1; + size_t test_iteration = 0; + size_t ri; unsigned char in[32]; poly r0, r1; - - FILE *urandom = fopen("/dev/urandom", "r"); - fread(in, 1, 32, urandom); - fclose(urandom); - poly_frommsg(&r0, in); - poly_frommsg_jazz(&r1, in); + FILE *urandom = fopen("/dev/urandom", "r"); - for(int i=0;i +#include #include "../poly.h" #include "../ntt.h" #include "../params.h" +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif int main(void) { + int test_ok = 1; + size_t test_iteration = 0; + size_t ri; poly r0, r1; unsigned char seed[MLKEM_SYMBYTES]; FILE *urandom = fopen("/dev/urandom", "r"); - fread(seed, 1, MLKEM_SYMBYTES, urandom); - fclose(urandom); - for(int i = 0; i < 1; i++) + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) { - poly_getnoise(&r0, seed, i); - poly_getnoise_jazz(&r1, seed, i); + ri = fread(seed, 1, MLKEM_SYMBYTES, urandom); + assert(ri == MLKEM_SYMBYTES); - for(int j=0;j +#include #include "../poly.h" #include "../ntt.h" -void poly_setrandom(poly *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); - for(int i=0;icoeffs[i] %= 2*MLKEM_Q; - } - fclose(urandom); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_poly_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; poly r0, r1; - poly_setrandom(&r0); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + poly_setrandom_mod2q(&r0); + for(int i=0;i +#include #include "../poly.h" #include "../ntt.h" -void poly_setrandom(poly *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); - for(int i=0;icoeffs[i] %= 2*MLKEM_Q; - } - fclose(urandom); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_poly_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; poly r0, r1; - poly_setrandom(&r0); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + poly_setrandom_mod2q(&r0); - for(int i=0;i +#include #include "../poly.h" #include "../ntt.h" -void poly_setrandom(poly *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); - fclose(urandom); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_poly_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; poly r0, r1; - poly_setrandom(&r0); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + poly_setrandom_nomodq(&r0); - for(int i=0;i +#include +#include "../poly.h" + +// note: extend to *_setrandom_open; *_setrandom; *_setrandom_close; +// to not open the file so many times + +void poly_setrandom(poly *r) +{ + FILE *urandom = fopen("/dev/urandom", "r"); + size_t ri = fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); + assert(ri == MLKEM_N); + for(int i=0;icoeffs[i] %= MLKEM_Q; } + fclose(urandom); +} + +void poly_setrandom_mod2q(poly *r) +{ + FILE *urandom = fopen("/dev/urandom", "r"); + size_t ri = fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); + assert(ri == MLKEM_N); + for(int i=0;icoeffs[i] %= 2*MLKEM_Q; } + fclose(urandom); +} + +void poly_setrandom_nomodq(poly *r) +{ + FILE *urandom = fopen("/dev/urandom", "r"); + size_t ri = fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); + assert(ri == MLKEM_N); + fclose(urandom); + poly_reduce(r); +} + +#endif diff --git a/code/jasmin/mlkem_ref/test/test_poly_sub.c b/code/jasmin/mlkem_ref/test/test_poly_sub.c index f46326f2..08510804 100644 --- a/code/jasmin/mlkem_ref/test/test_poly_sub.c +++ b/code/jasmin/mlkem_ref/test/test_poly_sub.c @@ -1,29 +1,40 @@ #include +#include #include "../poly.h" -void poly_setrandom(poly *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); - for(int i=0;icoeffs[i] %= MLKEM_Q; - fclose(urandom); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_poly_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; poly a, b, r0, r1; - poly_setrandom(&a); - poly_setrandom(&b); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + poly_setrandom(&a); + poly_setrandom(&b); + + poly_sub(&r0, &a, &b); + + poly_sub_jazz(&r1, &a, &b); + + for(int i=0;i +#include #include "../poly.h" #include "../ntt.h" -void poly_setrandom(poly *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); - fclose(urandom); - poly_reduce(r); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_poly_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; unsigned char out0[MLKEM_POLYBYTES]; unsigned char out1[MLKEM_POLYBYTES]; poly a; - - poly_setrandom(&a); - - poly_tobytes(out0, &a); - poly_tobytes_jazz(out1, &a); - for(int i=0;i +#include #include "../poly.h" #include "../ntt.h" -void poly_setrandom(poly *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - fread(r->coeffs, sizeof(int16_t), MLKEM_N, urandom); - fclose(urandom); - poly_reduce(r); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_poly_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; unsigned char out0[MLKEM_INDCPA_MSGBYTES]; unsigned char out1[MLKEM_INDCPA_MSGBYTES]; poly a; - - poly_setrandom(&a); - - poly_tomsg(out0, &a); - poly_tomsg_jazz(out1, &a); - for(int i=0;i +#include #include "../polyvec.h" -void polyvec_setrandom(polyvec *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - for(int i=0;ivec[i].coeffs, sizeof(int16_t), MLKEM_N, urandom); - for(int i=0;ivec[i].coeffs[j] %= MLKEM_Q; - fclose(urandom); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_polyvec_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; polyvec a, b, r0; - polyvec_setrandom(&a); - polyvec_setrandom(&b); - - polyvec_add(&r0, &a, &b); - polyvec_add2_jazz(&a, &b); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + polyvec_setrandom(&a); + polyvec_setrandom(&b); + + polyvec_add(&r0, &a, &b); + polyvec_add2_jazz(&a, &b); + + for(int i=0;i +#include #include "../polyvec.h" #include "../ntt.h" -void polyvec_setrandom(polyvec *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - for(int i=0;ivec[i].coeffs, sizeof(int16_t), MLKEM_N, urandom); +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif - polyvec_reduce(r); - fclose(urandom); -} +#include "test_polyvec_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; unsigned char out0[MLKEM_POLYVECCOMPRESSEDBYTES]; unsigned char out1[MLKEM_POLYVECCOMPRESSEDBYTES]; polyvec a; - polyvec_setrandom(&a); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + polyvec_setrandom_reduce(&a); - polyvec_compress(out0, &a); - polyvec_compress_jazz(out1, &a); + polyvec_compress(out0, &a); + polyvec_compress_jazz(out1, &a); - for(int i=0;i +#include #include "../poly.h" #include "../polyvec.h" -void polyvec_setrandom(polyvec *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - for(int i=0;ivec[i].coeffs, sizeof(int16_t), MLKEM_N, urandom); - fclose(urandom); - polyvec_reduce(r); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_polyvec_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; polyvec r0, r1; - polyvec_setrandom(&r0); - - for(int i = 0;i +#include #include "../polyvec.h" +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + int main(void) { + int test_ok = 1; + size_t test_iteration = 0; + size_t ri; + unsigned char in[MLKEM_POLYVECCOMPRESSEDBYTES]; polyvec r0, r1; - + FILE *urandom = fopen("/dev/urandom", "r"); - fread(in, 1, MLKEM_POLYVECCOMPRESSEDBYTES, urandom); - fclose(urandom); - polyvec_decompress(&r0, in); - polyvec_decompress_jazz(&r1, in); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + ri = fread(in, 1, MLKEM_POLYVECCOMPRESSEDBYTES, urandom); + assert(ri == MLKEM_POLYVECCOMPRESSEDBYTES); + + polyvec_decompress(&r0, in); + polyvec_decompress_jazz(&r1, in); + + for(int i=0;i +#include #include "../polyvec.h" +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + int main(void) { + int test_ok = 1; + size_t test_iteration = 0; + size_t ri; unsigned char in[MLKEM_POLYVECBYTES]; polyvec r0, r1; - + FILE *urandom = fopen("/dev/urandom", "r"); - fread(in, 1, MLKEM_POLYVECBYTES, urandom); - fclose(urandom); - polyvec_frombytes(&r0, in); - polyvec_frombytes_jazz(&r1, in); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + ri = fread(in, 1, MLKEM_POLYVECBYTES, urandom); + assert(ri == MLKEM_POLYVECBYTES); + + polyvec_frombytes(&r0, in); + polyvec_frombytes_jazz(&r1, in); + + for(int i=0;i +#include #include "../ntt.h" #include "../poly.h" #include "../polyvec.h" -void polyvec_setrandom(polyvec *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - for(int i=0;ivec[i].coeffs, sizeof(int16_t), MLKEM_N, urandom); - for(int i=0;ivec[i].coeffs[j] %= 2*MLKEM_Q; - fclose(urandom); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_polyvec_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; polyvec r0, r1; - polyvec_setrandom(&r0); - - for(int i = 0;i +#include #include "../ntt.h" #include "../poly.h" #include "../polyvec.h" -void polyvec_setrandom(polyvec *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - for(int i=0;ivec[i].coeffs, sizeof(int16_t), MLKEM_N, urandom); - for(int i=0;ivec[i].coeffs[j] %= 2*MLKEM_Q; - fclose(urandom); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_polyvec_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; polyvec r0, r1; - polyvec_setrandom(&r0); - - for(int i = 0;i +#include #include "../ntt.h" #include "../polyvec.h" -void polyvec_setrandom(polyvec *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - for(int i=0;ivec[i].coeffs, sizeof(int16_t), MLKEM_N, urandom); - for(int i=0;ivec[i].coeffs[j] %= MLKEM_Q; - fclose(urandom); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_polyvec_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; polyvec a, b; poly r0, r1; - polyvec_setrandom(&a); - polyvec_setrandom(&b); - - polyvec_pointwise_acc(&r0, &a, &b); - polyvec_pointwise_acc_jazz(&r1, &a, &b); + while(test_ok == 1 && test_iteration < TEST_ITERATIONS) + { + polyvec_setrandom(&a); + polyvec_setrandom(&b); + + polyvec_pointwise_acc(&r0, &a, &b); + polyvec_pointwise_acc_jazz(&r1, &a, &b); for(int j=0;j +#include #include "../poly.h" #include "../polyvec.h" -void polyvec_setrandom(polyvec *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - for(int i=0;ivec[i].coeffs, sizeof(int16_t), MLKEM_N, urandom); - fclose(urandom); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_polyvec_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; polyvec r0, r1; - polyvec_setrandom(&r0); - - for(int i = 0;i +#include +#include "../polyvec.h" + +// note: extend to *_setrandom_open; *_setrandom; *_setrandom_close; +// to not open the file so many times + +void polyvec_setrandom(polyvec *r) +{ + FILE *urandom = fopen("/dev/urandom", "r"); + for(int i=0;ivec[i].coeffs, sizeof(int16_t), MLKEM_N, urandom); + assert(ri == MLKEM_N); + } + for(int i=0;ivec[i].coeffs[j] %= MLKEM_Q; + fclose(urandom); +} + +void polyvec_setrandom_reduce(polyvec *r) +{ + FILE *urandom = fopen("/dev/urandom", "r"); + for(int i=0;ivec[i].coeffs, sizeof(int16_t), MLKEM_N, urandom); + assert(ri == MLKEM_N); + } + polyvec_reduce(r); + fclose(urandom); +} + +void polyvec_setrandom_mod2q(polyvec *r) +{ + FILE *urandom = fopen("/dev/urandom", "r"); + for(int i=0;ivec[i].coeffs, sizeof(int16_t), MLKEM_N, urandom); + assert(ri == MLKEM_N); + } + for(int i=0;ivec[i].coeffs[j] %= 2*MLKEM_Q; + fclose(urandom); +} + +void polyvec_setrandom_nomodq(polyvec *r) +{ + FILE *urandom = fopen("/dev/urandom", "r"); + for(int i=0;ivec[i].coeffs, sizeof(int16_t), MLKEM_N, urandom); + assert(ri == MLKEM_N); + } + fclose(urandom); +} + +#endif diff --git a/code/jasmin/mlkem_ref/test/test_polyvec_tobytes.c b/code/jasmin/mlkem_ref/test/test_polyvec_tobytes.c index d23acb49..d17f8941 100644 --- a/code/jasmin/mlkem_ref/test/test_polyvec_tobytes.c +++ b/code/jasmin/mlkem_ref/test/test_polyvec_tobytes.c @@ -1,34 +1,42 @@ #include +#include #include "../polyvec.h" #include "../ntt.h" -void polyvec_setrandom(polyvec *r) -{ - FILE *urandom = fopen("/dev/urandom", "r"); - for(int i=0;ivec[i].coeffs, sizeof(int16_t), MLKEM_N, urandom); - for(int i=0;ivec[i].coeffs[j] %= MLKEM_Q; - fclose(urandom); -} +#ifndef TEST_ITERATIONS +#define TEST_ITERATIONS 10000 +#endif + +#include "test_polyvec_setrandom.c" int main(void) { + int test_ok = 1; + size_t test_iteration = 0; unsigned char out0[MLKEM_POLYVECBYTES]; unsigned char out1[MLKEM_POLYVECBYTES]; polyvec a; - - polyvec_setrandom(&a); - polyvec_tobytes(out0, &a); - polyvec_tobytes_jazz(out1, &a); - - for(int i=0;i reg bool { pk, sk, ct, ss1, ss2, coins = setup(true); #[inline] - _ = avx::jade_kem_mlkem_mlkem768_amd64_avx2v_keypair_derand(pk, sk, coins); + _ = avx::jade_kem_mlkem_mlkem768_amd64_avx2_keypair_derand(pk, sk, coins); #[inline] - _ = avx::jade_kem_mlkem_mlkem768_amd64_avx2v_enc_derand(ct, ss1, pk, coins + 32); + _ = avx::jade_kem_mlkem_mlkem768_amd64_avx2_enc_derand(ct, ss1, pk, coins + 32); #[inline] - _ = avx::jade_kem_mlkem_mlkem768_amd64_avx2v_dec(ss2, ct, sk); + _ = avx::jade_kem_mlkem_mlkem768_amd64_avx2_dec(ss2, ct, sk); reg bool r; r = check(ss1, ss2); @@ -85,11 +85,11 @@ fn test_avx() -> reg bool { pk, sk, ct, ss1, ss2, _ = setup(false); #[inline] - _ = avx::jade_kem_mlkem_mlkem768_amd64_avx2v_keypair(pk, sk); + _ = avx::jade_kem_mlkem_mlkem768_amd64_avx2_keypair(pk, sk); #[inline] - _ = avx::jade_kem_mlkem_mlkem768_amd64_avx2v_enc(ct, ss1, pk); + _ = avx::jade_kem_mlkem_mlkem768_amd64_avx2_enc(ct, ss1, pk); #[inline] - _ = avx::jade_kem_mlkem_mlkem768_amd64_avx2v_dec(ss2, ct, sk); + _ = avx::jade_kem_mlkem_mlkem768_amd64_avx2_dec(ss2, ct, sk); reg bool r; r = check(ss1, ss2); diff --git a/ext/randombytes/Makefile b/ext/randombytes/Makefile new file mode 100644 index 00000000..cecfea6c --- /dev/null +++ b/ext/randombytes/Makefile @@ -0,0 +1,6 @@ +all: jasmin_syscall.o + +jasmin_syscall.o: jasmin_syscall.c jasmin_syscall.h + +clean: + rm -f jasmin_syscall.o diff --git a/ext/randombytes/jasmin_syscall.c b/ext/randombytes/jasmin_syscall.c new file mode 100644 index 00000000..628b900a --- /dev/null +++ b/ext/randombytes/jasmin_syscall.c @@ -0,0 +1,45 @@ + +#include "jasmin_syscall.h" + +#if defined(__linux__) + +#include +#include +#include + +uint8_t* __jasmin_syscall_randombytes__(uint8_t* _x, uint64_t xlen) +{ + int i; + uint8_t* x = _x; + + while (xlen > 0) { + if (xlen < 1048576) i = xlen; else i = 1048576; + + i = getrandom(x,i,0); + if (i < 1) { + sleep(1); + continue; + } + x += i; + xlen -= i; + } + + return _x; +} + +#endif + +#if defined(__APPLE__) + +#include + +#if !(defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200) +#error "macOS version not supported (>= 10.12)" +#endif + +uint8_t* __jasmin_syscall_randombytes__(uint8_t* x, uint64_t xlen){ + arc4random_buf(x, xlen); + return x; +} + +#endif diff --git a/ext/randombytes/jasmin_syscall.h b/ext/randombytes/jasmin_syscall.h new file mode 100644 index 00000000..5ba562a2 --- /dev/null +++ b/ext/randombytes/jasmin_syscall.h @@ -0,0 +1,8 @@ +#include +#ifndef JASMIN_SYSCALL +#define JASMIN_SYSCALL +/* FIXME this need xlen to be Uptr */ +uint8_t* __jasmin_syscall_randombytes__(uint8_t* x, uint64_t xlen) +asm("__jasmin_syscall_randombytes__"); + +#endif diff --git a/shell.nix b/shell.nix index 7f98f533..81ca9434 100644 --- a/shell.nix +++ b/shell.nix @@ -36,7 +36,7 @@ in mkShell ({ JASMINC = "${jasmin-compiler.bin}/bin/jasminc"; - JAZZCT = "${jasmin-compiler.bin}/bin/jazzct"; + JASMIN_CT = "${jasmin-compiler.bin}/bin/jazzct"; } // lib.optionalAttrs full { packages = [ ec